20 struct AddIOpInterface
21 :
public ValueBoundsOpInterface::ExternalModel<AddIOpInterface, AddIOp> {
24 auto addIOp = cast<AddIOp>(op);
25 assert(value == addIOp.getResult() &&
"invalid value");
35 cstr.
bound(value) == lhs + rhs;
39 struct ConstantOpInterface
40 :
public ValueBoundsOpInterface::ExternalModel<ConstantOpInterface,
44 auto constantOp = cast<ConstantOp>(op);
45 assert(value == constantOp.getResult() &&
"invalid value");
47 if (
auto attr = llvm::dyn_cast<IntegerAttr>(constantOp.getValue()))
48 cstr.
bound(value) == attr.getInt();
52 struct SubIOpInterface
53 :
public ValueBoundsOpInterface::ExternalModel<SubIOpInterface, SubIOp> {
56 auto subIOp = cast<SubIOp>(op);
57 assert(value == subIOp.getResult() &&
"invalid value");
61 cstr.
bound(value) == lhs - rhs;
65 struct MulIOpInterface
66 :
public ValueBoundsOpInterface::ExternalModel<MulIOpInterface, MulIOp> {
69 auto mulIOp = cast<MulIOp>(op);
70 assert(value == mulIOp.getResult() &&
"invalid value");
74 cstr.
bound(value) == lhs *rhs;
78 struct SelectOpInterface
79 :
public ValueBoundsOpInterface::ExternalModel<SelectOpInterface,
82 static void populateBounds(SelectOp selectOp, std::optional<int64_t> dim,
84 Value value = selectOp.getResult();
85 Value condition = selectOp.getCondition();
86 Value trueValue = selectOp.getTrueValue();
87 Value falseValue = selectOp.getFalseValue();
89 if (isa<ShapedType>(condition.
getType())) {
93 cstr.
bound(value)[*dim] == cstr.
getExpr(falseValue, dim);
102 auto boundsBuilder = cstr.
bound(value);
110 if (cstr.
compare({trueValue, dim},
111 ValueBoundsConstraintSet::ComparisonOperator::LE,
112 {falseValue, dim})) {
114 cstr.
bound(value)[*dim] >= cstr.
getExpr(trueValue, dim);
115 cstr.
bound(value)[*dim] <= cstr.
getExpr(falseValue, dim);
117 cstr.
bound(value) >= trueValue;
118 cstr.
bound(value) <= falseValue;
124 if (cstr.
compare({falseValue, dim},
125 ValueBoundsConstraintSet::ComparisonOperator::LE,
128 cstr.
bound(value)[*dim] >= cstr.
getExpr(falseValue, dim);
129 cstr.
bound(value)[*dim] <= cstr.
getExpr(trueValue, dim);
131 cstr.
bound(value) >= falseValue;
132 cstr.
bound(value) <= trueValue;
139 populateBounds(cast<SelectOp>(op), std::nullopt, cstr);
142 void populateBoundsForShapedValueDim(
Operation *op,
Value value, int64_t dim,
144 populateBounds(cast<SelectOp>(op), dim, cstr);
154 arith::AddIOp::attachInterface<arith::AddIOpInterface>(*ctx);
155 arith::ConstantOp::attachInterface<arith::ConstantOpInterface>(*ctx);
156 arith::SubIOp::attachInterface<arith::SubIOpInterface>(*ctx);
157 arith::MulIOp::attachInterface<arith::MulIOpInterface>(*ctx);
158 arith::SelectOp::attachInterface<arith::SelectOpInterface>(*ctx);
Base type for affine expression.
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.
static bool compare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
Return "true" if "lhs cmp rhs" was proven to hold.
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.
void populateConstraints(Value value, std::optional< int64_t > dim)
Traverse the IR starting from the given value/dim and populate constraints as long as the stop condit...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Type getType() const
Return the type of this value.
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.