编译器相关

LLVM基础(IR简介&CFG图生成&可视化)

2019-05-25  本文已影响0人  HAPPYers

LLVM IR

LLVM 提供了一个详细的汇编语言表示(参阅 参考资料 获取相关的链接)。在开始编写我们之前讨论的自己的 Hello World 程序版本之前,有几个需知事项:

declare  i32 @puts(i8*) 
@global_str = constant [13 x i8] c"Hello World!\00"
define i32 @main { 
  call i32 @puts( [13 x i8] @global_str )
  ret i32 0 
}

这里提供了来自 lli 的日志:

lli: test.s:5:29: error: global variable reference must have pointer type
  call i32 @puts( [13 x i8] @global_str )
                            ^

程序并未按预期的运行。发生了什么?如之前所提及的,LLVM 拥有一个强大的类型系统。因为 puts 期望提供一个指向 i8 的指针,并且您能传递一个 i8 矢量,这样 lli 才能快速指出错误。该问题的常用解决方法(来自 C 编程背景)是使用类型转换。这将您引向了 LLVM 指令 getelementptr。请注意,您必须将 清单 3 中的 puts 调用修改为与 call i32 @puts(i8* %t)类似,其中 %t 是类型 i8*,并且是 [13 x i8] to i8* 的类型转换结果。(请参阅 参考资料,获取 getelementptr 的详细描述的链接。)在进一步探讨之前,清单 4 提供了可行的代码。

declare i32 @puts (i8*)
@global_str = constant [13 x i8] c"Hello World!\00"
 
define i32 @main() {
  %temp = getelementptr [13 x i8]*  @global_str, i64 0, i64 0
  call i32 @puts(i8* %temp)
  ret i32 0
}

getelementptr 的第一个参数是全局字符串变量的指针。要单步执行全局变量的指针,则需要使用第一个索引,即 i64 0。因为 getelementptr 指令的第一个参数必须始终是 pointer 类型的值,所以第一个索引会单步调试该指针。0 值表示从该指针起偏移 0 元素偏移量。我的开发计算机运行的是 64 位 Linux®,所以该指针是 8 字节。第二个索引 (i64 0) 用于选择字符串的第 0 个元素,该元素是作为 puts 的参数来提供的。

创建一个自定义的 LLVM IR 代码生成器

LLVM 提供了一款出色的工具,叫做 llvm-config(参阅 参考资料)。运行 llvm-config –cxxflags,获取需要传递至 g++ 的编译标志、链接器选项的 llvm-config –ldflags 以及 llvm-config –ldflags,以便针对正确的 LLVM 库进行链接。在 清单 5 的样例中,所有的选项均需要传递至 g++。

一个自动生成函数流程控制图(Control Flow Graph, CFG)和调用关系图(Call Graph,CG)的脚本

clang $1.c -emit-llvm -S
opt -dot-cfg $1.ll > /dev/null
opt -dot-callgraph $1.ll > /dev/null
dot -Tpng -o $1.png cfg.main.dot
rm cfg.main.dot
dot -Tpng -o $1.callgraph.png callgraph.dot
rm callgraph.dot

使用sh gen_bc2dot.sh 1,文件名不带拓展名即可。

可视化LLVM IR控制流图

使用LLC生成可视化SelectionDAG
https://blog.csdn.net/qq_27885505/article/details/80366525
依赖安装graphviz:

sudo apt-get install graphviz

llvm:debug版本(我看网上有人说只有debug版本才能够使用可视化的命令,其他release版本没有尝试过)默认前提已经装好了llvm,就不再讲述llvm编译过程。

llc -view-dag-combine1-dags mul.ll
llc -view-legalize-dags test.ll
llc -view-dag-combine2-dags mul.ll
llc -view-isel-dags mul.ll
llc -view-sched-dags test.ll
llc -view-sunit-dags test.ll

参考资料

https://www.ibm.com/developerworks/cn/opensource/os-createcompilerllvm1/index.html
LLVM Cookbook

上一篇 下一篇

猜你喜欢

热点阅读