LLVM笔记2 Intermediate Representation (IR)

参考链接: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。
  • 实现高效的代码优化

LLVM笔记2 Intermediate Representation (IR)_第1张图片

LLVM笔记2 Intermediate Representation (IR)_第2张图片

IR的布局

ABI Application Binary Interface 应用程序二进制接口
API Application Program Interface 应用程序接口
右上方的图片里显示了一个Module的组成。
LLVM笔记2 Intermediate Representation (IR)_第3张图片

1. IR语法

  • 局部变量未命名:%
  • 局部变量命名:%
  • declare申明一个函数,返回值和传入参数是i32大小
  • 函数名@开头
  • define定义一个函数
  • icmp比较指令返回一个i1类型的值
  • eqne,分别代表相等或不相等
  • 无符号的比较ugt, uge, ult, ule,分别代表大于、大于等于、小于、小于等于;这里每个方案的u就代表以无符号的形式进行比较
  • 有符号的比较sgt, sge, slt, sle

LangRef Language Reference Manual是LLVM的语言参考手册,有很多指令详解,在其中可以查到:
call指令用于使控制流转移到指定的函数,其传入参数绑定到指定的值。根据被调用函数中的“ret”指令,控制流继续执行函数调用后的指令,并且函数的返回值绑定到结果参数。
LLVM笔记2 Intermediate Representation (IR)_第4张图片
IR代码中每一句都会强调变量的类型

  • i3232位4字节
  • i832位1字节
  • i1相当于bool类型,用bit位存数据
    每当在不接受该类型但接受某种其他类型的上下文中使用某种类型的表达式时,就会执行隐式转换。但是LLVM IR没有隐式转换,需要显式转换,否则会报错。
    LLVM IR中提供三种转换指令
  • trunc … to指令,将长的整型转换成短的整型。
  • zext … to指令,将短的整型变成长的整型,零扩展,直接在高位补0。
  • sext … to指令,将短的整型变成长的整型,符号扩展则是用原数的符号位来填充。
    LLVM笔记2 Intermediate Representation (IR)_第5张图片

2.IR递归函数

Branch - “br”,分支结构,由声明的label表示。label将Moudle分为3个basic block。有的label是隐式的,比如{后可以加一句entry:
LLVM笔记2 Intermediate Representation (IR)_第6张图片

3.使用迭代的方式

LLVM笔记2 Intermediate Representation (IR)_第7张图片
SSA Static Single Assignment静态单一分配:

  • 每个变量都只分配一次。
  • 每个变量在使用之前都已定义。

需要使用Phi指令根据之前执行的BasicBlock选择一个值,使用格式是:

 <result> = phi <ty> [<val0>, <label0>], [<val1>, <label1>]

相当于用这个实现变量自己的更新
LLVM笔记2 Intermediate Representation (IR)_第8张图片
最后的写法:

LLVM笔记2 Intermediate Representation (IR)_第9张图片

或者使用写入内存的方式实现变量自我更新,摆脱SSA限制。主要是利用指针:
LLVM笔记2 Intermediate Representation (IR)_第10张图片
内存访问和寻址操作

  • 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

计算指针偏移
LLVM笔记2 Intermediate Representation (IR)_第11张图片

这个详见intel的pdf,图画的很清晰,就不搬运贴过来了。59/91页


Next:
Learn how to manipulate IR using the LLVM library
Look at the OPT code

你可能感兴趣的:(Linux,笔记)