Skip to content

Commit bf0d50a

Browse files
authored
[core] Update some of the terms and comments in loop analysis. (#3351)
Signed-off-by: Eric Schweitz <[email protected]>
1 parent 9653cc9 commit bf0d50a

File tree

3 files changed

+36
-11
lines changed

3 files changed

+36
-11
lines changed

lib/Optimizer/Transforms/LoopAnalysis.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ using namespace mlir;
3030
/// A \em monotonic loop: a loop that counts from $i$ up to (down to) $j$
3131
/// stepping by positive (negative) integral values; mathematically, it is a
3232
/// strictly monotonic sequence. If the step is a compile-time constant, $k$,
33-
/// then a closed iterval monotonic loop must execute exactly $\max(0, \floor{(j
34-
/// - i + k) / k})$ iterations. By normalizing a monotonic loop and constant
35-
/// folding and propagation, we may be able to convert it to static control
36-
/// flow.
33+
/// then a closed iterval definite monotonic loop must execute exactly $\max(0,
34+
/// \floor{(j - i + k) / k})$ iterations. By normalizing a monotonic loop and
35+
/// constant folding and propagation, we may be able to convert it to static
36+
/// control flow.
3737
///
3838
/// For completeness, a \em{conditionally iterated} loop is a monotonic loop
3939
/// that has a second auxilliary condition to determine if a given loop
@@ -309,10 +309,9 @@ bool opt::isaCountedLoop(cc::LoopOp loop, bool allowClosedInterval) {
309309
isaConstant(c.compareValue);
310310
}
311311

312-
bool opt::isaConstantUpperBoundLoop(cc::LoopOp loop, bool allowClosedInterval) {
312+
bool opt::isaIndefiniteCountedLoop(cc::LoopOp loop, bool allowClosedInterval) {
313313
LoopComponents c;
314-
return isaInvariantLoop(loop, allowClosedInterval, /*allowEarlyExit=*/true,
315-
&c) &&
314+
return isaIndefiniteInvariantLoop(loop, allowClosedInterval, &c) &&
316315
isaConstant(c.compareValue);
317316
}
318317

lib/Optimizer/Transforms/LoopAnalysis.h

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ bool isSignedPredicate(mlir::arith::CmpIPredicate p);
7474
bool isaCountedLoop(cc::LoopOp op, bool allowClosedInterval = true);
7575

7676
bool loopContainsBreak(cc::LoopOp op);
77-
bool isaConstantUpperBoundLoop(cc::LoopOp op, bool allowClosedInterval = true);
77+
78+
/// An indefinite counted loop is a counted loop which may have early exits.
79+
bool isaIndefiniteCountedLoop(cc::LoopOp op, bool allowClosedInterval = true);
7880

7981
/// An invariant loop is defined to be a loop that will execute some run-time
8082
/// invariant number of iterations. We recognize a normalized, semi-open
@@ -88,6 +90,23 @@ bool isaInvariantLoop(cc::LoopOp op, bool allowClosedInterval = true,
8890
bool allowEarlyExit = false, LoopComponents *c = nullptr);
8991
bool isaInvariantLoop(const LoopComponents &c, bool allowClosedInterval);
9092

93+
/// An indefinite invariant loop is an invariant loop which may have early
94+
/// exits. The number of iterations will be at most the upper bound expression.
95+
/// We recognize the normalized, semi-open interval loop such as
96+
/// ```
97+
/// for(i = 0; i < invariant_expression; ++i) {
98+
/// ...
99+
/// break;
100+
/// ...
101+
/// }
102+
/// ```
103+
/// is a canonical indefinite loop.
104+
inline bool isaIndefiniteInvariantLoop(cc::LoopOp op,
105+
bool allowClosedInterval = true,
106+
LoopComponents *c = nullptr) {
107+
return isaInvariantLoop(op, allowClosedInterval, /*allowEarlyExit=*/true, c);
108+
}
109+
91110
// We expect the loop control value to have the following form.
92111
//
93112
// %final = cc.loop while ((%iter = %initial) -> (iN)) {
@@ -118,8 +137,9 @@ bool hasMonotonicControlInduction(cc::LoopOp loop, LoopComponents *c = nullptr);
118137
/// ```
119138
/// for(i = start; i < stop; i += step)
120139
/// ```
121-
/// is a monotonic loop that must execute a number of iterations as given
122-
/// by the following equation. Early exits (break statements) are not permitted.
140+
/// is a (definite) monotonic loop that must execute a number of iterations as
141+
/// given by the following equation. Early exits (break statements) are
142+
/// permitted in \e indefinite monotonic loops.
123143
/// ```
124144
/// let iterations = (stop - 1 - start + step) / step
125145
/// iterations : if iterations > 0
@@ -130,6 +150,12 @@ bool hasMonotonicControlInduction(cc::LoopOp loop, LoopComponents *c = nullptr);
130150
bool isaMonotonicLoop(mlir::Operation *op, bool allowEarlyExit = false,
131151
LoopComponents *c = nullptr);
132152

153+
/// An indefinite monotonic loop is a monotonic loop that may have early exits.
154+
inline bool isaIndefiniteMonotonicLoop(mlir::Operation *op,
155+
LoopComponents *c = nullptr) {
156+
return isaMonotonicLoop(op, /*allowEarlyExit=*/true, c);
157+
}
158+
133159
/// Recover the different subexpressions from the loop if it conforms to the
134160
/// pattern. Given a LoopOp where induction is in a register:
135161
/// ```

lib/Optimizer/Transforms/LoopUnrollPatterns.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct UnrollCountedLoop : public OpRewritePattern<cudaq::cc::LoopOp> {
7272
loop.emitOpError("not a simple counted loop");
7373
return failure();
7474
}
75-
if (allowBreak && !cudaq::opt::isaConstantUpperBoundLoop(loop)) {
75+
if (allowBreak && !cudaq::opt::isaIndefiniteCountedLoop(loop)) {
7676
if (signalFailure)
7777
loop.emitOpError("not a constant upper bound loop");
7878
return failure();

0 commit comments

Comments
 (0)