添加 llvm 指令
Add an llvm instruction
我是 LLVM 的新手,我想知道你是否可以帮助我在 LLVM IR 中构建一个重复指令的传递,我面临的问题是无法使用(用户 class), 这是正确的方法吗?还有其他方法吗(不包括这个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);
}
}
}
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
作为助手 class 可以让您轻松地在代码中插入指令。但它不会构建您的临时指令。通过调用 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 已经死了(即没有用户),而您的克隆指令仍然存在。
我是 LLVM 的新手,我想知道你是否可以帮助我在 LLVM IR 中构建一个重复指令的传递,我面临的问题是无法使用(用户 class), 这是正确的方法吗?还有其他方法吗(不包括这个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);
}
}
}
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
作为助手 class 可以让您轻松地在代码中插入指令。但它不会构建您的临时指令。通过调用 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 已经死了(即没有用户),而您的克隆指令仍然存在。