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 }