Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVDuplicatesTracker.cpp
35266 views
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
108