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::pair<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(key.first, key.second); 48 } 49 50 unsigned width : 30; 51 IntegerType::SignednessSemantics signedness : 2; 52 }; 53 54 /// Function Type Storage and Uniquing. 55 struct FunctionTypeStorage : public TypeStorage { FunctionTypeStorageFunctionTypeStorage56 FunctionTypeStorage(unsigned numInputs, unsigned numResults, 57 Type const *inputsAndResults) 58 : numInputs(numInputs), numResults(numResults), 59 inputsAndResults(inputsAndResults) {} 60 61 /// The hash key used for uniquing. 62 using KeyTy = std::pair<TypeRange, TypeRange>; 63 bool operator==(const KeyTy &key) const { 64 if (std::get<0>(key) == getInputs()) 65 return std::get<1>(key) == getResults(); 66 return false; 67 } 68 69 /// Construction. constructFunctionTypeStorage70 static FunctionTypeStorage *construct(TypeStorageAllocator &allocator, 71 const KeyTy &key) { 72 TypeRange inputs = key.first, results = key.second; 73 74 // Copy the inputs and results into the bump pointer. 75 SmallVector<Type, 16> types; 76 types.reserve(inputs.size() + results.size()); 77 types.append(inputs.begin(), inputs.end()); 78 types.append(results.begin(), results.end()); 79 auto typesList = allocator.copyInto(ArrayRef<Type>(types)); 80 81 // Initialize the memory using placement new. 82 return new (allocator.allocate<FunctionTypeStorage>()) 83 FunctionTypeStorage(inputs.size(), results.size(), typesList.data()); 84 } 85 getInputsFunctionTypeStorage86 ArrayRef<Type> getInputs() const { 87 return ArrayRef<Type>(inputsAndResults, numInputs); 88 } getResultsFunctionTypeStorage89 ArrayRef<Type> getResults() const { 90 return ArrayRef<Type>(inputsAndResults + numInputs, numResults); 91 } 92 93 unsigned numInputs; 94 unsigned numResults; 95 Type const *inputsAndResults; 96 }; 97 98 /// A type representing a collection of other types. 99 struct TupleTypeStorage final 100 : public TypeStorage, 101 public llvm::TrailingObjects<TupleTypeStorage, Type> { 102 using KeyTy = TypeRange; 103 TupleTypeStoragefinal104 TupleTypeStorage(unsigned numTypes) : numElements(numTypes) {} 105 106 /// Construction. constructfinal107 static TupleTypeStorage *construct(TypeStorageAllocator &allocator, 108 TypeRange key) { 109 // Allocate a new storage instance. 110 auto byteSize = TupleTypeStorage::totalSizeToAlloc<Type>(key.size()); 111 auto *rawMem = allocator.allocate(byteSize, alignof(TupleTypeStorage)); 112 auto *result = ::new (rawMem) TupleTypeStorage(key.size()); 113 114 // Copy in the element types into the trailing storage. 115 std::uninitialized_copy(key.begin(), key.end(), 116 result->getTrailingObjects<Type>()); 117 return result; 118 } 119 120 bool operator==(const KeyTy &key) const { return key == getTypes(); } 121 122 /// Return the number of held types. sizefinal123 unsigned size() const { return numElements; } 124 125 /// Return the held types. getTypesfinal126 ArrayRef<Type> getTypes() const { 127 return {getTrailingObjects<Type>(), size()}; 128 } 129 130 /// The number of tuple elements. 131 unsigned numElements; 132 }; 133 134 /// Checks if the memorySpace has supported Attribute type. 135 bool isSupportedMemorySpace(Attribute memorySpace); 136 137 /// Wraps deprecated integer memory space to the new Attribute form. 138 Attribute wrapIntegerMemorySpace(unsigned memorySpace, MLIRContext *ctx); 139 140 /// Replaces default memorySpace (integer == `0`) with empty Attribute. 141 Attribute skipDefaultMemorySpace(Attribute memorySpace); 142 143 /// [deprecated] Returns the memory space in old raw integer representation. 144 /// New `Attribute getMemorySpace()` method should be used instead. 145 unsigned getMemorySpaceAsInt(Attribute memorySpace); 146 147 } // namespace detail 148 } // namespace mlir 149 150 #endif // TYPEDETAIL_H_ 151