type
status
date
slug
summary
tags
icon
password
LLVM IR的一些基本知识
函数体基本块
基本块的特点:
- 仅有一个入口(entry):作为基本块中的第一条指令。
- 仅有一个出口:基本块的最后一条指令(被称为terminator instruction)。该指令要么跳转到其他的基本块,要么就从函数返回。
- 函数体出现的第一个基本块,又称为入口基本块(Entry Basic Block)。它是一个特殊的基本块。进入函数时立即执行该基本块。该基本块不允许有前继节点。
一些指令
内存指令:
- alloca:用于在栈上分配内存,并返回一个指向新分配内存的指针。
格式:%array=alloca [5 x i32]。表示分配包含5个整数的数组给array。
- load:用于从内存中读取数据,并将数据加载到寄存器中。
格式:%val=load i32,i32*%ptr。表示load指令将%ptr指向的内存块中的数据加载到%val寄存器中。
- store:用于将数据从寄存器写入内存中。
格式:store i32 42,i32* %ptr。将整数值42存储到%ptr指向的内存块中
- getelementptr:用于计算指针的偏移量。
格式:%ptr=getelementptr[3 x [4 x i32]],[3 x [4 x i32]]* %array,i32 1,i32 2。表示计算array二行三列的偏移量。
- malloc:在堆上分配内存,并返回一个指向新分配内存的指针。
- free:释放之前通过malloc指令分配的内存
格式:call void @free(i8* %ptr)。Call指令调用free函数释放内存
控制流指令
- br:条件分支指令
- switch:多路分支指令,根据输入值跳转到不同的基本块
- ret:函数返回指令,返回到调用函数的地方
- invoke:调用指令,调用带异常处理的函数,并在异常发生时传递控制权
if语句指令
一般if语句指令里面都会有icmp、br两个指令。
- icmp指令:根据比较规则,比较两个操作数,将比较的结果以布尔值进行返回
例:

对应的IR语句就为:

在这个里面cmp接收的是判断结果的布尔值,icmp代表的是比较规则;eq代表的是比较规则(在这里因为是等于,所以是eq。如果是大于的话就会是sgt);i32 是操作数类型;比较的是%rem和0的值是否相等。
整个来说,就是看%rem的值和0的值是否相等,并将最后比较的结果放到%cmp中。
- br指令有两种形式,分别对应的是条件分支和无条件分支。
有条件分支在条件分支上接受一个“i1”值和两个“label”值。i1类型的值是进行判断的条件(也就是接受上述%cmp的布尔类型的值),如果为true就进入第一个label,如果为false就进入第二个label
while语句指令
所谓的while语句就是“跳转+分支”
while的运行流程就是:首先跳转到while.cond进行判断,如果满足条件(使用的是条件判断语句,)的话就进入到while.body进行循环的实际操作。循环完一次之后就进入到while.cond进行条件判断。一直到循环条件不匹配,进入while.end结束循环。

switch语句指令
switch在LLVM IR里面就是switch指令。对%conv选取一个值,与%conv相同的值就跳进去。

对指针的操作
对指针的操作就是指针的指针,开辟一块指针类型的内存。


参考链接:
- 作者:JucanaYu
- 链接:https://jucanayu.top/article/10e7ab71-7095-80d2-b9db-f863cff5cbd7
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。