Index: llvm/docs/LoopTerminology.rst =================================================================== --- llvm/docs/LoopTerminology.rst +++ llvm/docs/LoopTerminology.rst @@ -170,4 +170,163 @@ "More Canonical" Loops ====================== -TBD +.. _loop-terminology-loop-rotate: + +Rotated Loops +------------- + +Loops are rotated by the LoopRotate (:ref:`loop-rotate `) +pass, which converts loops into do/while style loops and is +implemented in +`LoopRotation.h `_. Example: + +.. code-block:: C + + void test(int n) { + for (int i = 0; i < n; i += 1) + // Loop body + } + +is transformed to: + +.. code-block:: C + + void test(int n) { + int i = 0; + do { + // Loop body + i += 1; + } while (i < n); + } + +**Warning**: This transformation is valid only if the compiler +can prove that the loop body will be executed at least once. Otherwise, +it has to insert a guard which will test it at runtime. In the example +above, that would be: + +.. code-block:: C + + void test(int n) { + int i = 0; + if (n > 0) { + do { + // Loop body + i += 1; + } while (i < n); + } + } + +It's important to understand the effect of loop rotation +at the LLVM IR level. We follow with the previous examples +in LLVM IR while also providing a graphical reprensentation +of the control-flow graphs (CFG). You can get the same graphical +results by utilizing the `view-cfg ` pass. + +The initial **for** loop could be translated to: + +.. code-block:: none + + define void @test(i32 %n) { + entry: + br label %for.header + + for.header: + %i = phi i32 [ 0, %entry ], [ %i.next, %latch ] + %cond = icmp slt i32 %i, %n + br i1 %cond, label %body, label %exit + + body: + ; Loop body + br label %latch + + latch: + %i.next = add nsw i32 %i, 1 + br label %for.header + + exit: + ret void + } + +.. image:: ./loop-terminology-initial-loop.png + :width: 400 px + +The loop-rotate pass will effectively transform it to: + +.. code-block:: none + + define void @test(i32 %n) { + entry: + br label %body + + body: + %i = phi i32 [ 0, %entry ], [ %i.next, %latch ] + ; Loop body + br label %latch + + latch: + %i.next = add nsw i32 %i, 1 + %cond = icmp slt i32 %i.next, %n + br i1 %cond, label %body, label %exit + + exit: + ret void + } + +.. image:: ./loop-terminology-rotated-loop.png + :width: 400 px + +Note a couple of things: + +* The condition check was moved to the "bottom" of the loop, i.e. + the latch. Effectively this transformation copies the header + of the loop to the latch. +* It is obvious that the %body and %latch don't need to be separate. + loop-rotate will usually merge them. +* The compiler in this case can't deduce that the loop will + definitely execute at least once so the above transformation + is not valid. As mentioned above, a guard has to be inserted + resulting in the following: + +.. code-block:: none + + define void @test(i32 %n) { + entry: + %guard_cond = icmp slt i32 0, %n + br i1 %guard_cond, label %loop.preheader, label %exit + + loop.preheader: + br label %body + + body: + %i2 = phi i32 [ 0, %loop.preheader ], [ %i.next, %latch ] + br label %latch + + latch: + %i.next = add nsw i32 %i2, 1 + %cond = icmp slt i32 %i.next, %n + br i1 %cond, label %body, label %loop.exit + + loop.exit: + br label %exit + + exit: + ret void + } + +.. image:: ./loop-terminology-guarded-loop.png + :width: 500 px + +The result is a little bit more complicated than we may expect +because loop-rotate triggers the +:ref:`-loop-simplify ` pass to run. +In this case, it inserted the %loop.preheader basic block so +that the loop has a preheader and it introduced the %loop.exit +basic block so that the loop has dedicated exits +(otherwise, %exit would be jumped from both %latch and %entry, +but %entry is not contained in the loop). + +One of the advantages of this form is that it allows hoisting +invariant loads into the preheader. In non-rotated loops, a load in the +preaheader would be executed even if the memory was never accessed +in the original loop. That happens in the case that the loop is not +executed at all. Index: llvm/docs/Passes.rst =================================================================== --- llvm/docs/Passes.rst +++ llvm/docs/Passes.rst @@ -798,10 +798,14 @@ access for the first iteration, and then creating a new GEP instruction in the loop to increment the value by the appropriate amount. +.. _passes-loop-rotate: + ``-loop-rotate``: Rotate Loops ------------------------------ -A simple loop rotation transformation. +A simple loop rotation transformation. A summary of it can be found in +:ref:`Loop Terminology for Rotated Loops `. + .. _passes-loop-simplify: @@ -1194,6 +1198,8 @@ Note that this does not provide full security verification (like Java), but instead just tries to ensure that code is well-formed. +.. _passes-view-cfg: + ``-view-cfg``: View CFG of function -----------------------------------