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