文章目录

  • ​​一. 说明​​
  • ​​二. 重要命令​​
  • ​​2.1 C语言llvm clang命令​​
  • ​​2.2 rust 转IR的指令​​
  • ​​三.生成利用LLVM-IR转CFG图可视化​​
  • ​​四. LLVM-IR语言的标识符和解释​​

一. 说明

二. 重要命令

2.1 C语言llvm clang命令

​​llvm基本命令​​

  • c到IR
    ​​​clang -emit-llvm -S multiply.c -o multiply.ll​​​​clang -cc1 -emit-llvm testfile.c -o testfile.ll​
  • IR到bitcode
    ​​​llvm-as test.ll –o test.bc​
  • bitcode到汇编
    ​​​llc test.bc –o test.s​​​​clang -S test.bc -o test.s –fomit-frame-pointer​
  • bitcode到IR
    ​​​llvm-dis test.bc –o test.ll​
  • opt执行转换Pass
opt –passname input.ll –o output.ll
adce:入侵式无用代码消除。
bb-vectorize:基本块向量化。
constprop:简单常量传播。
dce:无用代码消除。
deadargelim:无用参数消除。
globaldce:无用全局变量消除。
globalopt:全局变量优化。
gvn:全局变量编号。
inline:函数内联。
instcombine:冗余指令合并。
licm:循环常量代码外提。
loop-unswitch:循环外提。
loweratomic:原子内建函数lowering。
lowerinvoke:invode指令lowering,以支持不稳定的代码生成器。
lowerswitch:switch指令lowering。
mem2reg:内存访问优化。
memcpyopt:MemCpy优化。
simplifycfg:简化CFG。
sink:代码提升。
tailcallelim:尾调用消除。
  • 链接两个bitcode
    ​​​llvm-link test1.bc test2.bc –o output.bc​
  • 执行bitcode文件
    ​​​lli output.bc​
  • C转bitcode
    ​​​clang -O3 -emit-llvm hello.c -c -o hello.bc​

2.2 rust 转IR的指令

  • 利用cargo项目管理生成ir
    ​​​cargo rustc -- --emit=llvm-ir​
  • 直接对rs文件生成对应的ir
    ​​​rustc 文件名 --emit=llvm-ir​

三.生成利用LLVM-IR转CFG图可视化

这里 通过​​opt​​​即​​llvm​​​自带的​​pass​​​将​​llvm-ir​​​即​​ll​​​文件先转化为每一个函数对应的dot文件, 而这个​​dot​​​文件其实就是一个图的格式, 然后再根据绘图工具​​graphviz​​​将​​opt​​​生成的​​dot​​​文件转化为可视化的图
​​​LLVM基础(IR简介&CFG图生成&可视化)​

# 生成cdfg图可视化 *表示文件名称
# sudo apt-get install graphviz # 需要安装的依赖
clang *.c -emit-llvm -S -o *.ll # 生成ll文件
opt -dot-cfg *.ll # 对ll文件解析成一个一个函数, 转为CDF
opt -dot-callgraph *.ll #
# 画图命令
dot -Tpng -o 1.png *.dot # 将dot文件生成图
dot -Tpng -o 2.png *callgraph.dot

四. LLVM-IR语言的标识符和解释

Identifiers 标识符

@ 全局
% 局部

后接字符串 命名量 @name %name
无符号数字 未命名量 @42 %42


类型系统

