LLVM不生成CFG

2024-01-30

我有程序foo.c我用它编译clang -c -emit-llvm foo.c -o foo.bc。它返回一个foo.bc。 所以,我跑opt -dot-cfg foo.bc为了获得一个.dotCFG。但是,我收到警告:

警告:您正在尝试打印位码文件。 这是不可取的,因为它可能会导致显示问题。如果 你真的很想亲身体验 LLVM 位代码,你 可以强制输出-f option.

如果我使用-f,我得到一个无法读取的文件。


Update

  1. The WARNING关于位码输出opt,与点输出无关。您可以使用-disable-output禁用位码输出或使用-S生成人类可读的.ll文件来抑制警告。
  2. clang将优化级别设置为-O0默认情况下,因此每个函数都附加了optnone 属性 https://llvm.org/docs/LangRef.html#function-attributes,阻止大多数优化过程操作该函数。
  3. opt启用新的通行证管理器(这里的解释,虽然有点过时了 https://blog.llvm.org/posts/2021-03-26-the-new-pass-manager/)最近,以及可选通行证(IIUC,那些不影响功能)如果目标函数有,将自动跳过optnone.
  4. -dot-cfg是可选通行证。

所以你的函数有optnone属性,因为它是在下面编译的-O0,以及CFGPrinter跳过它,因此您不会得到任何点文件输出。

您有多种选择:

  1. Disable optnone属性生成下-O0:
clang -S -emit-llvm foo.c -o foo.ll -disable-O0-optnone
  1. Remove optnone属性在foo.ll手动,然后保存。
  2. 使用时切换回旧版 Pass Manageropt:
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";
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

LLVM不生成CFG 的相关文章

随机推荐