LLVM 用函数替换操作数
LLVM replace operand with function
使用 LLVM pass,我希望遍历 if(a==b)
形式的所有条件分支并将这些语句更改为 if(func(a)==func(b))
从而替换原始操作数 a
和 b
与函数调用 func(a)
和 func(b)
的结果。只要发现 if(a==b)
形式的 if
语句,就会出现这种情况。
这里的a
是操作数。我可以在我的 LLVM 传递中访问这个操作数,但我不能将它更改为函数的结果。我应该使用什么方法来实现这个。
可以假设a
和b
总是相同的类型并且func
接受任何类型的参数和returns相同类型的参数范围。为简单起见,还可以假设 a
和 b
是整数,并且 func
returns 也是整数。
详细说明我的评论(虽然还有一些地方还不清楚)
采用以下简化:
- 我们正在对整数进行运算
- 要调用的函数已经定义
我们可以在 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;
}
从那时起,您可以扩展和处理其他参数类型,具体取决于需要处理。
使用 LLVM pass,我希望遍历 if(a==b)
形式的所有条件分支并将这些语句更改为 if(func(a)==func(b))
从而替换原始操作数 a
和 b
与函数调用 func(a)
和 func(b)
的结果。只要发现 if(a==b)
形式的 if
语句,就会出现这种情况。
这里的a
是操作数。我可以在我的 LLVM 传递中访问这个操作数,但我不能将它更改为函数的结果。我应该使用什么方法来实现这个。
可以假设a
和b
总是相同的类型并且func
接受任何类型的参数和returns相同类型的参数范围。为简单起见,还可以假设 a
和 b
是整数,并且 func
returns 也是整数。
详细说明我的评论(虽然还有一些地方还不清楚)
采用以下简化:
- 我们正在对整数进行运算
- 要调用的函数已经定义
我们可以在 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;
}
从那时起,您可以扩展和处理其他参数类型,具体取决于需要处理。