Question about handling inner loop in MachineLICM pass

Hi All,

I am looking at an example. It has a nested loop and the innermost loop has a loop invariant MIR as below.

Loop at depth 1 containing: %bb.2<header>,%bb.3,%bb.4,%bb.5,%bb.6,%bb.7,%bb.8<latch><exiting>
    Loop at depth 2 containing: %bb.4<header><latch><exiting>
    Loop at depth 2 containing: %bb.7<header><latch><exiting>

%bb.2: --> outer loop
%bb.3:
  %bb.4: --> inner loop
    loop invariant code
%bb.5:
%bb.6:
  %bb.7: --> inner loop
%bb.8:

I expected MachineLICM pass hoists it to %bb.3, which is preheader of the loop with %bb.4, but it is not hoisted. It looks the pass handles only outmost loop and the definition of the invariant code’s operand is in %bb.2 which is inside outer loop. In the end, the isLoopInvariant returns false for the loop invariant code… If the CurLoop is inner loop, the isLoopInvariant would return true.

I am not sure why the MachineLICM pass handles outmost loop in pre-regalloc stage… I think the pass could consider the inner loops…

Experimentally, I tried to handle the inner loops with below change.

diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index 4e80e9b58c06..702a92f7f389 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -374,10 +374,16 @@ bool MachineLICMBase::runOnMachineFunction(MachineFunction &MF) {

     // If this is done before regalloc, only visit outer-most preheader-sporting
     // loops.
+#if 0
     if (PreRegAlloc && !LoopIsOuterMostWithPredecessor(CurLoop)) {
       Worklist.append(CurLoop->begin(), CurLoop->end());
       continue;
     }
+#endif
+    if (PreRegAlloc && !CurLoop->isInnermost()) {
+      Worklist.append(CurLoop->begin(), CurLoop->end());
+      continue;
+    }

If someone know the reason or I missed something, please let me know.

Thanks
JinGu Kang

As an experiment, I have created a review. ⚙ D154205 [MachineLICM] Handle subloops