14 FailureOr<ConstantOrScalableBound::BoundSize>
20 auto binop = dyn_cast<AffineBinaryOpExpr>(
map.
getResult(0));
23 auto matchConstant = [&](
AffineExpr expr, int64_t &constant) ->
bool {
24 if (
auto cst = dyn_cast<AffineConstantExpr>(expr)) {
25 constant = cst.getValue();
32 auto lhs = binop.getLHS();
33 auto rhs = binop.getRHS();
34 if ((matchConstant(lhs, cst) && isa<AffineSymbolExpr>(rhs)) ||
35 (matchConstant(rhs, cst) && isa<AffineSymbolExpr>(lhs))) {
43 FailureOr<ConstantOrScalableBound>
45 Value value, std::optional<int64_t> dim,
unsigned vscaleMin,
48 using namespace presburger;
49 assert(vscaleMin <= vscaleMax);
53 auto defaultStopCondition = [&](
Value v, std::optional<int64_t> dim,
59 value.
getContext(), stopCondition ? stopCondition : defaultStopCondition,
60 vscaleMin, vscaleMax);
61 int64_t pos = scalableCstr.insert(value, dim,
false);
62 scalableCstr.processWorklist();
65 if (scalableCstr.cstr.isEmpty()) {
71 auto projectOutFn = [&](ValueDim p) {
72 bool isStartingPoint =
75 return p.first != scalableCstr.
getVscaleValue() && !isStartingPoint;
77 scalableCstr.projectOut(projectOutFn);
78 scalableCstr.projectOutAnonymous(pos);
81 for (
unsigned i = 0, e = scalableCstr.cstr.getNumLocalVars(); i < e; ++i) {
82 scalableCstr.cstr.projectOut(scalableCstr.cstr.getNumDimAndSymbolVars());
85 assert(scalableCstr.cstr.getNumDimAndSymbolVars() ==
86 scalableCstr.positionToValueDim.size() &&
87 "inconsistent mapping state");
90 for (int64_t i = 0; i < scalableCstr.cstr.getNumDimAndSymbolVars(); ++i) {
93 if (scalableCstr.positionToValueDim[i] !=
101 scalableCstr.cstr.getSliceBounds(pos, 1, value.
getContext(), &lowerBound,
102 &upperBound, closedUB);
104 auto invalidBound = [](
auto &bound) {
105 return !bound[0] || bound[0].getNumResults() != 1;
109 if (boundType == BoundType::EQ && !invalidBound(lowerBound) &&
110 lowerBound[0] == upperBound[0]) {
111 return lowerBound[0];
112 }
else if (boundType == BoundType::LB && !invalidBound(lowerBound)) {
113 return lowerBound[0];
114 }
else if (boundType == BoundType::UB && !invalidBound(upperBound)) {
115 return upperBound[0];
function_ref< bool(Region *, ArrayRef< bool > visited)> StopConditionFn
Stop condition for traverseRegionGraph.
Base type for affine expression.
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
int64_t getSingleConstantResult() const
Returns the constant result of this map.
bool isSingleConstant() const
Returns true if this affine map is a single result constant function.
unsigned getNumResults() const
unsigned getNumInputs() const
AffineExpr getResult(unsigned idx) const
A helper class to be used with ValueBoundsOpInterface.
static constexpr int64_t kIndexValue
Dimension identifier to indicate a value is index-typed.
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.
BoundType
The type of bound: equal, lower bound or upper bound.
@ Mul
RHS of mul is always a constant or a symbolic expression.
A thin wrapper over an AffineMap which can represent a constant bound, or a scalable bound (in terms ...
FailureOr< BoundSize > getSize() const
Get the (possibly) scalable size of the bound, returns failure if the bound cannot be represented as ...
A version of ValueBoundsConstraintSet that can solve for scalable bounds.
static FailureOr< ConstantOrScalableBound > computeScalableBound(Value value, std::optional< int64_t > dim, unsigned vscaleMin, unsigned vscaleMax, presburger::BoundType boundType, bool closedUB=true, StopConditionFn stopCondition=nullptr)
Computes a (possibly) scalable bound for a given value.
Value getVscaleValue() const
Get the value of vscale. Returns nullptr vscale as not been encountered.