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