LLVM用函数替换操作数

问题描述 投票:0回答:1

使用LLVM传递,我希望迭代if(a==b)形式的所有条件分支,并将这些语句更改为if(func(a)==func(b)),从而用函数调用ab的结果替换原始操作数func(a)func(b)。这应该发生在找到if形式的if(a==b)声明的任何地方。

这里a是操作数。我可以在LLVM传递中访问此操作数,但我无法将其更改为函数的结果。我应该采用什么方法来实现这一目标。

可以假设ab总是相同类型,func接受任何类型的参数并返回相同类型的参数。为简单起见,也可以假设ab是整数,func也返回整数。

c++ llvm llvm-clang llvm-ir
1个回答
1
投票

阐述我的评论(虽然有些方面仍不清楚)

采用以下简化:

  • 我们在整数上运作
  • 要调用的函数已经定义

我们可以在llvm::Function传递中做这样的事情:

bool runOnFunction(llvm::Function &CurFunc) override {
    bool hasChanged = false;

    // the llvm::Function to be called could be specified here
    auto *toCallFunc = [...];

    for (auto &bb : CurFunc) {
      auto *ti = bb.getTerminator();
      auto *bri = llvm::dyn_cast<llvm::BranchInst>(ti);
      if (!bri)
        continue;
      if (!bri->isConditional())
        continue;

      auto *cond = bri->getCondition();

      // please note that this cast is for integer comparisons
      // adjust according to your needs
      auto cmpi = llvm::dyn_cast<llvm::ICmpInst>(cond);
      if (!cmpi)
        continue;

      auto *opA = cmpi->getOperand(0);
      auto *opB = cmpi->getOperand(1);

      auto argsA = llvm::ArrayRef<llvm::Value *>(&opA, 1);
      auto argsB = llvm::ArrayRef<llvm::Value *>(&opB, 1);

      // note the insertion before the comparison operation
      auto *ciA = llvm::CallInst(toCallFunc, argsA, "funcA", cmpi);
      auto *ciB = llvm::CallInst(toCallFunc, argsB, "funcB", cmpi);

      cmpi->setOperand(1, opA);
      cmpi->setOperand(1, opB);
      hasChanged |= true;
    }

    return hasChanged;
  }

从那时起,您可以扩展和处理其他参数类型,具体取决于所需的处理。

© www.soinside.com 2019 - 2024. All rights reserved.