Path: blob/main/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp
35266 views
//===-- SPIRVDuplicatesTracker.cpp - SPIR-V Duplicates Tracker --*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// General infrastructure for keeping track of the values that according to9// the SPIR-V binary layout should be global to the whole module.10//11//===----------------------------------------------------------------------===//1213#include "SPIRVDuplicatesTracker.h"1415using namespace llvm;1617template <typename T>18void SPIRVGeneralDuplicatesTracker::prebuildReg2Entry(19SPIRVDuplicatesTracker<T> &DT, SPIRVReg2EntryTy &Reg2Entry) {20for (auto &TPair : DT.getAllUses()) {21for (auto &RegPair : TPair.second) {22const MachineFunction *MF = RegPair.first;23Register R = RegPair.second;24MachineInstr *MI = MF->getRegInfo().getUniqueVRegDef(R);25if (!MI)26continue;27Reg2Entry[&MI->getOperand(0)] = &TPair.second;28}29}30}3132void SPIRVGeneralDuplicatesTracker::buildDepsGraph(33std::vector<SPIRV::DTSortableEntry *> &Graph,34MachineModuleInfo *MMI = nullptr) {35SPIRVReg2EntryTy Reg2Entry;36prebuildReg2Entry(TT, Reg2Entry);37prebuildReg2Entry(CT, Reg2Entry);38prebuildReg2Entry(GT, Reg2Entry);39prebuildReg2Entry(FT, Reg2Entry);40prebuildReg2Entry(AT, Reg2Entry);41prebuildReg2Entry(MT, Reg2Entry);42prebuildReg2Entry(ST, Reg2Entry);4344for (auto &Op2E : Reg2Entry) {45SPIRV::DTSortableEntry *E = Op2E.second;46Graph.push_back(E);47for (auto &U : *E) {48const MachineRegisterInfo &MRI = U.first->getRegInfo();49MachineInstr *MI = MRI.getUniqueVRegDef(U.second);50if (!MI)51continue;52assert(MI && MI->getParent() && "No MachineInstr created yet");53for (auto i = MI->getNumDefs(); i < MI->getNumOperands(); i++) {54MachineOperand &Op = MI->getOperand(i);55if (!Op.isReg())56continue;57MachineInstr *VRegDef = MRI.getVRegDef(Op.getReg());58// References to a function via function pointers generate virtual59// registers without a definition. We are able to resolve this60// reference using Globar Register info into an OpFunction instruction61// but do not expect to find it in Reg2Entry.62if (MI->getOpcode() == SPIRV::OpConstantFunctionPointerINTEL && i == 2)63continue;64MachineOperand *RegOp = &VRegDef->getOperand(0);65assert((MI->getOpcode() == SPIRV::OpVariable && i == 3) ||66Reg2Entry.count(RegOp));67if (Reg2Entry.count(RegOp))68E->addDep(Reg2Entry[RegOp]);69}7071if (E->getIsFunc()) {72MachineInstr *Next = MI->getNextNode();73if (Next && (Next->getOpcode() == SPIRV::OpFunction ||74Next->getOpcode() == SPIRV::OpFunctionParameter)) {75E->addDep(Reg2Entry[&Next->getOperand(0)]);76}77}78}79}8081#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)82if (MMI) {83const Module *M = MMI->getModule();84for (auto F = M->begin(), E = M->end(); F != E; ++F) {85const MachineFunction *MF = MMI->getMachineFunction(*F);86if (!MF)87continue;88for (const MachineBasicBlock &MBB : *MF) {89for (const MachineInstr &CMI : MBB) {90MachineInstr &MI = const_cast<MachineInstr &>(CMI);91MI.dump();92if (MI.getNumExplicitDefs() > 0 &&93Reg2Entry.count(&MI.getOperand(0))) {94dbgs() << "\t[";95for (SPIRV::DTSortableEntry *D :96Reg2Entry.lookup(&MI.getOperand(0))->getDeps())97dbgs() << Register::virtReg2Index(D->lookup(MF)) << ", ";98dbgs() << "]\n";99}100}101}102}103}104#endif105}106107108