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