@@ -34,6 +34,7 @@ void initializeNVPTXProxyRegErasurePass(PassRegistry &);
34
34
namespace {
35
35
36
36
struct NVPTXProxyRegErasure : public MachineFunctionPass {
37
+ public:
37
38
static char ID;
38
39
NVPTXProxyRegErasure () : MachineFunctionPass(ID) {
39
40
initializeNVPTXProxyRegErasurePass (*PassRegistry::getPassRegistry ());
@@ -48,22 +49,23 @@ struct NVPTXProxyRegErasure : public MachineFunctionPass {
48
49
void getAnalysisUsage (AnalysisUsage &AU) const override {
49
50
MachineFunctionPass::getAnalysisUsage (AU);
50
51
}
52
+
53
+ private:
54
+ void replaceMachineInstructionUsage (MachineFunction &MF, MachineInstr &MI);
55
+
56
+ void replaceRegisterUsage (MachineInstr &Instr, MachineOperand &From,
57
+ MachineOperand &To);
51
58
};
52
59
53
60
} // namespace
54
61
55
62
char NVPTXProxyRegErasure::ID = 0 ;
56
63
57
- INITIALIZE_PASS (NVPTXProxyRegErasure, " nvptx-proxyreg-erasure" ,
58
- " NVPTX ProxyReg Erasure" , false , false )
64
+ INITIALIZE_PASS (NVPTXProxyRegErasure, " nvptx-proxyreg-erasure" , " NVPTX ProxyReg Erasure" , false , false )
59
65
60
66
bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
61
67
SmallVector<MachineInstr *, 16 > RemoveList;
62
68
63
- // ProxyReg instructions forward a register as another: `%dst = mov.iN %src`.
64
- // Bulk RAUW the `%dst` registers in two passes over the machine function.
65
- DenseMap<Register, Register> RAUWBatch;
66
-
67
69
for (auto &BB : MF) {
68
70
for (auto &MI : BB) {
69
71
switch (MI.getOpcode ()) {
@@ -72,42 +74,44 @@ bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
72
74
case NVPTX::ProxyRegI32:
73
75
case NVPTX::ProxyRegI64:
74
76
case NVPTX::ProxyRegF32:
75
- case NVPTX::ProxyRegF64: {
76
- auto &InOp = *MI.uses ().begin ();
77
- auto &OutOp = *MI.defs ().begin ();
78
- assert (InOp.isReg () && " ProxyReg input should be a register." );
79
- assert (OutOp.isReg () && " ProxyReg output should be a register." );
77
+ case NVPTX::ProxyRegF64:
78
+ replaceMachineInstructionUsage (MF, MI);
80
79
RemoveList.push_back (&MI);
81
- RAUWBatch.try_emplace (OutOp.getReg (), InOp.getReg ());
82
80
break ;
83
81
}
84
- }
85
82
}
86
83
}
87
84
88
- // If there were no proxy instructions, exit early.
89
- if (RemoveList.empty ())
90
- return false ;
91
-
92
- // Erase the proxy instructions first.
93
85
for (auto *MI : RemoveList) {
94
86
MI->eraseFromParent ();
95
87
}
96
88
97
- // Now go replace the registers.
89
+ return !RemoveList.empty ();
90
+ }
91
+
92
+ void NVPTXProxyRegErasure::replaceMachineInstructionUsage (MachineFunction &MF,
93
+ MachineInstr &MI) {
94
+ auto &InOp = *MI.uses ().begin ();
95
+ auto &OutOp = *MI.defs ().begin ();
96
+
97
+ assert (InOp.isReg () && " ProxyReg input operand should be a register." );
98
+ assert (OutOp.isReg () && " ProxyReg output operand should be a register." );
99
+
98
100
for (auto &BB : MF) {
99
- for (auto &MI : BB) {
100
- for (auto &Op : MI.uses ()) {
101
- if (!Op.isReg ())
102
- continue ;
103
- auto it = RAUWBatch.find (Op.getReg ());
104
- if (it != RAUWBatch.end ())
105
- Op.setReg (it->second );
106
- }
101
+ for (auto &I : BB) {
102
+ replaceRegisterUsage (I, OutOp, InOp);
107
103
}
108
104
}
105
+ }
109
106
110
- return true ;
107
+ void NVPTXProxyRegErasure::replaceRegisterUsage (MachineInstr &Instr,
108
+ MachineOperand &From,
109
+ MachineOperand &To) {
110
+ for (auto &Op : Instr.uses ()) {
111
+ if (Op.isReg () && Op.getReg () == From.getReg ()) {
112
+ Op.setReg (To.getReg ());
113
+ }
114
+ }
111
115
}
112
116
113
117
MachineFunctionPass *llvm::createNVPTXProxyRegErasurePass () {
0 commit comments