参考链接:https://llvm.org/devmtg/2019-04/slides/Tutorial-Bridgers-LLVM_IR_tutorial.pdf
https://zhuanlan.zhihu.com/p/163063995
https://zhuanlan.zhihu.com/p/163328574
文章目录
- IR的布局
- 1. IR语法
- 2.IR递归函数
- 3.使用迭代的方式
- 4.全局变量
- 5.LLVM’s type system
- IR是一种低级编程语言——类似 RISC 的指令集……
- 同时能够代表高级思想。即高级语言可以清晰地映射到 IR。
- 实现高效的代码优化


IR的布局
ABI Application Binary Interface 应用程序二进制接口
 API Application Program Interface 应用程序接口
 右上方的图片里显示了一个Module的组成。
 
1. IR语法
- 局部变量未命名:%<number>
- 局部变量命名:%<name>
- declare申明一个函数,返回值和传入参数是- i32大小
- 函数名@开头
- define定义一个函数
- icmp比较指令返回一个- i1类型的值
- eq与- ne,分别代表相等或不相等
- 无符号的比较ugt,uge,ult,ule,分别代表大于、大于等于、小于、小于等于;这里每个方案的u就代表以无符号的形式进行比较
- 有符号的比较sgt,sge,slt,sle
LangRef Language Reference Manual是LLVM的语言参考手册,有很多指令详解,在其中可以查到:
 call指令用于使控制流转移到指定的函数,其传入参数绑定到指定的值。根据被调用函数中的“ret”指令,控制流继续执行函数调用后的指令,并且函数的返回值绑定到结果参数。
 
 IR代码中每一句都会强调变量的类型
- i3232位4字节
- i832位1字节
- i1相当于bool类型,用bit位存数据
 每当在不接受该类型但接受某种其他类型的上下文中使用某种类型的表达式时,就会执行隐式转换。但是LLVM IR没有隐式转换,需要显式转换,否则会报错。
 LLVM IR中提供三种转换指令:
- trunc … to指令,将长的整型转换成短的整型。
- zext … to指令,将短的整型变成长的整型,零扩展,直接在高位补0。
- sext … to指令,将短的整型变成长的整型,符号扩展则是用原数的符号位来填充。
  
2.IR递归函数
Branch - “br”,分支结构,由声明的label表示。label将Moudle分为3个basic block。有的label是隐式的,比如{后可以加一句entry:
 
3.使用迭代的方式

 SSA Static Single Assignment静态单一分配:
- 每个变量都只分配一次。
- 每个变量在使用之前都已定义。
需要使用Phi指令根据之前执行的BasicBlock选择一个值,使用格式是:
 <result> = phi <ty> [<val0>, <label0>], [<val1>, <label1>] …
相当于用这个实现变量自己的更新
 
 最后的写法:

或者使用写入内存的方式实现变量自我更新,摆脱SSA限制。主要是利用指针:
 
 内存访问和寻址操作:
- alloca指令在当前执行函数的堆栈帧上分配内存,当该函数返回到其调用者时自动释放内存。如果没有显式指定地址空间,则对象将从 datalayout string.alloca 分配到 alloca 地址空间中。
- load读取某个位置的值。
- store写入内存。
%ptr = alloca i32                               ; yields ptr
store i32 3, ptr %ptr                           ; yields void
%val = load i32, ptr %ptr                       ; yields i32:val = i32 3
4.全局变量
它们始终是指针,就像 Allocas 返回的值一样。总是一个常量指针
const int *p=&a; // 指针的指向可以修改,但是指针指向的值不可以修改
全局变量必须需要@开头,申明大小比如i8,被初始化,加上关键词global
@gv = global i8 42
或者是一个常量,永远不能被改变其值
@gv = constant i8 42
5.LLVM’s type system
计算指针偏移
 
这个详见intel的pdf,图画的很清晰,就不搬运贴过来了。59/91页
Next:
 Learn how to manipulate IR using the LLVM library
 Look at the OPT code

















