@@ -291,10 +291,11 @@ Loop Closed SSA (LCSSA)
291
291
A program is in Loop Closed SSA Form if it is in SSA form
292
292
and all values that are defined in a loop are used only inside
293
293
this loop.
294
+
294
295
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 .
298
299
In particular, consider the following loop:
299
300
300
301
.. code-block :: C
@@ -336,8 +337,23 @@ scheduling a LoopPass.
336
337
After the loop optimizations are done, these extra phi nodes
337
338
will be deleted by :ref: `-instcombine <passes-instcombine >`.
338
339
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.
341
357
342
358
First of all, a simple observation is that if one needs to see all
343
359
the outside users, they can just iterate over all the (loop closing)
@@ -436,6 +452,27 @@ the context / scope / relative loop.
436
452
.. [#lcssa-construction ] To insert these loop-closing PHI nodes, one has to
437
453
(re-)compute dominance frontiers (if the loop has multiple exits).
438
454
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
+
439
476
.. [#def-use-chain ] A property of SSA is that there exists a def-use chain
440
477
for each definition, which is a list of all the uses of this definition.
441
478
LLVM implements this property by keeping a list of all the uses of a Value
0 commit comments