//===- DataLayoutInterfaces.h - Data Layout Interface Decls -----*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Defines the interfaces for the data layout specification, operations to which // they can be attached, types subject to data layout and dialects containing // data layout entries. // //===----------------------------------------------------------------------===// #ifndef MLIR_INTERFACES_DATALAYOUTINTERFACES_H #define MLIR_INTERFACES_DATALAYOUTINTERFACES_H #include "mlir/IR/DialectInterface.h" #include "mlir/IR/OpDefinition.h" #include "llvm/ADT/DenseMap.h" #include "llvm/Support/TypeSize.h" namespace mlir { class DataLayout; class DataLayoutEntryInterface; class DLTIQueryInterface; class TargetDeviceSpecInterface; class TargetSystemSpecInterface; DataLayoutEntryKey; // Using explicit SmallVector size because we cannot infer the size from the // forward declaration, and we need the typedef in the actual declaration. DataLayoutEntryList; DataLayoutEntryListRef; TargetDeviceSpecListRef; DeviceIDTargetDeviceSpecPair; DeviceIDTargetDeviceSpecPairListRef; class DataLayoutOpInterface; class DataLayoutSpecInterface; class ModuleOp; namespace detail { /// Default handler for the type size request. Computes results for built-in /// types and dispatches to the DataLayoutTypeInterface for other types. llvm::TypeSize getDefaultTypeSize(Type type, const DataLayout &dataLayout, DataLayoutEntryListRef params); /// Default handler for the type size in bits request. Computes results for /// built-in types and dispatches to the DataLayoutTypeInterface for other /// types. llvm::TypeSize getDefaultTypeSizeInBits(Type type, const DataLayout &dataLayout, DataLayoutEntryListRef params); /// Default handler for the required alignment request. Computes results for /// built-in types and dispatches to the DataLayoutTypeInterface for other /// types. uint64_t getDefaultABIAlignment(Type type, const DataLayout &dataLayout, ArrayRef<DataLayoutEntryInterface> params); /// Default handler for the preferred alignment request. Computes results for /// built-in types and dispatches to the DataLayoutTypeInterface for other /// types. uint64_t getDefaultPreferredAlignment(Type type, const DataLayout &dataLayout, ArrayRef<DataLayoutEntryInterface> params); /// Default handler for the index bitwidth request. Computes the result for /// the built-in index type and dispatches to the DataLayoutTypeInterface for /// other types. std::optional<uint64_t> getDefaultIndexBitwidth(Type type, const DataLayout &dataLayout, ArrayRef<DataLayoutEntryInterface> params); /// Default handler for endianness request. Dispatches to the /// DataLayoutInterface if specified, otherwise returns the default. Attribute getDefaultEndianness(DataLayoutEntryInterface entry); /// Default handler for alloca memory space request. Dispatches to the /// DataLayoutInterface if specified, otherwise returns the default. Attribute getDefaultAllocaMemorySpace(DataLayoutEntryInterface entry); /// Default handler for program memory space request. Dispatches to the /// DataLayoutInterface if specified, otherwise returns the default. Attribute getDefaultProgramMemorySpace(DataLayoutEntryInterface entry); /// Default handler for global memory space request. Dispatches to the /// DataLayoutInterface if specified, otherwise returns the default. Attribute getDefaultGlobalMemorySpace(DataLayoutEntryInterface entry); /// Default handler for the stack alignment request. Dispatches to the /// DataLayoutInterface if specified, otherwise returns the default. uint64_t getDefaultStackAlignment(DataLayoutEntryInterface entry); /// Returns the value of the property from the specified DataLayoutEntry. If the /// property is missing from the entry, returns std::nullopt. std::optional<Attribute> getDevicePropertyValue(DataLayoutEntryInterface entry); /// Given a list of data layout entries, returns a new list containing the /// entries with keys having the given type ID, i.e. belonging to the same type /// class. DataLayoutEntryList filterEntriesForType(DataLayoutEntryListRef entries, TypeID typeID); /// Given a list of data layout entries, returns the entry that has the given /// identifier as key, if such an entry exists in the list. DataLayoutEntryInterface filterEntryForIdentifier(DataLayoutEntryListRef entries, StringAttr id); /// Given a list of target device entries, returns the entry that has the given /// identifier as key, if such an entry exists in the list. TargetDeviceSpecInterface filterEntryForIdentifier(TargetDeviceSpecListRef entries, StringAttr id); /// Verifies that the operation implementing the data layout interface, or a /// module operation, is valid. This calls the verifier of the spec attribute /// and checks if the layout is compatible with specs attached to the enclosing /// operations. LogicalResult verifyDataLayoutOp(Operation *op); /// Verifies that a data layout spec is valid. This dispatches to individual /// entry verifiers, and then to the verifiers implemented by the relevant type /// and dialect interfaces for type and identifier keys respectively. LogicalResult verifyDataLayoutSpec(DataLayoutSpecInterface spec, Location loc); /// Verifies that a target system desc spec is valid. This dispatches to /// individual entry verifiers, and then to the verifiers implemented by the /// relevant dialect interfaces for identifier keys. LogicalResult verifyTargetSystemSpec(TargetSystemSpecInterface spec, Location loc); /// Divides the known min value of the numerator by the denominator and rounds /// the result up to the next integer. Preserves the scalable flag. llvm::TypeSize divideCeil(llvm::TypeSize numerator, uint64_t denominator); } // namespace detail } // namespace mlir #include "mlir/Interfaces/DataLayoutAttrInterface.h.inc" #include "mlir/Interfaces/DataLayoutOpInterface.h.inc" #include "mlir/Interfaces/DataLayoutTypeInterface.h.inc" namespace mlir { //===----------------------------------------------------------------------===// // DataLayoutDialectInterface //===----------------------------------------------------------------------===// /// An interface to be implemented by dialects that can have identifiers in the /// data layout specification entries. Provides hooks for verifying the entry /// validity and combining two entries. class DataLayoutDialectInterface : public DialectInterface::Base<DataLayoutDialectInterface> { … }; //===----------------------------------------------------------------------===// // DataLayout //===----------------------------------------------------------------------===// /// The main mechanism for performing data layout queries. Instances of this /// class can be created for an operation implementing DataLayoutOpInterface. /// Upon construction, a layout spec combining that of the given operation with /// all its ancestors will be computed and used to handle further requests. For /// efficiency, results to all requests will be cached in this object. /// Therefore, if the data layout spec for the scoping operation, or any of the /// enclosing operations, changes, the cache is no longer valid. The user is /// responsible creating a new DataLayout object after any spec change. In debug /// mode, the cache validity is being checked in every request. class DataLayout { … }; } // namespace mlir #endif // MLIR_INTERFACES_DATALAYOUTINTERFACES_H