我是LLVM的新手,我想知道你是否可以帮我构建一个复制LLVM IR中的指令,我面临的问题是无法使用(用户类)返回克隆的指令,这是正确的方法吗?还有其他方式(不包括http://llvm.org/docs/ExtendingLLVM.html) 我的通行证:
BasicBlock *B = I->getParent();
if (auto *op = dyn_cast<BinaryOperator>(&*I))
{
auto temp = op->clone();
B->getInstList().insert(op, temp);
temp->setName(op->getName());
if (temp->getOpcode() == Instruction::Add)
{
IRBuilder<> builder(temp); //building the cloned instruction
Value *lhs = temp->getOperand(0);
Value *rhs = temp->getOperand(1);
Value *add1 = builder.CreateAdd(lhs, rhs);
for (auto &v : temp->uses()) {
User *user = v.getUser(); // A User is anything with operands.
user->setOperand(v.getOperandNo(), add1);
}
}
}
答案 0 :(得分:2)
BasicBlock *B = I->getParent();
if (auto *op = dyn_cast<BinaryOperator>(&*I))
{
auto temp = op->clone();
B->getInstList().insert(op, temp);
temp->setName(op->getName());
此时您已成功克隆指令并将其插入原始指令所在的BasicBlock中。
if (temp->getOpcode() == Instruction::Add)
{
IRBuilder<> builder(temp); //building the cloned instruction
Value *lhs = temp->getOperand(0);
Value *rhs = temp->getOperand(1);
Value *add1 = builder.CreateAdd(lhs, rhs);
现在您正在构建IRBuilder
。 IRBuilder
作为帮助程序类,允许您在代码中轻松插入指令。但它不会构建你的临时指令。临时指令已经在调用clone
并将其插入BasicBlock
中。
您创建原始指令的另一个副本(add1
)。
for (auto &v : temp->uses()) {
User *user = v.getUser(); // A User is anything with operands.
user->setOperand(v.getOperandNo(), add1);
}
您要更新temp
的所有用户。但此时temp
没有用户。 temp
只是原始指令的克隆。您已经创建了两个未使用的原始指令副本,并将通过消除代码删除。
您要做的是用一份副本替换op
的所有用途。
实现此目的的更简单方法是使用RAUW ReplaceAllUsesWith
。
BasicBlock *B = I->getParent();
if (auto *op = dyn_cast<BinaryOperator>(&*I))
{
auto temp = op->clone();
B->getInstList().insert(op, temp);
temp->setName(op->getName());
op->replaceAllUsesWith(temp);
}
使用RAUW现在op已死(即没有用户)并且您的克隆指令处于活动状态。