LLVM 不生成 CFG

问题描述 投票:0回答:3

我有我用

foo.c
编译的程序
clang -c -emit-llvm foo.c -o foo.bc
。它返回一个
foo.bc
。 所以,我运行
opt -dot-cfg foo.bc
以获得
.dot
CFG。但是,我收到警告:

警告:您正在尝试打印位码文件。 这是不可取的,因为它可能会导致显示问题。如果 你真的想亲身体验 LLVM bitcode,你 可以使用

-f
选项强制输出。

如果我使用

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

clang llvm
3个回答
8
投票

更新

  1. WARNING是关于
    opt
    的位码输出,与点输出无关。您可以使用
    -disable-output
    禁用位码输出或使用
    -S
    生成人类可读的
    .ll
    文件来抑制警告。
  2. clang
    默认将优化级别设置为
    -O0
    ,因此每个功能都附加了
    optnone
    属性,防止大多数优化过程运行该功能。
  3. opt
    最近启用了新的通行证管理器(这里有解释,虽然有点过时),如果目标函数有optnone
    optional passes
    (IIUC,那些不影响功能)将自动跳过。
  4. -dot-cfg
    是可选通行证。

所以你的函数有

optnone
attrubite 因为它是在
-O0
下编译的,而
CFGPrinter
跳过它,所以你没有得到任何点文件输出。

您有多种选择:

  1. optnone
    下禁用
    -O0
    属性生成:
clang -S -emit-llvm foo.c -o foo.ll -disable-O0-optnone
  1. 手动删除
    optnone
    中的
    foo.ll
    属性,并保存。
  2. 使用时切换回旧版 Pass Manager
    opt
opt -dot-cfg foo.ll -disable-output -enable-new-pm=0

注意:旧版通行证管理器确实尊重

optnone
属性,但它是通过在真正想要这样做的通行证中明确添加
skipFunction()
来完成的。
CFGPrinter
不处理
optnone
所以在遗留的通行证管理器管道中,点文件可以按预期转储。

顺便说一句,点输出将直接写入名称以

.
开头的文件(如果您没有为
-cfg-dot-filename-prefix
指定
opt
参数)。试试
ls -a

this

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";
}

0
投票

修复 Nuullll 的答案

clang -Xclang -disable-O0-optnone -S -emit-llvm foo.c -o foo.ll 

需要在

-Xclang
前加上
-disable-O0-optnone


0
投票

没有足够的代表评论 Null 的回答,但最近在 master 分支上更改了标志:

opt -dot-cfg foo.ll -disable-output -bugpoint-disable-legacy-pm=1

© www.soinside.com 2019 - 2024. All rights reserved.