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