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