只有一个可能的前任的 LLVM IR phi 节点
LLVM IR phi node with only one possible predecessor
当只有一个可能的前任时,使用 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>
如果只有一个可能的前任,上面的不应该和
完全一样吗
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
不要误会我的意思,我是 phi 节点的忠实粉丝,但我只是好奇在只有一个可能的前任节点时添加 phi 节点时除了提高可读性和警告之外是否还有其他好处.
当然,你是对的,两者是等价的。但是,前一个环路是 LCSSA(loop closed SSA)形式。这种形式提供了一些非常有用的保证,可以简化许多循环优化。
这不是 LLVM 特有的,GCC 也是如此。他们对 LCSSA 形式的具体好处进行了很好的总结:https://gcc.gnu.org/onlinedocs/gccint/LCSSA.html
在典型的编译通道管道中,LCSSA PHI 节点将在 InstCombine 通道优化循环后被删除。 (如果您 运行 在所有循环优化后选择 -instcombine
,您将获得预期的输出。)
当只有一个可能的前任时,使用 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>
如果只有一个可能的前任,上面的不应该和
完全一样吗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
不要误会我的意思,我是 phi 节点的忠实粉丝,但我只是好奇在只有一个可能的前任节点时添加 phi 节点时除了提高可读性和警告之外是否还有其他好处.
当然,你是对的,两者是等价的。但是,前一个环路是 LCSSA(loop closed SSA)形式。这种形式提供了一些非常有用的保证,可以简化许多循环优化。
这不是 LLVM 特有的,GCC 也是如此。他们对 LCSSA 形式的具体好处进行了很好的总结:https://gcc.gnu.org/onlinedocs/gccint/LCSSA.html
在典型的编译通道管道中,LCSSA PHI 节点将在 InstCombine 通道优化循环后被删除。 (如果您 运行 在所有循环优化后选择 -instcombine
,您将获得预期的输出。)