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
23namespace mlir {
24
25namespace detail {
26
27/// Integer Type Storage and Uniquing.
28struct IntegerTypeStorage : public TypeStorage {
29 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
36 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
44 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
50 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.
57struct FunctionTypeStorage : public TypeStorage {
58 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>(t: key) == getInputs())
67 return std::get<1>(t: key) == getResults();
68 return false;
69 }
70
71 /// Construction.
72 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(N: inputs.size() + results.size());
79 types.append(in_start: inputs.begin(), in_end: inputs.end());
80 types.append(in_start: results.begin(), in_end: results.end());
81 auto typesList = allocator.copyInto(elements: 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
88 ArrayRef<Type> getInputs() const {
89 return ArrayRef<Type>(inputsAndResults, numInputs);
90 }
91 ArrayRef<Type> getResults() const {
92 return ArrayRef<Type>(inputsAndResults + numInputs, numResults);
93 }
94
95 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.
103struct TupleTypeStorage final
104 : public TypeStorage,
105 public llvm::TrailingObjects<TupleTypeStorage, Type> {
106 using KeyTy = TypeRange;
107
108 TupleTypeStorage(unsigned numTypes) : numElements(numTypes) {}
109
110 /// Construction.
111 static TupleTypeStorage *construct(TypeStorageAllocator &allocator,
112 TypeRange key) {
113 // Allocate a new storage instance.
114 auto byteSize = TupleTypeStorage::totalSizeToAlloc<Type>(Counts: key.size());
115 auto *rawMem = allocator.allocate(size: byteSize, alignment: 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(first: key.begin(), last: key.end(),
120 result: 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.
127 unsigned size() const { return numElements; }
128
129 /// Return the held types.
130 ArrayRef<Type> getTypes() const {
131 return {getTrailingObjects<Type>(), size()};
132 }
133
134 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.
141bool isSupportedMemorySpace(Attribute memorySpace);
142
143/// Wraps deprecated integer memory space to the new Attribute form.
144Attribute wrapIntegerMemorySpace(unsigned memorySpace, MLIRContext *ctx);
145
146/// Replaces default memorySpace (integer == `0`) with empty Attribute.
147Attribute skipDefaultMemorySpace(Attribute memorySpace);
148
149/// [deprecated] Returns the memory space in old raw integer representation.
150/// New `Attribute getMemorySpace()` method should be used instead.
151unsigned getMemorySpaceAsInt(Attribute memorySpace);
152
153} // namespace detail
154} // namespace mlir
155
156#endif // TYPEDETAIL_H_
157

source code of mlir/lib/IR/TypeDetail.h