LLVM不生成CFG

Eva*_*ldo 2 llvm clang

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

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

如果我使用-f,我会得到一个不可读的文件。

Nuu*_*lll 9

更新

  1. 警告是关于 的位码输出opt与点输出无关。您可以使用-disable-output禁用位码输出或使用-S生成人类可读的.ll文件来抑制警告。
  2. clang默认情况下将优化级别设置为-O0,因此每个函数都附加有optnone 属性,从而防止大多数优化过程操作该函数。
  3. opt最近启用了新的 Pass Manager(这里有解释,虽然有点过时),如果目标函数有optnone.
  4. -dot-cfg是可选通行证。

所以你的函数有optnoneattrubite,因为它是在 下编译的-O0,并且CFGPrinter跳过它,所以你不会得到任何点文件输出。

您有多种选择:

  1. 禁用optnone属性生成-O0
clang -S -emit-llvm foo.c -o foo.ll -disable-O0-optnone
Run Code Online (Sandbox Code Playgroud)
  1. 手动删除optnone属性foo.ll,然后保存。
  2. 使用时切换回旧版 Pass Manager opt
opt -dot-cfg foo.ll -disable-output -enable-new-pm=0
Run Code Online (Sandbox Code Playgroud)

注意:旧的 Pass Manager 确实尊重该optnone属性,但这是通过在skipFunction()真正想要这样做的 pass 中显式添加 a 来完成的。CFGPrinter在旧版通道管理器管道中不处理optnone,因此可以按预期转储点文件。

顺便说一句,点输出将直接写入名称以 a 开头的文件.(如果您未指定 的-cfg-dot-filename-prefix参数opt)。尝试ls -a

请参阅了解opt实施细节:

clang -S -emit-llvm foo.c -o foo.ll -disable-O0-optnone
Run Code Online (Sandbox Code Playgroud)