@@ -34,7 +34,6 @@ void initializeNVPTXProxyRegErasurePass(PassRegistry &);
3434namespace {
3535
3636struct NVPTXProxyRegErasure : public MachineFunctionPass {
37- public:
3837 static char ID;
3938 NVPTXProxyRegErasure () : MachineFunctionPass(ID) {
4039 initializeNVPTXProxyRegErasurePass (*PassRegistry::getPassRegistry ());
@@ -49,23 +48,22 @@ struct NVPTXProxyRegErasure : public MachineFunctionPass {
4948 void getAnalysisUsage (AnalysisUsage &AU) const override {
5049 MachineFunctionPass::getAnalysisUsage (AU);
5150 }
52-
53- private:
54- void replaceMachineInstructionUsage (MachineFunction &MF, MachineInstr &MI);
55-
56- void replaceRegisterUsage (MachineInstr &Instr, MachineOperand &From,
57- MachineOperand &To);
5851};
5952
6053} // namespace
6154
6255char NVPTXProxyRegErasure::ID = 0 ;
6356
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 )
6559
6660bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
6761 SmallVector<MachineInstr *, 16 > RemoveList;
6862
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+
6967 for (auto &BB : MF) {
7068 for (auto &MI : BB) {
7169 switch (MI.getOpcode ()) {
@@ -74,44 +72,42 @@ bool NVPTXProxyRegErasure::runOnMachineFunction(MachineFunction &MF) {
7472 case NVPTX::ProxyRegI32:
7573 case NVPTX::ProxyRegI64:
7674 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." );
7980 RemoveList.push_back (&MI);
81+ RAUWBatch.try_emplace (OutOp.getReg (), InOp.getReg ());
8082 break ;
8183 }
84+ }
8285 }
8386 }
8487
88+ // If there were no proxy instructions, exit early.
89+ if (RemoveList.empty ())
90+ return false ;
91+
92+ // Erase the proxy instructions first.
8593 for (auto *MI : RemoveList) {
8694 MI->eraseFromParent ();
8795 }
8896
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.
10098 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+ }
103107 }
104108 }
105- }
106109
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 ;
115111}
116112
117113MachineFunctionPass *llvm::createNVPTXProxyRegErasurePass () {
0 commit comments