LLVM IRBuilder 学习笔记

本文详细介绍了IRBuilder,一个用于生成LLVMIR的类,包括其与Module和LLVMContext的关系,插入点管理,以及各种操作方法,如构造函数、全局变量生成和不同类型的插入。特别强调了IRBuilder的非线程安全性和插入点的设定方式。
摘要由CSDN通过智能技术生成

Basic

IRBuilder 是用于帮助生成 LLVM IR 的类。 一个 module 和一个 LLVM context 是一一对应的关系。

IR Builder 在 module, function, basic block 中跟踪下一行指令的插入位置 ( 插入点 )。

它还可以插入对应 C 标准库函数的调用, 创建全局变量或函数,以及内联汇编代码。

要注意 IR Builder 不是线程安全的。 在多线程生成代码时, 每个线程都要分配独立的 context, module 和 IR Builder。

IRBuilderBase

这个类代码量有点大, 头文件中声明就用了 2000 多行...

属性

protected:
  BasicBlock *BB;
  BasicBlock::iterator InsertPt;
  LLVMContext &Context;
  const IRBuilderFolder &Folder;
  const IRBuilderDefaultInserter &Inserter;

  MDNode *DefaultFPMathTag;
  FastMathFlags FMF;

  bool IsFPConstrained = false;
  fp::ExceptionBehavior DefaultConstrainedExcept = fp::ebStrict;
  RoundingMode DefaultConstrainedRounding = RoundingMode::Dynamic;

  ArrayRef<OperandBundleDef> DefaultOperandBundles;

private:

 SmallVector<std::pair<unsigned, MDNode *>, 2> MetadataToCopy;

方法

可以分为以下几种:

  1. 构造函数
  2. 元属性相关
  3. 插入点相关
  4. debug 定位信息相关
  5. 生成 全局变量 的方法
  6. 生成 类型 的方法
  7. 生成 常量 的方法
  8. 生成 Intrinsic 的方法
  9. 生成 向量操作 的方法
  10. 生成 控制指令 的方法
  11. 生成 二元操作 的方法
  12. 生成 内存指令 的方法
  13. 生成 类型转换操作 的方法
  14. 生成比较指令的方法
  15. 生成其它指令的方法

插入点相关

  /// Clear the insertion point: created instructions will not be
  /// inserted into a block.
  void ClearInsertionPoint() {
    BB = nullptr;
    InsertPt = BasicBlock::iterator();
  }

  BasicBlock *GetInsertBlock() const { return BB; }
  BasicBlock::iterator GetInsertPoint() const { return InsertPt; }

还有一系列 SetInsertPoint 的变体和重载

  /// This specifies that created instructions should be appended to the
  /// end of the specified block.

  void SetInsertPoint(BasicBlock *TheBB) {
    BB = TheBB;
    InsertPt = BB->end();
  }

  /// This specifies that created instructions should be inserted before
  /// the specified instruction.
  void SetInsertPoint(Instruction *I) {
    BB = I->getParent();
    InsertPt = I->getIterator();
    assert(InsertPt != BB->end() && "Can't read debug loc from end()");
    SetCurrentDebugLocation(I->getStableDebugLoc());
  }

  /// This specifies that created instructions should be inserted at the
  /// specified point.
  void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
    BB = TheBB;
    InsertPt = IP;
    if (IP != TheBB->end())
      SetCurrentDebugLocation(IP->getStableDebugLoc());
  }

  /// This specifies that created instructions should be inserted at
  /// the specified point, but also requires that \p IP is dereferencable.
  void SetInsertPoint(BasicBlock::iterator IP) {
    BB = IP->getParent();
    InsertPt = IP;
    SetCurrentDebugLocation(IP->getStableDebugLoc());
  }

  /// This specifies that created instructions should inserted at the beginning
  /// end of the specified function, but after already existing static alloca
  /// instructions that are at the start.
  void SetInsertPointPastAllocas(Function *F) {
    BB = &F->getEntryBlock();
    InsertPt = BB->getFirstNonPHIOrDbgOrAlloca();
  }

  /// Returns the current insert point.
  InsertPoint saveIP() const {
    return InsertPoint(GetInsertBlock(), GetInsertPoint());
  }

  /// Returns the current insert point, clearing it in the process.
  InsertPoint saveAndClearIP() {
    InsertPoint IP(GetInsertBlock(), GetInsertPoint());
    ClearInsertionPoint();
    return IP;
  }

  /// Sets the current insert point to a previously-saved location.
  void restoreIP(InsertPoint IP) {
    if (IP.isSet())
      SetInsertPoint(IP.getBlock(), IP.getPoint());
    else
      ClearInsertionPoint();
  }

Insert

可以看出泛泛的三种插入情况: 指令, 常量, 变量。 所有的插入操作, 都是以这 3 种 insert 为基础操作的。

  /// Insert and return the specified instruction.
  template<typename InstTy>
  InstTy *Insert(InstTy *I, const Twine &Name = "") const {
    Inserter.InsertHelper(I, Name, BB, InsertPt);
    AddMetadataToInst(I);
    return I;
  }

  /// No-op overload to handle constants.
  Constant *Insert(Constant *C, const Twine& = "") const {
    return C;
  }

  Value *Insert(Value *V, const Twine &Name = "") const {
    if (Instruction *I = dyn_cast<Instruction>(V))
      return Insert(I, Name);
    assert(isa<Constant>(V));
    return V;
  }


 

IRBuilder

类声明

template <typename FolderTy = ConstantFolder,
          typename InserterTy = IRBuilderDefaultInserter>
class IRBuilder : public IRBuilderBase {...}

继承了 IRBuilderBase

属性 ( 不包含父类的属性)

private:

  FolderTy Folder;
  InserterTy Inserter;
 

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值