MLIR 22.0.0git
PtrTypes.cpp
Go to the documentation of this file.
1//===- PtrTypes.cpp - Pointer dialect types ---------------------*- C++ -*-===//
2//
3// This file is licensed 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// This file defines the Ptr dialect types.
10//
11//===----------------------------------------------------------------------===//
12
15
16using namespace mlir;
17using namespace mlir::ptr;
18
19//===----------------------------------------------------------------------===//
20// Pointer type
21//===----------------------------------------------------------------------===//
22
23constexpr const static unsigned kDefaultPointerSizeBits = 64;
24constexpr const static unsigned kBitsInByte = 8;
25constexpr const static unsigned kDefaultPointerAlignmentBits = 8;
26
27/// Searches the data layout for the pointer spec, returns nullptr if it is not
28/// found.
29static SpecAttr getPointerSpec(DataLayoutEntryListRef params, PtrType type,
30 MemorySpaceAttrInterface defaultMemorySpace) {
31 for (DataLayoutEntryInterface entry : params) {
32 if (!entry.isTypeEntry())
33 continue;
34 if (cast<PtrType>(cast<Type>(entry.getKey())).getMemorySpace() ==
35 type.getMemorySpace()) {
36 if (auto spec = dyn_cast<SpecAttr>(entry.getValue()))
37 return spec;
38 }
39 }
40 // If not found, and this is the pointer to the default memory space or if
41 // `defaultMemorySpace` is null, assume 64-bit pointers. `defaultMemorySpace`
42 // might be null if the data layout doesn't define the default memory space.
43 if (type.getMemorySpace() == defaultMemorySpace ||
44 defaultMemorySpace == nullptr)
45 return SpecAttr::get(type.getContext(), kDefaultPointerSizeBits,
48 return nullptr;
49}
50
51bool PtrType::areCompatible(DataLayoutEntryListRef oldLayout,
52 DataLayoutEntryListRef newLayout,
53 DataLayoutSpecInterface newSpec,
54 const DataLayoutIdentifiedEntryMap &map) const {
55 for (DataLayoutEntryInterface newEntry : newLayout) {
56 if (!newEntry.isTypeEntry())
57 continue;
58 uint32_t size = kDefaultPointerSizeBits;
59 uint32_t abi = kDefaultPointerAlignmentBits;
60 auto newType = llvm::cast<PtrType>(llvm::cast<Type>(newEntry.getKey()));
61 const auto *it =
62 llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
63 if (auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
64 return llvm::cast<PtrType>(type).getMemorySpace() ==
65 newType.getMemorySpace();
66 }
67 return false;
68 });
69 if (it == oldLayout.end()) {
71 map.lookup(newSpec.getDefaultMemorySpaceIdentifier(getContext())));
72 it = llvm::find_if(oldLayout, [&](DataLayoutEntryInterface entry) {
73 if (auto type = llvm::dyn_cast_if_present<Type>(entry.getKey())) {
74 auto ptrTy = llvm::cast<PtrType>(type);
75 return ptrTy.getMemorySpace() == defaultMemorySpace;
76 }
77 return false;
78 });
79 }
80 if (it != oldLayout.end()) {
81 auto spec = llvm::cast<SpecAttr>(*it);
82 size = spec.getSize();
83 abi = spec.getAbi();
84 }
85
86 auto newSpec = llvm::cast<SpecAttr>(newEntry.getValue());
87 uint32_t newSize = newSpec.getSize();
88 uint32_t newAbi = newSpec.getAbi();
89 if (size != newSize || abi < newAbi || abi % newAbi != 0)
90 return false;
91 }
92 return true;
93}
94
95uint64_t PtrType::getABIAlignment(const DataLayout &dataLayout,
96 DataLayoutEntryListRef params) const {
97 auto defaultMemorySpace = llvm::cast_if_present<MemorySpaceAttrInterface>(
98 dataLayout.getDefaultMemorySpace());
99 if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace))
100 return spec.getAbi() / kBitsInByte;
101
102 return dataLayout.getTypeABIAlignment(get(defaultMemorySpace));
103}
104
105std::optional<uint64_t>
106PtrType::getIndexBitwidth(const DataLayout &dataLayout,
107 DataLayoutEntryListRef params) const {
108 auto defaultMemorySpace = llvm::cast_if_present<MemorySpaceAttrInterface>(
109 dataLayout.getDefaultMemorySpace());
110 if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace)) {
111 return spec.getIndex() == SpecAttr::kOptionalSpecValue ? spec.getSize()
112 : spec.getIndex();
113 }
114
115 return dataLayout.getTypeIndexBitwidth(get(defaultMemorySpace));
116}
117
118llvm::TypeSize PtrType::getTypeSizeInBits(const DataLayout &dataLayout,
119 DataLayoutEntryListRef params) const {
120 auto defaultMemorySpace = llvm::cast_if_present<MemorySpaceAttrInterface>(
121 dataLayout.getDefaultMemorySpace());
122 if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace))
123 return llvm::TypeSize::getFixed(spec.getSize());
124
125 // For other memory spaces, use the size of the pointer to the default memory
126 // space.
127 return dataLayout.getTypeSizeInBits(get(defaultMemorySpace));
128}
129
130uint64_t PtrType::getPreferredAlignment(const DataLayout &dataLayout,
131 DataLayoutEntryListRef params) const {
132 auto defaultMemorySpace = llvm::cast_if_present<MemorySpaceAttrInterface>(
133 dataLayout.getDefaultMemorySpace());
134 if (SpecAttr spec = getPointerSpec(params, *this, defaultMemorySpace))
135 return spec.getPreferred() / kBitsInByte;
136
137 return dataLayout.getTypePreferredAlignment(get(defaultMemorySpace));
138}
139
140LogicalResult PtrType::verifyEntries(DataLayoutEntryListRef entries,
141 Location loc) const {
142 for (DataLayoutEntryInterface entry : entries) {
143 if (!entry.isTypeEntry())
144 continue;
145 auto key = llvm::cast<Type>(entry.getKey());
146 if (!llvm::isa<SpecAttr>(entry.getValue())) {
147 return emitError(loc) << "expected layout attribute for " << key
148 << " to be a #ptr.spec attribute";
149 }
150 }
151 return success();
152}
153
154//===----------------------------------------------------------------------===//
155// Pointer metadata
156//===----------------------------------------------------------------------===//
157
158LogicalResult
159PtrMetadataType::verify(function_ref<InFlightDiagnostic()> emitError,
160 PtrLikeTypeInterface type) {
161 if (!type.hasPtrMetadata())
162 return emitError() << "the ptr-like type has no metadata";
163 return success();
164}
return success()
constexpr static const uint64_t kDefaultPointerSizeBits
constexpr static const uint64_t kBitsInByte
Definition LLVMTypes.cpp:30
b getContext())
constexpr static const unsigned kDefaultPointerAlignmentBits
Definition PtrTypes.cpp:25
static SpecAttr getPointerSpec(DataLayoutEntryListRef params, PtrType type, MemorySpaceAttrInterface defaultMemorySpace)
Searches the data layout for the pointer spec, returns nullptr if it is not found.
Definition PtrTypes.cpp:29
Attributes are known-constant values of operations.
Definition Attributes.h:25
The main mechanism for performing data layout queries.
std::optional< uint64_t > getTypeIndexBitwidth(Type t) const
Returns the bitwidth that should be used when performing index computations for the given pointer-lik...
uint64_t getTypePreferredAlignment(Type t) const
Returns the preferred of the given type in the current scope.
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 getDefaultMemorySpace() const
Returns the default memory space used for memory operations.
This class represents a diagnostic that is inflight and set to be reported.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
Attribute getDefaultMemorySpace(DataLayoutEntryInterface entry)
Default handler for the default memory space request.
Include the generated interface declarations.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
::llvm::MapVector<::mlir::StringAttr, ::mlir::DataLayoutEntryInterface > DataLayoutIdentifiedEntryMap
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
llvm::ArrayRef< DataLayoutEntryInterface > DataLayoutEntryListRef
llvm::function_ref< Fn > function_ref
Definition LLVM.h:152