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