1 //===- TypeDetail.h - MLIR Type storage details -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This holds implementation details of Type.
11 //===----------------------------------------------------------------------===//
15 #include "mlir/IR/AffineMap.h"
16 #include "mlir/IR/BuiltinTypes.h"
17 #include "mlir/IR/MLIRContext.h"
18 #include "mlir/IR/OperationSupport.h"
19 #include "mlir/IR/TypeRange.h"
20 #include "llvm/ADT/bit.h"
21 #include "llvm/Support/TrailingObjects.h"
27 /// Integer Type Storage and Uniquing.
28 struct IntegerTypeStorage
: public TypeStorage
{
29 IntegerTypeStorage(unsigned width
,
30 IntegerType::SignednessSemantics signedness
)
31 : width(width
), signedness(signedness
) {}
33 /// The hash key used for uniquing.
34 using KeyTy
= std::tuple
<unsigned, IntegerType::SignednessSemantics
>;
36 static llvm::hash_code
hashKey(const KeyTy
&key
) {
37 return llvm::hash_value(key
);
40 bool operator==(const KeyTy
&key
) const {
41 return KeyTy(width
, signedness
) == key
;
44 static IntegerTypeStorage
*construct(TypeStorageAllocator
&allocator
,
46 return new (allocator
.allocate
<IntegerTypeStorage
>())
47 IntegerTypeStorage(std::get
<0>(key
), std::get
<1>(key
));
50 KeyTy
getAsKey() const { return KeyTy(width
, signedness
); }
53 IntegerType::SignednessSemantics signedness
: 2;
56 /// Function Type Storage and Uniquing.
57 struct FunctionTypeStorage
: public TypeStorage
{
58 FunctionTypeStorage(unsigned numInputs
, unsigned numResults
,
59 Type
const *inputsAndResults
)
60 : numInputs(numInputs
), numResults(numResults
),
61 inputsAndResults(inputsAndResults
) {}
63 /// The hash key used for uniquing.
64 using KeyTy
= std::tuple
<TypeRange
, TypeRange
>;
65 bool operator==(const KeyTy
&key
) const {
66 if (std::get
<0>(key
) == getInputs())
67 return std::get
<1>(key
) == getResults();
72 static FunctionTypeStorage
*construct(TypeStorageAllocator
&allocator
,
74 auto [inputs
, results
] = key
;
76 // Copy the inputs and results into the bump pointer.
77 SmallVector
<Type
, 16> types
;
78 types
.reserve(inputs
.size() + results
.size());
79 types
.append(inputs
.begin(), inputs
.end());
80 types
.append(results
.begin(), results
.end());
81 auto typesList
= allocator
.copyInto(ArrayRef
<Type
>(types
));
83 // Initialize the memory using placement new.
84 return new (allocator
.allocate
<FunctionTypeStorage
>())
85 FunctionTypeStorage(inputs
.size(), results
.size(), typesList
.data());
88 ArrayRef
<Type
> getInputs() const {
89 return ArrayRef
<Type
>(inputsAndResults
, numInputs
);
91 ArrayRef
<Type
> getResults() const {
92 return ArrayRef
<Type
>(inputsAndResults
+ numInputs
, numResults
);
95 KeyTy
getAsKey() const { return KeyTy(getInputs(), getResults()); }
99 Type
const *inputsAndResults
;
102 /// A type representing a collection of other types.
103 struct TupleTypeStorage final
104 : public TypeStorage
,
105 public llvm::TrailingObjects
<TupleTypeStorage
, Type
> {
106 using KeyTy
= TypeRange
;
108 TupleTypeStorage(unsigned numTypes
) : numElements(numTypes
) {}
111 static TupleTypeStorage
*construct(TypeStorageAllocator
&allocator
,
113 // Allocate a new storage instance.
114 auto byteSize
= TupleTypeStorage::totalSizeToAlloc
<Type
>(key
.size());
115 auto *rawMem
= allocator
.allocate(byteSize
, alignof(TupleTypeStorage
));
116 auto *result
= ::new (rawMem
) TupleTypeStorage(key
.size());
118 // Copy in the element types into the trailing storage.
119 std::uninitialized_copy(key
.begin(), key
.end(),
120 result
->getTrailingObjects
<Type
>());
124 bool operator==(const KeyTy
&key
) const { return key
== getTypes(); }
126 /// Return the number of held types.
127 unsigned size() const { return numElements
; }
129 /// Return the held types.
130 ArrayRef
<Type
> getTypes() const {
131 return {getTrailingObjects
<Type
>(), size()};
134 KeyTy
getAsKey() const { return getTypes(); }
136 /// The number of tuple elements.
137 unsigned numElements
;
140 /// Checks if the memorySpace has supported Attribute type.
141 bool isSupportedMemorySpace(Attribute memorySpace
);
143 /// Wraps deprecated integer memory space to the new Attribute form.
144 Attribute
wrapIntegerMemorySpace(unsigned memorySpace
, MLIRContext
*ctx
);
146 /// Replaces default memorySpace (integer == `0`) with empty Attribute.
147 Attribute
skipDefaultMemorySpace(Attribute memorySpace
);
149 /// [deprecated] Returns the memory space in old raw integer representation.
150 /// New `Attribute getMemorySpace()` method should be used instead.
151 unsigned getMemorySpaceAsInt(Attribute memorySpace
);
153 } // namespace detail
156 #endif // TYPEDETAIL_H_