我正在尝试复制指令(例如添加二进制操作),并在LLVM IR中显示它们,但是下面的代码只返回我构建的第一条指令(add1)。如何返回两条内置指令?< / p>
IRBuilder<> builder(op);
Value *lhs = op->getOperand(0);
Value *rhs = op->getOperand(1);
Value *add1 = builder.CreateAdd(lhs, rhs);
Value *add2 = builder.CreateAdd(lhs, rhs);
for (auto &U : op->uses()) {
User *user = U.getUser(); // A User is anything with operands.
user->setOperand(U.getOperandNo(), add1);
user->setOperand(U.getOperandNo(), add2);
}
答案 0 :(得分:1)
假设add
指令。你有BinaryOperator
有两个操作数,例如:%op = add i32 10, 32
您将其视为Value *lhs = op->getOperand(0);
和Value *rhs = op->getOperand(1);
所以这么好。现在,您要在实际添加之前创建两个新的add
tnstructions,因为您构建了IRBuilder
,并将op作为插入点。
%add1 = add i32 10, 32
%add2 = add i32 10, 32
%op = add i32 10, 32
最后,您更新了原始说明的用户,例如其他BinaryOperator
:%0 = mul i32 %op, %op
仔细查看循环时,您会看到将(add1和add2)都设置为User的同一操作数。在循环之后,乘法将看起来像%0 = mul i32 %add2, %add2
如果您在插入后直接插入说明插入的BasicBlock
,您会看到如下内容:
%add1 = add i32 10, 32
%add2 = add i32 10, 32
%op = add i32 10, 32
%0 = mul i32 %add2, %add2
但是如果你运行另一个执行死代码消除的LLVM Pass(例如,InstCombine),你最终会得到:
%add2 = add i32 10, 32
%0 = mul i32 %add2, %add2
因为add1
没有用户。您已立即将add1
的使用替换为add2
。由于现在所有用户都使用add2
而不是op
,因此操作系统也已消失。
从你的问题中很难猜出你的代码是什么意思,但这就是为什么你会在最终的IR中只看到你的一条指令。