@@ -62,17 +62,15 @@ static bool canBeHoisted(Operation *op,
6262 auto thisOpIsSideEffecting = sideEffecting;
6363 if (thisOpIsSideEffecting != SideEffecting::Never) {
6464 thisOpIsSideEffecting = interface.isSideEffecting (op);
65- // If the op always has sideeffects , we cannot hoist.
65+ // If the op always has side effects , we cannot hoist.
6666 if (thisOpIsSideEffecting == SideEffecting::Always)
6767 return false ;
6868 }
6969 // Recurse into the regions for this op and check whether the contained ops
7070 // can be hoisted.
7171 for (auto ®ion : op->getRegions ()) {
7272 for (auto &block : region.getBlocks ()) {
73- for (auto &innerOp : block) {
74- if (innerOp.isKnownTerminator ())
75- continue ;
73+ for (auto &innerOp : block.without_terminator ()) {
7674 if (!canBeHoisted (&innerOp, definedOutside, thisOpIsSideEffecting,
7775 interface))
7876 return false ;
@@ -112,7 +110,7 @@ static LogicalResult moveLoopInvariantCode(LoopLikeOpInterface looplike,
112110 }
113111 }
114112
115- // For all instructions that we found to be invariant, move outside of the
113+ // For all operations that we found to be invariant, move outside of the
116114 // loop.
117115 auto result = looplike.moveOutOfLoop (opsToMove);
118116 LLVM_DEBUG (looplike.print (llvm::dbgs () << " Modified loop\n " ));
@@ -126,12 +124,16 @@ void LoopInvariantCodeMotion::runOnOperation() {
126124 // Walk through all loops in a function in innermost-loop-first order. This
127125 // way, we first LICM from the inner loop, and place the ops in
128126 // the outer loop, which in turn can be further LICM'ed.
129- getOperation ()->walk ([&](Operation *op) {
130- if (auto looplike = dyn_cast<LoopLikeOpInterface>(op)) {
131- LLVM_DEBUG (op->print (llvm::dbgs () << " \n Original loop\n " ));
132- if (failed (moveLoopInvariantCode (looplike, interface)))
133- signalPassFailure ();
134- }
127+ getOperation ()->walk ([&](LoopLikeOpInterface loopLikeOp) {
128+ // Skip zero trip count loops. For unknown trip counts, we still move
129+ // invariant code since it is side-effect free, and in general profitable.
130+ // TODO: when necessary, we could only move when the trip count is
131+ // guaranteed to be at least one.
132+ if (loopLikeOp.getConstantTripCount () == 0UL )
133+ return ;
134+ LLVM_DEBUG (loopLikeOp.print (llvm::dbgs () << " \n Original loop\n " ));
135+ if (failed (moveLoopInvariantCode (loopLikeOp, interface)))
136+ signalPassFailure ();
135137 });
136138}
137139
@@ -146,4 +148,4 @@ std::unique_ptr<Pass> mlir::createLoopInvariantCodeMotionPass() {
146148
147149static PassRegistration<LoopInvariantCodeMotion>
148150 pass (" loop-invariant-code-motion" ,
149- " Hoist loop invariant instructions outside of the loop" );
151+ " Hoist loop invariant operations outside of the loop" );
0 commit comments