llvm 下构建配置小技巧
1、使能-DLLVM_CCACHE_BUILD=ON ,需要本地ccache工具的支持
llvm 下gdb的小技巧
1、llvm编写了自己的一些实用的类stl库,没有配置过的gdb没法直观的显示这些数据结构的内容
在llvm仓下 ./utils/gdb-scripts/prettyprinters.py, 在~/.gdbinit中添加source ${path}/prettyprinters.py,就可以较为直观的显示了
2、假如发现clang编译下的stl也无法显示,可以在构建配置的-DCMAKE_CXX_FLAGS选项加上-fno-limit-debug-info选项
3、标准的gdb,没法在gui界面回溯命令,并且在gui界面偶尔会花屏, 推荐使用cgdb(包装了一下gdb),网上下载就有
llvm 下vim的推荐配置
1、在utils/vim/syntax/目录下有2个vim语法高亮文件llvm.vim tablegen.vim, 分别对应这llvm的IR(*.ll)以及tablegen(*.td)文件语法高亮, 将2个文件移入~/.vim/syntax/中并在~/.vimrc中添加
au BufNewFile,BufRead *.td set filetype=tablegen
au BufRead,BufNewFile *.ll set filetype=llvm
就可以实现这2种类型的vim语法高亮
2、在tools/clang/tools/clang-format/clang-format.py,存放着clang-format的功能脚本,用于自动纠正LLVM的代码风格(与wecode的codestyle纠正类似不过codestyle规范符合LLVM规范), 在.vimrc中添加对应路径的脚本文件快捷键后,vim编辑下选中对应代码,ctrl+k就可以自动纠正一些codestyle (像超过80列自动换行,大括号风格等)
map <C-K> :py3f /home2/panyt/usr/bin/clang-format.py<cr>
imap <C-K> <c-o>:py3f /home2/panyt/usr/bin/clang-format.py<cr>
常用的调试选项
传递编译选项给clang -cc1:-Xclang
-cc1 选项:实际的编译命令
传递编译选项给llvm编译:-mllvm
打印token:-Xclang -dump-tokens
打印AST: -Xclang -ast-dump
打印llvm IR:-S -emit-llvm
打印汇编:-S
打印pass列表: -mllvm -debug-pass=Structure
打印clang driver:-###
在pass执行完打印IR:-mllvm -print-after-all ;llc 也可以 -print-after-all, or stop-before=xx, stop-after=xx
DAGToDAG Debug日志:-mllvm -debug
选项-verify-each能够使能每个pass后的验证
打印模块信息: -print-module-scope,由于默认print-after-all 仅在模块信息发生变化时才重新打印,导致过程中的IR内容不能直接用于pass的输入,因此配合此选项可以避免额外适配
获取指定函数的lr文件:-mllvm -opt-bisect-limit=-1 -S -emit-llvm -filter-print-funcs=poo
邮件Which optimization pass deals with heap values标题中提到选项-mllvm -print-changed可以显示变化
使用选项-mllvm --print-changed=quiet -mllvm --print-module-scope查看状态变化,参考
Why is llvm.loop.unroll.disable appended for -O1 -emit-llvm - #2 by aeubanks - IR & Optimizations - LLVM Discussion Forums
a) 用例裁剪:llvm提供llvm-reduce及使用示例
~/test/issue2485/err » cat test1.sh
#!/bin/bash
opt $1 -instcombine -S 2>&1 | grep SafeReplacementConstant # 匹配返回0是感兴趣
------------------------------------------------------------
~/test/issue2485/err » llvm-reduce --test=test1.sh test-2485.ll
如果是lto优化,则需要使用-Wl,-plugin-opt=save-temps保留中间文件,生成的*.opt.bc使用llvm-dis转换为*.ll文件,后续裁剪方法同上
llvm-dis a.out.0.4.opt.bc -- 生成 a.out.0.4.opt.ll
opt -instcombine a.out.0.4.opt.ll
b) 源码裁剪:llvm后端中的llvm-reduce只能对非后端的IR进行裁剪,无法对后端的IR进行裁剪。因此可以先使用C-Reduce对C 源码裁剪,间接的进行简化,使用方法类似llvm-reduce
MIR 相关的调试补充介绍
MIR 的调试参考 Machine IR (MIR) Format Reference Manual — LLVM 13 documentation
You can use the MIR format for testing in two different ways:
- You can write MIR tests that invoke a single code generation pass using the
-run-pass
option in llc.- You can use llc’s
-stop-after
option with existing or new LLVM assembly tests and check the MIR output of a specific code generation pass.
参考CodeGen/AMDGPU/fold-reload-into-m0.mir,可以使用 -start-before=greedy -stop-after=virtregmap指定开始和结束要执行的pass, 也就是并不需要都重头开始执行,示例:
llc -O3 reduced.ll -stop-before=virtregmap -o - &> machine-scheduler1.mir
llc -O3 reduced.ll -simplify-mir -o - -print-after-all 也可以打印mir
注意: -o - 是关键,和llc -O3 reduced.ll -stop-before=virtregmap -debug-only=machine-scheduler 得到的内容存在差异
学习mllvm -opt-bisect-limit用法:Using -opt-bisect-limit to debug optimization errors — LLVM 15.0.0git documentation
cgdb 类似emacs + gdb 功能,可以实时查看代码执行位置, 参考 https://blog.csdn.net/yzhang6_10/article/details/83626226
IRbuilder或者MachineIRBuilder是为了建新的语句的一个接口类,可以使用
p Builder.GetInsertBlock()->dump() 打印当前basicblock的信息
3、常用debug API,查看过程状态
p L.getHeader()->getParent()->dump() 查看循环体的内容