添加 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 已经死了(即没有用户),而您的克隆指令仍然存在。