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指令:根据比较规则,比较两个操作数,将比较的结果以布尔值进行返回
例:
notion image
对应的IR语句就为:
notion image
在这个里面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结束循环。
notion image

switch语句指令

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

对指针的操作

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

参考链接:

随便一谈-新阶段CMake的一些小技巧
Loading...
JucanaYu
JucanaYu
干饭人,干饭魂🍚
最新发布
Python练习-类型转换
2025-4-9
Python练习-count、remove、append、extend
2025-4-8
Python练习-set和sorted
2025-4-6
Python练习-insert和del
2025-4-6
Python练习-range
2025-4-6
Python练习-双指针法
2025-4-6