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>
prebuildReg2Entry(SPIRVDuplicatesTracker<T> & DT,SPIRVReg2EntryTy & Reg2Entry)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(R);
26 if (!MI)
27 continue;
28 Reg2Entry[&MI->getOperand(0)] = &TPair.second;
29 }
30 }
31 }
32
buildDepsGraph(std::vector<SPIRV::DTSortableEntry * > & Graph,MachineModuleInfo * MMI=nullptr)33 void SPIRVGeneralDuplicatesTracker::buildDepsGraph(
34 std::vector<SPIRV::DTSortableEntry *> &Graph,
35 MachineModuleInfo *MMI = nullptr) {
36 SPIRVReg2EntryTy Reg2Entry;
37 prebuildReg2Entry(TT, Reg2Entry);
38 prebuildReg2Entry(CT, Reg2Entry);
39 prebuildReg2Entry(GT, Reg2Entry);
40 prebuildReg2Entry(FT, Reg2Entry);
41 prebuildReg2Entry(AT, Reg2Entry);
42
43 for (auto &Op2E : Reg2Entry) {
44 SPIRV::DTSortableEntry *E = Op2E.second;
45 Graph.push_back(E);
46 for (auto &U : *E) {
47 const MachineRegisterInfo &MRI = U.first->getRegInfo();
48 MachineInstr *MI = MRI.getUniqueVRegDef(U.second);
49 if (!MI)
50 continue;
51 assert(MI && MI->getParent() && "No MachineInstr created yet");
52 for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) {
53 MachineOperand &Op = MI->getOperand(i);
54 if (!Op.isReg())
55 continue;
56 MachineOperand *RegOp = &MRI.getVRegDef(Op.getReg())->getOperand(0);
57 assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) ||
58 Reg2Entry.count(RegOp));
59 if (Reg2Entry.count(RegOp))
60 E->addDep(Reg2Entry[RegOp]);
61 }
62
63 if (E->getIsFunc()) {
64 MachineInstr *Next = MI->getNextNode();
65 if (Next && (Next->getOpcode() == SPIRV::OpFunction ||
66 Next->getOpcode() == SPIRV::OpFunctionParameter)) {
67 E->addDep(Reg2Entry[&Next->getOperand(0)]);
68 }
69 }
70 }
71 }
72
73 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
74 if (MMI) {
75 const Module *M = MMI->getModule();
76 for (auto F = M->begin(), E = M->end(); F != E; ++F) {
77 const MachineFunction *MF = MMI->getMachineFunction(*F);
78 if (!MF)
79 continue;
80 for (const MachineBasicBlock &MBB : *MF) {
81 for (const MachineInstr &CMI : MBB) {
82 MachineInstr &MI = const_cast<MachineInstr &>(CMI);
83 MI.dump();
84 if (MI.getNumExplicitDefs() > 0 &&
85 Reg2Entry.count(&MI.getOperand(0))) {
86 dbgs() << "\t[";
87 for (SPIRV::DTSortableEntry *D :
88 Reg2Entry.lookup(&MI.getOperand(0))->getDeps())
89 dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", ";
90 dbgs() << "]\n";
91 }
92 }
93 }
94 }
95 }
96 #endif
97 }
98