如何用LLVM c++filt解析opt生成的函数名并精简调用图?
解决方案
1. macOS平台解析C++修饰函数名
macOS下clang生成的C++修饰名遵循Itanium ABI规范,使用LLVM自带的llvm-cxxfilt工具解析比系统默认的c++filt更准确(尤其是处理模板、命名空间等复杂场景):
解析单个修饰名:
llvm-cxxfilt __Z3foov # 输出对应的原函数名,比如foo()批量处理.dot文件中的所有修饰名:
用sed结合llvm-cxxfilt批量替换,生成可读性强的dot文件:sed -E 's/(__Z[a-zA-Z0-9_]+)/`echo \1 | llvm-cxxfilt`/g' original.dot | bash > readable.dot
对于模板函数的长修饰名,llvm-cxxfilt能完整还原模板参数和命名空间,比系统c++filt更可靠。
2. 精简调用图冗余节点
调用图过大通常是因为包含了标准库函数、编译器自动生成的辅助函数、inline展开节点等冗余内容,可通过以下方式精简:
方式一:生成阶段过滤冗余函数
编译时启用优化(如-O1/-O2)减少编译器生成的辅助函数,同时在生成dot后通过grep过滤不需要的节点:
# 过滤标准库(_ZNSt开头)、全局初始化函数、匿名命名空间函数 grep -v "_ZNSt\|__cxx_global_var_init\|_ZN12_GLOBAL__N_1" readable.dot > filtered.dot
如果只关心自己代码中的函数,可反向保留目标节点(假设你的代码在MyProject命名空间,修饰后前缀为_ZN9MyProject):
grep -E "(digraph|node|edge|_ZN9MyProject)" readable.dot > filtered.dot
方式二:用dot工具优化图形布局
利用Graphviz的dot工具自带选项压缩图形、修剪孤立节点:
# 修剪孤立节点+压缩布局+缩小字体 dot -Gprune=true -Gratio=compress -Nfontsize=8 -Tpng filtered.dot -o compact_callgraph.png
方式三:优化LLVM pass参数
生成调用图时,使用opt -dot-callgraph而非-print-callgraph,可避免无关的Pass::print not implemented提示(该提示不影响dot文件生成,也可直接忽略)。若需要更精准的过滤,可编写简单的LLVM小pass,在生成调用图前剔除冗余函数。
内容的提问来源于stack exchange,提问作者LiuYuan
相关产品推荐
相关产品推荐

