LLVM 17.0.0git
SPIRVDuplicatesTracker.h
Go to the documentation of this file.
1//===-- SPIRVDuplicatesTracker.h - SPIR-V Duplicates Tracker ----*- 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// General infrastructure for keeping track of the values that according to
10// the SPIR-V binary layout should be global to the whole module.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
15#define LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
16
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/MapVector.h"
23
24#include <type_traits>
25
26namespace llvm {
27namespace SPIRV {
28// NOTE: using MapVector instead of DenseMap because it helps getting
29// everything ordered in a stable manner for a price of extra (NumKeys)*PtrSize
30// memory and expensive removals which do not happen anyway.
31class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
33
34 struct FlagsTy {
35 unsigned IsFunc : 1;
36 unsigned IsGV : 1;
37 // NOTE: bit-field default init is a C++20 feature.
38 FlagsTy() : IsFunc(0), IsGV(0) {}
39 };
40 FlagsTy Flags;
41
42public:
43 // Common hoisting utility doesn't support function, because their hoisting
44 // require hoisting of params as well.
45 bool getIsFunc() const { return Flags.IsFunc; }
46 bool getIsGV() const { return Flags.IsGV; }
47 void setIsFunc(bool V) { Flags.IsFunc = V; }
48 void setIsGV(bool V) { Flags.IsGV = V; }
49
50 const SmallVector<DTSortableEntry *, 2> &getDeps() const { return Deps; }
52};
53
62 STK_Last = -1
63 };
65
66 unsigned Hash;
67
70
71 unsigned getHash() const { return Hash; }
72
74};
75
77 union ImageAttrs {
78 struct BitFlags {
79 unsigned Dim : 3;
80 unsigned Depth : 2;
81 unsigned Arrayed : 1;
82 unsigned MS : 1;
83 unsigned Sampled : 2;
84 unsigned ImageFormat : 6;
85 unsigned AQ : 2;
87 unsigned Val;
88 };
89
90 ImageTypeDescriptor(const Type *SampledTy, unsigned Dim, unsigned Depth,
91 unsigned Arrayed, unsigned MS, unsigned Sampled,
92 unsigned ImageFormat, unsigned AQ = 0)
94 ImageAttrs Attrs;
95 Attrs.Val = 0;
96 Attrs.Flags.Dim = Dim;
97 Attrs.Flags.Depth = Depth;
98 Attrs.Flags.Arrayed = Arrayed;
99 Attrs.Flags.MS = MS;
100 Attrs.Flags.Sampled = Sampled;
101 Attrs.Flags.ImageFormat = ImageFormat;
102 Attrs.Flags.AQ = AQ;
103 Hash = (DenseMapInfo<Type *>().getHashValue(SampledTy) & 0xffff) ^
104 ((Attrs.Val << 8) | Kind);
105 }
106
107 static bool classof(const SpecialTypeDescriptor *TD) {
108 return TD->Kind == SpecialTypeKind::STK_Image;
109 }
110};
111
113 SampledImageTypeDescriptor(const Type *SampledTy, const MachineInstr *ImageTy)
115 assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
117 SampledTy, ImageTy->getOperand(2).getImm(),
118 ImageTy->getOperand(3).getImm(), ImageTy->getOperand(4).getImm(),
119 ImageTy->getOperand(5).getImm(), ImageTy->getOperand(6).getImm(),
120 ImageTy->getOperand(7).getImm(), ImageTy->getOperand(8).getImm());
121 Hash = TD.getHash() ^ Kind;
122 }
123
124 static bool classof(const SpecialTypeDescriptor *TD) {
126 }
127};
128
132 Hash = Kind;
133 }
134
135 static bool classof(const SpecialTypeDescriptor *TD) {
137 }
138};
139
141
144 Hash = (AQ << 8) | Kind;
145 }
146
147 static bool classof(const SpecialTypeDescriptor *TD) {
148 return TD->Kind == SpecialTypeKind::STK_Pipe;
149 }
150};
151
153
156 Hash = Kind;
157 }
158
159 static bool classof(const SpecialTypeDescriptor *TD) {
161 }
162};
163} // namespace SPIRV
164
165template <> struct DenseMapInfo<SPIRV::SpecialTypeDescriptor> {
169 }
172 }
174 return Val.getHash();
175 }
178 return getHashValue(LHS) == getHashValue(RHS);
179 }
180};
181
182template <typename KeyTy> class SPIRVDuplicatesTrackerBase {
183public:
184 // NOTE: using MapVector instead of DenseMap helps getting everything ordered
185 // in a stable manner for a price of extra (NumKeys)*PtrSize memory and
186 // expensive removals which don't happen anyway.
188
189private:
190 StorageTy Storage;
191
192public:
193 void add(KeyTy V, const MachineFunction *MF, Register R) {
194 if (find(V, MF).isValid())
195 return;
196
197 Storage[V][MF] = R;
198 if (std::is_same<Function,
199 typename std::remove_const<
200 typename std::remove_pointer<KeyTy>::type>::type>() ||
201 std::is_same<Argument,
202 typename std::remove_const<
203 typename std::remove_pointer<KeyTy>::type>::type>())
204 Storage[V].setIsFunc(true);
205 if (std::is_same<GlobalVariable,
206 typename std::remove_const<
207 typename std::remove_pointer<KeyTy>::type>::type>())
208 Storage[V].setIsGV(true);
209 }
210
211 Register find(KeyTy V, const MachineFunction *MF) const {
212 auto iter = Storage.find(V);
213 if (iter != Storage.end()) {
214 auto Map = iter->second;
215 auto iter2 = Map.find(MF);
216 if (iter2 != Map.end())
217 return iter2->second;
218 }
219 return Register();
220 }
221
222 const StorageTy &getAllUses() const { return Storage; }
223
224private:
225 StorageTy &getAllUses() { return Storage; }
226
227 // The friend class needs to have access to the internal storage
228 // to be able to build dependency graph, can't declare only one
229 // function a 'friend' due to the incomplete declaration at this point
230 // and mutual dependency problems.
232};
233
234template <typename T>
236
237template <>
238class SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor>
239 : public SPIRVDuplicatesTrackerBase<SPIRV::SpecialTypeDescriptor> {};
240
248
249 // NOTE: using MOs instead of regs to get rid of MF dependency to be able
250 // to use flat data structure.
251 // NOTE: replacing DenseMap with MapVector doesn't affect overall correctness
252 // but makes LITs more stable, should prefer DenseMap still due to
253 // significant perf difference.
254 using SPIRVReg2EntryTy =
256
257 template <typename T>
258 void prebuildReg2Entry(SPIRVDuplicatesTracker<T> &DT,
259 SPIRVReg2EntryTy &Reg2Entry);
260
261public:
262 void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
263 MachineModuleInfo *MMI);
264
265 void add(const Type *T, const MachineFunction *MF, Register R) {
266 TT.add(T, MF, R);
267 }
268
269 void add(const Constant *C, const MachineFunction *MF, Register R) {
270 CT.add(C, MF, R);
271 }
272
273 void add(const GlobalVariable *GV, const MachineFunction *MF, Register R) {
274 GT.add(GV, MF, R);
275 }
276
277 void add(const Function *F, const MachineFunction *MF, Register R) {
278 FT.add(F, MF, R);
279 }
280
281 void add(const Argument *Arg, const MachineFunction *MF, Register R) {
282 AT.add(Arg, MF, R);
283 }
284
286 Register R) {
287 ST.add(TD, MF, R);
288 }
289
290 Register find(const Type *T, const MachineFunction *MF) {
291 return TT.find(const_cast<Type *>(T), MF);
292 }
293
295 return CT.find(const_cast<Constant *>(C), MF);
296 }
297
299 return GT.find(const_cast<GlobalVariable *>(GV), MF);
300 }
301
303 return FT.find(const_cast<Function *>(F), MF);
304 }
305
307 return AT.find(const_cast<Argument *>(Arg), MF);
308 }
309
311 const MachineFunction *MF) {
312 return ST.find(TD, MF);
313 }
314
315 const SPIRVDuplicatesTracker<Type> *getTypes() { return &TT; }
316};
317} // namespace llvm
318#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define F(x, y, z)
Definition: MD5.cpp:55
This file declares the MachineIRBuilder class.
This file implements a map that provides insertion order iteration.
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ Flags
Definition: TextStubV5.cpp:93
Value * RHS
Value * LHS
This class represents an incoming formal argument to a Function.
Definition: Argument.h:28
This is an important base class in LLVM.
Definition: Constant.h:41
Representation of each machine instruction.
Definition: MachineInstr.h:68
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:516
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
This class contains meta information specific to a module.
int64_t getImm() const
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:37
iterator end()
Definition: MapVector.h:72
iterator find(const KeyT &Key)
Definition: MapVector.h:147
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
void add(KeyTy V, const MachineFunction *MF, Register R)
Register find(KeyTy V, const MachineFunction *MF) const
MapVector< KeyTy, SPIRV::DTSortableEntry > StorageTy
const StorageTy & getAllUses() const
void add(const GlobalVariable *GV, const MachineFunction *MF, Register R)
Register find(const Function *F, const MachineFunction *MF)
void add(const SPIRV::SpecialTypeDescriptor &TD, const MachineFunction *MF, Register R)
void add(const Function *F, const MachineFunction *MF, Register R)
void buildDepsGraph(std::vector< SPIRV::DTSortableEntry * > &Graph, MachineModuleInfo *MMI)
Register find(const Constant *C, const MachineFunction *MF)
Register find(const Argument *Arg, const MachineFunction *MF)
void add(const Argument *Arg, const MachineFunction *MF, Register R)
Register find(const SPIRV::SpecialTypeDescriptor &TD, const MachineFunction *MF)
void add(const Constant *C, const MachineFunction *MF, Register R)
const SPIRVDuplicatesTracker< Type > * getTypes()
void add(const Type *T, const MachineFunction *MF, Register R)
Register find(const GlobalVariable *GV, const MachineFunction *MF)
Register find(const Type *T, const MachineFunction *MF)
const SmallVector< DTSortableEntry *, 2 > & getDeps() const
void addDep(DTSortableEntry *E)
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
static SPIRV::SpecialTypeDescriptor getEmptyKey()
static SPIRV::SpecialTypeDescriptor getTombstoneKey()
static bool isEqual(SPIRV::SpecialTypeDescriptor LHS, SPIRV::SpecialTypeDescriptor RHS)
static unsigned getHashValue(SPIRV::SpecialTypeDescriptor Val)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:51
static bool classof(const SpecialTypeDescriptor *TD)
ImageTypeDescriptor(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
static bool classof(const SpecialTypeDescriptor *TD)
static bool classof(const SpecialTypeDescriptor *TD)
static bool classof(const SpecialTypeDescriptor *TD)
SampledImageTypeDescriptor(const Type *SampledTy, const MachineInstr *ImageTy)
static bool classof(const SpecialTypeDescriptor *TD)
struct llvm::SPIRV::ImageTypeDescriptor::ImageAttrs::BitFlags Flags