LLVM 学习记录:调试技巧 2

Posted by 叉叉敌 on May 28, 2024

这里直接推荐一个 https://blog.csdn.net/zhongyunde/article/details/109013865

工具的选项

传递编译选项给 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

裁剪 case

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() 查看循环体的内容