Update
- The WARNING关于位码输出
opt
,与点输出无关。您可以使用-disable-output
禁用位码输出或使用-S
生成人类可读的.ll
文件来抑制警告。
-
clang
将优化级别设置为-O0
默认情况下,因此每个函数都附加了optnone
属性 https://llvm.org/docs/LangRef.html#function-attributes,阻止大多数优化过程操作该函数。
-
opt
启用新的通行证管理器(这里的解释,虽然有点过时了 https://blog.llvm.org/posts/2021-03-26-the-new-pass-manager/)最近,以及可选通行证(IIUC,那些不影响功能)如果目标函数有,将自动跳过optnone
.
-
-dot-cfg
是可选通行证。
所以你的函数有optnone
属性,因为它是在下面编译的-O0
,以及CFGPrinter
跳过它,因此您不会得到任何点文件输出。
您有多种选择:
- Disable
optnone
属性生成下-O0
:
clang -S -emit-llvm foo.c -o foo.ll -disable-O0-optnone
- Remove
optnone
属性在foo.ll
手动,然后保存。
- 使用时切换回旧版 Pass Manager
opt
:
opt -dot-cfg foo.ll -disable-output -enable-new-pm=0
注意:旧版 Pass Manager 确实尊重optnone
属性,但它是通过显式添加一个来完成的skipFunction()
在真正想要这样做的通行证中。CFGPrinter
不处理optnone
因此,在旧版通道管理器管道中,可以按预期转储点文件。
顺便说一句,点输出将直接写入名称以 a 开头的文件中.
(如果您不指定-cfg-dot-filename-prefix
论证opt
). Try ls -a
!
See this https://llvm.org/doxygen/CFGPrinter_8cpp_source.html#l00058 for opt
实施细节:
static void writeCFGToDotFile(Function &F, BlockFrequencyInfo *BFI,
BranchProbabilityInfo *BPI, uint64_t MaxFreq,
bool CFGOnly = false) {
std::string Filename =
(CFGDotFilenamePrefix + "." + F.getName() + ".dot").str();
errs() << "Writing '" << Filename << "'...";
std::error_code EC;
raw_fd_ostream File(Filename, EC, sys::fs::OF_Text);
DOTFuncInfo CFGInfo(&F, BFI, BPI, MaxFreq);
CFGInfo.setHeatColors(ShowHeatColors);
CFGInfo.setEdgeWeights(ShowEdgeWeight);
CFGInfo.setRawEdgeWeights(UseRawEdgeWeight);
if (!EC)
WriteGraph(File, &CFGInfo, CFGOnly);
else
errs() << " error opening file for writing!";
errs() << "\n";
}