21 :
public ValueBoundsOpInterface::ExternalModel<ForOpInterface, ForOp> {
45 static void populateIterArgBounds(scf::ForOp forOp,
Value value,
46 std::optional<int64_t> dim,
50 if (
auto iterArg = llvm::dyn_cast<BlockArgument>(value)) {
51 iterArgIdx = iterArg.getArgNumber() - forOp.getNumInductionVars();
53 iterArgIdx = llvm::cast<OpResult>(value).getResultNumber();
56 Value yieldedValue = cast<scf::YieldOp>(forOp.getBody()->getTerminator())
57 .getOperand(iterArgIdx);
58 Value iterArg = forOp.getRegionIterArg(iterArgIdx);
59 Value initArg = forOp.getInitArgs()[iterArgIdx];
65 ValueBoundsConstraintSet::ComparisonOperator::EQ,
67 if (dim.has_value()) {
77 auto forOp = cast<ForOp>(op);
79 if (value == forOp.getInductionVar()) {
81 cstr.
bound(value) >= forOp.getLowerBound();
82 cstr.
bound(value) < forOp.getUpperBound();
87 populateIterArgBounds(forOp, value, std::nullopt, cstr);
90 void populateBoundsForShapedValueDim(
Operation *op,
Value value, int64_t dim,
92 auto forOp = cast<ForOp>(op);
94 populateIterArgBounds(forOp, value, dim, cstr);
99 :
public ValueBoundsOpInterface::ExternalModel<IfOpInterface, IfOp> {
101 static void populateBounds(scf::IfOp ifOp,
Value value,
102 std::optional<int64_t> dim,
104 unsigned int resultNum = cast<OpResult>(value).getResultNumber();
105 Value thenValue = ifOp.thenYield().getResults()[resultNum];
106 Value elseValue = ifOp.elseYield().getResults()[resultNum];
108 auto boundsBuilder = cstr.
bound(value);
118 ValueBoundsConstraintSet::ComparisonOperator::LE,
121 cstr.
bound(value)[*dim] >= cstr.
getExpr(thenValue, dim);
122 cstr.
bound(value)[*dim] <= cstr.
getExpr(elseValue, dim);
124 cstr.
bound(value) >= thenValue;
125 cstr.
bound(value) <= elseValue;
133 ValueBoundsConstraintSet::ComparisonOperator::LE,
136 cstr.
bound(value)[*dim] >= cstr.
getExpr(elseValue, dim);
137 cstr.
bound(value)[*dim] <= cstr.
getExpr(thenValue, dim);
139 cstr.
bound(value) >= elseValue;
140 cstr.
bound(value) <= thenValue;
147 populateBounds(cast<IfOp>(op), value, std::nullopt, cstr);
150 void populateBoundsForShapedValueDim(
Operation *op,
Value value, int64_t dim,
152 populateBounds(cast<IfOp>(op), value, dim, cstr);
163 scf::ForOp::attachInterface<scf::ForOpInterface>(*ctx);
164 scf::IfOp::attachInterface<scf::IfOpInterface>(*ctx);
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
MLIRContext is the top-level object for a collection of MLIR operations.
Operation is the basic unit of execution within MLIR.
A helper class to be used with ValueBoundsOpInterface.
AffineExpr getExpr(Value value, std::optional< int64_t > dim=std::nullopt)
Return an expression that represents the given index-typed value or shaped value dimension.
BoundBuilder bound(Value value)
Add a bound for the given index-typed value or shaped value.
bool populateAndCompare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
Populate constraints for lhs/rhs (until the stop condition is met).
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.