@@ -74,7 +74,9 @@ bool isSignedPredicate(mlir::arith::CmpIPredicate p);
74
74
bool isaCountedLoop (cc::LoopOp op, bool allowClosedInterval = true );
75
75
76
76
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 );
78
80
79
81
// / An invariant loop is defined to be a loop that will execute some run-time
80
82
// / invariant number of iterations. We recognize a normalized, semi-open
@@ -88,6 +90,23 @@ bool isaInvariantLoop(cc::LoopOp op, bool allowClosedInterval = true,
88
90
bool allowEarlyExit = false , LoopComponents *c = nullptr );
89
91
bool isaInvariantLoop (const LoopComponents &c, bool allowClosedInterval);
90
92
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
+
91
110
// We expect the loop control value to have the following form.
92
111
//
93
112
// %final = cc.loop while ((%iter = %initial) -> (iN)) {
@@ -118,8 +137,9 @@ bool hasMonotonicControlInduction(cc::LoopOp loop, LoopComponents *c = nullptr);
118
137
// / ```
119
138
// / for(i = start; i < stop; i += step)
120
139
// / ```
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.
123
143
// / ```
124
144
// / let iterations = (stop - 1 - start + step) / step
125
145
// / iterations : if iterations > 0
@@ -130,6 +150,12 @@ bool hasMonotonicControlInduction(cc::LoopOp loop, LoopComponents *c = nullptr);
130
150
bool isaMonotonicLoop (mlir::Operation *op, bool allowEarlyExit = false ,
131
151
LoopComponents *c = nullptr );
132
152
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
+
133
159
// / Recover the different subexpressions from the loop if it conforms to the
134
160
// / pattern. Given a LoopOp where induction is in a register:
135
161
// / ```
0 commit comments