@@ -39,24 +39,25 @@ namespace {
3939class MachineLateInstrsCleanup : public MachineFunctionPass {
4040 const TargetRegisterInfo *TRI = nullptr ;
4141 const TargetInstrInfo *TII = nullptr ;
42- const MachineRegisterInfo *MRI = nullptr ;
4342
44- // Data structure to map regs to their definitions per MBB.
43+ // Data structures to map regs to their definitions and kills per MBB.
4544 struct Reg2MIMap : public SmallDenseMap <Register, MachineInstr *> {
4645 bool hasIdentical (Register Reg, MachineInstr *ArgMI) {
4746 MachineInstr *MI = lookup (Reg);
4847 return MI && MI->isIdenticalTo (*ArgMI);
4948 }
5049 };
50+ typedef SmallDenseMap<Register, TinyPtrVector<MachineInstr *>> Reg2MIVecMap;
5151 std::vector<Reg2MIMap> RegDefs;
52+ std::vector<Reg2MIVecMap> RegKills;
5253
5354 // Walk through the instructions in MBB and remove any redundant
5455 // instructions.
5556 bool processBlock (MachineBasicBlock *MBB);
5657
5758 void removeRedundantDef (MachineInstr *MI);
58- void updateLiveInLists (Register Reg, MachineBasicBlock *MBB,
59- BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
59+ void clearKillsForDef (Register Reg, MachineBasicBlock *MBB,
60+ BitVector &VisitedPreds, MachineInstr *ToRemoveMI);
6061
6162public:
6263 static char ID; // Pass identification, replacement for typeid
@@ -93,10 +94,11 @@ bool MachineLateInstrsCleanup::runOnMachineFunction(MachineFunction &MF) {
9394
9495 TRI = MF.getSubtarget ().getRegisterInfo ();
9596 TII = MF.getSubtarget ().getInstrInfo ();
96- MRI = &MF.getRegInfo ();
9797
9898 RegDefs.clear ();
9999 RegDefs.resize (MF.getNumBlockIDs ());
100+ RegKills.clear ();
101+ RegKills.resize (MF.getNumBlockIDs ());
100102
101103 // Visit all MBBs in an order that maximises the reuse from predecessors.
102104 bool Changed = false ;
@@ -109,36 +111,41 @@ bool MachineLateInstrsCleanup::runOnMachineFunction(MachineFunction &MF) {
109111
110112// Clear any preceding kill flag on Reg after removing a redundant
111113// definition.
112- void MachineLateInstrsCleanup::updateLiveInLists (Register Reg,
114+ void MachineLateInstrsCleanup::clearKillsForDef (Register Reg,
113115 MachineBasicBlock *MBB,
114116 BitVector &VisitedPreds,
115117 MachineInstr *ToRemoveMI) {
116118 VisitedPreds.set (MBB->getNumber ());
117119
120+ // Clear kill flag(s) in MBB, that have been seen after the preceding
121+ // definition. If Reg or one of its subregs was killed, it would actually
122+ // be ok to stop after removing that (and any other) kill-flag, but it
123+ // doesn't seem noticeably faster while it would be a bit more complicated.
124+ Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber ()];
125+ if (MBBKills.contains (Reg))
126+ for (auto *KillMI : MBBKills[Reg])
127+ KillMI->clearRegisterKills (Reg, TRI);
128+
118129 // Definition in current MBB: done.
119130 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber ()];
120131 MachineInstr *DefMI = MBBDefs[Reg];
121132 assert (DefMI->isIdenticalTo (*ToRemoveMI) && " Previous def not identical?" );
122133 if (DefMI->getParent () == MBB)
123134 return ;
124135
125- // If the earlier def is not in MBB, it has now become live in. Continue in
126- // predecessors until the defining MBB has been reached.
136+ // If an earlier def is not in MBB, continue in predecessors.
127137 if (!MBB->isLiveIn (Reg))
128138 MBB->addLiveIn (Reg);
129139 assert (!MBB->pred_empty () && " Predecessor def not found!" );
130140 for (MachineBasicBlock *Pred : MBB->predecessors ())
131141 if (!VisitedPreds.test (Pred->getNumber ()))
132- updateLiveInLists (Reg, Pred, VisitedPreds, ToRemoveMI);
142+ clearKillsForDef (Reg, Pred, VisitedPreds, ToRemoveMI);
133143}
134144
135145void MachineLateInstrsCleanup::removeRedundantDef (MachineInstr *MI) {
136146 Register Reg = MI->getOperand (0 ).getReg ();
137- // Clear any and all kill flags.
138- for (MCPhysReg SReg : TRI->superregs_inclusive (Reg))
139- MRI->clearKillFlags (SReg);
140147 BitVector VisitedPreds (MI->getMF ()->getNumBlockIDs ());
141- updateLiveInLists (Reg, MI->getParent (), VisitedPreds, MI);
148+ clearKillsForDef (Reg, MI->getParent (), VisitedPreds, MI);
142149 MI->eraseFromParent ();
143150 ++NumRemoved;
144151}
@@ -174,6 +181,7 @@ static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
174181bool MachineLateInstrsCleanup::processBlock (MachineBasicBlock *MBB) {
175182 bool Changed = false ;
176183 Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber ()];
184+ Reg2MIVecMap &MBBKills = RegKills[MBB->getNumber ()];
177185
178186 // Find reusable definitions in the predecessor(s).
179187 if (!MBB->pred_empty () && !MBB->isEHPad () &&
@@ -200,6 +208,7 @@ bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
200208 // it) are valid.
201209 if (MI.modifiesRegister (FrameReg, TRI)) {
202210 MBBDefs.clear ();
211+ MBBKills.clear ();
203212 continue ;
204213 }
205214
@@ -218,15 +227,20 @@ bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
218227 // Clear any entries in map that MI clobbers.
219228 for (auto DefI : llvm::make_early_inc_range (MBBDefs)) {
220229 Register Reg = DefI.first ;
221- if (MI.modifiesRegister (Reg, TRI))
230+ if (MI.modifiesRegister (Reg, TRI)) {
222231 MBBDefs.erase (Reg);
232+ MBBKills.erase (Reg);
233+ } else if (MI.findRegisterUseOperandIdx (Reg, TRI, true /* isKill*/ ) != -1 )
234+ // Keep track of all instructions that fully or partially kills Reg.
235+ MBBKills[Reg].push_back (&MI);
223236 }
224237
225238 // Record this MI for potential later reuse.
226239 if (IsCandidate) {
227240 LLVM_DEBUG (dbgs () << " Found interesting instruction in "
228241 << printMBBReference (*MBB) << " : " << MI;);
229242 MBBDefs[DefedReg] = &MI;
243+ assert (!MBBKills.count (DefedReg) && " Should already have been removed." );
230244 }
231245 }
232246
0 commit comments