MLIR  22.0.0git
LLVMDialect.h
Go to the documentation of this file.
1 //===- LLVMDialect.h - MLIR LLVM IR dialect ---------------------*- C++ -*-===//
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 //
9 // This file defines the LLVM IR dialect in MLIR, containing LLVM operations and
10 // LLVM type system.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
15 #define MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
16 
21 #include "mlir/IR/BuiltinOps.h"
22 #include "mlir/IR/Dialect.h"
23 #include "mlir/IR/OpDefinition.h"
25 #include "mlir/IR/TypeSupport.h"
26 #include "mlir/IR/Types.h"
34 #include "llvm/ADT/PointerEmbeddedInt.h"
35 
36 namespace llvm {
37 class Type;
38 class LLVMContext;
39 namespace sys {
40 template <bool mt_only>
41 class SmartMutex;
42 } // namespace sys
43 } // namespace llvm
44 
45 namespace mlir {
46 namespace LLVM {
47 class LLVMDialect;
48 
49 namespace detail {
50 struct LLVMTypeStorage;
51 struct LLVMDialectImpl;
52 } // namespace detail
53 } // namespace LLVM
54 } // namespace mlir
55 
56 namespace mlir {
57 namespace LLVM {
58 template <typename Values>
59 class GEPIndicesAdaptor;
60 
61 /// Bit-width of a 'GEPConstantIndex' within GEPArg.
62 constexpr int kGEPConstantBitWidth = 29;
63 /// Wrapper around a int32_t for use in a PointerUnion.
65  llvm::PointerEmbeddedInt<int32_t, kGEPConstantBitWidth>;
66 
67 /// Class used for building a 'llvm.getelementptr'. A single instance represents
68 /// a sum type that is either a 'Value' or a constant 'GEPConstantIndex' index.
69 /// The former represents a dynamic index in a GEP operation, while the later is
70 /// a constant index as is required for indices into struct types.
71 class GEPArg : public PointerUnion<Value, GEPConstantIndex> {
73 
74 public:
75  /// Constructs a GEPArg with a constant index.
76  /*implicit*/ GEPArg(int32_t integer) : BaseT(integer) {}
77 
78  /// Constructs a GEPArg with a dynamic index.
79  /*implicit*/ GEPArg(Value value) : BaseT(value) {}
80 
81  using BaseT::operator=;
82 };
83 } // namespace LLVM
84 } // namespace mlir
85 
86 namespace mlir {
87 namespace LLVM {
88 struct AssumeAlignTag {};
90 } // namespace LLVM
91 } // namespace mlir
92 
93 ///// Ops /////
94 #define GET_OP_CLASSES
95 #include "mlir/Dialect/LLVMIR/LLVMOps.h.inc"
96 #define GET_OP_CLASSES
97 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicOps.h.inc"
98 
99 #include "mlir/Dialect/LLVMIR/LLVMOpsDialect.h.inc"
100 
101 namespace mlir {
102 namespace LLVM {
103 
104 /// Class used for convenient access and iteration over GEP indices.
105 /// This class is templated to support not only retrieving the dynamic operands
106 /// of a GEP operation, but also as an adaptor during folding or conversion to
107 /// LLVM IR.
108 ///
109 /// GEP indices may either be constant indices or dynamic indices. The
110 /// 'rawConstantIndices' is specially encoded by GEPOp and contains either the
111 /// constant index or the information that an index is a dynamic index.
112 ///
113 /// When an access to such an index is made it is done through the
114 /// 'DynamicRange' of this class. This way it can be used as getter in GEPOp via
115 /// 'GEPIndicesAdaptor<ValueRange>' or during folding via
116 /// 'GEPIndicesAdaptor<ArrayRef<Attribute>>'.
117 template <typename DynamicRange>
119 public:
120  /// Return type of 'operator[]' and the iterators 'operator*'. It is depended
121  /// upon the value type of 'DynamicRange'. If 'DynamicRange' contains
122  /// Attributes or subclasses thereof, then value_type is 'Attribute'. In
123  /// all other cases it is a pointer union between the value type of
124  /// 'DynamicRange' and IntegerAttr.
125  using value_type = std::conditional_t<
126  std::is_base_of<Attribute,
127  llvm::detail::ValueOfRange<DynamicRange>>::value,
128  Attribute,
130 
131  /// Constructs a GEPIndicesAdaptor with the raw constant indices of a GEPOp
132  /// and the range that is indexed into for retrieving dynamic indices.
133  GEPIndicesAdaptor(DenseI32ArrayAttr rawConstantIndices, DynamicRange values)
134  : rawConstantIndices(rawConstantIndices), values(std::move(values)) {}
135 
136  /// Returns the GEP index at the given position. Note that this operation has
137  /// a linear complexity in regards to the accessed position. To iterate over
138  /// all indices, use the iterators.
139  ///
140  /// This operation is invalid if the index is out of bounds.
141  value_type operator[](size_t index) const {
142  assert(index < size() && "index out of bounds");
143  return *std::next(begin(), index);
144  }
145 
146  /// Returns whether the GEP index at the given position is a dynamic index.
147  bool isDynamicIndex(size_t index) const {
148  return rawConstantIndices[index] == GEPOp::kDynamicIndex;
149  }
150 
151  /// Returns the amount of indices of the GEPOp.
152  size_t size() const { return rawConstantIndices.size(); }
153 
154  /// Returns true if this GEPOp does not have any indices.
155  bool empty() const { return rawConstantIndices.empty(); }
156 
157  class iterator
158  : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
159  value_type, std::ptrdiff_t,
160  value_type *, value_type> {
161  public:
163  ArrayRef<int32_t>::iterator rawConstantIter,
164  llvm::detail::IterOfRange<const DynamicRange> valuesIter)
165  : base(base), rawConstantIter(rawConstantIter), valuesIter(valuesIter) {
166  }
167 
169  if (*rawConstantIter == GEPOp::kDynamicIndex)
170  return *valuesIter;
171 
172  return IntegerAttr::get(base->rawConstantIndices.getElementType(),
173  *rawConstantIter);
174  }
175 
177  if (*rawConstantIter == GEPOp::kDynamicIndex)
178  valuesIter++;
179  rawConstantIter++;
180  return *this;
181  }
182 
183  bool operator==(const iterator &rhs) const {
184  return base == rhs.base && rawConstantIter == rhs.rawConstantIter &&
185  valuesIter == rhs.valuesIter;
186  }
187 
188  private:
189  const GEPIndicesAdaptor *base;
190  ArrayRef<int32_t>::const_iterator rawConstantIter;
191  llvm::detail::IterOfRange<const DynamicRange> valuesIter;
192  };
193 
194  /// Returns the begin iterator, iterating over all GEP indices.
195  iterator begin() const {
196  return iterator(this, rawConstantIndices.asArrayRef().begin(),
197  values.begin());
198  }
199 
200  /// Returns the end iterator, iterating over all GEP indices.
201  iterator end() const {
202  return iterator(this, rawConstantIndices.asArrayRef().end(), values.end());
203  }
204 
205 private:
206  DenseI32ArrayAttr rawConstantIndices;
207  DynamicRange values;
208 };
209 
210 /// Create an LLVM global containing the string "value" at the module containing
211 /// surrounding the insertion point of builder. Obtain the address of that
212 /// global and use it to compute the address of the first character in the
213 /// string (operations inserted at the builder insertion point).
214 Value createGlobalString(Location loc, OpBuilder &builder, StringRef name,
215  StringRef value, Linkage linkage);
216 
217 /// LLVM requires some operations to be inside of a Module operation. This
218 /// function confirms that the Operation has the desired properties.
220 
221 /// Lookup parent Module satisfying LLVM conditions on the Module Operation.
223 
224 /// Convert an array of integer attributes to a vector of integers that can be
225 /// used as indices in LLVM operations.
226 template <typename IntT = int64_t>
228  SmallVector<IntT> indices;
229  indices.reserve(attrs.size());
230  for (Attribute attr : attrs)
231  indices.push_back(cast<IntegerAttr>(attr).getInt());
232  return indices;
233 }
234 
235 /// Convert an `ArrayAttr` of integer attributes to a vector of integers that
236 /// can be used as indices in LLVM operations.
237 template <typename IntT = int64_t>
239  return convertArrayToIndices<IntT>(attrs.getValue());
240 }
241 
242 } // namespace LLVM
243 } // namespace mlir
244 
245 namespace llvm {
246 
247 // Allow llvm::cast style functions.
248 template <typename To>
249 struct CastInfo<To, mlir::LLVM::GEPArg>
250  : public CastInfo<To, mlir::LLVM::GEPArg::PointerUnion> {};
251 
252 template <typename To>
253 struct CastInfo<To, const mlir::LLVM::GEPArg>
254  : public CastInfo<To, const mlir::LLVM::GEPArg::PointerUnion> {};
255 
256 } // namespace llvm
257 
258 #endif // MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
Attributes are known-constant values of operations.
Definition: Attributes.h:25
Class used for building a 'llvm.getelementptr'.
Definition: LLVMDialect.h:71
GEPArg(int32_t integer)
Constructs a GEPArg with a constant index.
Definition: LLVMDialect.h:76
GEPArg(Value value)
Constructs a GEPArg with a dynamic index.
Definition: LLVMDialect.h:79
iterator(const GEPIndicesAdaptor *base, ArrayRef< int32_t >::iterator rawConstantIter, llvm::detail::IterOfRange< const DynamicRange > valuesIter)
Definition: LLVMDialect.h:162
bool operator==(const iterator &rhs) const
Definition: LLVMDialect.h:183
Class used for convenient access and iteration over GEP indices.
Definition: LLVMDialect.h:118
iterator begin() const
Returns the begin iterator, iterating over all GEP indices.
Definition: LLVMDialect.h:195
std::conditional_t< std::is_base_of< Attribute, llvm::detail::ValueOfRange< DynamicRange > >::value, Attribute, PointerUnion< IntegerAttr, llvm::detail::ValueOfRange< DynamicRange > >> value_type
Return type of 'operator[]' and the iterators 'operator*'.
Definition: LLVMDialect.h:129
iterator end() const
Returns the end iterator, iterating over all GEP indices.
Definition: LLVMDialect.h:201
bool isDynamicIndex(size_t index) const
Returns whether the GEP index at the given position is a dynamic index.
Definition: LLVMDialect.h:147
size_t size() const
Returns the amount of indices of the GEPOp.
Definition: LLVMDialect.h:152
bool empty() const
Returns true if this GEPOp does not have any indices.
Definition: LLVMDialect.h:155
value_type operator[](size_t index) const
Returns the GEP index at the given position.
Definition: LLVMDialect.h:141
GEPIndicesAdaptor(DenseI32ArrayAttr rawConstantIndices, DynamicRange values)
Constructs a GEPIndicesAdaptor with the raw constant indices of a GEPOp and the range that is indexed...
Definition: LLVMDialect.h:133
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:76
This class helps build Operations.
Definition: Builders.h:207
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:96
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
Value createGlobalString(Location loc, OpBuilder &builder, StringRef name, StringRef value, Linkage linkage)
Create an LLVM global containing the string "value" at the module containing surrounding the insertio...
Operation * parentLLVMModule(Operation *op)
Lookup parent Module satisfying LLVM conditions on the Module Operation.
bool satisfiesLLVMModule(Operation *op)
LLVM requires some operations to be inside of a Module operation.
llvm::PointerEmbeddedInt< int32_t, kGEPConstantBitWidth > GEPConstantIndex
Wrapper around a int32_t for use in a PointerUnion.
Definition: LLVMDialect.h:65
constexpr int kGEPConstantBitWidth
Bit-width of a 'GEPConstantIndex' within GEPArg.
Definition: LLVMDialect.h:62
SmallVector< IntT > convertArrayToIndices(ArrayRef< Attribute > attrs)
Convert an array of integer attributes to a vector of integers that can be used as indices in LLVM op...
Definition: LLVMDialect.h:227
@ Type
An inlay hint that for a type annotation.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...