@@ -191,52 +191,55 @@ void DependenceAnalysisWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
191191
192192namespace {
193193
194- // / The type of monotonicity of a SCEV. This property is defined with respect to
195- // / the outermost loop that DA is analyzing.
194+ // / The property of monotonicity of a SCEV. To define the monotonicity, assume
195+ // / a SCEV defined within N-nested loops. Let i_k denote the iteration number
196+ // / of the k-th loop. Then we can regard the SCEV as an N-ary function:
196197// /
197- // / This is designed to classify the behavior of AddRec expressions, and does
198- // / not care about other SCEVs. For example, given the two loop-invariant values
199- // / `A` and `B`, `A + B` is treated as Invariant even if the addition wraps.
198+ // / F(i_1, i_2, ..., i_N)
199+ // /
200+ // / The domain of i_k is the closed range [0, BTC_k], where BTC_k is the
201+ // / backedge-taken count of the k-th loop.
202+ // /
203+ // / A function F is said to be "monotonically increasing with respect to the
204+ // / k-th loop" if x <= y implies the following condition:
205+ // /
206+ // / F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) <=
207+ // / F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
208+ // /
209+ // / where i_1, ..., i_{k-1}, i_{k+1}, ..., i_N, x, y in their domains.
210+ // /
211+ // / Likewise F is "monotonically decreasing with respect to the k-th loop"
212+ // / if x <= y implies
213+ // /
214+ // / F(i_1, ..., i_{k-1}, x, i_{k+1}, ..., i_N) >=
215+ // / F(i_1, ..., i_{k-1}, y, i_{k+1}, ..., i_N)
216+ // /
217+ // / A function F with either monotonically increasing or decreasing with
218+ // / respect to the k-th loop is simply called
219+ // / "monotonic with respect to k-th loop".
220+ // /
221+ // / A function F is said to be "multimonotonic" when it is monotonic with
222+ // / respect to all of the N loops.
223+ // /
224+ // / Since integer comparison can be either signed or unsigned, we need to
225+ // / distinguish monotonicity in the signed sense from that in the unsigned
226+ // / sense. Note that the inequality "x <= y" merely indicates loop progression
227+ // / and is not affected by the difference between signed and unsigned order.
228+ // /
229+ // / Currently we only consider monotonicity in a signed sense.
200230enum class SCEVMonotonicityType {
201- // / The expression is neither loop-invariant nor monotonic (or we fail to
202- // / prove it).
231+ // / We don't know anything about the monotonicity of the SCEV.
203232 Unknown,
204233
205- // / The expression is loop-invariant with respect to the outermost loop.
234+ // / The SCEV is loop-invariant with respect to the outermost loop. In other
235+ // / words, the function F corresponding to the SCEV is a constant function.
206236 Invariant,
207237
208- // / The expression is a (nested) affine AddRec and is monotonically increasing
209- // / or decreasing in a signed sense with respect to each loop. Monotonicity is
210- // / checked independently for each loop, and the expression is classified as
211- // / MultiSignedMonotonic if all AddRecs are nsw. For example, in the following
212- // / loop:
213- // /
214- // / for (i = 0; i < 100; i++)
215- // / for (j = 0; j < 100; j++)
216- // / A[i + j] = ...;
217- // /
218- // / The SCEV for `i + j` is classified as MultiSignedMonotonic. On the other
219- // / hand, in the following loop:
220- // /
221- // / for (i = 0; i < 100; i++)
222- // / for (j = 0; j <= (1ULL << 63); j++)
223- // / A[i + j] = ...;
224- // /
225- // / The SCEV for `i + j` is NOT classified as MultiMonotonic, because the
226- // / AddRec for `j` wraps in a signed sense. We don't consider the "direction"
227- // / of each AddRec. For example, in the following loop:
228- // /
229- // / for (int i = 0; i < 100; i++)
230- // / for (int j = 0; j < 100; j++)
231- // / A[i - j] = ...;
232- // /
233- // / The SCEV for `i - j` is classified as MultiSignedMonotonic, even though it
234- // / contains both increasing and decreasing AddRecs.
235- // /
236- // / Note that we don't check if the step recurrence can be zero. For
237- // / example,an AddRec `{0,+,%a}<nsw> is classifed as Monotonic if `%a` can be
238- // / zero. That is, the expression can be Invariant.
239- MultiSignedMonotonic,
238+ // / The function F corresponding to the SCEV is multimonotonic in a signed
239+ // / sense. Note that the multimonotonic function may also be a constant
240+ // / function. The order employed in the definition of monotonicity is not
241+ // / strict order.
242+ MultivariateSignedMonotonic,
240243};
241244
242245struct SCEVMonotonicity {
@@ -881,8 +884,8 @@ void SCEVMonotonicity::print(raw_ostream &OS, unsigned Depth) const {
881884 case SCEVMonotonicityType::Invariant:
882885 OS << " Invariant\n " ;
883886 break ;
884- case SCEVMonotonicityType::MultiSignedMonotonic :
885- OS << " MultiSignedMonotonic \n " ;
887+ case SCEVMonotonicityType::MultivariateSignedMonotonic :
888+ OS << " MultivariateSignedMonotonic \n " ;
886889 break ;
887890 }
888891}
@@ -905,6 +908,8 @@ SCEVMonotonicityChecker::checkMonotonicity(const SCEV *Expr,
905908 return visit (Expr);
906909}
907910
911+ // / We only care about an affine AddRec at the moment. For an affine AddRec,
912+ // / the monotonicity can be inferred from its nowrap property.
908913SCEVMonotonicity
909914SCEVMonotonicityChecker::visitAddRecExpr (const SCEVAddRecExpr *Expr) {
910915 if (!Expr->isAffine () || !Expr->hasNoSignedWrap ())
@@ -920,7 +925,7 @@ SCEVMonotonicityChecker::visitAddRecExpr(const SCEVAddRecExpr *Expr) {
920925 if (!isLoopInvariant (Step))
921926 return createUnknown (Expr);
922927
923- return SCEVMonotonicity (SCEVMonotonicityType::MultiSignedMonotonic );
928+ return SCEVMonotonicity (SCEVMonotonicityType::MultivariateSignedMonotonic );
924929}
925930
926931// ===----------------------------------------------------------------------===//
0 commit comments