Skip to content

Commit a334530

Browse files
committed
[LCSSA] Doc for special treatment of PHIs
Differential Revision: https://reviews.llvm.org/D89739
1 parent 3556114 commit a334530

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

llvm/docs/LoopTerminology.rst

+42-5
Original file line numberDiff line numberDiff line change
@@ -291,10 +291,11 @@ Loop Closed SSA (LCSSA)
291291
A program is in Loop Closed SSA Form if it is in SSA form
292292
and all values that are defined in a loop are used only inside
293293
this loop.
294+
294295
Programs written in LLVM IR are always in SSA form but not necessarily
295-
in LCSSA. To achieve the latter, single entry PHI nodes are inserted
296-
at the end of the loops for all values that are live
297-
across the loop boundary [#lcssa-construction]_.
296+
in LCSSA. To achieve the latter, for each value that is live across the
297+
loop boundary, single entry PHI nodes are inserted to each of the exit blocks
298+
[#lcssa-construction]_ in order to "close" these values inside the loop.
298299
In particular, consider the following loop:
299300

300301
.. code-block:: C
@@ -336,8 +337,23 @@ scheduling a LoopPass.
336337
After the loop optimizations are done, these extra phi nodes
337338
will be deleted by :ref:`-instcombine <passes-instcombine>`.
338339

339-
The major benefit of this transformation is that it makes many other
340-
loop optimizations simpler.
340+
Note that an exit block is outside of a loop, so how can such a phi "close"
341+
the value inside the loop since it uses it outside of it ? First of all,
342+
for phi nodes, as
343+
`mentioned in the LangRef <https://llvm.org/docs/LangRef.html#id311>`_:
344+
"the use of each incoming value is deemed to occur on the edge from the
345+
corresponding predecessor block to the current block". Now, an
346+
edge to an exit block is considered outside of the loop because
347+
if we take that edge, it leads us clearly out of the loop.
348+
349+
However, an edge doesn't actually contain any IR, so in source code,
350+
we have to choose a convention of whether the use happens in
351+
the current block or in the respective predecessor. For LCSSA's purpose,
352+
we consider the use happens in the latter (so as to consider the
353+
use inside) [#point-of-use-phis]_.
354+
355+
The major benefit of LCSSA is that it makes many other loop optimizations
356+
simpler.
341357

342358
First of all, a simple observation is that if one needs to see all
343359
the outside users, they can just iterate over all the (loop closing)
@@ -436,6 +452,27 @@ the context / scope / relative loop.
436452
.. [#lcssa-construction] To insert these loop-closing PHI nodes, one has to
437453
(re-)compute dominance frontiers (if the loop has multiple exits).
438454
455+
.. [#point-of-use-phis] Considering the point of use of a PHI entry value
456+
to be in the respective predecessor is a convention across the whole LLVM.
457+
The reason is mostly practical; for example it preserves the dominance
458+
property of SSA. It is also just an overapproximation of the actual
459+
number of uses; the incoming block could branch to another block in which
460+
case the value is not actually used but there are no side-effects (it might
461+
increase its live range which is not relevant in LCSSA though).
462+
Furthermore, we can gain some intuition if we consider liveness:
463+
A PHI is *usually* inserted in the current block because the value can't
464+
be used from this point and onwards (i.e. the current block is a dominance
465+
frontier). It doesn't make sense to consider that the value is used in
466+
the current block (because of the PHI) since the value stops being live
467+
before the PHI. In some sense the PHI definition just "replaces" the original
468+
value definition and doesn't actually use it. It should be stressed that
469+
this analogy is only used as an example and does not pose any strict
470+
requirements. For example, the value might dominate the current block
471+
but we can still insert a PHI (as we do with LCSSA PHI nodes) *and*
472+
use the original value afterwards (in which case the two live ranges overlap,
473+
although in LCSSA (the whole point is that) we never do that).
474+
475+
439476
.. [#def-use-chain] A property of SSA is that there exists a def-use chain
440477
for each definition, which is a list of all the uses of this definition.
441478
LLVM implements this property by keeping a list of all the uses of a Value

llvm/lib/Analysis/LoopInfo.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,10 @@ static bool isBlockInLCSSAForm(const Loop &L, const BasicBlock &BB,
431431
for (const Use &U : I.uses()) {
432432
const Instruction *UI = cast<Instruction>(U.getUser());
433433
const BasicBlock *UserBB = UI->getParent();
434+
435+
// For practical purposes, we consider that the use in a PHI
436+
// occurs in the respective predecessor block. For more info,
437+
// see the `phi` doc in LangRef and the LCSSA doc.
434438
if (const PHINode *P = dyn_cast<PHINode>(UI))
435439
UserBB = P->getIncomingBlock(U);
436440

llvm/lib/Transforms/Utils/LCSSA.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,10 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
111111
for (Use &U : I->uses()) {
112112
Instruction *User = cast<Instruction>(U.getUser());
113113
BasicBlock *UserBB = User->getParent();
114+
115+
// For practical purposes, we consider that the use in a PHI
116+
// occurs in the respective predecessor block. For more info,
117+
// see the `phi` doc in LangRef and the LCSSA doc.
114118
if (auto *PN = dyn_cast<PHINode>(User))
115119
UserBB = PN->getIncomingBlock(U);
116120

@@ -160,7 +164,12 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
160164
I->getName() + ".lcssa");
161165
// Get the debug location from the original instruction.
162166
PN->setDebugLoc(I->getDebugLoc());
163-
// Add inputs from inside the loop for this PHI.
167+
168+
// Add inputs from inside the loop for this PHI. This is valid
169+
// because `I` dominates `ExitBB` (checked above). This implies
170+
// that every incoming block/edge is dominated by `I` as well,
171+
// i.e. we can add uses of `I` to those incoming edges/append to the incoming
172+
// blocks without violating the SSA dominance property.
164173
for (BasicBlock *Pred : PredCache.get(ExitBB)) {
165174
PN->addIncoming(I, Pred);
166175

@@ -194,15 +203,19 @@ bool llvm::formLCSSAForInstructions(SmallVectorImpl<Instruction *> &Worklist,
194203
// Rewrite all uses outside the loop in terms of the new PHIs we just
195204
// inserted.
196205
for (Use *UseToRewrite : UsesToRewrite) {
197-
// If this use is in an exit block, rewrite to use the newly inserted PHI.
198-
// This is required for correctness because SSAUpdate doesn't handle uses
199-
// in the same block. It assumes the PHI we inserted is at the end of the
200-
// block.
201206
Instruction *User = cast<Instruction>(UseToRewrite->getUser());
202207
BasicBlock *UserBB = User->getParent();
208+
209+
// For practical purposes, we consider that the use in a PHI
210+
// occurs in the respective predecessor block. For more info,
211+
// see the `phi` doc in LangRef and the LCSSA doc.
203212
if (auto *PN = dyn_cast<PHINode>(User))
204213
UserBB = PN->getIncomingBlock(*UseToRewrite);
205214

215+
// If this use is in an exit block, rewrite to use the newly inserted PHI.
216+
// This is required for correctness because SSAUpdate doesn't handle uses
217+
// in the same block. It assumes the PHI we inserted is at the end of the
218+
// block.
206219
if (isa<PHINode>(UserBB->begin()) && isExitBlock(UserBB, ExitBlocks)) {
207220
UseToRewrite->set(&UserBB->front());
208221
continue;

0 commit comments

Comments
 (0)