LLVM IR phi节点只有一个可能的前身

Dan*_*son 2 llvm ssa llvm-ir

当只有一个可能的前身时,使用phi节点有什么好处?例如,当我运行时opt -loop-<some specific pass> some-cool-file.ll -S,如果我还没有添加一个,那么输出通常会包含一个只有一个可能的前任的phi节点.

例:

endcond.loopexit:                      ; preds = %loop <- note: one predecessor
  %res.lcssa = phi i64 [ %res, %loop ] ; I'm assuming this is from the
  br label %endcond                    ; loop-closed ssa form pass

endcond:
  %var = phi i64 [ %res.lcssa, %endcond.loopexit ], <other-pred>
Run Code Online (Sandbox Code Playgroud)

如果只有一个可能的前任不应该与上面完全相同

endcond.loopexit:                      ; preds = %loop 
  br label %endcond                    ; res assigned a value in %loop

endcond:
  %var = phi i64 [ %res, %endcond.loopexit ], <other-pred> ; use %res directly
Run Code Online (Sandbox Code Playgroud)

不要误会我的意思,我是phi节点的忠实粉丝,但我只是好奇,除了在只有一个可能的前任时添加phi节点时提高可读性和警告还有其他好处.

Che*_*Sun 6

当然,你说这两个是等价的是正确的.但是,前一个循环是LCSSA(循环闭合SSA)形式.这种形式提供了一些非常有用的保证,简化了许多循环优化.

这不是LLVM特有的,GCC也是如此.他们对LCSSA表格的具体好处有一个很好的总结:https://gcc.gnu.org/onlinedocs/gccint/LCSSA.html

在典型的编译传递管道期间,LCSSA PHI节点将在InstCombine传递进行循环优化后被删除.(如果-instcombine在所有循环优化之后运行opt ,您将获得预期的输出.)