1 //===-- SPIRVDuplicatesTracker.cpp - SPIR-V Duplicates Tracker --*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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.
12 //===----------------------------------------------------------------------===//
14 #include "SPIRVDuplicatesTracker.h"
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
);
28 Reg2Entry
[&MI
->getOperand(0)] = &TPair
.second
;
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
);
45 for (auto &Op2E
: Reg2Entry
) {
46 SPIRV::DTSortableEntry
*E
= Op2E
.second
;
49 const MachineRegisterInfo
&MRI
= U
.first
->getRegInfo();
50 MachineInstr
*MI
= MRI
.getUniqueVRegDef(U
.second
);
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
);
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)
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
]);
73 MachineInstr
*Next
= MI
->getNextNode();
74 if (Next
&& (Next
->getOpcode() == SPIRV::OpFunction
||
75 Next
->getOpcode() == SPIRV::OpFunctionParameter
)) {
76 E
->addDep(Reg2Entry
[&Next
->getOperand(0)]);
82 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
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
);
89 for (const MachineBasicBlock
&MBB
: *MF
) {
90 for (const MachineInstr
&CMI
: MBB
) {
91 MachineInstr
&MI
= const_cast<MachineInstr
&>(CMI
);
93 if (MI
.getNumExplicitDefs() > 0 &&
94 Reg2Entry
.count(&MI
.getOperand(0))) {
96 for (SPIRV::DTSortableEntry
*D
:
97 Reg2Entry
.lookup(&MI
.getOperand(0))->getDeps())
98 dbgs() << Register::virtReg2Index(D
->lookup(MF
)) << ", ";