void 空类型
<type> * 指针类型
<returntype> (<parameter list>) 函数类型
< <# elements> x <elementtype> > 向量类型
[<# elements> x <elementtype>] 数组类型
{ <type list> } 普通结构体类型
<{ <type list> }> 打包结构体类型
metadata 元数据类型
label 标签类型
token 词元类型

类型系统(例子)

void 空
i32 * 指针
i32 (i32) 函数
<5 x i32> 向量
[5 x i32] 数组
{ i32, i32, i32 } 普通结构体
<{ i32, i32, i32 }> 打包结构体

元数据

; 未命名元数据节点
; 用于被命名元数据引用
!0 = !{!"zero"}
!1 = !{!"one"}
!2 = !{!"two"}

; 命名元数据
!name = !{!0, !1, !2}

!name --- !0
|-- !1
|-- !2

模块层次内联汇编

module asm "内联汇编代码"

Target Triple

target triple = "x86_64-amd64-freebsd"

First Class Types 第一类型
Single Value Types 单值类型
只在寄存器里头有效

Integer Type 整数类型

iN ;N为比特数 (通用描述)

i1 一个比特整数
i32 32为整数

Floating-Point Types 浮点类型

half - 16位浮点值
float - 32位浮点值
double - 64位浮点值
fp128 - 128位浮点值
x86_fp80 - 80位浮点值
ppc_fp128 - 128位浮点值

模块结构
程序由模块组成,每个模块都是输入程序的翻译单元。
Hello, world 模块

; 定义字符串常量作为全局常量
@.str = private unnamed_addr constant [13 x i8] c"hello world\0A\00"

; 外部声明的 puts 函数
declare i32 @puts(i8* nocapture) nounwind

; main 函数的定义
define i32 @main() { ; i32()*
; [13 x i8] 转换到 i8...
%cast210 = getelementptr [13 x i8], [13 x i8]* @.str, i64 0, i64 0

; 调用 puts 函数,将字符串写入 stdout
call i32 @puts(i8* %cast210)
ret i32 0
}

; 命名元信息
!0 = !{i32 42, null, !"string"}
!foo = !{!0}

指令参考
=========

Terminator Instructions
指示当前块完成后,执行哪个块。
终结指令典型的产生一个 void 值:他们影响控制流,而不是值。(invoke指令是一个例外)

ret 返回
br 二元条件分支/无条件转移
switch 多条件分支
indirectbr
invoke 普通/带异常调用
resume 抛出异常?
catchswitch 捕获异常
catchret
cleanupret
unreachable 不可到达(无语义)

Binary Operations

add 加
fadd 浮点加
sub 减
fsub 浮点减
mul 乘
fmul 浮点乘
udiv 无符号整数除
sdib 带符号整数除
fdiv 浮点除
urem 无符号整数求余
srem 带符号整数求余
frem 浮点数求余

运算\类型 无符号整数 带符号整数 浮点数
+ add fadd
- sub fsub
* mul fmul
/ udiv sdiv fdiv
% urem srem frem

Bitwise Binary Operations

shl 左移
lshr 逻辑右移
ashr 算数右移
and 与
or 或
xor 异或

Vector Operations

extractelement 取出元素
insertelement 插入元素
shufflevector

Aggregate Operations

extractvalue 取出值
insertvalue 插入值

Memory Access and Addressing Operations

alloca 分配内存
load 从内存加载
store 储存到内存
fence
cmpxchg
atomicrmw 自动修改内存
getelementptr 获取 aggregate(集合) 数据结构的子成员地址

Coversion Operations

这个类型为转换指令(强制类型转换|铸造casting)
都取一个单一运算对象和一个类型。
对运算对象提供一系列位转换。

trunc .. to 截断转换
zext .. to 零扩展转换
sext .. to 符号位扩展转换
fptrunc .. to 浮点截断转换
fpext .. to 浮点扩展
fptoui .. to 浮点转无符号整数
fptosi .. to 浮点转带符号整数
uitofp .. to 无符号整数转浮点
sitofp .. to 带符号整数转浮点
ptrtoint .. to 指针转整数
inttoptr .. to 整数转指针
bitcast .. to 位模式转换(重新解释,不改变任何二进制位)
addrepacecast .. to 地址空间转换

Other Operations

icmp 整数比较
fcmp 浮点数比较
phi φ 节点
select 条件值选择
call 简单函数调用
va_arg 可变参数
landingpad
catchpad
cleanuppad