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