12 #include "llvm/ADT/APSInt.h"
13 #include "llvm/Support/MathExtras.h"
23 return *constint == 0;
26 std::tuple<SmallVector<OpFoldResult>, SmallVector<OpFoldResult>,
27 SmallVector<OpFoldResult>>
30 offsets.reserve(ranges.size());
31 sizes.reserve(ranges.size());
32 strides.reserve(ranges.size());
33 for (
const auto &[offset, size, stride] : ranges) {
34 offsets.push_back(offset);
35 sizes.push_back(size);
36 strides.push_back(stride);
38 return std::make_tuple(offsets, sizes, strides);
50 auto v = llvm::dyn_cast_if_present<Value>(ofr);
52 APInt apInt = cast<IntegerAttr>(ofr.get<
Attribute>()).getValue();
53 staticVec.push_back(apInt.getSExtValue());
56 dynamicVec.push_back(v);
57 staticVec.push_back(ShapedType::kDynamic);
81 return llvm::to_vector(
88 res.reserve(arrayAttr.size());
100 return llvm::to_vector(llvm::map_range(
107 if (
auto val = llvm::dyn_cast_if_present<Value>(ofr)) {
110 return intVal.getSExtValue();
114 Attribute attr = llvm::dyn_cast_if_present<Attribute>(ofr);
115 if (
auto intAttr = dyn_cast_or_null<IntegerAttr>(attr))
116 return intAttr.getValue().getSExtValue();
120 std::optional<SmallVector<int64_t>>
127 return cv.has_value() ? cv.value() : 0;
137 return val && *val == value;
146 if (cst1 && cst2 && *cst1 == *cst2)
148 auto v1 = llvm::dyn_cast_if_present<Value>(ofr1),
149 v2 = llvm::dyn_cast_if_present<Value>(ofr2);
150 return v1 && v1 == v2;
155 if (ofrs1.size() != ofrs2.size())
157 for (
auto [ofr1, ofr2] : llvm::zip_equal(ofrs1, ofrs2))
169 res.reserve(staticValues.size());
170 unsigned numDynamic = 0;
171 unsigned count =
static_cast<unsigned>(staticValues.size());
172 for (
unsigned idx = 0; idx < count; ++idx) {
173 int64_t value = staticValues[idx];
174 res.push_back(ShapedType::isDynamic(value)
183 std::pair<SmallVector<int64_t>, SmallVector<Value>>
187 for (
const auto &it : mixedValues) {
189 staticValues.push_back(cast<IntegerAttr>(it.get<
Attribute>()).getInt());
191 staticValues.push_back(ShapedType::kDynamic);
192 dynamicValues.push_back(it.get<
Value>());
195 return {staticValues, dynamicValues};
199 template <
typename K,
typename V>
200 static SmallVector<V>
205 assert(keys.size() == values.size() &&
"unexpected mismatching sizes");
206 auto indices = llvm::to_vector(llvm::seq<int64_t>(0, values.size()));
207 std::sort(indices.begin(), indices.end(),
208 [&](int64_t i, int64_t
j) { return compare(keys[i], keys[j]); });
210 res.reserve(values.size());
211 for (int64_t i = 0, e = indices.size(); i < e; ++i)
212 res.push_back(values[indices[i]]);
222 SmallVector<OpFoldResult>
251 return llvm::divideCeilSigned(*ubConstant - *lbConstant, *stepConstant);
255 return llvm::none_of(sizesOrOffsets, [](int64_t value) {
256 return !ShapedType::isDynamic(value) && value < 0;
261 return llvm::none_of(strides, [](int64_t value) {
262 return !ShapedType::isDynamic(value) && value == 0;
267 bool onlyNonNegative,
bool onlyNonZero) {
268 bool valuesChanged =
false;
280 valuesChanged =
true;
283 return success(valuesChanged);
Attributes are known-constant values of operations.
This class is a general helper class for creating context-global objects like types,...
IntegerAttr getI64IntegerAttr(int64_t value)
MLIRContext is the top-level object for a collection of MLIR operations.
This class represents a single result from folding an operation.
This class provides an abstraction over the different types of ranges over Values.
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
int compare(const Fraction &x, const Fraction &y)
Three-way comparison between two fractions.
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
bool isConstantIntValue(OpFoldResult ofr, int64_t value)
Return true if ofr is constant integer equal to value.
bool isZeroIndex(OpFoldResult v)
Return true if v is an IntegerAttr with value 0 of a ConstantIndexOp with attribute with value 0.
detail::constant_int_value_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
OpFoldResult getAsIndexOpFoldResult(MLIRContext *ctx, int64_t val)
Convert int64_t to integer attributes of index type and return them as OpFoldResult.
std::tuple< SmallVector< OpFoldResult >, SmallVector< OpFoldResult >, SmallVector< OpFoldResult > > getOffsetsSizesAndStrides(ArrayRef< Range > ranges)
Given an array of Range values, return a tuple of (offset vector, sizes vector, and strides vector) f...
std::optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
LogicalResult foldDynamicStrideList(SmallVectorImpl< OpFoldResult > &strides)
Returns "success" when any of the elements in strides is a constant value.
bool isEqualConstantIntOrValue(OpFoldResult ofr1, OpFoldResult ofr2)
Return true if ofr1 and ofr2 are the same integer constant attribute values or the same SSA value.
bool hasValidSizesOffsets(SmallVector< int64_t > sizesOrOffsets)
Helper function to check whether the passed in sizes or offsets are valid.
std::optional< int64_t > constantTripCount(OpFoldResult lb, OpFoldResult ub, OpFoldResult step)
Return the number of iterations for a loop with a lower bound lb, upper bound ub and step step.
bool hasValidStrides(SmallVector< int64_t > strides)
Helper function to check whether the passed in strides are valid.
void dispatchIndexOpFoldResults(ArrayRef< OpFoldResult > ofrs, SmallVectorImpl< Value > &dynamicVec, SmallVectorImpl< int64_t > &staticVec)
Helper function to dispatch multiple OpFoldResults according to the behavior of dispatchIndexOpFoldRe...
std::pair< SmallVector< int64_t >, SmallVector< Value > > decomposeMixedValues(const SmallVectorImpl< OpFoldResult > &mixedValues)
Decompose a vector of mixed static or dynamic values into the corresponding pair of arrays.
static SmallVector< V > getValuesSortedByKeyImpl(ArrayRef< K > keys, ArrayRef< V > values, llvm::function_ref< bool(K, K)> compare)
Helper to sort values according to matching keys.
bool isEqualConstantIntOrValueArray(ArrayRef< OpFoldResult > ofrs1, ArrayRef< OpFoldResult > ofrs2)
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
SmallVector< OpFoldResult > getMixedValues(ArrayRef< int64_t > staticValues, ValueRange dynamicValues, Builder &b)
Return a vector of OpFoldResults with the same size a staticValues, but all elements for which Shaped...
void dispatchIndexOpFoldResult(OpFoldResult ofr, SmallVectorImpl< Value > &dynamicVec, SmallVectorImpl< int64_t > &staticVec)
Helper function to dispatch an OpFoldResult into staticVec if: a) it is an IntegerAttr In other cases...
OpFoldResult getAsOpFoldResult(Value val)
Given a value, try to extract a constant Attribute.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
std::optional< SmallVector< int64_t > > getConstantIntValues(ArrayRef< OpFoldResult > ofrs)
If all ofrs are constant integers or IntegerAttrs, return the integers.
SmallVector< Value > getValuesSortedByKey(ArrayRef< Attribute > keys, ArrayRef< Value > values, llvm::function_ref< bool(Attribute, Attribute)> compare)
Helper to sort values according to matching keys.
LogicalResult foldDynamicOffsetSizeList(SmallVectorImpl< OpFoldResult > &offsetsOrSizes)
Returns "success" when any of the elements in offsetsOrSizes is a constant value.
LogicalResult foldDynamicIndexList(SmallVectorImpl< OpFoldResult > &ofrs, bool onlyNonNegative=false, bool onlyNonZero=false)
Returns "success" when any of the elements in ofrs is a constant value.
Eliminates variable at the specified position using Fourier-Motzkin variable elimination.