写一个pass替换所有的llvm指令

Write a pass to replace all llvm instructions

我正在尝试编写一个 llvm pass 以通过乘法替换所有 BinaryOperator 指令,问题是只有第一个指令被替换:

virtual bool runOnFunction(Function &F) {
  for (auto &B : F) {
     for (BasicBlock::iterator DI = B.begin(); DI != B.end(); ) {
      Instruction *Inst = DI++;

      if (auto *op = dyn_cast<BinaryOperator>(&*Inst)) {
        // Insert at the point where the instruction `op` appears.
        IRBuilder<> builder(op);

        // Make a multiply with the same operands as `op`.
        Value *lhs = op->getOperand(0);
        Value *rhs = op->getOperand(1);
        Value *mul = builder.CreateMul(lhs, rhs);

        // Everywhere the old instruction was used as an operand, use our
        // new multiply instruction instead.
        for (auto &U : op->uses()) {
          User *user = U.getUser();  // A User is anything with operands.
          user->setOperand(U.getOperandNo(), mul);
        }


        // We modified the code.
        return true;
      }


    }
  }

  return false;
}

试试这个

virtual bool runOnFunction(Function &F) {
  bool bModified = false;
 for (auto &B : F) {
  for (BasicBlock::iterator DI = B.begin(); DI != B.end(); ) {
   Instruction *Inst = DI++;

   if (auto *op = dyn_cast<BinaryOperator>(&*Inst)) {
    // Insert at the point where the instruction `op` appears.
    IRBuilder<> builder(op);

    // Make a multiply with the same operands as `op`.
    Value *lhs = op->getOperand(0);
    Value *rhs = op->getOperand(1);
    Value *mul = builder.CreateMul(lhs, rhs);

    // Everywhere the old instruction was used as an operand, use our
    // new multiply instruction instead.
    for (auto &U : op->uses()) {
      User *user = U.getUser();  // A User is anything with operands.
      user->setOperand(U.getOperandNo(), mul);
     }

    // We modified the code.
    bModified |= true;
    }
   }
 }
 return bModified;
}

此代码完成工作:

 for (BasicBlock::iterator DI = B.begin(); DI != B.end(); ) {

  Instruction *Inst = DI++;

  if (auto *op = dyn_cast<BinaryOperator>(&*Inst)) {
    // Insert at the point where the instruction `op` appears.
    IRBuilder<> builder(op);

    // Make a multiply with the same operands as `op`.
    Value *lhs = op->getOperand(0);
    Value *rhs = op->getOperand(1);
    Value *mul = builder.CreateMul(lhs, rhs);

    // Everywhere the old instruction was used as an operand, use our
    // new multiply instruction instead.
    for (auto &U : op->uses()) {
      User *user = U.getUser();  // A User is anything with operands.
      user->setOperand(U.getOperandNo(), mul);
    }

    // We modified the code.

  }

  return true;
}