@@ -62,17 +62,15 @@ static bool canBeHoisted(Operation *op,
62
62
auto thisOpIsSideEffecting = sideEffecting;
63
63
if (thisOpIsSideEffecting != SideEffecting::Never) {
64
64
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.
66
66
if (thisOpIsSideEffecting == SideEffecting::Always)
67
67
return false ;
68
68
}
69
69
// Recurse into the regions for this op and check whether the contained ops
70
70
// can be hoisted.
71
71
for (auto ®ion : op->getRegions ()) {
72
72
for (auto &block : region.getBlocks ()) {
73
- for (auto &innerOp : block) {
74
- if (innerOp.isKnownTerminator ())
75
- continue ;
73
+ for (auto &innerOp : block.without_terminator ()) {
76
74
if (!canBeHoisted (&innerOp, definedOutside, thisOpIsSideEffecting,
77
75
interface))
78
76
return false ;
@@ -112,7 +110,7 @@ static LogicalResult moveLoopInvariantCode(LoopLikeOpInterface looplike,
112
110
}
113
111
}
114
112
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
116
114
// loop.
117
115
auto result = looplike.moveOutOfLoop (opsToMove);
118
116
LLVM_DEBUG (looplike.print (llvm::dbgs () << " Modified loop\n " ));
@@ -126,12 +124,16 @@ void LoopInvariantCodeMotion::runOnOperation() {
126
124
// Walk through all loops in a function in innermost-loop-first order. This
127
125
// way, we first LICM from the inner loop, and place the ops in
128
126
// 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 () == uint64_t (0 ))
133
+ return ;
134
+ LLVM_DEBUG (loopLikeOp.print (llvm::dbgs () << " \n Original loop\n " ));
135
+ if (failed (moveLoopInvariantCode (loopLikeOp, interface)))
136
+ signalPassFailure ();
135
137
});
136
138
}
137
139
@@ -146,4 +148,4 @@ std::unique_ptr<Pass> mlir::createLoopInvariantCodeMotionPass() {
146
148
147
149
static PassRegistration<LoopInvariantCodeMotion>
148
150
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