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