xref: /llvm-project/mlir/lib/IR/TypeDetail.h (revision 03d136cf5f3f10b618b7e17f897ebf6019518dcc)
1 //===- TypeDetail.h - MLIR Type storage details -----------------*- 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 // This holds implementation details of Type.
10 //
11 //===----------------------------------------------------------------------===//
12 #ifndef TYPEDETAIL_H_
13 #define TYPEDETAIL_H_
14 
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"
22 
23 namespace mlir {
24 
25 namespace detail {
26 
27 /// Integer Type Storage and Uniquing.
28 struct IntegerTypeStorage : public TypeStorage {
IntegerTypeStorageIntegerTypeStorage29   IntegerTypeStorage(unsigned width,
30                      IntegerType::SignednessSemantics signedness)
31       : width(width), signedness(signedness) {}
32 
33   /// The hash key used for uniquing.
34   using KeyTy = std::tuple<unsigned, IntegerType::SignednessSemantics>;
35 
hashKeyIntegerTypeStorage36   static llvm::hash_code hashKey(const KeyTy &key) {
37     return llvm::hash_value(key);
38   }
39 
40   bool operator==(const KeyTy &key) const {
41     return KeyTy(width, signedness) == key;
42   }
43 
constructIntegerTypeStorage44   static IntegerTypeStorage *construct(TypeStorageAllocator &allocator,
45                                        KeyTy key) {
46     return new (allocator.allocate<IntegerTypeStorage>())
47         IntegerTypeStorage(std::get<0>(key), std::get<1>(key));
48   }
49 
getAsKeyIntegerTypeStorage50   KeyTy getAsKey() const { return KeyTy(width, signedness); }
51 
52   unsigned width : 30;
53   IntegerType::SignednessSemantics signedness : 2;
54 };
55 
56 /// Function Type Storage and Uniquing.
57 struct FunctionTypeStorage : public TypeStorage {
FunctionTypeStorageFunctionTypeStorage58   FunctionTypeStorage(unsigned numInputs, unsigned numResults,
59                       Type const *inputsAndResults)
60       : numInputs(numInputs), numResults(numResults),
61         inputsAndResults(inputsAndResults) {}
62 
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();
68     return false;
69   }
70 
71   /// Construction.
constructFunctionTypeStorage72   static FunctionTypeStorage *construct(TypeStorageAllocator &allocator,
73                                         const KeyTy &key) {
74     auto [inputs, results] = key;
75 
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));
82 
83     // Initialize the memory using placement new.
84     return new (allocator.allocate<FunctionTypeStorage>())
85         FunctionTypeStorage(inputs.size(), results.size(), typesList.data());
86   }
87 
getInputsFunctionTypeStorage88   ArrayRef<Type> getInputs() const {
89     return ArrayRef<Type>(inputsAndResults, numInputs);
90   }
getResultsFunctionTypeStorage91   ArrayRef<Type> getResults() const {
92     return ArrayRef<Type>(inputsAndResults + numInputs, numResults);
93   }
94 
getAsKeyFunctionTypeStorage95   KeyTy getAsKey() const { return KeyTy(getInputs(), getResults()); }
96 
97   unsigned numInputs;
98   unsigned numResults;
99   Type const *inputsAndResults;
100 };
101 
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;
107 
TupleTypeStoragefinal108   TupleTypeStorage(unsigned numTypes) : numElements(numTypes) {}
109 
110   /// Construction.
constructfinal111   static TupleTypeStorage *construct(TypeStorageAllocator &allocator,
112                                      TypeRange key) {
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());
117 
118     // Copy in the element types into the trailing storage.
119     std::uninitialized_copy(key.begin(), key.end(),
120                             result->getTrailingObjects<Type>());
121     return result;
122   }
123 
124   bool operator==(const KeyTy &key) const { return key == getTypes(); }
125 
126   /// Return the number of held types.
sizefinal127   unsigned size() const { return numElements; }
128 
129   /// Return the held types.
getTypesfinal130   ArrayRef<Type> getTypes() const {
131     return {getTrailingObjects<Type>(), size()};
132   }
133 
getAsKeyfinal134   KeyTy getAsKey() const { return getTypes(); }
135 
136   /// The number of tuple elements.
137   unsigned numElements;
138 };
139 
140 /// Checks if the memorySpace has supported Attribute type.
141 bool isSupportedMemorySpace(Attribute memorySpace);
142 
143 /// Wraps deprecated integer memory space to the new Attribute form.
144 Attribute wrapIntegerMemorySpace(unsigned memorySpace, MLIRContext *ctx);
145 
146 /// Replaces default memorySpace (integer == `0`) with empty Attribute.
147 Attribute skipDefaultMemorySpace(Attribute memorySpace);
148 
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);
152 
153 } // namespace detail
154 } // namespace mlir
155 
156 #endif // TYPEDETAIL_H_
157