Напишите пропуск для замены всех дополнений (BinaryОператор) в инструкциях llvm путем умножения

#c 11 #llvm #llvm-ir

Вопрос:

Я пытаюсь написать пропуск llvm и хочу заменить все инструкции, имеющие двоичный оператор сложения, теми же инструкциями, но с умножением вместо сложения. Я запускаю проход по нижеприведенному test.cpp код:

 int add( int x, int y) {
    x = x   y;
    // x = x   x;
    y = x   y;
    return x;
}
 

Я могу заменить все добавления умножением в приведенном выше коде, но когда я раскомментирую строку x = x x , она запускается и переходит в бесконечный цикл, и я понял, что бесконечный цикл находится for (auto amp;U : bop->uses()) в приведенном ниже коде llvm pass.

Итак, может ли кто-нибудь, пожалуйста, помочь мне изменить приведенный ниже код, чтобы он также заменил сложение умножением в инструкции для строки x = x x .

 bool runOnFunction(llvm::Function amp;Func) {
    std::string func_name = Func.getName();

    for(llvm::BasicBlockamp; b : Func ) {
        // llvm::errs() << "nBasic block '" << b.getName() << "' has " << b.size() << " instructions.n";
        for (llvm::BasicBlock::iterator DI = b.begin(); DI != b.end(); ) {
            llvm::Instruction *I = amp;*DI  ;
            // llvm::errs() << "Instruction : " << *I << "n";
            if(auto bop = llvm::dyn_cast<llvm::BinaryOperator>(I) ) {
                llvm::IRBuilder<> Builder(bop);

                auto op0 = bop->getOperand( 0 );
                auto op1 = bop->getOperand( 1 );
                unsigned op = bop->getOpcode();

                if( op == llvm::Instruction::Add ) {
                    llvm::Value *mul = Builder.CreateMul(op0, op1);
                    for (auto amp;U : bop->uses()) {
                        // llvm::errs() << "Instruction inside uses: " << *I << "n";
                        llvm::User *user = U.getUser();  // A User is anything with operands.
                        user->setOperand(U.getOperandNo(), mul);
                    }
                    I->eraseFromParent();
                }
            }
        }
    }
    return false;
}
 

Комментарии:

1. Я не присматривался внимательно… но такого рода ошибка часто возникает из-за того, что изменение списка во время его повторения приводит к удивительным результатам. Я уверен, что это работает, но то, как это работает, обычно удивляет людей. Попробуйте изменить свой код, чтобы сначала найти инструкции для изменения и добавить их в отдельную коллекцию. Затем повторите эту коллекцию.