@@ -67,8 +67,11 @@ 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) {
73+ assert (stopCondition && " expected non-null stop condition" );
74+ }
7275
7376char ValueBoundsConstraintSet::ID = 0 ;
7477
@@ -193,7 +196,8 @@ static Operation *getOwnerOfValue(Value value) {
193196 return value.getDefiningOp ();
194197}
195198
196- void ValueBoundsConstraintSet::processWorklist (StopConditionFn stopCondition) {
199+ void ValueBoundsConstraintSet::processWorklist () {
200+ LLVM_DEBUG (llvm::dbgs () << " Processing value bounds worklist...\n " );
197201 while (!worklist.empty ()) {
198202 int64_t pos = worklist.front ();
199203 worklist.pop ();
@@ -214,13 +218,19 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
214218
215219 // Do not process any further if the stop condition is met.
216220 auto maybeDim = dim == kIndexValue ? std::nullopt : std::make_optional (dim);
217- if (stopCondition (value, maybeDim))
221+ if (stopCondition (value, maybeDim, *this )) {
222+ LLVM_DEBUG (llvm::dbgs () << " Stop condition met for: " << value
223+ << " (dim: " << maybeDim << " )\n " );
218224 continue ;
225+ }
219226
220227 // Query `ValueBoundsOpInterface` for constraints. New items may be added to
221228 // the worklist.
222229 auto valueBoundsOp =
223230 dyn_cast<ValueBoundsOpInterface>(getOwnerOfValue (value));
231+ LLVM_DEBUG (llvm::dbgs ()
232+ << " Query value bounds for: " << value
233+ << " (owner: " << getOwnerOfValue (value)->getName () << " )\n " );
224234 if (valueBoundsOp) {
225235 if (dim == kIndexValue ) {
226236 valueBoundsOp.populateBoundsForIndexValue (value, *this );
@@ -229,6 +239,7 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
229239 }
230240 continue ;
231241 }
242+ LLVM_DEBUG (llvm::dbgs () << " --> ValueBoundsOpInterface not implemented\n " );
232243
233244 // If the op does not implement `ValueBoundsOpInterface`, check if it
234245 // implements the `DestinationStyleOpInterface`. OpResults of such ops are
@@ -278,8 +289,6 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
278289 bool closedUB) {
279290#ifndef NDEBUG
280291 assertValidValueDim (value, dim);
281- assert (!stopCondition (value, dim) &&
282- " stop condition should not be satisfied for starting point" );
283292#endif // NDEBUG
284293
285294 int64_t ubAdjustment = closedUB ? 0 : 1 ;
@@ -289,9 +298,11 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
289298 // Process the backward slice of `value` (i.e., reverse use-def chain) until
290299 // `stopCondition` is met.
291300 ValueDim valueDim = std::make_pair (value, dim.value_or (kIndexValue ));
292- ValueBoundsConstraintSet cstr (value.getContext ());
301+ ValueBoundsConstraintSet cstr (value.getContext (), stopCondition);
302+ assert (!stopCondition (value, dim, cstr) &&
303+ " stop condition should not be satisfied for starting point" );
293304 int64_t pos = cstr.insert (value, dim, /* isSymbol=*/ false );
294- cstr.processWorklist (stopCondition );
305+ cstr.processWorklist ();
295306
296307 // Project out all variables (apart from `valueDim`) that do not match the
297308 // stop condition.
@@ -301,7 +312,7 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
301312 return false ;
302313 auto maybeDim =
303314 p.second == kIndexValue ? std::nullopt : std::make_optional (p.second );
304- return !stopCondition (p.first , maybeDim);
315+ return !stopCondition (p.first , maybeDim, cstr );
305316 });
306317
307318 // Compute lower and upper bounds for `valueDim`.
@@ -407,7 +418,7 @@ LogicalResult ValueBoundsConstraintSet::computeDependentBound(
407418 bool closedUB) {
408419 return computeBound (
409420 resultMap, mapOperands, type, value, dim,
410- [&](Value v, std::optional<int64_t > d) {
421+ [&](Value v, std::optional<int64_t > d, ValueBoundsConstraintSet &cstr ) {
411422 return llvm::is_contained (dependencies, std::make_pair (v, d));
412423 },
413424 closedUB);
@@ -443,7 +454,9 @@ LogicalResult ValueBoundsConstraintSet::computeIndependentBound(
443454 // Reify bounds in terms of any independent values.
444455 return computeBound (
445456 resultMap, mapOperands, type, value, dim,
446- [&](Value v, std::optional<int64_t > d) { return isIndependent (v); },
457+ [&](Value v, std::optional<int64_t > d, ValueBoundsConstraintSet &cstr) {
458+ return isIndependent (v);
459+ },
447460 closedUB);
448461}
449462
@@ -476,43 +489,42 @@ FailureOr<int64_t> ValueBoundsConstraintSet::computeConstantBound(
476489 presburger::BoundType type, AffineMap map, ValueDimList operands,
477490 StopConditionFn stopCondition, bool closedUB) {
478491 assert (map.getNumResults () == 1 && " expected affine map with one result" );
479- ValueBoundsConstraintSet cstr (map.getContext ());
480492
481- int64_t pos = 0 ;
482- if (stopCondition) {
483- cstr.populateConstraintsSet (map, operands, stopCondition, &pos);
484- } else {
485- // No stop condition specified: Keep adding constraints until a bound could
486- // be computed.
487- cstr.populateConstraintsSet (
488- map, operands,
489- [&](Value v, std::optional<int64_t > dim) {
490- return cstr.cstr .getConstantBound64 (type, pos).has_value ();
491- },
492- &pos);
493- }
493+ // Default stop condition if none was specified: Keep adding constraints until
494+ // a bound could be computed.
495+ int64_t pos;
496+ auto defaultStopCondition = [&](Value v, std::optional<int64_t > dim,
497+ ValueBoundsConstraintSet &cstr) {
498+ return cstr.cstr .getConstantBound64 (type, pos).has_value ();
499+ };
500+
501+ ValueBoundsConstraintSet cstr (
502+ map.getContext (), stopCondition ? stopCondition : defaultStopCondition);
503+ cstr.populateConstraintsSet (map, operands, &pos);
504+
494505 // Compute constant bound for `valueDim`.
495506 int64_t ubAdjustment = closedUB ? 0 : 1 ;
496507 if (auto bound = cstr.cstr .getConstantBound64 (type, pos))
497508 return type == BoundType::UB ? *bound + ubAdjustment : *bound;
498509 return failure ();
499510}
500511
501- int64_t ValueBoundsConstraintSet::populateConstraintsSet (
502- Value value, std::optional<int64_t > dim, StopConditionFn stopCondition) {
512+ int64_t
513+ ValueBoundsConstraintSet::populateConstraintsSet (Value value,
514+ std::optional<int64_t > dim) {
503515#ifndef NDEBUG
504516 assertValidValueDim (value, dim);
505517#endif // NDEBUG
506518
507519 AffineMap map =
508520 AffineMap::get (/* dimCount=*/ 1 , /* symbolCount=*/ 0 ,
509521 Builder (value.getContext ()).getAffineDimExpr (0 ));
510- return populateConstraintsSet (map, {{value, dim}}, stopCondition );
522+ return populateConstraintsSet (map, {{value, dim}});
511523}
512524
513- int64_t ValueBoundsConstraintSet::populateConstraintsSet (
514- AffineMap map, ValueDimList operands, StopConditionFn stopCondition ,
515- int64_t *posOut) {
525+ int64_t ValueBoundsConstraintSet::populateConstraintsSet (AffineMap map,
526+ ValueDimList operands ,
527+ int64_t *posOut) {
516528 assert (map.getNumResults () == 1 && " expected affine map with one result" );
517529 int64_t pos = insert (/* isSymbol=*/ false );
518530 if (posOut)
@@ -533,13 +545,7 @@ int64_t ValueBoundsConstraintSet::populateConstraintsSet(
533545
534546 // Process the backward slice of `operands` (i.e., reverse use-def chain)
535547 // until `stopCondition` is met.
536- if (stopCondition) {
537- processWorklist (stopCondition);
538- } else {
539- // No stop condition specified: Keep adding constraints until the worklist
540- // is empty.
541- processWorklist ([](Value v, std::optional<int64_t > dim) { return false ; });
542- }
548+ processWorklist ();
543549
544550 return pos;
545551}
0 commit comments