MLIR  21.0.0git
DataLayoutInterfaces.h
Go to the documentation of this file.
1 //===- DataLayoutInterfaces.h - Data Layout Interface Decls -----*- 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 // Defines the interfaces for the data layout specification, operations to which
10 // they can be attached, types subject to data layout and dialects containing
11 // data layout entries.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef MLIR_INTERFACES_DATALAYOUTINTERFACES_H
16 #define MLIR_INTERFACES_DATALAYOUTINTERFACES_H
17 
18 #include "mlir/IR/Attributes.h"
20 #include "mlir/IR/OpDefinition.h"
21 #include "llvm/ADT/DenseMap.h"
22 #include "llvm/ADT/MapVector.h"
23 #include "llvm/Support/TypeSize.h"
24 
25 namespace mlir {
26 class DataLayout;
27 class DataLayoutEntryInterface;
28 class DLTIQueryInterface;
29 class TargetDeviceSpecInterface;
30 class TargetSystemSpecInterface;
32 // Using explicit SmallVector size because we cannot infer the size from the
33 // forward declaration, and we need the typedef in the actual declaration.
37 using TargetDeviceSpecEntry = std::pair<StringAttr, TargetDeviceSpecInterface>;
39  ::llvm::MapVector<::mlir::StringAttr, ::mlir::DataLayoutEntryInterface>;
40 class DataLayoutOpInterface;
41 class DataLayoutSpecInterface;
42 class ModuleOp;
43 
44 namespace detail {
45 /// Default handler for the type size request. Computes results for built-in
46 /// types and dispatches to the DataLayoutTypeInterface for other types.
47 llvm::TypeSize getDefaultTypeSize(Type type, const DataLayout &dataLayout,
48  DataLayoutEntryListRef params);
49 
50 /// Default handler for the type size in bits request. Computes results for
51 /// built-in types and dispatches to the DataLayoutTypeInterface for other
52 /// types.
53 llvm::TypeSize getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout,
54  DataLayoutEntryListRef params);
55 
56 /// Default handler for the required alignment request. Computes results for
57 /// built-in types and dispatches to the DataLayoutTypeInterface for other
58 /// types.
59 uint64_t getDefaultABIAlignment(Type type, const DataLayout &dataLayout,
61 
62 /// Default handler for the preferred alignment request. Computes results for
63 /// built-in types and dispatches to the DataLayoutTypeInterface for other
64 /// types.
65 uint64_t
66 getDefaultPreferredAlignment(Type type, const DataLayout &dataLayout,
68 
69 /// Default handler for the index bitwidth request. Computes the result for
70 /// the built-in index type and dispatches to the DataLayoutTypeInterface for
71 /// other types.
72 std::optional<uint64_t>
73 getDefaultIndexBitwidth(Type type, const DataLayout &dataLayout,
75 
76 /// Default handler for endianness request. Dispatches to the
77 /// DataLayoutInterface if specified, otherwise returns the default.
78 Attribute getDefaultEndianness(DataLayoutEntryInterface entry);
79 
80 /// Default handler for the default memory space request. Dispatches to the
81 /// DataLayoutInterface if specified, otherwise returns the default.
82 Attribute getDefaultMemorySpace(DataLayoutEntryInterface entry);
83 
84 /// Default handler for alloca memory space request. Dispatches to the
85 /// DataLayoutInterface if specified, otherwise returns the default.
86 Attribute getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry);
87 
88 /// Default handler for mangling mode request. Dispatches to the
89 /// DataLayoutInterface if specified, otherwise returns the default.
90 Attribute getDefaultManglingMode(DataLayoutEntryInterface entry);
91 
92 /// Default handler for program memory space request. Dispatches to the
93 /// DataLayoutInterface if specified, otherwise returns the default.
94 Attribute getDefaultProgramMemorySpace(DataLayoutEntryInterface entry);
95 
96 /// Default handler for global memory space request. Dispatches to the
97 /// DataLayoutInterface if specified, otherwise returns the default.
98 Attribute getDefaultGlobalMemorySpace(DataLayoutEntryInterface entry);
99 
100 /// Default handler for the stack alignment request. Dispatches to the
101 /// DataLayoutInterface if specified, otherwise returns the default.
102 uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry);
103 
104 /// Returns the value of the property from the specified DataLayoutEntry. If the
105 /// property is missing from the entry, returns std::nullopt.
106 std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry);
107 
108 /// Given a list of data layout entries, returns a new list containing the
109 /// entries with keys having the given type ID, i.e. belonging to the same type
110 /// class.
112  TypeID typeID);
113 
114 /// Given a list of data layout entries, returns the entry that has the given
115 /// identifier as key, if such an entry exists in the list.
116 DataLayoutEntryInterface
117 filterEntryForIdentifier(DataLayoutEntryListRef entries, StringAttr id);
118 
119 /// Given a list of target device entries, returns the entry that has the given
120 /// identifier as key, if such an entry exists in the list.
121 TargetDeviceSpecInterface
123 
124 /// Verifies that the operation implementing the data layout interface, or a
125 /// module operation, is valid. This calls the verifier of the spec attribute
126 /// and checks if the layout is compatible with specs attached to the enclosing
127 /// operations.
128 LogicalResult verifyDataLayoutOp(Operation *op);
129 
130 /// Verifies that a data layout spec is valid. This dispatches to individual
131 /// entry verifiers, and then to the verifiers implemented by the relevant type
132 /// and dialect interfaces for type and identifier keys respectively.
133 LogicalResult verifyDataLayoutSpec(DataLayoutSpecInterface spec, Location loc);
134 
135 /// Verifies that a target system desc spec is valid. This dispatches to
136 /// individual entry verifiers, and then to the verifiers implemented by the
137 /// relevant dialect interfaces for identifier keys.
138 LogicalResult verifyTargetSystemSpec(TargetSystemSpecInterface spec,
139  Location loc);
140 
141 /// Divides the known min value of the numerator by the denominator and rounds
142 /// the result up to the next integer. Preserves the scalable flag.
143 llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator);
144 } // namespace detail
145 } // namespace mlir
146 
147 #include "mlir/Interfaces/DataLayoutAttrInterface.h.inc"
148 #include "mlir/Interfaces/DataLayoutOpInterface.h.inc"
149 #include "mlir/Interfaces/DataLayoutTypeInterface.h.inc"
150 
151 namespace mlir {
152 
153 //===----------------------------------------------------------------------===//
154 // DataLayoutDialectInterface
155 //===----------------------------------------------------------------------===//
156 
157 /// An interface to be implemented by dialects that can have identifiers in the
158 /// data layout specification entries. Provides hooks for verifying the entry
159 /// validity and combining two entries.
161  : public DialectInterface::Base<DataLayoutDialectInterface> {
162 public:
163  DataLayoutDialectInterface(Dialect *dialect) : Base(dialect) {}
164 
165  /// Checks whether the given data layout entry is valid and reports any errors
166  /// at the provided location. Derived classes should override this.
167  virtual LogicalResult verifyEntry(DataLayoutEntryInterface entry,
168  Location loc) const {
169  return success();
170  }
171 
172  /// Checks whether the given data layout entry is valid and reports any errors
173  /// at the provided location. Derived classes should override this.
174  virtual LogicalResult verifyEntry(TargetDeviceSpecInterface entry,
175  Location loc) const {
176  return success();
177  }
178 
179  /// Default implementation of entry combination that combines identical
180  /// entries and returns null otherwise.
181  static DataLayoutEntryInterface
182  defaultCombine(DataLayoutEntryInterface outer,
183  DataLayoutEntryInterface inner) {
184  if (!outer || outer == inner)
185  return inner;
186  return {};
187  }
188 
189  /// Combines two entries with identifiers that belong to this dialect. Returns
190  /// the combined entry or null if the entries are not compatible. Derived
191  /// classes likely need to reimplement this.
192  virtual DataLayoutEntryInterface
193  combine(DataLayoutEntryInterface outer,
194  DataLayoutEntryInterface inner) const {
195  return defaultCombine(outer, inner);
196  }
197 };
198 
199 //===----------------------------------------------------------------------===//
200 // DataLayout
201 //===----------------------------------------------------------------------===//
202 
203 /// The main mechanism for performing data layout queries. Instances of this
204 /// class can be created for an operation implementing DataLayoutOpInterface.
205 /// Upon construction, a layout spec combining that of the given operation with
206 /// all its ancestors will be computed and used to handle further requests. For
207 /// efficiency, results to all requests will be cached in this object.
208 /// Therefore, if the data layout spec for the scoping operation, or any of the
209 /// enclosing operations, changes, the cache is no longer valid. The user is
210 /// responsible creating a new DataLayout object after any spec change. In debug
211 /// mode, the cache validity is being checked in every request.
212 class DataLayout {
213 public:
214  explicit DataLayout();
215  explicit DataLayout(DataLayoutOpInterface op);
216  explicit DataLayout(ModuleOp op);
217 
218  /// Returns the layout of the closest parent operation carrying layout info.
219  static DataLayout closest(Operation *op);
220 
221  /// Returns the size of the given type in the current scope.
222  llvm::TypeSize getTypeSize(Type t) const;
223 
224  /// Returns the size in bits of the given type in the current scope.
225  llvm::TypeSize getTypeSizeInBits(Type t) const;
226 
227  /// Returns the required alignment of the given type in the current scope.
228  uint64_t getTypeABIAlignment(Type t) const;
229 
230  /// Returns the preferred of the given type in the current scope.
231  uint64_t getTypePreferredAlignment(Type t) const;
232 
233  /// Returns the bitwidth that should be used when performing index
234  /// computations for the given pointer-like type in the current scope. If the
235  /// type is not a pointer-like type, it returns std::nullopt.
236  std::optional<uint64_t> getTypeIndexBitwidth(Type t) const;
237 
238  /// Returns the specified endianness.
239  Attribute getEndianness() const;
240 
241  /// Returns the default memory space used for memory operations.
243 
244  /// Returns the memory space used for AllocaOps.
246 
247  /// Returns the mangling mode.
248  Attribute getManglingMode() const;
249 
250  /// Returns the memory space used for program memory operations.
252 
253  /// Returns the memory space used for global operations.
255 
256  /// Returns the natural alignment of the stack in bits. Alignment promotion of
257  /// stack variables should be limited to the natural stack alignment to
258  /// prevent dynamic stack alignment. Returns zero if the stack alignment is
259  /// unspecified.
260  uint64_t getStackAlignment() const;
261 
262  /// Returns the value of the specified property if the property is defined for
263  /// the given device ID, otherwise returns std::nullopt.
264  std::optional<Attribute>
265  getDevicePropertyValue(TargetSystemSpecInterface::DeviceID,
266  StringAttr propertyName) const;
267 
268 private:
269  /// Combined layout spec at the given scope.
270  const DataLayoutSpecInterface originalLayout;
271 
272  /// Combined target system desc spec at the given scope.
273  const TargetSystemSpecInterface originalTargetSystemDesc;
274 
275 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
276  /// List of enclosing layout specs.
278 #endif
279 
280  /// Asserts that the cache is still valid. Expensive in debug mode. No-op in
281  /// release mode.
282  void checkValid() const;
283 
284  /// Operation defining the scope of requests.
285  Operation *scope;
286 
287  /// Caches for individual requests.
288  mutable DenseMap<Type, llvm::TypeSize> sizes;
289  mutable DenseMap<Type, llvm::TypeSize> bitsizes;
290  mutable DenseMap<Type, uint64_t> abiAlignments;
291  mutable DenseMap<Type, uint64_t> preferredAlignments;
292  mutable DenseMap<Type, std::optional<uint64_t>> indexBitwidths;
293 
294  /// Cache for the endianness.
295  mutable std::optional<Attribute> endianness;
296  /// Cache for the mangling mode.
297  mutable std::optional<Attribute> manglingMode;
298  /// Cache for default, alloca, global, and program memory spaces.
299  mutable std::optional<Attribute> defaultMemorySpace;
300  mutable std::optional<Attribute> allocaMemorySpace;
301  mutable std::optional<Attribute> programMemorySpace;
302  mutable std::optional<Attribute> globalMemorySpace;
303 
304  /// Cache for stack alignment.
305  mutable std::optional<uint64_t> stackAlignment;
306 };
307 
308 } // namespace mlir
309 
310 #endif // MLIR_INTERFACES_DATALAYOUTINTERFACES_H
Attributes are known-constant values of operations.
Definition: Attributes.h:25
An interface to be implemented by dialects that can have identifiers in the data layout specification...
static DataLayoutEntryInterface defaultCombine(DataLayoutEntryInterface outer, DataLayoutEntryInterface inner)
Default implementation of entry combination that combines identical entries and returns null otherwis...
virtual DataLayoutEntryInterface combine(DataLayoutEntryInterface outer, DataLayoutEntryInterface inner) const
Combines two entries with identifiers that belong to this dialect.
virtual LogicalResult verifyEntry(TargetDeviceSpecInterface entry, Location loc) const
Checks whether the given data layout entry is valid and reports any errors at the provided location.
virtual LogicalResult verifyEntry(DataLayoutEntryInterface entry, Location loc) const
Checks whether the given data layout entry is valid and reports any errors at the provided location.
The main mechanism for performing data layout queries.
Attribute getAllocaMemorySpace() const
Returns the memory space used for AllocaOps.
static DataLayout closest(Operation *op)
Returns the layout of the closest parent operation carrying layout info.
std::optional< uint64_t > getTypeIndexBitwidth(Type t) const
Returns the bitwidth that should be used when performing index computations for the given pointer-lik...
llvm::TypeSize getTypeSize(Type t) const
Returns the size of the given type in the current scope.
Attribute getManglingMode() const
Returns the mangling mode.
uint64_t getStackAlignment() const
Returns the natural alignment of the stack in bits.
Attribute getProgramMemorySpace() const
Returns the memory space used for program memory operations.
uint64_t getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
Attribute getGlobalMemorySpace() const
Returns the memory space used for global operations.
uint64_t getTypeABIAlignment(Type t) const
Returns the required alignment of the given type in the current scope.
llvm::TypeSize getTypeSizeInBits(Type t) const
Returns the size in bits of the given type in the current scope.
Attribute getDefaultMemorySpace() const
Returns the default memory space used for memory operations.
Attribute getEndianness() const
Returns the specified endianness.
std::optional< Attribute > getDevicePropertyValue(TargetSystemSpecInterface::DeviceID, StringAttr propertyName) const
Returns the value of the specified property if the property is defined for the given device ID,...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:38
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:66
Operation is the basic unit of execution within MLIR.
Definition: Operation.h:88
This class provides an efficient unique identifier for a specific C++ type.
Definition: TypeID.h:107
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
The base class used for all derived interface types.
Attribute getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry)
Default handler for alloca memory space request.
Attribute getDefaultProgramMemorySpace(DataLayoutEntryInterface entry)
Default handler for program memory space request.
Attribute getDefaultEndianness(DataLayoutEntryInterface entry)
Default handler for endianness request.
std::optional< uint64_t > getDefaultIndexBitwidth(Type type, const DataLayout &dataLayout, ArrayRef< DataLayoutEntryInterface > params)
Default handler for the index bitwidth request.
DataLayoutEntryList filterEntriesForType(DataLayoutEntryListRef entries, TypeID typeID)
Given a list of data layout entries, returns a new list containing the entries with keys having the g...
LogicalResult verifyTargetSystemSpec(TargetSystemSpecInterface spec, Location loc)
Verifies that a target system desc spec is valid.
std::optional< Attribute > getDevicePropertyValue(DataLayoutEntryInterface entry)
Returns the value of the property from the specified DataLayoutEntry.
Attribute getDefaultManglingMode(DataLayoutEntryInterface entry)
Default handler for mangling mode request.
uint64_t getDefaultABIAlignment(Type type, const DataLayout &dataLayout, ArrayRef< DataLayoutEntryInterface > params)
Default handler for the required alignment request.
llvm::TypeSize getDefaultTypeSize(Type type, const DataLayout &dataLayout, DataLayoutEntryListRef params)
Default handler for the type size request.
llvm::TypeSize getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout, DataLayoutEntryListRef params)
Default handler for the type size in bits request.
uint64_t getDefaultPreferredAlignment(Type type, const DataLayout &dataLayout, ArrayRef< DataLayoutEntryInterface > params)
Default handler for the preferred alignment request.
llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator)
Divides the known min value of the numerator by the denominator and rounds the result up to the next ...
uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry)
Default handler for the stack alignment request.
Attribute getDefaultGlobalMemorySpace(DataLayoutEntryInterface entry)
Default handler for global memory space request.
Attribute getDefaultMemorySpace(DataLayoutEntryInterface entry)
Default handler for the default memory space request.
LogicalResult verifyDataLayoutOp(Operation *op)
Verifies that the operation implementing the data layout interface, or a module operation,...
LogicalResult verifyDataLayoutSpec(DataLayoutSpecInterface spec, Location loc)
Verifies that a data layout spec is valid.
DataLayoutEntryInterface filterEntryForIdentifier(DataLayoutEntryListRef entries, StringAttr id)
Given a list of data layout entries, returns the entry that has the given identifier as key,...
Include the generated interface declarations.
::llvm::MapVector<::mlir::StringAttr, ::mlir::DataLayoutEntryInterface > DataLayoutIdentifiedEntryMap
std::pair< StringAttr, TargetDeviceSpecInterface > TargetDeviceSpecEntry