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