MLIR  16.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 
18 #include "mlir/IR/BuiltinOps.h"
19 #include "mlir/IR/Dialect.h"
21 #include "mlir/IR/OpDefinition.h"
23 #include "mlir/IR/TypeSupport.h"
24 #include "mlir/IR/Types.h"
30 #include "llvm/ADT/PointerEmbeddedInt.h"
31 #include "llvm/IR/DerivedTypes.h"
32 #include "llvm/IR/LLVMContext.h"
33 #include "llvm/IR/Module.h"
34 #include "llvm/IR/Type.h"
35 
36 #include "mlir/Dialect/LLVMIR/LLVMOpsEnums.h.inc"
37 
38 namespace mlir {
39 namespace LLVM {
40 // Inline the LLVM generated Linkage enum and utility.
41 // This is only necessary to isolate the "enum generated code" from the
42 // attribute definition itself.
43 // TODO: this shouldn't be needed after we unify the attribute generation, i.e.
44 // --gen-attr-* and --gen-attrdef-*.
45 using cconv::CConv;
46 using linkage::Linkage;
47 } // namespace LLVM
48 } // namespace mlir
49 
50 #include "mlir/Dialect/LLVMIR/LLVMOpsInterfaces.h.inc"
51 
52 namespace llvm {
53 class Type;
54 class LLVMContext;
55 namespace sys {
56 template <bool mt_only>
57 class SmartMutex;
58 } // namespace sys
59 } // namespace llvm
60 
61 namespace mlir {
62 namespace LLVM {
63 class LLVMDialect;
64 class LoopOptionsAttrBuilder;
65 
66 namespace detail {
67 struct LLVMTypeStorage;
68 struct LLVMDialectImpl;
69 } // namespace detail
70 } // namespace LLVM
71 } // namespace mlir
72 
73 #define GET_ATTRDEF_CLASSES
74 #include "mlir/Dialect/LLVMIR/LLVMOpsAttrDefs.h.inc"
75 
76 namespace mlir {
77 namespace LLVM {
78 template <typename Values>
80 
81 /// Bit-width of a 'GEPConstantIndex' within GEPArg.
82 constexpr int kGEPConstantBitWidth = 29;
83 /// Wrapper around a int32_t for use in a PointerUnion.
84 using GEPConstantIndex =
85  llvm::PointerEmbeddedInt<int32_t, kGEPConstantBitWidth>;
86 
87 /// Class used for building a 'llvm.getelementptr'. A single instance represents
88 /// a sum type that is either a 'Value' or a constant 'GEPConstantIndex' index.
89 /// The former represents a dynamic index in a GEP operation, while the later is
90 /// a constant index as is required for indices into struct types.
91 class GEPArg : public PointerUnion<Value, GEPConstantIndex> {
93 
94 public:
95  /// Constructs a GEPArg with a constant index.
96  /*implicit*/ GEPArg(int32_t integer) : BaseT(integer) {}
97 
98  /// Constructs a GEPArg with a dynamic index.
99  /*implicit*/ GEPArg(Value value) : BaseT(value) {}
100 
101  using BaseT::operator=;
102 };
103 } // namespace LLVM
104 } // namespace mlir
105 
106 ///// Ops /////
107 #define GET_OP_CLASSES
108 #include "mlir/Dialect/LLVMIR/LLVMOps.h.inc"
109 #define GET_OP_CLASSES
110 #include "mlir/Dialect/LLVMIR/LLVMIntrinsicOps.h.inc"
111 
112 #include "mlir/Dialect/LLVMIR/LLVMOpsDialect.h.inc"
113 
114 namespace mlir {
115 namespace LLVM {
116 
117 /// Class used for convenient access and iteration over GEP indices.
118 /// This class is templated to support not only retrieving the dynamic operands
119 /// of a GEP operation, but also as an adaptor during folding or conversion to
120 /// LLVM IR.
121 ///
122 /// GEP indices may either be constant indices or dynamic indices. The
123 /// 'rawConstantIndices' is specially encoded by GEPOp and contains either the
124 /// constant index or the information that an index is a dynamic index.
125 ///
126 /// When an access to such an index is made it is done through the
127 /// 'DynamicRange' of this class. This way it can be used as getter in GEPOp via
128 /// 'GEPIndicesAdaptor<ValueRange>' or during folding via
129 /// 'GEPIndicesAdaptor<ArrayRef<Attribute>>'.
130 template <typename DynamicRange>
131 class GEPIndicesAdaptor {
132 public:
133  /// Return type of 'operator[]' and the iterators 'operator*'. It is depended
134  /// upon the value type of 'DynamicRange'. If 'DynamicRange' contains
135  /// Attributes or subclasses thereof, then value_type is 'Attribute'. In
136  /// all other cases it is a pointer union between the value type of
137  /// 'DynamicRange' and IntegerAttr.
138  using value_type = std::conditional_t<
139  std::is_base_of<Attribute,
140  llvm::detail::ValueOfRange<DynamicRange>>::value,
141  Attribute,
143 
144  /// Constructs a GEPIndicesAdaptor with the raw constant indices of a GEPOp
145  /// and the range that is indexed into for retrieving dynamic indices.
146  GEPIndicesAdaptor(DenseI32ArrayAttr rawConstantIndices, DynamicRange values)
147  : rawConstantIndices(rawConstantIndices), values(std::move(values)) {}
148 
149  /// Returns the GEP index at the given position. Note that this operation has
150  /// a linear complexity in regards to the accessed position. To iterate over
151  /// all indices, use the iterators.
152  ///
153  /// This operation is invalid if the index is out of bounds.
154  value_type operator[](size_t index) const {
155  assert(index < size() && "index out of bounds");
156  return *std::next(begin(), index);
157  }
158 
159  /// Returns whether the GEP index at the given position is a dynamic index.
160  bool isDynamicIndex(size_t index) const {
161  return rawConstantIndices[index] == GEPOp::kDynamicIndex;
162  }
163 
164  /// Returns the amount of indices of the GEPOp.
165  size_t size() const { return rawConstantIndices.size(); }
166 
167  /// Returns true if this GEPOp does not have any indices.
168  bool empty() const { return rawConstantIndices.empty(); }
169 
170  class iterator
171  : public llvm::iterator_facade_base<iterator, std::forward_iterator_tag,
172  value_type, std::ptrdiff_t,
173  value_type *, value_type> {
174  public:
176  ArrayRef<int32_t>::iterator rawConstantIter,
177  llvm::detail::IterOfRange<const DynamicRange> valuesIter)
178  : base(base), rawConstantIter(rawConstantIter), valuesIter(valuesIter) {
179  }
180 
182  if (*rawConstantIter == GEPOp::kDynamicIndex)
183  return *valuesIter;
184 
185  return IntegerAttr::get(
186  ElementsAttr::getElementType(base->rawConstantIndices),
187  *rawConstantIter);
188  }
189 
191  if (*rawConstantIter == GEPOp::kDynamicIndex)
192  valuesIter++;
193  rawConstantIter++;
194  return *this;
195  }
196 
197  bool operator==(const iterator &rhs) const {
198  return base == rhs.base && rawConstantIter == rhs.rawConstantIter &&
199  valuesIter == rhs.valuesIter;
200  }
201 
202  private:
203  const GEPIndicesAdaptor *base;
204  ArrayRef<int32_t>::const_iterator rawConstantIter;
205  llvm::detail::IterOfRange<const DynamicRange> valuesIter;
206  };
207 
208  /// Returns the begin iterator, iterating over all GEP indices.
209  iterator begin() const {
210  return iterator(this, rawConstantIndices.asArrayRef().begin(),
211  values.begin());
212  }
213 
214  /// Returns the end iterator, iterating over all GEP indices.
215  iterator end() const {
216  return iterator(this, rawConstantIndices.asArrayRef().end(), values.end());
217  }
218 
219 private:
220  DenseI32ArrayAttr rawConstantIndices;
221  DynamicRange values;
222 };
223 
224 /// Create an LLVM global containing the string "value" at the module containing
225 /// surrounding the insertion point of builder. Obtain the address of that
226 /// global and use it to compute the address of the first character in the
227 /// string (operations inserted at the builder insertion point).
228 Value createGlobalString(Location loc, OpBuilder &builder, StringRef name,
229  StringRef value, Linkage linkage);
230 
231 /// LLVM requires some operations to be inside of a Module operation. This
232 /// function confirms that the Operation has the desired properties.
234 
235 /// Builder class for LoopOptionsAttr. This helper class allows to progressively
236 /// build a LoopOptionsAttr one option at a time, and pay the price of attribute
237 /// creation once all the options are in place.
239 public:
240  /// Construct a empty builder.
241  LoopOptionsAttrBuilder() = default;
242 
243  /// Construct a builder with an initial list of options from an existing
244  /// LoopOptionsAttr.
245  LoopOptionsAttrBuilder(LoopOptionsAttr attr);
246 
247  /// Set the `disable_licm` option to the provided value. If no value
248  /// is provided the option is deleted.
249  LoopOptionsAttrBuilder &setDisableLICM(Optional<bool> value);
250 
251  /// Set the `interleave_count` option to the provided value. If no value
252  /// is provided the option is deleted.
253  LoopOptionsAttrBuilder &setInterleaveCount(Optional<uint64_t> count);
254 
255  /// Set the `disable_unroll` option to the provided value. If no value
256  /// is provided the option is deleted.
257  LoopOptionsAttrBuilder &setDisableUnroll(Optional<bool> value);
258 
259  /// Set the `disable_pipeline` option to the provided value. If no value
260  /// is provided the option is deleted.
261  LoopOptionsAttrBuilder &setDisablePipeline(Optional<bool> value);
262 
263  /// Set the `pipeline_initiation_interval` option to the provided value.
264  /// If no value is provided the option is deleted.
266  setPipelineInitiationInterval(Optional<uint64_t> count);
267 
268  /// Returns true if any option has been set.
269  bool empty() { return options.empty(); }
270 
271 private:
272  template <typename T>
273  LoopOptionsAttrBuilder &setOption(LoopOptionCase tag, Optional<T> value);
274 
275  friend class LoopOptionsAttr;
277 };
278 
279 /// Convert an array of integer attributes to a vector of integers that can be
280 /// used as indices in LLVM operations.
281 template <typename IntT = int64_t>
283  SmallVector<IntT> indices;
284  indices.reserve(attrs.size());
285  for (Attribute attr : attrs)
286  indices.push_back(attr.cast<IntegerAttr>().getInt());
287  return indices;
288 }
289 
290 /// Convert an `ArrayAttr` of integer attributes to a vector of integers that
291 /// can be used as indices in LLVM operations.
292 template <typename IntT = int64_t>
294  return convertArrayToIndices<IntT>(attrs.getValue());
295 }
296 
297 } // namespace LLVM
298 } // namespace mlir
299 
300 #endif // MLIR_DIALECT_LLVMIR_LLVMDIALECT_H_
Include the generated interface declarations.
The OpAsmOpInterface, see OpAsmInterface.td for more details.
Definition: CallGraph.h:229
Operation is a basic unit of execution within MLIR.
Definition: Operation.h:28
value_type operator[](size_t index) const
Returns the GEP index at the given position.
Definition: LLVMDialect.h:154
bool empty()
Returns true if any option has been set.
Definition: LLVMDialect.h:269
size_t size() const
Returns the amount of indices of the GEPOp.
Definition: LLVMDialect.h:165
static Type getElementType(Type type, ArrayRef< int32_t > indices, function_ref< InFlightDiagnostic(StringRef)> emitErrorFn)
Walks the given type hierarchy with the given indices, potentially down to component granularity...
Definition: SPIRVOps.cpp:694
constexpr int kGEPConstantBitWidth
Bit-width of a &#39;GEPConstantIndex&#39; within GEPArg.
Definition: LLVMDialect.h:82
llvm::PointerEmbeddedInt< int32_t, kGEPConstantBitWidth > GEPConstantIndex
Wrapper around a int32_t for use in a PointerUnion.
Definition: LLVMDialect.h:85
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:282
An inlay hint that for a type annotation.
GEPArg(Value value)
Constructs a GEPArg with a dynamic index.
Definition: LLVMDialect.h:99
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
Attributes are known-constant values of operations.
Definition: Attributes.h:25
bool empty() const
Returns true if this GEPOp does not have any indices.
Definition: LLVMDialect.h:168
Class used for building a &#39;llvm.getelementptr&#39;.
Definition: LLVMDialect.h:91
bool isDynamicIndex(size_t index) const
Returns whether the GEP index at the given position is a dynamic index.
Definition: LLVMDialect.h:160
bool satisfiesLLVMModule(Operation *op)
LLVM requires some operations to be inside of a Module operation.
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...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
iterator(const GEPIndicesAdaptor *base, ArrayRef< int32_t >::iterator rawConstantIter, llvm::detail::IterOfRange< const DynamicRange > valuesIter)
Definition: LLVMDialect.h:175
static llvm::ManagedStatic< PassManagerOptions > options
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 &#39;operator[]&#39; and the iterators &#39;operator*&#39;.
Definition: LLVMDialect.h:142
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:146
bool operator==(const iterator &rhs) const
Definition: LLVMDialect.h:197
GEPArg(int32_t integer)
Constructs a GEPArg with a constant index.
Definition: LLVMDialect.h:96
Class used for convenient access and iteration over GEP indices.
Definition: LLVMDialect.h:79
This class helps build Operations.
Definition: Builders.h:196
iterator begin() const
Returns the begin iterator, iterating over all GEP indices.
Definition: LLVMDialect.h:209
Builder class for LoopOptionsAttr.
Definition: LLVMDialect.h:238
iterator end() const
Returns the end iterator, iterating over all GEP indices.
Definition: LLVMDialect.h:215