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(MT, Reg2Entry); 43 prebuildReg2Entry(ST, Reg2Entry); 44 45 for (auto &Op2E : Reg2Entry) { 46 SPIRV::DTSortableEntry *E = Op2E.second; 47 Graph.push_back(E); 48 for (auto &U : *E) { 49 const MachineRegisterInfo &MRI = U.first->getRegInfo(); 50 MachineInstr *MI = MRI.getUniqueVRegDef(U.second); 51 if (!MI) 52 continue; 53 assert(MI && MI->getParent() && "No MachineInstr created yet"); 54 for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) { 55 MachineOperand &Op = MI->getOperand(i); 56 if (!Op.isReg()) 57 continue; 58 MachineInstr *VRegDef = MRI.getVRegDef(Op.getReg()); 59 // References to a function via function pointers generate virtual 60 // registers without a definition. We are able to resolve this 61 // reference using Globar Register info into an OpFunction instruction 62 // but do not expect to find it in Reg2Entry. 63 if (MI->getOpcode() == SPIRV::OpConstantFunctionPointerINTEL && i == 2) 64 continue; 65 MachineOperand *RegOp = &VRegDef->getOperand(0); 66 assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) || 67 Reg2Entry.count(RegOp)); 68 if (Reg2Entry.count(RegOp)) 69 E->addDep(Reg2Entry[RegOp]); 70 } 71 72 if (E->getIsFunc()) { 73 MachineInstr *Next = MI->getNextNode(); 74 if (Next && (Next->getOpcode() == SPIRV::OpFunction || 75 Next->getOpcode() == SPIRV::OpFunctionParameter)) { 76 E->addDep(Reg2Entry[&Next->getOperand(0)]); 77 } 78 } 79 } 80 } 81 82 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 83 if (MMI) { 84 const Module *M = MMI->getModule(); 85 for (auto F = M->begin(), E = M->end(); F != E; ++F) { 86 const MachineFunction *MF = MMI->getMachineFunction(*F); 87 if (!MF) 88 continue; 89 for (const MachineBasicBlock &MBB : *MF) { 90 for (const MachineInstr &CMI : MBB) { 91 MachineInstr &MI = const_cast<MachineInstr &>(CMI); 92 MI.dump(); 93 if (MI.getNumExplicitDefs() > 0 && 94 Reg2Entry.count(&MI.getOperand(0))) { 95 dbgs() << "\t["; 96 for (SPIRV::DTSortableEntry *D : 97 Reg2Entry.lookup(&MI.getOperand(0))->getDeps()) 98 dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", "; 99 dbgs() << "]\n"; 100 } 101 } 102 } 103 } 104 } 105 #endif 106 } 107