【问题标题】:simplifyCFG pass in llvmllvm 中的简化CFG 传递
【发布时间】:2017-11-19 11:53:51
【问题描述】:

我试图在 LLVM 中运行简化 CFG Pass,并在运行我自己的一个 IR 转换后删除一个无法访问的基本块,但我一直得到 错误 -

删除时:i8* %g

使用在 Def 被销毁后仍然卡住:store i8 0, i8* %g

我很清楚这意味着什么,但“simplifyCFGPass”的全部目的不就是为我们删除无法访问的基本块吗?为什么它必须抛出这个错误?我认为它应该能够简单地管理所有 use-def 依赖项并删除下面无法访问的“继续”基本块中的指令。

以下是相关的 IR -

entry:
  %a3 = alloca i32
  store i32 %a, i32* %a3
  %a4 = load i32, i32* %a3 
  %ifcond = icmp ne i32 %a4, 0
  br i1 %ifcond, label %then, label %else



then:                                             ; preds = %entry
  %gclone1 = alloca i32
  store i32 0, i32* %gclone1
  ret i5 0

else:                                             ; preds = %entry
  %gclone4 = alloca i64
  store i64 0, i64* %gclone4
  ret i5 0

continuation:                                     ; No predecessors!
  %iftmp = phi i32 [ 32, %then ], [ 64, %else ], !range !0
  %datasize = alloca i32
  store i32 %iftmp, i32* %datasize

  %g = alloca i8 ---------------------> Issue
  store i8 0, i8* %g ---------------------> Issue
  ret i5 0
}

有人能解释一下为什么会出现这个错误吗? API 不应该处理这个吗?

【问题讨论】:

  • 在您运行转换或运行 simpleCFGPass 时是否会出现此错误?
  • 我运行 CFG 通行证(使用 FPM->run(*F) )...我的通行证只是一些改变 IR 的 C++ 代码,我没有在 opt 工具或任何东西中使用它像那样...

标签: llvm control-flow-graph


【解决方案1】:

您的 IR 显然已损坏。你有:

%iftmp = phi i32 [ 32, %then ], [ 64, %else ], !range !0

但是,根据 LLVM IR 规范 (http://llvm.org/docs/LangRef.html#phi-instruction):

传入值的类型用第一种类型指定 场地。在此之后,“phi”指令将一个对列表作为 参数,每个前导基本块都有一对 当前块。只有第一类类型的值可以用作 PHI 节点的值参数。只有标签可以用作标签 论据。

这显然违反了您的情况,因此后续的 IR 转换传递可能很容易失败。我建议您在转换通过后运行 IR 验证通过(例如通过 opt -verify)。

【讨论】:

  • 不。我想我已经在“运行我自己的一个 IR 转换后删除无法访问的基本块”这个问题中明确提到过。 phi 节点未损坏(验证者通过未检测到问题)
  • phi 节点肯定坏了。 %else 和 %then 都不是 %continuation 的前身
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-16
  • 2016-07-10
相关资源
最近更新 更多