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