LLVM version 11.0.0
Clang version 11.0.0
Target: x86_64-unknown-linux-gnu
Linux: ubuntu 20.04
Create LLVM IR By IRBuilder
LLVM version 11.0.0
Clang version 11.0.0
Target: x86_64-unknown-linux-gnu
Linux: ubuntu 20.04
写在开头
为了实现插桩,所以有了如何手动生成LLVM IR呢?
C++使用Instructions.h文件中的命令生成IR- 使用llvm提供的C接口生成IR
- 使用IRBuilder生成IR
首先,回忆一下LLVM的基本组成吧,Module、Function、BasicBlock、Instruction以及它们间的关系是:
| |
是的,一个module中包含多个function,function中又包含多个basic block,basic block中又包含多条`instruction'.

介绍一下一个简单的手动生成Demo流程,会使用到:
- 创建一个
LLVMContext - 在
LLVMContext中创建一个Module - 在
Module中创建添加Function- 一个
Function是有函数类型FunctionType FunctionType可以解释为返回值类型returnType+参数argument+不定参数false/true- 以及函数签名
- 一个
- 在
Function中创建Basic Block- 一个
Function有且只有一个labal为entry的基本块 - 所以,先创建一个label为
entry的基本块 - 接着,创建更多需要的基本块
- 一个
- 在
Basic Block中创建Instruction- 指令在
Basic Block中,通过IRBuilder类创建
- 指令在
起飞
以一下main.cpp作为手动生成LLVM IR的代码例子.
| |
使用到的一些类
| 类名 | 解释 |
|---|---|
| LLVMContext | 上下文类,保存上下文符号 |
| Module | 模块类,一般以文件一个模块,有函数列表和全局变量表 |
| Function | 函数类 |
| BasicBlock | 基本块类 |
| IRBuilder | IR建造类 |
| Value | 各类型值的基类,函数、常量、变量、表达式等都可以转换为Value类型 |
| Type | 类型类,各种内部类型或用户类型,Value可通过getType()取类型 |
| Constant | 常量类,能够生产各种常量 |
step 1 创建一Mudule
| |
step 2 声明一个Function
在这里以int max(int a, int b)为例.
| |
step 3 创建Basic Block
label名字为entry的基本块为Function入口,一个Function有且只有一个labe为entry的基本块,并且不能作为跳转指令的目标,也不能存在phi指令.
在这里每一个 Basic Block分别使用IRBuilder生成指令,当然也可以不这么做.
| |
step 4 使用JIT引擎
当然,这里是为了执行生成的机器码,如果仅仅是想生成LLVM IR到step3就够了(PS记得释放new的内存).
| |
输出到文件中:
| |
最后
完整main.cpp
| |
使用命令:
| |
使用命令:
| |
最后,得到的main.ll.
| |
额外的
还可以通过Instructions.h中提供的方法创建,参考于 第二篇博客.
Instructions.h中有很多类,比如AllocaInst、LoadInst、StoreInst等,具体可以查看参考,都是以IR名称+Inst为类名.
接下来,应该会去看Instructions.h和IR的分类,如一元指令、二元指令、内存操作指令等,以及实现一个Pass 虽然已经写过.HelloDemo
| |
结果:
| |
暂时先整理这些,今后追补上.
REF
给了极大的帮助:IR API(一)——使用LLVM提供的C接口和IRBuilder来生成LLVM IR(if 和 while 语句)
以及参考了:LLVM IR 三部曲之二 — 创建IR