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