@@ -67,8 +67,11 @@ static std::optional<int64_t> getConstantIntValue(OpFoldResult ofr) {
67
67
return std::nullopt;
68
68
}
69
69
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
+ }
72
75
73
76
char ValueBoundsConstraintSet::ID = 0 ;
74
77
@@ -193,7 +196,8 @@ static Operation *getOwnerOfValue(Value value) {
193
196
return value.getDefiningOp ();
194
197
}
195
198
196
- void ValueBoundsConstraintSet::processWorklist (StopConditionFn stopCondition) {
199
+ void ValueBoundsConstraintSet::processWorklist () {
200
+ LLVM_DEBUG (llvm::dbgs () << " Processing value bounds worklist...\n " );
197
201
while (!worklist.empty ()) {
198
202
int64_t pos = worklist.front ();
199
203
worklist.pop ();
@@ -214,13 +218,19 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
214
218
215
219
// Do not process any further if the stop condition is met.
216
220
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 " );
218
224
continue ;
225
+ }
219
226
220
227
// Query `ValueBoundsOpInterface` for constraints. New items may be added to
221
228
// the worklist.
222
229
auto valueBoundsOp =
223
230
dyn_cast<ValueBoundsOpInterface>(getOwnerOfValue (value));
231
+ LLVM_DEBUG (llvm::dbgs ()
232
+ << " Query value bounds for: " << value
233
+ << " (owner: " << getOwnerOfValue (value)->getName () << " )\n " );
224
234
if (valueBoundsOp) {
225
235
if (dim == kIndexValue ) {
226
236
valueBoundsOp.populateBoundsForIndexValue (value, *this );
@@ -229,6 +239,7 @@ void ValueBoundsConstraintSet::processWorklist(StopConditionFn stopCondition) {
229
239
}
230
240
continue ;
231
241
}
242
+ LLVM_DEBUG (llvm::dbgs () << " --> ValueBoundsOpInterface not implemented\n " );
232
243
233
244
// If the op does not implement `ValueBoundsOpInterface`, check if it
234
245
// implements the `DestinationStyleOpInterface`. OpResults of such ops are
@@ -278,8 +289,6 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
278
289
bool closedUB) {
279
290
#ifndef NDEBUG
280
291
assertValidValueDim (value, dim);
281
- assert (!stopCondition (value, dim) &&
282
- " stop condition should not be satisfied for starting point" );
283
292
#endif // NDEBUG
284
293
285
294
int64_t ubAdjustment = closedUB ? 0 : 1 ;
@@ -289,9 +298,11 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
289
298
// Process the backward slice of `value` (i.e., reverse use-def chain) until
290
299
// `stopCondition` is met.
291
300
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" );
293
304
int64_t pos = cstr.insert (value, dim, /* isSymbol=*/ false );
294
- cstr.processWorklist (stopCondition );
305
+ cstr.processWorklist ();
295
306
296
307
// Project out all variables (apart from `valueDim`) that do not match the
297
308
// stop condition.
@@ -301,7 +312,7 @@ LogicalResult ValueBoundsConstraintSet::computeBound(
301
312
return false ;
302
313
auto maybeDim =
303
314
p.second == kIndexValue ? std::nullopt : std::make_optional (p.second );
304
- return !stopCondition (p.first , maybeDim);
315
+ return !stopCondition (p.first , maybeDim, cstr );
305
316
});
306
317
307
318
// Compute lower and upper bounds for `valueDim`.
@@ -407,7 +418,7 @@ LogicalResult ValueBoundsConstraintSet::computeDependentBound(
407
418
bool closedUB) {
408
419
return computeBound (
409
420
resultMap, mapOperands, type, value, dim,
410
- [&](Value v, std::optional<int64_t > d) {
421
+ [&](Value v, std::optional<int64_t > d, ValueBoundsConstraintSet &cstr ) {
411
422
return llvm::is_contained (dependencies, std::make_pair (v, d));
412
423
},
413
424
closedUB);
@@ -443,7 +454,9 @@ LogicalResult ValueBoundsConstraintSet::computeIndependentBound(
443
454
// Reify bounds in terms of any independent values.
444
455
return computeBound (
445
456
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
+ },
447
460
closedUB);
448
461
}
449
462
@@ -476,43 +489,42 @@ FailureOr<int64_t> ValueBoundsConstraintSet::computeConstantBound(
476
489
presburger::BoundType type, AffineMap map, ValueDimList operands,
477
490
StopConditionFn stopCondition, bool closedUB) {
478
491
assert (map.getNumResults () == 1 && " expected affine map with one result" );
479
- ValueBoundsConstraintSet cstr (map.getContext ());
480
492
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
+
494
505
// Compute constant bound for `valueDim`.
495
506
int64_t ubAdjustment = closedUB ? 0 : 1 ;
496
507
if (auto bound = cstr.cstr .getConstantBound64 (type, pos))
497
508
return type == BoundType::UB ? *bound + ubAdjustment : *bound;
498
509
return failure ();
499
510
}
500
511
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) {
503
515
#ifndef NDEBUG
504
516
assertValidValueDim (value, dim);
505
517
#endif // NDEBUG
506
518
507
519
AffineMap map =
508
520
AffineMap::get (/* dimCount=*/ 1 , /* symbolCount=*/ 0 ,
509
521
Builder (value.getContext ()).getAffineDimExpr (0 ));
510
- return populateConstraintsSet (map, {{value, dim}}, stopCondition );
522
+ return populateConstraintsSet (map, {{value, dim}});
511
523
}
512
524
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) {
516
528
assert (map.getNumResults () == 1 && " expected affine map with one result" );
517
529
int64_t pos = insert (/* isSymbol=*/ false );
518
530
if (posOut)
@@ -533,13 +545,7 @@ int64_t ValueBoundsConstraintSet::populateConstraintsSet(
533
545
534
546
// Process the backward slice of `operands` (i.e., reverse use-def chain)
535
547
// 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 ();
543
549
544
550
return pos;
545
551
}
0 commit comments