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