LLVM 20.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 "SPIRVUtils.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/MapVector.h"
24
25#include <type_traits>
26
27namespace llvm {
28namespace SPIRV {
29class SPIRVInstrInfo;
30// NOTE: using MapVector instead of DenseMap because it helps getting
31// everything ordered in a stable manner for a price of extra (NumKeys)*PtrSize
32// memory and expensive removals which do not happen anyway.
33class DTSortableEntry : public MapVector<const MachineFunction *, Register> {
35
36 struct FlagsTy {
37 unsigned IsFunc : 1;
38 unsigned IsGV : 1;
39 unsigned IsConst : 1;
40 // NOTE: bit-field default init is a C++20 feature.
41 FlagsTy() : IsFunc(0), IsGV(0), IsConst(0) {}
42 };
43 FlagsTy Flags;
44
45public:
46 // Common hoisting utility doesn't support function, because their hoisting
47 // require hoisting of params as well.
48 bool getIsFunc() const { return Flags.IsFunc; }
49 bool getIsGV() const { return Flags.IsGV; }
50 bool getIsConst() const { return Flags.IsConst; }
51 void setIsFunc(bool V) { Flags.IsFunc = V; }
52 void setIsGV(bool V) { Flags.IsGV = V; }
53 void setIsConst(bool V) { Flags.IsConst = V; }
54
55 const SmallVector<DTSortableEntry *, 2> &getDeps() const { return Deps; }
57};
58
67 STK_Last = -1
68};
69
70using SpecialTypeDescriptor = std::tuple<const Type *, unsigned, unsigned>;
71
73 struct BitFlags {
74 unsigned Dim : 3;
75 unsigned Depth : 2;
76 unsigned Arrayed : 1;
77 unsigned MS : 1;
78 unsigned Sampled : 2;
79 unsigned ImageFormat : 6;
80 unsigned AQ : 2;
82 unsigned Val;
83
84 ImageAttrs(unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS,
85 unsigned Sampled, unsigned ImageFormat, unsigned AQ = 0) {
86 Val = 0;
87 Flags.Dim = Dim;
89 Flags.Arrayed = Arrayed;
90 Flags.MS = MS;
91 Flags.Sampled = Sampled;
92 Flags.ImageFormat = ImageFormat;
93 Flags.AQ = AQ;
94 }
95};
96
98make_descr_image(const Type *SampledTy, unsigned Dim, unsigned Depth,
99 unsigned Arrayed, unsigned MS, unsigned Sampled,
100 unsigned ImageFormat, unsigned AQ = 0) {
101 return std::make_tuple(
102 SampledTy,
103 ImageAttrs(Dim, Depth, Arrayed, MS, Sampled, ImageFormat, AQ).Val,
105}
106
108make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy) {
109 assert(ImageTy->getOpcode() == SPIRV::OpTypeImage);
110 unsigned AC = AccessQualifier::AccessQualifier::None;
111 if (ImageTy->getNumOperands() > 8)
112 AC = ImageTy->getOperand(8).getImm();
113 return std::make_tuple(
114 SampledTy,
116 ImageTy->getOperand(2).getImm(), ImageTy->getOperand(3).getImm(),
117 ImageTy->getOperand(4).getImm(), ImageTy->getOperand(5).getImm(),
118 ImageTy->getOperand(6).getImm(), ImageTy->getOperand(7).getImm(), AC)
119 .Val,
121}
122
124 return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_Sampler);
125}
126
128 return std::make_tuple(nullptr, AQ, SpecialTypeKind::STK_Pipe);
129}
130
132 return std::make_tuple(nullptr, 0U, SpecialTypeKind::STK_DeviceEvent);
133}
134
136 unsigned AddressSpace) {
137 return std::make_tuple(ElementType, AddressSpace,
139}
140} // namespace SPIRV
141
142template <typename KeyTy> class SPIRVDuplicatesTrackerBase {
143public:
144 // NOTE: using MapVector instead of DenseMap helps getting everything ordered
145 // in a stable manner for a price of extra (NumKeys)*PtrSize memory and
146 // expensive removals which don't happen anyway.
148
149private:
150 StorageTy Storage;
151
152public:
153 void add(KeyTy V, const MachineFunction *MF, Register R) {
154 if (find(V, MF).isValid())
155 return;
156
157 Storage[V][MF] = R;
158 if (std::is_same<Function,
159 typename std::remove_const<
160 typename std::remove_pointer<KeyTy>::type>::type>() ||
161 std::is_same<Argument,
162 typename std::remove_const<
163 typename std::remove_pointer<KeyTy>::type>::type>())
164 Storage[V].setIsFunc(true);
165 if (std::is_same<GlobalVariable,
166 typename std::remove_const<
167 typename std::remove_pointer<KeyTy>::type>::type>())
168 Storage[V].setIsGV(true);
169 if (std::is_same<Constant,
170 typename std::remove_const<
171 typename std::remove_pointer<KeyTy>::type>::type>())
172 Storage[V].setIsConst(true);
173 }
174
175 Register find(KeyTy V, const MachineFunction *MF) const {
176 auto iter = Storage.find(V);
177 if (iter != Storage.end()) {
178 auto Map = iter->second;
179 auto iter2 = Map.find(MF);
180 if (iter2 != Map.end())
181 return iter2->second;
182 }
183 return Register();
184 }
185
186 const StorageTy &getAllUses() const { return Storage; }
187
188private:
189 StorageTy &getAllUses() { return Storage; }
190
191 // The friend class needs to have access to the internal storage
192 // to be able to build dependency graph, can't declare only one
193 // function a 'friend' due to the incomplete declaration at this point
194 // and mutual dependency problems.
196};
197
198template <typename T>
200
201template <>
202class SPIRVDuplicatesTracker<SPIRV::SpecialTypeDescriptor>
203 : public SPIRVDuplicatesTrackerBase<SPIRV::SpecialTypeDescriptor> {};
204
213
214 // NOTE: using MOs instead of regs to get rid of MF dependency to be able
215 // to use flat data structure.
216 // NOTE: replacing DenseMap with MapVector doesn't affect overall correctness
217 // but makes LITs more stable, should prefer DenseMap still due to
218 // significant perf difference.
219 using SPIRVReg2EntryTy =
221
222 template <typename T>
223 void prebuildReg2Entry(SPIRVDuplicatesTracker<T> &DT,
224 SPIRVReg2EntryTy &Reg2Entry,
225 const SPIRVInstrInfo *TII);
226
227public:
228 void buildDepsGraph(std::vector<SPIRV::DTSortableEntry *> &Graph,
230
231 void add(const Type *Ty, const MachineFunction *MF, Register R) {
232 TT.add(unifyPtrType(Ty), MF, R);
233 }
234
235 void add(const Type *PointeeTy, unsigned AddressSpace,
236 const MachineFunction *MF, Register R) {
238 R);
239 }
240
241 void add(const Constant *C, const MachineFunction *MF, Register R) {
242 CT.add(C, MF, R);
243 }
244
245 void add(const GlobalVariable *GV, const MachineFunction *MF, Register R) {
246 GT.add(GV, MF, R);
247 }
248
249 void add(const Function *F, const MachineFunction *MF, Register R) {
250 FT.add(F, MF, R);
251 }
252
253 void add(const Argument *Arg, const MachineFunction *MF, Register R) {
254 AT.add(Arg, MF, R);
255 }
256
257 void add(const MachineInstr *MI, const MachineFunction *MF, Register R) {
258 MT.add(MI, MF, R);
259 }
260
262 Register R) {
263 ST.add(TD, MF, R);
264 }
265
266 Register find(const Type *Ty, const MachineFunction *MF) {
267 return TT.find(unifyPtrType(Ty), MF);
268 }
269
270 Register find(const Type *PointeeTy, unsigned AddressSpace,
271 const MachineFunction *MF) {
272 return ST.find(
274 }
275
277 return CT.find(const_cast<Constant *>(C), MF);
278 }
279
281 return GT.find(const_cast<GlobalVariable *>(GV), MF);
282 }
283
285 return FT.find(const_cast<Function *>(F), MF);
286 }
287
288 Register find(const Argument *Arg, const MachineFunction *MF) {
289 return AT.find(const_cast<Argument *>(Arg), MF);
290 }
291
293 return MT.find(const_cast<MachineInstr *>(MI), MF);
294 }
295
297 const MachineFunction *MF) {
298 return ST.find(TD, MF);
299 }
300
301 const SPIRVDuplicatesTracker<Type> *getTypes() { return &TT; }
302};
303} // namespace llvm
304#endif // LLVM_LIB_TARGET_SPIRV_SPIRVDUPLICATESTRACKER_H
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#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())
spirv structurize SPIRV
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
This is an important base class in LLVM.
Definition: Constant.h:42
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:575
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:578
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:585
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:36
iterator end()
Definition: MapVector.h:71
iterator find(const KeyT &Key)
Definition: MapVector.h:167
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 Type *Ty, const MachineFunction *MF, Register R)
void add(const MachineInstr *MI, const MachineFunction *MF, Register R)
void add(const Function *F, const MachineFunction *MF, Register R)
Register find(const Type *Ty, const MachineFunction *MF)
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)
void add(const Type *PointeeTy, unsigned AddressSpace, const MachineFunction *MF, Register R)
Register find(const SPIRV::SpecialTypeDescriptor &TD, const MachineFunction *MF)
void buildDepsGraph(std::vector< SPIRV::DTSortableEntry * > &Graph, const SPIRVInstrInfo *TII, MachineModuleInfo *MMI)
Register find(const Type *PointeeTy, unsigned AddressSpace, const MachineFunction *MF)
void add(const Constant *C, const MachineFunction *MF, Register R)
const SPIRVDuplicatesTracker< Type > * getTypes()
Register find(const GlobalVariable *GV, const MachineFunction *MF)
Register find(const MachineInstr *MI, const MachineFunction *MF)
const SmallVector< DTSortableEntry *, 2 > & getDeps() const
void addDep(DTSortableEntry *E)
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
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
SpecialTypeDescriptor make_descr_pipe(uint8_t AQ)
SpecialTypeDescriptor make_descr_sampler()
std::tuple< const Type *, unsigned, unsigned > SpecialTypeDescriptor
SpecialTypeDescriptor make_descr_event()
SpecialTypeDescriptor make_descr_image(const Type *SampledTy, unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)
SpecialTypeDescriptor make_descr_pointee(const Type *ElementType, unsigned AddressSpace)
SpecialTypeDescriptor make_descr_sampled_image(const Type *SampledTy, const MachineInstr *ImageTy)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
const Type * unifyPtrType(const Type *Ty)
Definition: SPIRVUtils.h:374
struct llvm::SPIRV::ImageAttrs::BitFlags Flags
ImageAttrs(unsigned Dim, unsigned Depth, unsigned Arrayed, unsigned MS, unsigned Sampled, unsigned ImageFormat, unsigned AQ=0)