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