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