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 /// Default handler for the function pointer alignment request. Dispatches to
105 /// the DataLayoutInterface if specified, otherwise returns the default.
106 Attribute getDefaultFunctionPointerAlignment(DataLayoutEntryInterface entry);
107 
108 /// Default handler for the legal int widths request. Dispatches to the
109 /// DataLayoutInterface if specified, otherwise returns the default.
110 Attribute getDefaultLegalIntWidths(DataLayoutEntryInterface entry);
111 
112 /// Returns the value of the property from the specified DataLayoutEntry. If the
113 /// property is missing from the entry, returns std::nullopt.
114 std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry);
115 
116 /// Given a list of data layout entries, returns a new list containing the
117 /// entries with keys having the given type ID, i.e. belonging to the same type
118 /// class.
120  TypeID typeID);
121 
122 /// Given a list of data layout entries, returns the entry that has the given
123 /// identifier as key, if such an entry exists in the list.
124 DataLayoutEntryInterface
125 filterEntryForIdentifier(DataLayoutEntryListRef entries, StringAttr id);
126 
127 /// Given a list of target device entries, returns the entry that has the given
128 /// identifier as key, if such an entry exists in the list.
129 TargetDeviceSpecInterface
131 
132 /// Verifies that the operation implementing the data layout interface, or a
133 /// module operation, is valid. This calls the verifier of the spec attribute
134 /// and checks if the layout is compatible with specs attached to the enclosing
135 /// operations.
136 LogicalResult verifyDataLayoutOp(Operation *op);
137 
138 /// Verifies that a data layout spec is valid. This dispatches to individual
139 /// entry verifiers, and then to the verifiers implemented by the relevant type
140 /// and dialect interfaces for type and identifier keys respectively.
141 LogicalResult verifyDataLayoutSpec(DataLayoutSpecInterface spec, Location loc);
142 
143 /// Verifies that a target system desc spec is valid. This dispatches to
144 /// individual entry verifiers, and then to the verifiers implemented by the
145 /// relevant dialect interfaces for identifier keys.
146 LogicalResult verifyTargetSystemSpec(TargetSystemSpecInterface spec,
147  Location loc);
148 
149 /// Divides the known min value of the numerator by the denominator and rounds
150 /// the result up to the next integer. Preserves the scalable flag.
151 llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator);
152 } // namespace detail
153 } // namespace mlir
154 
155 #include "mlir/Interfaces/DataLayoutAttrInterface.h.inc"
156 #include "mlir/Interfaces/DataLayoutOpInterface.h.inc"
157 #include "mlir/Interfaces/DataLayoutTypeInterface.h.inc"
158 
159 namespace mlir {
160 
161 //===----------------------------------------------------------------------===//
162 // DataLayoutDialectInterface
163 //===----------------------------------------------------------------------===//
164 
165 /// An interface to be implemented by dialects that can have identifiers in the
166 /// data layout specification entries. Provides hooks for verifying the entry
167 /// validity and combining two entries.
169  : public DialectInterface::Base<DataLayoutDialectInterface> {
170 public:
171  DataLayoutDialectInterface(Dialect *dialect) : Base(dialect) {}
172 
173  /// Checks whether the given data layout entry is valid and reports any errors
174  /// at the provided location. Derived classes should override this.
175  virtual LogicalResult verifyEntry(DataLayoutEntryInterface entry,
176  Location loc) const {
177  return success();
178  }
179 
180  /// Checks whether the given data layout entry is valid and reports any errors
181  /// at the provided location. Derived classes should override this.
182  virtual LogicalResult verifyEntry(TargetDeviceSpecInterface entry,
183  Location loc) const {
184  return success();
185  }
186 
187  /// Default implementation of entry combination that combines identical
188  /// entries and returns null otherwise.
189  static DataLayoutEntryInterface
190  defaultCombine(DataLayoutEntryInterface outer,
191  DataLayoutEntryInterface inner) {
192  if (!outer || outer == inner)
193  return inner;
194  return {};
195  }
196 
197  /// Combines two entries with identifiers that belong to this dialect. Returns
198  /// the combined entry or null if the entries are not compatible. Derived
199  /// classes likely need to reimplement this.
200  virtual DataLayoutEntryInterface
201  combine(DataLayoutEntryInterface outer,
202  DataLayoutEntryInterface inner) const {
203  return defaultCombine(outer, inner);
204  }
205 };
206 
207 //===----------------------------------------------------------------------===//
208 // DataLayout
209 //===----------------------------------------------------------------------===//
210 
211 /// The main mechanism for performing data layout queries. Instances of this
212 /// class can be created for an operation implementing DataLayoutOpInterface.
213 /// Upon construction, a layout spec combining that of the given operation with
214 /// all its ancestors will be computed and used to handle further requests. For
215 /// efficiency, results to all requests will be cached in this object.
216 /// Therefore, if the data layout spec for the scoping operation, or any of the
217 /// enclosing operations, changes, the cache is no longer valid. The user is
218 /// responsible creating a new DataLayout object after any spec change. In debug
219 /// mode, the cache validity is being checked in every request.
220 class DataLayout {
221 public:
222  explicit DataLayout();
223  explicit DataLayout(DataLayoutOpInterface op);
224  explicit DataLayout(ModuleOp op);
225 
226  /// Returns the layout of the closest parent operation carrying layout info.
227  static DataLayout closest(Operation *op);
228 
229  /// Returns the size of the given type in the current scope.
230  llvm::TypeSize getTypeSize(Type t) const;
231 
232  /// Returns the size in bits of the given type in the current scope.
233  llvm::TypeSize getTypeSizeInBits(Type t) const;
234 
235  /// Returns the required alignment of the given type in the current scope.
236  uint64_t getTypeABIAlignment(Type t) const;
237 
238  /// Returns the preferred of the given type in the current scope.
239  uint64_t getTypePreferredAlignment(Type t) const;
240 
241  /// Returns the bitwidth that should be used when performing index
242  /// computations for the given pointer-like type in the current scope. If the
243  /// type is not a pointer-like type, it returns std::nullopt.
244  std::optional<uint64_t> getTypeIndexBitwidth(Type t) const;
245 
246  /// Returns the specified endianness.
247  Attribute getEndianness() const;
248 
249  /// Returns the default memory space used for memory operations.
251 
252  /// Returns the memory space used for AllocaOps.
254 
255  /// Returns the mangling mode.
256  Attribute getManglingMode() const;
257 
258  /// Returns the memory space used for program memory operations.
260 
261  /// Returns the memory space used for global operations.
263 
264  /// Returns the natural alignment of the stack in bits. Alignment promotion of
265  /// stack variables should be limited to the natural stack alignment to
266  /// prevent dynamic stack alignment. Returns zero if the stack alignment is
267  /// unspecified.
268  uint64_t getStackAlignment() const;
269 
270  /// Returns function pointer alignment.
272 
273  /// Returns the legal int widths.
275 
276  /// Returns the value of the specified property if the property is defined for
277  /// the given device ID, otherwise returns std::nullopt.
278  std::optional<Attribute>
279  getDevicePropertyValue(TargetSystemSpecInterface::DeviceID,
280  StringAttr propertyName) const;
281 
282 private:
283  /// Combined layout spec at the given scope.
284  const DataLayoutSpecInterface originalLayout;
285 
286  /// Combined target system desc spec at the given scope.
287  const TargetSystemSpecInterface originalTargetSystemDesc;
288 
289 #if LLVM_ENABLE_ABI_BREAKING_CHECKS
290  /// List of enclosing layout specs.
292 #endif
293 
294  /// Asserts that the cache is still valid. Expensive in debug mode. No-op in
295  /// release mode.
296  void checkValid() const;
297 
298  /// Operation defining the scope of requests.
299  Operation *scope;
300 
301  /// Caches for individual requests.
302  mutable DenseMap<Type, llvm::TypeSize> sizes;
303  mutable DenseMap<Type, llvm::TypeSize> bitsizes;
304  mutable DenseMap<Type, uint64_t> abiAlignments;
305  mutable DenseMap<Type, uint64_t> preferredAlignments;
306  mutable DenseMap<Type, std::optional<uint64_t>> indexBitwidths;
307 
308  /// Cache for the endianness.
309  mutable std::optional<Attribute> endianness;
310  /// Cache for the mangling mode.
311  mutable std::optional<Attribute> manglingMode;
312  /// Cache for default, alloca, global, and program memory spaces.
313  mutable std::optional<Attribute> defaultMemorySpace;
314  mutable std::optional<Attribute> allocaMemorySpace;
315  mutable std::optional<Attribute> programMemorySpace;
316  mutable std::optional<Attribute> globalMemorySpace;
317 
318  /// Cache for stack alignment.
319  mutable std::optional<uint64_t> stackAlignment;
320  /// Cache for function pointer alignment.
321  mutable std::optional<Attribute> functionPointerAlignment;
322  /// Cache for legal int widths.
323  mutable std::optional<Attribute> legalIntWidths;
324 };
325 
326 } // namespace mlir
327 
328 #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 getFunctionPointerAlignment() const
Returns function pointer alignment.
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.
Attribute getLegalIntWidths() const
Returns the legal int widths.
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:76
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.
Attribute getDefaultLegalIntWidths(DataLayoutEntryInterface entry)
Default handler for the legal int widths 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.
Attribute getDefaultFunctionPointerAlignment(DataLayoutEntryInterface entry)
Default handler for the function pointer alignment request.
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