3

What is the benefit of using a phi node when there is only one possible predecessor? For example, when I run opt -loop-<some specific pass> some-cool-file.ll -S, the output will frequently include a phi node with only one possible predecessor if I haven't already added one.

Example:

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>

If there is only one possible predecessor shouldn't the above be exactly the same as

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

Don't get me wrong, I'm a huge fan of phi nodes, but I was just curious if there were any other benefits besides improving readability and warnings when adding a phi node when there is only one possible predecessor.

Daniel Robertson
  • 1,354
  • 13
  • 22

1 Answers1

7

Absolutely, you're right that the two are equivalent. However, the former loop is in LCSSA (loop closed SSA) form. This form provides some very useful guarantees which simplify many loop optimisations.

This isn't specific to LLVM, GCC does this as well. They have a nice summary of the concrete benefits of LCSSA form: https://gcc.gnu.org/onlinedocs/gccint/LCSSA.html

During a typical compilation pass pipeline the LCSSA PHI nodes will be removed after loop optimisations by the InstCombine pass. (If you run opt with -instcombine after all your loop optimisations, you'll get the output you expected.)

Cheng Sun
  • 1,025
  • 6
  • 9
  • Thanks! Another flawless answer! So my follow-up question is, I use a phi node at the start of every block (minus the entry) for the error messages and readability. Is that good or bad style? Or does it even matter as long as I use `-instcombine`? – Daniel Robertson Oct 08 '15 at 22:29
  • I guess there are two reasons why you may be concerned about error messages and readability: if you were handwriting IR for whatever reason, or while you were debugging a frontend that generates IR. Either way, what you do with the IR is completely up to you -- after all, an end-user should never have to know about IR, and LLVM doesn't care (because of InstCombine, and later because phi nodes are completely eliminated anyway). – Cheng Sun Oct 08 '15 at 22:42