21 :
public ValueBoundsOpInterface::ExternalModel<AddIOpInterface, AddIOp> {
22 void populateBoundsForIndexValue(Operation *op, Value value,
23 ValueBoundsConstraintSet &cstr)
const {
24 auto addIOp = cast<AddIOp>(op);
25 assert(value == addIOp.getResult() &&
"invalid value");
33 AffineExpr
lhs = cstr.
getExpr(addIOp.getLhs());
34 AffineExpr
rhs = cstr.
getExpr(addIOp.getRhs());
39struct ConstantOpInterface
40 :
public ValueBoundsOpInterface::ExternalModel<ConstantOpInterface,
42 void populateBoundsForIndexValue(Operation *op, Value value,
43 ValueBoundsConstraintSet &cstr)
const {
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();
53 :
public ValueBoundsOpInterface::ExternalModel<SubIOpInterface, SubIOp> {
54 void populateBoundsForIndexValue(Operation *op, Value value,
55 ValueBoundsConstraintSet &cstr)
const {
56 auto subIOp = cast<SubIOp>(op);
57 assert(value == subIOp.getResult() &&
"invalid value");
59 AffineExpr
lhs = cstr.
getExpr(subIOp.getLhs());
60 AffineExpr
rhs = cstr.
getExpr(subIOp.getRhs());
66 :
public ValueBoundsOpInterface::ExternalModel<MulIOpInterface, MulIOp> {
67 void populateBoundsForIndexValue(Operation *op, Value value,
68 ValueBoundsConstraintSet &cstr)
const {
69 auto mulIOp = cast<MulIOp>(op);
70 assert(value == mulIOp.getResult() &&
"invalid value");
72 AffineExpr
lhs = cstr.
getExpr(mulIOp.getLhs());
73 AffineExpr
rhs = cstr.
getExpr(mulIOp.getRhs());
78struct FloorDivSIOpInterface
79 :
public ValueBoundsOpInterface::ExternalModel<FloorDivSIOpInterface,
81 void populateBoundsForIndexValue(Operation *op, Value value,
82 ValueBoundsConstraintSet &cstr)
const {
83 auto divSIOp = cast<FloorDivSIOp>(op);
84 assert(value == divSIOp.getResult() &&
"invalid value");
86 AffineExpr
lhs = cstr.
getExpr(divSIOp.getLhs());
87 AffineExpr
rhs = cstr.
getExpr(divSIOp.getRhs());
92struct SelectOpInterface
93 :
public ValueBoundsOpInterface::ExternalModel<SelectOpInterface,
96 static void populateBounds(SelectOp selectOp, std::optional<int64_t> dim,
97 ValueBoundsConstraintSet &cstr) {
98 Value value = selectOp.getResult();
99 Value condition = selectOp.getCondition();
100 Value trueValue = selectOp.getTrueValue();
101 Value falseValue = selectOp.getFalseValue();
103 if (isa<ShapedType>(condition.
getType())) {
106 cstr.
bound(value)[*dim] == cstr.
getExpr(trueValue, dim);
107 cstr.
bound(value)[*dim] == cstr.
getExpr(falseValue, dim);
108 cstr.
bound(value)[*dim] == cstr.
getExpr(condition, dim);
116 auto boundsBuilder = cstr.
bound(value);
127 {falseValue, dim})) {
129 cstr.
bound(value)[*dim] >= cstr.
getExpr(trueValue, dim);
130 cstr.
bound(value)[*dim] <= cstr.
getExpr(falseValue, dim);
132 cstr.
bound(value) >= trueValue;
133 cstr.
bound(value) <= falseValue;
144 cstr.
bound(value)[*dim] >= cstr.
getExpr(falseValue, dim);
145 cstr.
bound(value)[*dim] <= cstr.
getExpr(trueValue, dim);
147 cstr.
bound(value) >= falseValue;
148 cstr.
bound(value) <= trueValue;
153 void populateBoundsForIndexValue(Operation *op, Value value,
154 ValueBoundsConstraintSet &cstr)
const {
155 populateBounds(cast<SelectOp>(op), std::nullopt, cstr);
158 void populateBoundsForShapedValueDim(Operation *op, Value value, int64_t dim,
159 ValueBoundsConstraintSet &cstr)
const {
160 populateBounds(cast<SelectOp>(op), dim, cstr);
170 arith::AddIOp::attachInterface<arith::AddIOpInterface>(*ctx);
171 arith::ConstantOp::attachInterface<arith::ConstantOpInterface>(*ctx);
172 arith::SubIOp::attachInterface<arith::SubIOpInterface>(*ctx);
173 arith::MulIOp::attachInterface<arith::MulIOpInterface>(*ctx);
174 arith::FloorDivSIOp::attachInterface<arith::FloorDivSIOpInterface>(*ctx);
175 arith::SelectOp::attachInterface<arith::SelectOpInterface>(*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.
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...
bool populateAndCompare(const Variable &lhs, ComparisonOperator cmp, const Variable &rhs)
Populate constraints for lhs/rhs (until the stop condition is met).
Type getType() const
Return the type of this value.
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
Include the generated interface declarations.