MLIR  16.0.0git
StaticValueUtils.cpp
Go to the documentation of this file.
1 //===- StaticValueUtils.cpp - Utilities for dealing with static values ----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
11 #include "mlir/IR/Matchers.h"
12 #include "mlir/Support/LLVM.h"
13 #include "llvm/ADT/APSInt.h"
14 
15 namespace mlir {
16 
17 std::tuple<SmallVector<OpFoldResult>, SmallVector<OpFoldResult>,
18  SmallVector<OpFoldResult>>
20  SmallVector<OpFoldResult> offsets, sizes, strides;
21  offsets.reserve(ranges.size());
22  sizes.reserve(ranges.size());
23  strides.reserve(ranges.size());
24  for (const auto &[offset, size, stride] : ranges) {
25  offsets.push_back(offset);
26  sizes.push_back(size);
27  strides.push_back(stride);
28  }
29  return std::make_tuple(offsets, sizes, strides);
30 }
31 
32 /// Helper function to dispatch an OpFoldResult into `staticVec` if:
33 /// a) it is an IntegerAttr
34 /// In other cases, the OpFoldResult is dispached to the `dynamicVec`.
35 /// In such dynamic cases, a copy of the `sentinel` value is also pushed to
36 /// `staticVec`. This is useful to extract mixed static and dynamic entries that
37 /// come from an AttrSizedOperandSegments trait.
39  SmallVectorImpl<Value> &dynamicVec,
40  SmallVectorImpl<int64_t> &staticVec,
41  int64_t sentinel) {
42  auto v = ofr.dyn_cast<Value>();
43  if (!v) {
44  APInt apInt = ofr.get<Attribute>().cast<IntegerAttr>().getValue();
45  staticVec.push_back(apInt.getSExtValue());
46  return;
47  }
48  dynamicVec.push_back(v);
49  staticVec.push_back(sentinel);
50 }
51 
53  SmallVectorImpl<Value> &dynamicVec,
54  SmallVectorImpl<int64_t> &staticVec,
55  int64_t sentinel) {
56  for (OpFoldResult ofr : ofrs)
57  dispatchIndexOpFoldResult(ofr, dynamicVec, staticVec, sentinel);
58 }
59 
60 /// Extract int64_t values from the assumed ArrayAttr of IntegerAttr.
62  return llvm::to_vector<4>(
63  llvm::map_range(attr.cast<ArrayAttr>(), [](Attribute a) -> int64_t {
64  return a.cast<IntegerAttr>().getInt();
65  }));
66 }
67 
68 /// Given a value, try to extract a constant Attribute. If this fails, return
69 /// the original value.
71  if (!val)
72  return OpFoldResult();
73  Attribute attr;
74  if (matchPattern(val, m_Constant(&attr)))
75  return attr;
76  return val;
77 }
78 
79 /// Given an array of values, try to extract a constant Attribute from each
80 /// value. If this fails, return the original value.
82  return llvm::to_vector<4>(
83  llvm::map_range(values, [](Value v) { return getAsOpFoldResult(v); }));
84 }
85 
86 /// Convert `arrayAttr` to a vector of OpFoldResult.
89  res.reserve(arrayAttr.size());
90  for (Attribute a : arrayAttr)
91  res.push_back(a);
92  return res;
93 }
94 
95 /// If ofr is a constant integer or an IntegerAttr, return the integer.
97  // Case 1: Check for Constant integer.
98  if (auto val = ofr.dyn_cast<Value>()) {
99  APSInt intVal;
100  if (matchPattern(val, m_ConstantInt(&intVal)))
101  return intVal.getSExtValue();
102  return llvm::None;
103  }
104  // Case 2: Check for IntegerAttr.
105  Attribute attr = ofr.dyn_cast<Attribute>();
106  if (auto intAttr = attr.dyn_cast_or_null<IntegerAttr>())
107  return intAttr.getValue().getSExtValue();
108  return llvm::None;
109 }
110 
111 /// Return true if `ofr` is constant integer equal to `value`.
113  auto val = getConstantIntValue(ofr);
114  return val && *val == value;
115 }
116 
117 /// Return true if ofr1 and ofr2 are the same integer constant attribute values
118 /// or the same SSA value.
119 /// Ignore integer bitwidth and type mismatch that come from the fact there is
120 /// no IndexAttr and that IndexType has no bitwidth.
122  auto cst1 = getConstantIntValue(ofr1), cst2 = getConstantIntValue(ofr2);
123  if (cst1 && cst2 && *cst1 == *cst2)
124  return true;
125  auto v1 = ofr1.dyn_cast<Value>(), v2 = ofr2.dyn_cast<Value>();
126  return v1 && v1 == v2;
127 }
128 
129 /// Helper function to convert a vector of `OpFoldResult`s into a vector of
130 /// `Value`s. For each `OpFoldResult` in `valueOrAttrVec` return the fold result
131 /// if it casts to a `Value` or create an index-type constant if it casts to
132 /// `IntegerAttr`. No other attribute types are supported.
134  ArrayRef<OpFoldResult> valueOrAttrVec) {
135  return llvm::to_vector<4>(
136  llvm::map_range(valueOrAttrVec, [&](OpFoldResult value) -> Value {
137  return getValueOrCreateConstantIndexOp(b, loc, value);
138  }));
139 }
140 
141 /// Return a vector of OpFoldResults with the same size a staticValues, but all
142 /// elements for which ShapedType::isDynamic is true, will be replaced by
143 /// dynamicValues.
145  ValueRange dynamicValues, Builder &b) {
147  res.reserve(staticValues.size());
148  unsigned numDynamic = 0;
149  unsigned count = static_cast<unsigned>(staticValues.size());
150  for (unsigned idx = 0; idx < count; ++idx) {
151  int64_t value = staticValues[idx];
152  res.push_back(ShapedType::isDynamic(value)
153  ? OpFoldResult{dynamicValues[numDynamic++]}
154  : OpFoldResult{b.getI64IntegerAttr(staticValues[idx])});
155  }
156  return res;
157 }
158 
159 /// Decompose a vector of mixed static or dynamic values into the corresponding
160 /// pair of arrays. This is the inverse function of `getMixedValues`.
161 std::pair<ArrayAttr, SmallVector<Value>>
163  const SmallVectorImpl<OpFoldResult> &mixedValues) {
164  SmallVector<int64_t> staticValues;
165  SmallVector<Value> dynamicValues;
166  for (const auto &it : mixedValues) {
167  if (it.is<Attribute>()) {
168  staticValues.push_back(it.get<Attribute>().cast<IntegerAttr>().getInt());
169  } else {
170  staticValues.push_back(ShapedType::kDynamic);
171  dynamicValues.push_back(it.get<Value>());
172  }
173  }
174  return {b.getI64ArrayAttr(staticValues), dynamicValues};
175 }
176 
177 } // namespace mlir
static constexpr const bool value
Attributes are known-constant values of operations.
Definition: Attributes.h:25
U dyn_cast_or_null() const
Definition: Attributes.h:132
U cast() const
Definition: Attributes.h:137
This class is a general helper class for creating context-global objects like types,...
Definition: Builders.h:49
IntegerAttr getI64IntegerAttr(int64_t value)
Definition: Builders.cpp:113
ArrayAttr getI64ArrayAttr(ArrayRef< int64_t > values)
Definition: Builders.cpp:262
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:64
This class helps build Operations.
Definition: Builders.h:198
This class represents a single result from folding an operation.
Definition: OpDefinition.h:233
This class provides an abstraction over the different types of ranges over Values.
Definition: ValueRange.h:349
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
Include the generated interface declarations.
bool matchPattern(Value value, const Pattern &pattern)
Entry point for matching a pattern over a Value.
Definition: Matchers.h:329
bool isConstantIntValue(OpFoldResult ofr, int64_t value)
Return true if ofr is constant integer equal to value.
SmallVector< Value > getAsValues(OpBuilder &b, Location loc, ArrayRef< OpFoldResult > valueOrAttrVec)
Helper function to convert a vector of OpFoldResults into a vector of Values.
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...
void dispatchIndexOpFoldResult(OpFoldResult ofr, SmallVectorImpl< Value > &dynamicVec, SmallVectorImpl< int64_t > &staticVec, int64_t sentinel)
Helper function to dispatch an OpFoldResult into staticVec if: a) it is an IntegerAttr In other cases...
bool isEqualConstantIntOrValue(OpFoldResult ofr1, OpFoldResult ofr2)
Return true if ofr1 and ofr2 are the same integer constant attribute values or the same SSA value.
SmallVector< int64_t, 4 > extractFromI64ArrayAttr(Attribute attr)
Extract int64_t values from the assumed ArrayAttr of IntegerAttr.
void dispatchIndexOpFoldResults(ArrayRef< OpFoldResult > ofrs, SmallVectorImpl< Value > &dynamicVec, SmallVectorImpl< int64_t > &staticVec, int64_t sentinel)
Helper function to dispatch multiple OpFoldResults according to the behavior of dispatchIndexOpFoldRe...
Optional< int64_t > getConstantIntValue(OpFoldResult ofr)
If ofr is a constant integer or an IntegerAttr, return the integer.
std::pair< ArrayAttr, SmallVector< Value > > decomposeMixedValues(Builder &b, const SmallVectorImpl< OpFoldResult > &mixedValues)
Decompose a vector of mixed static or dynamic values into the corresponding pair of arrays.
detail::constant_int_op_binder m_ConstantInt(IntegerAttr::ValueType *bind_value)
Matches a constant holding a scalar/vector/tensor integer (splat) and writes the integer value to bin...
Definition: Matchers.h:352
Value getValueOrCreateConstantIndexOp(OpBuilder &b, Location loc, OpFoldResult ofr)
Converts an OpFoldResult to a Value.
Definition: Utils.cpp:53
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...
OpFoldResult getAsOpFoldResult(Value val)
Given a value, try to extract a constant Attribute.
detail::constant_op_matcher m_Constant()
Matches a constant foldable operation.
Definition: Matchers.h:255