【问题标题】:How to Insert a LLVM Instruction?如何插入 LLVM 指令?
【发布时间】:2012-11-02 10:42:48
【问题描述】:

我已经搜索了好几个小时,但找不到任何可以帮助我的东西。我正在做一个涉及 FunctionPass 的项目。我已经实现了一个 runOnFunction(Function &f) 方法,并且工作正常。基本上它需要:

1) 检测存储指令

2) 将store指令的内存地址转换为Integer

3) 使用按位与运算 (0000FFFF) 更改整数

4) 将整数转换回指针

到目前为止,我得到了以下内容:

 virtual bool runOnFunction(Function &F) {
  for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
    BasicBlock& b = *bb;
    for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
      if(StoreInst *si = dyn_cast<StoreInst>(&*i)) {
        PtrToIntInst* ptrToInt = new PtrToIntInst(si->getPointerOperand(), IntegerType::get(si->getContext(), 32), "", si);
      }
    }
  }
  return true;
}

我终其一生都无法弄清楚如何实际插入指令,甚至无法找到创建 AND 指令的方法。如果有人能指出我正确的方向,那就太好了。

提前致谢。

【问题讨论】:

    标签: c++ llvm llvm-ir


    【解决方案1】:

    我建议您看一下Programmer's Manual - 它对基础知识的介绍相当不错。

    特别是a section about creating and inserting new instructions。最简单的方法是提供一条现有指令作为新指令的构造函数的最后一个参数,然后该指令将在现有指令之前立即插入该指令。

    或者,如果您只想添加到它的末尾,您可以传递封闭的基本块(但请记住,您需要注意终止符!)。最后,您可以在封闭的基本块上调用getInstList(),然后在其中插入新指令insertpush_back

    顺便说一句,您不必遍历所有块,然后遍历每个块中的所有指令,您可以直接遍历指令;见the section about the instruction iterator in the programmer's manual

    【讨论】:

    • 在传递封闭基本块的情况下如何处理终结符?
    • @PatoBeltran 以这种方式添加指令不会触发基本块的验证,因此您可以在这些中间阶段拥有格式错误的基本块。在完成 pass 函数之前,请确保在末尾放置一个终止符。
    【解决方案2】:
     virtual bool runOnFunction(Function &F) {
      for (Function::iterator bb = F.begin(), bbe = F.end(); bb != bbe; ++bb) {
        BasicBlock &b = *bb;
        for (BasicBlock::iterator i = b.begin(), ie = b.end(); i != ie; ++i) {
          if (StoreInst *si = dyn_cast<StoreInst>(&*i)) {
            IRBuilder Builder(si);
            Value *StoreAddr = Builder.CreatePtrToInt(si->getPointerOperand(), Builder.getInt32Ty());
            Value *Masked = Builder.CreateAnd(StoreAddr, 0xffff);
            Value *AlignedAddr = Builder.CreateIntToPtr(Masked, si->getPointerOperand()->getType());
            // ...
          }
        }
      }
      return true;
    }
    

    【讨论】:

      【解决方案3】:

      您可以使用IRBuilder 在另一条指令之前或基本块的末尾轻松插入新指令。

      或者,如果您需要在另一条指令之后插入一条指令,则需要在包含基本块中使用instruction list

      BasicBlock *pb = ...; 
      Instruction *pi = ...; 
      Instruction *newInst = new Instruction(...); 
      
      pb->getInstList().insertAfter(pi, newInst);
      

      取自here的代码和解决方案。

      【讨论】:

        猜你喜欢
        • 2014-12-28
        • 1970-01-01
        • 2013-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多