1 | //===-- SPIRVDuplicatesTracker.cpp - 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 | #include "SPIRVDuplicatesTracker.h" |
15 | |
16 | using namespace llvm; |
17 | |
18 | template <typename T> |
19 | void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry( |
20 | SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry) { |
21 | for (auto &TPair : DT.getAllUses()) { |
22 | for (auto &RegPair : TPair.second) { |
23 | const MachineFunction *MF = RegPair.first; |
24 | Register R = RegPair.second; |
25 | MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(Reg: R); |
26 | if (!MI) |
27 | continue; |
28 | Reg2Entry[&MI->getOperand(i: 0)] = &TPair.second; |
29 | } |
30 | } |
31 | } |
32 | |
33 | void SPIRVGeneralDuplicatesTracker::buildDepsGraph( |
34 | std::vector<SPIRV::DTSortableEntry *> &Graph, |
35 | MachineModuleInfo *MMI = nullptr) { |
36 | SPIRVReg2EntryTy Reg2Entry; |
37 | prebuildReg2Entry(DT&: TT, Reg2Entry); |
38 | prebuildReg2Entry(DT&: CT, Reg2Entry); |
39 | prebuildReg2Entry(DT&: GT, Reg2Entry); |
40 | prebuildReg2Entry(DT&: FT, Reg2Entry); |
41 | prebuildReg2Entry(DT&: AT, Reg2Entry); |
42 | prebuildReg2Entry(DT&: MT, Reg2Entry); |
43 | prebuildReg2Entry(DT&: ST, Reg2Entry); |
44 | |
45 | for (auto &Op2E : Reg2Entry) { |
46 | SPIRV::DTSortableEntry *E = Op2E.second; |
47 | Graph.push_back(x: E); |
48 | for (auto &U : *E) { |
49 | const MachineRegisterInfo &MRI = U.first->getRegInfo(); |
50 | MachineInstr *MI = MRI.getUniqueVRegDef(Reg: U.second); |
51 | if (!MI) |
52 | continue; |
53 | assert(MI && MI->getParent() && "No MachineInstr created yet" ); |
54 | for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) { |
55 | MachineOperand &Op = MI->getOperand(i); |
56 | if (!Op.isReg()) |
57 | continue; |
58 | MachineInstr *VRegDef = MRI.getVRegDef(Reg: Op.getReg()); |
59 | // References to a function via function pointers generate virtual |
60 | // registers without a definition. We are able to resolve this |
61 | // reference using Globar Register info into an OpFunction instruction |
62 | // but do not expect to find it in Reg2Entry. |
63 | if (MI->getOpcode() == SPIRV::OpConstantFunctionPointerINTEL && i == 2) |
64 | continue; |
65 | MachineOperand *RegOp = &VRegDef->getOperand(i: 0); |
66 | assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) || |
67 | Reg2Entry.count(RegOp)); |
68 | if (Reg2Entry.count(Key: RegOp)) |
69 | E->addDep(E: Reg2Entry[RegOp]); |
70 | } |
71 | |
72 | if (E->getIsFunc()) { |
73 | MachineInstr *Next = MI->getNextNode(); |
74 | if (Next && (Next->getOpcode() == SPIRV::OpFunction || |
75 | Next->getOpcode() == SPIRV::OpFunctionParameter)) { |
76 | E->addDep(E: Reg2Entry[&Next->getOperand(i: 0)]); |
77 | } |
78 | } |
79 | } |
80 | } |
81 | |
82 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
83 | if (MMI) { |
84 | const Module *M = MMI->getModule(); |
85 | for (auto F = M->begin(), E = M->end(); F != E; ++F) { |
86 | const MachineFunction *MF = MMI->getMachineFunction(F: *F); |
87 | if (!MF) |
88 | continue; |
89 | for (const MachineBasicBlock &MBB : *MF) { |
90 | for (const MachineInstr &CMI : MBB) { |
91 | MachineInstr &MI = const_cast<MachineInstr &>(CMI); |
92 | MI.dump(); |
93 | if (MI.getNumExplicitDefs() > 0 && |
94 | Reg2Entry.count(Key: &MI.getOperand(i: 0))) { |
95 | dbgs() << "\t[" ; |
96 | for (SPIRV::DTSortableEntry *D : |
97 | Reg2Entry.lookup(Key: &MI.getOperand(i: 0))->getDeps()) |
98 | dbgs() << Register::virtReg2Index(Reg: D->lookup(Key: MF)) << ", " ; |
99 | dbgs() << "]\n" ; |
100 | } |
101 | } |
102 | } |
103 | } |
104 | } |
105 | #endif |
106 | } |
107 | |