xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp (revision 753f127f3ace09432b2baeffd71a308760641a62)
1*753f127fSDimitry Andric //===-- SPIRVDuplicatesTracker.cpp - SPIR-V Duplicates Tracker --*- C++ -*-===//
2*753f127fSDimitry Andric //
3*753f127fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*753f127fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*753f127fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*753f127fSDimitry Andric //
7*753f127fSDimitry Andric //===----------------------------------------------------------------------===//
8*753f127fSDimitry Andric //
9*753f127fSDimitry Andric // General infrastructure for keeping track of the values that according to
10*753f127fSDimitry Andric // the SPIR-V binary layout should be global to the whole module.
11*753f127fSDimitry Andric //
12*753f127fSDimitry Andric //===----------------------------------------------------------------------===//
13*753f127fSDimitry Andric 
14*753f127fSDimitry Andric #include "SPIRVDuplicatesTracker.h"
15*753f127fSDimitry Andric 
16*753f127fSDimitry Andric using namespace llvm;
17*753f127fSDimitry Andric 
18*753f127fSDimitry Andric template <typename T>
19*753f127fSDimitry Andric void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry(
20*753f127fSDimitry Andric     SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry) {
21*753f127fSDimitry Andric   for (auto &TPair : DT.getAllUses()) {
22*753f127fSDimitry Andric     for (auto &RegPair : TPair.second) {
23*753f127fSDimitry Andric       const MachineFunction *MF = RegPair.first;
24*753f127fSDimitry Andric       Register R = RegPair.second;
25*753f127fSDimitry Andric       MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(R);
26*753f127fSDimitry Andric       if (!MI)
27*753f127fSDimitry Andric         continue;
28*753f127fSDimitry Andric       Reg2Entry[&MI->getOperand(0)] = &TPair.second;
29*753f127fSDimitry Andric     }
30*753f127fSDimitry Andric   }
31*753f127fSDimitry Andric }
32*753f127fSDimitry Andric 
33*753f127fSDimitry Andric void SPIRVGeneralDuplicatesTracker::buildDepsGraph(
34*753f127fSDimitry Andric     std::vector<SPIRV::DTSortableEntry *> &Graph,
35*753f127fSDimitry Andric     MachineModuleInfo *MMI = nullptr) {
36*753f127fSDimitry Andric   SPIRVReg2EntryTy Reg2Entry;
37*753f127fSDimitry Andric   prebuildReg2Entry(TT, Reg2Entry);
38*753f127fSDimitry Andric   prebuildReg2Entry(CT, Reg2Entry);
39*753f127fSDimitry Andric   prebuildReg2Entry(GT, Reg2Entry);
40*753f127fSDimitry Andric   prebuildReg2Entry(FT, Reg2Entry);
41*753f127fSDimitry Andric   prebuildReg2Entry(AT, Reg2Entry);
42*753f127fSDimitry Andric 
43*753f127fSDimitry Andric   for (auto &Op2E : Reg2Entry) {
44*753f127fSDimitry Andric     SPIRV::DTSortableEntry *E = Op2E.second;
45*753f127fSDimitry Andric     Graph.push_back(E);
46*753f127fSDimitry Andric     for (auto &U : *E) {
47*753f127fSDimitry Andric       const MachineRegisterInfo &MRI = U.first->getRegInfo();
48*753f127fSDimitry Andric       MachineInstr *MI = MRI.getUniqueVRegDef(U.second);
49*753f127fSDimitry Andric       if (!MI)
50*753f127fSDimitry Andric         continue;
51*753f127fSDimitry Andric       assert(MI && MI->getParent() && "No MachineInstr created yet");
52*753f127fSDimitry Andric       for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) {
53*753f127fSDimitry Andric         MachineOperand &Op = MI->getOperand(i);
54*753f127fSDimitry Andric         if (!Op.isReg())
55*753f127fSDimitry Andric           continue;
56*753f127fSDimitry Andric         MachineOperand *RegOp = &MRI.getVRegDef(Op.getReg())->getOperand(0);
57*753f127fSDimitry Andric         assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) ||
58*753f127fSDimitry Andric                Reg2Entry.count(RegOp));
59*753f127fSDimitry Andric         if (Reg2Entry.count(RegOp))
60*753f127fSDimitry Andric           E->addDep(Reg2Entry[RegOp]);
61*753f127fSDimitry Andric       }
62*753f127fSDimitry Andric 
63*753f127fSDimitry Andric       if (E->getIsFunc()) {
64*753f127fSDimitry Andric         MachineInstr *Next = MI->getNextNode();
65*753f127fSDimitry Andric         if (Next && (Next->getOpcode() == SPIRV::OpFunction ||
66*753f127fSDimitry Andric                      Next->getOpcode() == SPIRV::OpFunctionParameter)) {
67*753f127fSDimitry Andric           E->addDep(Reg2Entry[&Next->getOperand(0)]);
68*753f127fSDimitry Andric         }
69*753f127fSDimitry Andric       }
70*753f127fSDimitry Andric     }
71*753f127fSDimitry Andric   }
72*753f127fSDimitry Andric 
73*753f127fSDimitry Andric   if (MMI) {
74*753f127fSDimitry Andric     const Module *M = MMI->getModule();
75*753f127fSDimitry Andric     for (auto F = M->begin(), E = M->end(); F != E; ++F) {
76*753f127fSDimitry Andric       const MachineFunction *MF = MMI->getMachineFunction(*F);
77*753f127fSDimitry Andric       if (!MF)
78*753f127fSDimitry Andric         continue;
79*753f127fSDimitry Andric       for (const MachineBasicBlock &MBB : *MF) {
80*753f127fSDimitry Andric         for (const MachineInstr &CMI : MBB) {
81*753f127fSDimitry Andric           MachineInstr &MI = const_cast<MachineInstr &>(CMI);
82*753f127fSDimitry Andric           MI.dump();
83*753f127fSDimitry Andric           if (MI.getNumExplicitDefs() > 0 &&
84*753f127fSDimitry Andric               Reg2Entry.count(&MI.getOperand(0))) {
85*753f127fSDimitry Andric             dbgs() << "\t[";
86*753f127fSDimitry Andric             for (SPIRV::DTSortableEntry *D :
87*753f127fSDimitry Andric                  Reg2Entry.lookup(&MI.getOperand(0))->getDeps())
88*753f127fSDimitry Andric               dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", ";
89*753f127fSDimitry Andric             dbgs() << "]\n";
90*753f127fSDimitry Andric           }
91*753f127fSDimitry Andric         }
92*753f127fSDimitry Andric       }
93*753f127fSDimitry Andric     }
94*753f127fSDimitry Andric   }
95*753f127fSDimitry Andric }