xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
1753f127fSDimitry Andric //===-- SPIRVDuplicatesTracker.cpp - SPIR-V Duplicates Tracker --*- C++ -*-===//
2753f127fSDimitry Andric //
3753f127fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4753f127fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5753f127fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6753f127fSDimitry Andric //
7753f127fSDimitry Andric //===----------------------------------------------------------------------===//
8753f127fSDimitry Andric //
9753f127fSDimitry Andric // General infrastructure for keeping track of the values that according to
10753f127fSDimitry Andric // the SPIR-V binary layout should be global to the whole module.
11753f127fSDimitry Andric //
12753f127fSDimitry Andric //===----------------------------------------------------------------------===//
13753f127fSDimitry Andric 
14753f127fSDimitry Andric #include "SPIRVDuplicatesTracker.h"
15753f127fSDimitry Andric 
16753f127fSDimitry Andric using namespace llvm;
17753f127fSDimitry Andric 
18753f127fSDimitry Andric template <typename T>
19753f127fSDimitry Andric void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry(
20753f127fSDimitry Andric     SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry) {
21753f127fSDimitry Andric   for (auto &TPair : DT.getAllUses()) {
22753f127fSDimitry Andric     for (auto &RegPair : TPair.second) {
23753f127fSDimitry Andric       const MachineFunction *MF = RegPair.first;
24753f127fSDimitry Andric       Register R = RegPair.second;
25753f127fSDimitry Andric       MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(R);
26753f127fSDimitry Andric       if (!MI)
27753f127fSDimitry Andric         continue;
28753f127fSDimitry Andric       Reg2Entry[&MI->getOperand(0)] = &TPair.second;
29753f127fSDimitry Andric     }
30753f127fSDimitry Andric   }
31753f127fSDimitry Andric }
32753f127fSDimitry Andric 
33753f127fSDimitry Andric void SPIRVGeneralDuplicatesTracker::buildDepsGraph(
34753f127fSDimitry Andric     std::vector<SPIRV::DTSortableEntry *> &Graph,
35753f127fSDimitry Andric     MachineModuleInfo *MMI = nullptr) {
36753f127fSDimitry Andric   SPIRVReg2EntryTy Reg2Entry;
37753f127fSDimitry Andric   prebuildReg2Entry(TT, Reg2Entry);
38753f127fSDimitry Andric   prebuildReg2Entry(CT, Reg2Entry);
39753f127fSDimitry Andric   prebuildReg2Entry(GT, Reg2Entry);
40753f127fSDimitry Andric   prebuildReg2Entry(FT, Reg2Entry);
41753f127fSDimitry Andric   prebuildReg2Entry(AT, Reg2Entry);
42*bdd1243dSDimitry Andric   prebuildReg2Entry(ST, Reg2Entry);
43753f127fSDimitry Andric 
44753f127fSDimitry Andric   for (auto &Op2E : Reg2Entry) {
45753f127fSDimitry Andric     SPIRV::DTSortableEntry *E = Op2E.second;
46753f127fSDimitry Andric     Graph.push_back(E);
47753f127fSDimitry Andric     for (auto &U : *E) {
48753f127fSDimitry Andric       const MachineRegisterInfo &MRI = U.first->getRegInfo();
49753f127fSDimitry Andric       MachineInstr *MI = MRI.getUniqueVRegDef(U.second);
50753f127fSDimitry Andric       if (!MI)
51753f127fSDimitry Andric         continue;
52753f127fSDimitry Andric       assert(MI && MI->getParent() && "No MachineInstr created yet");
53753f127fSDimitry Andric       for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) {
54753f127fSDimitry Andric         MachineOperand &Op = MI->getOperand(i);
55753f127fSDimitry Andric         if (!Op.isReg())
56753f127fSDimitry Andric           continue;
57753f127fSDimitry Andric         MachineOperand *RegOp = &MRI.getVRegDef(Op.getReg())->getOperand(0);
58753f127fSDimitry Andric         assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) ||
59753f127fSDimitry Andric                Reg2Entry.count(RegOp));
60753f127fSDimitry Andric         if (Reg2Entry.count(RegOp))
61753f127fSDimitry Andric           E->addDep(Reg2Entry[RegOp]);
62753f127fSDimitry Andric       }
63753f127fSDimitry Andric 
64753f127fSDimitry Andric       if (E->getIsFunc()) {
65753f127fSDimitry Andric         MachineInstr *Next = MI->getNextNode();
66753f127fSDimitry Andric         if (Next && (Next->getOpcode() == SPIRV::OpFunction ||
67753f127fSDimitry Andric                      Next->getOpcode() == SPIRV::OpFunctionParameter)) {
68753f127fSDimitry Andric           E->addDep(Reg2Entry[&Next->getOperand(0)]);
69753f127fSDimitry Andric         }
70753f127fSDimitry Andric       }
71753f127fSDimitry Andric     }
72753f127fSDimitry Andric   }
73753f127fSDimitry Andric 
746246ae0bSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
75753f127fSDimitry Andric   if (MMI) {
76753f127fSDimitry Andric     const Module *M = MMI->getModule();
77753f127fSDimitry Andric     for (auto F = M->begin(), E = M->end(); F != E; ++F) {
78753f127fSDimitry Andric       const MachineFunction *MF = MMI->getMachineFunction(*F);
79753f127fSDimitry Andric       if (!MF)
80753f127fSDimitry Andric         continue;
81753f127fSDimitry Andric       for (const MachineBasicBlock &MBB : *MF) {
82753f127fSDimitry Andric         for (const MachineInstr &CMI : MBB) {
83753f127fSDimitry Andric           MachineInstr &MI = const_cast<MachineInstr &>(CMI);
84753f127fSDimitry Andric           MI.dump();
85753f127fSDimitry Andric           if (MI.getNumExplicitDefs() > 0 &&
86753f127fSDimitry Andric               Reg2Entry.count(&MI.getOperand(0))) {
87753f127fSDimitry Andric             dbgs() << "\t[";
88753f127fSDimitry Andric             for (SPIRV::DTSortableEntry *D :
89753f127fSDimitry Andric                  Reg2Entry.lookup(&MI.getOperand(0))->getDeps())
90753f127fSDimitry Andric               dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", ";
91753f127fSDimitry Andric             dbgs() << "]\n";
92753f127fSDimitry Andric           }
93753f127fSDimitry Andric         }
94753f127fSDimitry Andric       }
95753f127fSDimitry Andric     }
96753f127fSDimitry Andric   }
976246ae0bSDimitry Andric #endif
98753f127fSDimitry Andric }
99