@@ -67,8 +67,9 @@ static std::optional<int64_t> getConstantIntValue(OpFoldResult ofr) {
6767 return std::nullopt ;
6868}
6969
70- ValueBoundsConstraintSet::ValueBoundsConstraintSet (MLIRContext *ctx)
71- : builder(ctx) {}
70+ ValueBoundsConstraintSet::ValueBoundsConstraintSet (
71+ MLIRContext *ctx, StopConditionFn stopCondition)
72+ : builder(ctx), stopCondition(stopCondition) {}
7273
7374#ifndef NDEBUG
7475static void assertValidValueDim (Value value, std::optional<int64_t > dim) {
@@ -228,7 +229,8 @@ static Operation *getOwnerOfValue(Value value) {
228229 return value.getDefiningOp ();
229230}
230231
231- void ValueBoundsConstraintSet::processWorklist (StopConditionFn stopCondition) {
232+ void ValueBoundsConstraintSet::processWorklist () {
233+ LLVM_DEBUG (llvm::dbgs () << " Processing value bounds worklist...\n " );
232234 while (!worklist.empty ()) {
233235 int64_t pos = worklist.front ();
234236 worklist.pop ();
@@ -249,13 +251,19 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
249251
250252 // Do not process any further if the stop condition is met.
251253 auto maybeDim = dim == kIndexValue ? std::nullopt : std::make_optional (dim);
252- if (stopCondition (value, maybeDim))
254+ if (stopCondition (value, maybeDim, *this )) {
255+ LLVM_DEBUG (llvm::dbgs () << " Stop condition met for: " << value
256+ << " (dim: " << maybeDim << " )\n " );
253257 continue ;
258+ }
254259
255260 // Query `ValueBoundsOpInterface` for constraints. New items may be added to
256261 // the worklist.
257262 auto valueBoundsOp =
258263 dyn_cast<ValueBoundsOpInterface>(getOwnerOfValue (value));
264+ LLVM_DEBUG (llvm::dbgs ()
265+ << " Query value bounds for: " << value
266+ << " (owner: " << getOwnerOfValue (value)->getName () << " )\n " );
259267 if (valueBoundsOp) {
260268 if (dim == kIndexValue ) {
261269 valueBoundsOp.populateBoundsForIndexValue (value, *this );
@@ -264,6 +272,7 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
264272 }
265273 continue ;
266274 }
275+ LLVM_DEBUG (llvm::dbgs () << " --> ValueBoundsOpInterface not implemented\n " );
267276
268277 // If the op does not implement `ValueBoundsOpInterface`, check if it
269278 // implements the `DestinationStyleOpInterface`. OpResults of such ops are
@@ -313,8 +322,6 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
313322 bool closedUB) {
314323#ifndef NDEBUG
315324 assertValidValueDim (value, dim);
316- assert (!stopCondition (value, dim) &&
317- " stop condition should not be satisfied for starting point" );
318325#endif // NDEBUG
319326
320327 int64_t ubAdjustment = closedUB ? 0 : 1 ;
@@ -324,9 +331,11 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
324331 // Process the backward slice of `value` (i.e., reverse use-def chain) until
325332 // `stopCondition` is met.
326333 ValueDim valueDim = std::make_pair (value, dim.value_or (kIndexValue ));
327- ValueBoundsConstraintSet cstr (value.getContext ());
334+ ValueBoundsConstraintSet cstr (value.getContext (), stopCondition);
335+ assert (!stopCondition (value, dim, cstr) &&
336+ " stop condition should not be satisfied for starting point" );
328337 int64_t pos = cstr.insert (value, dim, /* isSymbol=*/ false );
329- cstr.processWorklist (stopCondition );
338+ cstr.processWorklist ();
330339
331340 // Project out all variables (apart from `valueDim`) that do not match the
332341 // stop condition.
@@ -336,7 +345,7 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
336345 return false ;
337346 auto maybeDim =
338347 p.second == kIndexValue ? std::nullopt : std::make_optional (p.second );
339- return !stopCondition (p.first , maybeDim);
348+ return !stopCondition (p.first , maybeDim, cstr );
340349 });
341350
342351 // Compute lower and upper bounds for `valueDim`.
@@ -442,7 +451,7 @@ LogicalResult ValueBoundsConstraintSet::computeDependentBound(
442451 bool closedUB) {
443452 return computeBound (
444453 resultMap, mapOperands, type, value, dim,
445- [&](Value v, std::optional<int64_t > d) {
454+ [&](Value v, std::optional<int64_t > d, ValueBoundsConstraintSet &cstr ) {
446455 return llvm::is_contained (dependencies, std::make_pair (v, d));
447456 },
448457 closedUB);
@@ -478,7 +487,9 @@ LogicalResult ValueBoundsConstraintSet::computeIndependentBound(
478487 // Reify bounds in terms of any independent values.
479488 return computeBound (
480489 resultMap, mapOperands, type, value, dim,
481- [&](Value v, std::optional<int64_t > d) { return isIndependent (v); },
490+ [&](Value v, std::optional<int64_t > d, ValueBoundsConstraintSet &cstr) {
491+ return isIndependent (v);
492+ },
482493 closedUB);
483494}
484495
@@ -500,8 +511,18 @@ FailureOr<int64_t> ValueBoundsConstraintSet::computeConstantBound(
500511 presburger::BoundType type, AffineMap map, ValueDimList operands,
501512 StopConditionFn stopCondition, bool closedUB) {
502513 assert (map.getNumResults () == 1 && " expected affine map with one result" );
503- ValueBoundsConstraintSet cstr (map.getContext ());
504- int64_t pos = cstr.insert (/* isSymbol=*/ false );
514+
515+ // Default stop condition if none was specified: Keep adding constraints until
516+ // a bound could be computed.
517+ int64_t pos;
518+ auto defaultStopCondition = [&](Value v, std::optional<int64_t > dim,
519+ ValueBoundsConstraintSet &cstr) {
520+ return cstr.cstr .getConstantBound64 (type, pos).has_value ();
521+ };
522+
523+ ValueBoundsConstraintSet cstr (
524+ map.getContext (), stopCondition ? stopCondition : defaultStopCondition);
525+ pos = cstr.insert (/* isSymbol=*/ false );
505526
506527 // Add map and operands to the constraint set. Dimensions are converted to
507528 // symbols. All operands are added to the worklist.
@@ -517,17 +538,8 @@ FailureOr<int64_t> ValueBoundsConstraintSet::computeConstantBound(
517538 map.getResult (0 ).replaceDimsAndSymbols (dimReplacements, symReplacements));
518539
519540 // Process the backward slice of `operands` (i.e., reverse use-def chain)
520- // until `stopCondition` is met.
521- if (stopCondition) {
522- cstr.processWorklist (stopCondition);
523- } else {
524- // No stop condition specified: Keep adding constraints until a bound could
525- // be computed.
526- cstr.processWorklist (
527- /* stopCondition=*/ [&](Value v, std::optional<int64_t > dim) {
528- return cstr.cstr .getConstantBound64 (type, pos).has_value ();
529- });
530- }
541+ // until the stop condition is met.
542+ cstr.processWorklist ();
531543
532544 // Compute constant bound for `valueDim`.
533545 int64_t ubAdjustment = closedUB ? 0 : 1 ;
0 commit comments