LLVM学习 之 寻找调试的单元测试用例

751 阅读2分钟

LLVM 学习,毕竟编译器是很复杂的,当然也发展了很久,总能从论坛或邮件列表等地方找到一些文字描述,理解整体或某个局部的模型。但还是一知半解。这时候有个相关的case用来调试就会方便很多。

LLVM 的单元测试用例,主要有.ll文件,一种可读的IR中间表示。可以用llc离线编译器编译,从而调试LLVM的相关Pass。LLVM的Pass分为分析Pass和转换Pass。Pass这个单词不是“通过”,就是“一趟”、“一遍”分析/转换的意思。还有一种,机器相关的MIR的case,.mir结尾,采用yaml格式,这个先不介绍。

下面是gdb中加载Python,通过set args来设置不同的单元测试用例,寻找在我需要的地方断点的用例。写得比较粗糙,这个意思和思路还是清楚的。算是一个学习LLVM实用的小技巧吧。

gdb 脚本

# 在gdb中使用
# 示例:
# Step1. 先gdb运行程序: gdb  /root/project/bin/llc
# Step2. 打断点 b SplitKit.cpp:1276
# commands 1
#     silent
#     p '+_+_+_+_+_+_+_+_+_+_+_+_+_+_+'
#     continue
# end
# Step3. 加载运行该脚本,找到在断点处停止的用例.ll,用于后修调试学习  source python_gdb.py
# Over.
 

import gdb
import os

base_dir = '/root/project/LLVM/llvm/test/CodeGen/X86/'
# arr = ["2003-08-03-CallArgLiveRanges.ll", "2003-08-23-DeadBlockTest.ll", "2003-11-03-GlobalBool.ll"]


flag = False
# base_dir下的.ll都是测试用例
# 分别set args设置后再运行该用例,观察是否有断点信息
for file in os.listdir(base_dir):
    # print(file)
    # if file in ['new-remat.ll', 'fold-vector-shuffle-crash.ll']:
    if file == 'fold-vector-shuffle-crash.ll':  # 这是上一个case,设置flag找它之后符合的case
        flag = True
        continue

    if flag:
        gdb.execute("set args -regalloc=greedy " + str(os.path.join(base_dir, file)))
        #gdb.execute("set args -regalloc=greedy -mtriple=x86_64 " + str(os.path.join(base_dir, file)))
        gdb.execute("show args")
        gdb.execute("r")

效果:

这不是找到了嘛,interval-update-remat.ll,这个case可以学习贪婪寄存器分配,中Split相关的代码,我的断点关注的是extendPHIRange这个函数。

image.png