添加llvm指令

时间:2016-02-04 10:45:19

标签: c++11 llvm

我是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);     
        }
    }
}

1 个答案:

答案 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);

现在您正在构建IRBuilderIRBuilder作为帮助程序类,允许您在代码中轻松插入指令。但它不会构建你的临时指令。临时指令已经在调用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已死(即没有用户)并且您的克隆指令处于活动状态。