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); 42753f127fSDimitry Andric 43753f127fSDimitry Andric for (auto &Op2E : Reg2Entry) { 44753f127fSDimitry Andric SPIRV::DTSortableEntry *E = Op2E.second; 45753f127fSDimitry Andric Graph.push_back(E); 46753f127fSDimitry Andric for (auto &U : *E) { 47753f127fSDimitry Andric const MachineRegisterInfo &MRI = U.first->getRegInfo(); 48753f127fSDimitry Andric MachineInstr *MI = MRI.getUniqueVRegDef(U.second); 49753f127fSDimitry Andric if (!MI) 50753f127fSDimitry Andric continue; 51753f127fSDimitry Andric assert(MI && MI->getParent() && "No MachineInstr created yet"); 52753f127fSDimitry Andric for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) { 53753f127fSDimitry Andric MachineOperand &Op = MI->getOperand(i); 54753f127fSDimitry Andric if (!Op.isReg()) 55753f127fSDimitry Andric continue; 56753f127fSDimitry Andric MachineOperand *RegOp = &MRI.getVRegDef(Op.getReg())->getOperand(0); 57753f127fSDimitry Andric assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) || 58753f127fSDimitry Andric Reg2Entry.count(RegOp)); 59753f127fSDimitry Andric if (Reg2Entry.count(RegOp)) 60753f127fSDimitry Andric E->addDep(Reg2Entry[RegOp]); 61753f127fSDimitry Andric } 62753f127fSDimitry Andric 63753f127fSDimitry Andric if (E->getIsFunc()) { 64753f127fSDimitry Andric MachineInstr *Next = MI->getNextNode(); 65753f127fSDimitry Andric if (Next && (Next->getOpcode() == SPIRV::OpFunction || 66753f127fSDimitry Andric Next->getOpcode() == SPIRV::OpFunctionParameter)) { 67753f127fSDimitry Andric E->addDep(Reg2Entry[&Next->getOperand(0)]); 68753f127fSDimitry Andric } 69753f127fSDimitry Andric } 70753f127fSDimitry Andric } 71753f127fSDimitry Andric } 72753f127fSDimitry Andric 73*6246ae0bSDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 74753f127fSDimitry Andric if (MMI) { 75753f127fSDimitry Andric const Module *M = MMI->getModule(); 76753f127fSDimitry Andric for (auto F = M->begin(), E = M->end(); F != E; ++F) { 77753f127fSDimitry Andric const MachineFunction *MF = MMI->getMachineFunction(*F); 78753f127fSDimitry Andric if (!MF) 79753f127fSDimitry Andric continue; 80753f127fSDimitry Andric for (const MachineBasicBlock &MBB : *MF) { 81753f127fSDimitry Andric for (const MachineInstr &CMI : MBB) { 82753f127fSDimitry Andric MachineInstr &MI = const_cast<MachineInstr &>(CMI); 83753f127fSDimitry Andric MI.dump(); 84753f127fSDimitry Andric if (MI.getNumExplicitDefs() > 0 && 85753f127fSDimitry Andric Reg2Entry.count(&MI.getOperand(0))) { 86753f127fSDimitry Andric dbgs() << "\t["; 87753f127fSDimitry Andric for (SPIRV::DTSortableEntry *D : 88753f127fSDimitry Andric Reg2Entry.lookup(&MI.getOperand(0))->getDeps()) 89753f127fSDimitry Andric dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", "; 90753f127fSDimitry Andric dbgs() << "]\n"; 91753f127fSDimitry Andric } 92753f127fSDimitry Andric } 93753f127fSDimitry Andric } 94753f127fSDimitry Andric } 95753f127fSDimitry Andric } 96*6246ae0bSDimitry Andric #endif 97753f127fSDimitry Andric } 98