基于LLVM的GCC与Clang编译器性能对比工具,通过汇编指令分析比较编译器优化效果。
LLVM IR文件
|
▼
llvm-nm 提取函数名
|
▼
llvm-extract 提取单函数
|
▼
llvm-dis 生成可读IR
|
▼
llvm-as 重新编译 (CBE需要干净的.bc格式)
|
▼
llvm-cbe 生成C代码
|
▼
|————————————————————————————————|
| |
▼ ▼
GCC编译 Clang编译
| |
▼ ▼
GCC汇编文件 Clang汇编文件
| |
|————————————————————————————————|
|
▼
指令统计对比
|
▼
CSV结果报告
|
▼
Excel转换
使用配置文件中的路径进行批量对比:
python3 compare.py -c --all参数说明:
-c, --use-config: 使用config.json中配置的输入路径--all: 输出所有函数结果(包括失败的)- 不加
--all: 只输出GCC表现更好的函数(指令数更少)
指定单个文件或目录:
python3 compare.py input.ll -o results.csv
python3 compare.py /path/to/directory -o output_dir完整功能分析:
python3 extract.py input.ll -o output_dir指定单个函数:
python3 extract.py input.ll -f function_name -o output_dirextract.py 特有输出:
- 详细处理日志:
function_name_processing.log- 记录每个编译步骤的详细信息和错误 - 优化管道日志:
function_name_opt_steps.log- 记录LLVM优化过程的每一步 - 中间文件保留: 保留所有中间文件(.ll, .c, .s)用于调试
- 实时状态输出: 显示每个函数的处理状态和错误信息
处理日志示例:
*** Processing Function Start ***
*** Function Name: test_fdiv ***
*** Step 1: llvm-extract Function Extraction ***
*** Command: /path/to/llvm-extract -func=test_fdiv input.ll -o temp.bc ***
*** llvm-extract Success ***
*** Step 4: CBE C Code Generation ***
*** CBE Failed (exit code: 1) ***
*** stderr: error: undefined struct 'l_vector_2_bool' ***
自动转换配置目录下所有CSV文件:
python3 csv_to_xlsx.py转换指定目录:
python3 csv_to_xlsx.py -d /path/to/csv/directory转换单个文件:
python3 csv_to_xlsx.py input.csv output.xlsx编辑 config.json 设置工具路径和编译参数:
{
"paths": {
"llvm_bin": "/path/to/llvm/build/bin",
"gcc_bin": "/path/to/gcc"
},
"input_paths": ["/path/to/llvm/tests"],
"output_dir": "comparison_results",
"timeout": 5
}| Function | GCC Instructions | Clang Instructions | Diff % | Status |
|---|---|---|---|---|
| test_func | 15 | 18 | 20.0 | |
| failed_func | - | - | - | CBE |
- LLVM工具链 (llvm-extract, llvm-nm, llvm-cbe等)
- GCC & Clang 编译器
- Python 3.7+ (pandas, openpyxl)
- 空白: 处理成功
llvm-extract: 函数提取失败llvm-dis: IR反汇编失败llvm-as: IR汇编失败CBE/cbe超时: C代码生成失败/超时GCC: GCC编译失败Clang: Clang编译失败
使用extract.py模式可以查看详细错误:
- processing.log: 包含完整的错误输出和命令行
- 终端输出: 实时显示每个函数的处理状态
- 中间文件: 保留失败时的中间文件用于调试分析
错误调试流程:
- 先用
compare.py批量处理查看整体失败情况 - 对失败的函数使用
extract.py -f function_name单独分析 - 查看生成的processing.log了解具体失败原因
- 检查中间文件(.c文件、编译器输出)定位问题