20 struct AffineApplyOpInterface
21 :
public ValueBoundsOpInterface::ExternalModel<AffineApplyOpInterface,
25 auto applyOp = cast<AffineApplyOp>(op);
26 assert(value == applyOp.getResult() &&
"invalid value");
27 assert(applyOp.getAffineMap().getNumResults() == 1 &&
28 "expected single result");
40 for (int64_t i = 0, e = map.
getNumDims(); i < e; ++i)
41 dimReplacements.push_back(cstr.
getExpr(operands[i]));
45 symReplacements.push_back(cstr.
getExpr(operands[i]));
48 cstr.
bound(value) == bound;
52 struct AffineMinOpInterface
53 :
public ValueBoundsOpInterface::ExternalModel<AffineMinOpInterface,
57 auto minOp = cast<AffineMinOp>(op);
58 assert(value == minOp.getResult() &&
"invalid value");
61 for (
AffineExpr expr : minOp.getAffineMap().getResults()) {
63 minOp.getDimOperands(), [&](
Value v) { return cstr.getExpr(v); }));
65 minOp.getSymbolOperands(), [&](
Value v) { return cstr.getExpr(v); }));
68 cstr.
bound(value) <= bound;
73 struct AffineMaxOpInterface
74 :
public ValueBoundsOpInterface::ExternalModel<AffineMaxOpInterface,
78 auto maxOp = cast<AffineMaxOp>(op);
79 assert(value == maxOp.getResult() &&
"invalid value");
82 for (
AffineExpr expr : maxOp.getAffineMap().getResults()) {
84 maxOp.getDimOperands(), [&](
Value v) { return cstr.getExpr(v); }));
86 maxOp.getSymbolOperands(), [&](
Value v) { return cstr.getExpr(v); }));
89 cstr.
bound(value) >= bound;
94 struct AffineDelinearizeIndexOpInterface
95 :
public ValueBoundsOpInterface::ExternalModel<
96 AffineDelinearizeIndexOpInterface, AffineDelinearizeIndexOp> {
99 auto op = cast<AffineDelinearizeIndexOp>(rawOp);
100 auto result = cast<OpResult>(value);
101 assert(result.getOwner() == rawOp &&
102 "bounded value isn't a result of this delinearize_index");
103 unsigned resIdx = result.getResultNumber();
109 for (
OpFoldResult basisElem : llvm::drop_begin(basis, resIdx + 1))
110 divisor = divisor * cstr.
getExpr(basisElem);
114 if (!basis.front().isNull())
119 cstr.
bound(value) == (linearIdx % (thisBasis * divisor)).floorDiv(divisor);
123 struct AffineLinearizeIndexOpInterface
124 :
public ValueBoundsOpInterface::ExternalModel<
125 AffineLinearizeIndexOpInterface, AffineLinearizeIndexOp> {
128 auto op = cast<AffineLinearizeIndexOp>(rawOp);
130 "value isn't the result of this linearize");
136 unsigned numArgs = multiIndex.size();
137 for (
auto [revArgNum, length] :
llvm::enumerate(llvm::reverse(basis))) {
138 unsigned argNum = numArgs - (revArgNum + 1);
142 bound = bound + cstr.
getExpr(indexAsFoldRes) * stride;
143 stride = stride * cstr.
getExpr(length);
145 bound = bound + cstr.
getExpr(op.getMultiIndex().front()) * stride;
146 cstr.
bound(value) == bound;
147 if (op.getDisjoint() && !basis.front().isNull()) {
148 cstr.
bound(value) < stride *cstr.
getExpr(basis.front());
158 AffineApplyOp::attachInterface<AffineApplyOpInterface>(*ctx);
159 AffineMaxOp::attachInterface<AffineMaxOpInterface>(*ctx);
160 AffineMinOp::attachInterface<AffineMinOpInterface>(*ctx);
161 AffineDelinearizeIndexOp::attachInterface<
162 AffineDelinearizeIndexOpInterface>(*ctx);
163 AffineLinearizeIndexOp::attachInterface<AffineLinearizeIndexOpInterface>(
182 mapOperands.push_back(value1);
183 mapOperands.push_back(value2);
Base type for affine expression.
AffineExpr replaceDimsAndSymbols(ArrayRef< AffineExpr > dimReplacements, ArrayRef< AffineExpr > symReplacements) const
This method substitutes any uses of dimensions and symbols (e.g.
AffineExpr floorDiv(uint64_t v) const
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
unsigned getNumSymbols() const
unsigned getNumDims() const
AffineExpr getResult(unsigned idx) const
This class is a general helper class for creating context-global objects like types,...
AffineExpr getAffineDimExpr(unsigned position)
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.
This class represents a single result from folding an operation.
This class implements the operand iterators for the Operation class.
Operation is the basic unit of execution within MLIR.
OpResult getResult(unsigned idx)
Get the 'idx'th result of this operation.
A variable that can be added to the constraint set as a "column".
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.
static FailureOr< int64_t > computeConstantBound(presburger::BoundType type, const Variable &var, StopConditionFn stopCondition=nullptr, bool closedUB=false)
Compute a constant bound for the given variable.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
MLIRContext * getContext() const
Utility to get the associated MLIRContext that this value is defined in.
Type getType() const
Return the type of this value.
void fullyComposeAffineMapAndOperands(AffineMap *map, SmallVectorImpl< Value > *operands)
Given an affine map map and its input operands, this method composes into map, maps of AffineApplyOps...
void registerValueBoundsOpInterfaceExternalModels(DialectRegistry ®istry)
FailureOr< int64_t > fullyComposeAndComputeConstantDelta(Value value1, Value value2)
Compute a constant delta of the given two values.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
Include the generated interface declarations.
OpFoldResult getAsOpFoldResult(Value val)
Given a value, try to extract a constant Attribute.