@@ -42,14 +42,31 @@ class MachineLateInstrsCleanup : public MachineFunctionPass {
42
42
const TargetRegisterInfo *TRI = nullptr ;
43
43
const TargetInstrInfo *TII = nullptr ;
44
44
45
- // Data structures to map regs to their definitions per MBB.
46
- using Reg2DefMap = std::map<Register, MachineInstr*>;
47
- std::vector<Reg2DefMap> RegDefs;
45
+ // Data structures to map regs to their definitions and kills per MBB.
46
+ struct Reg2MIMap : public SmallDenseMap <Register, MachineInstr *> {
47
+ MachineInstr *get (Register Reg) {
48
+ auto I = find (Reg);
49
+ return I != end () ? I->second : nullptr ;
50
+ }
51
+
52
+ bool hasIdentical (Register Reg, MachineInstr *ArgMI) {
53
+ MachineInstr *MI = get (Reg);
54
+ return MI && MI->isIdenticalTo (*ArgMI);
55
+ }
56
+ };
57
+
58
+ std::vector<Reg2MIMap> RegDefs;
59
+ std::vector<Reg2MIMap> RegKills;
48
60
49
61
// Walk through the instructions in MBB and remove any redundant
50
62
// instructions.
51
63
bool processBlock (MachineBasicBlock *MBB);
52
64
65
+ void removeRedundantDef (MachineInstr *MI);
66
+ void clearKillsForDef (Register Reg, MachineBasicBlock *MBB,
67
+ MachineBasicBlock::iterator I,
68
+ BitVector &VisitedPreds);
69
+
53
70
public:
54
71
static char ID; // Pass identification, replacement for typeid
55
72
@@ -88,6 +105,8 @@ bool MachineLateInstrsCleanup::runOnMachineFunction(MachineFunction &MF) {
88
105
89
106
RegDefs.clear ();
90
107
RegDefs.resize (MF.getNumBlockIDs ());
108
+ RegKills.clear ();
109
+ RegKills.resize (MF.getNumBlockIDs ());
91
110
92
111
// Visit all MBBs in an order that maximises the reuse from predecessors.
93
112
bool Changed = false ;
@@ -102,41 +121,36 @@ bool MachineLateInstrsCleanup::runOnMachineFunction(MachineFunction &MF) {
102
121
// in MBB and if needed continue in predecessors until a use/def of Reg is
103
122
// encountered. This seems to be faster in practice than tracking kill flags
104
123
// in a map.
105
- static void clearKillsForDef (Register Reg, MachineBasicBlock *MBB,
106
- MachineBasicBlock::iterator I ,
107
- BitVector &VisitedPreds ,
108
- const TargetRegisterInfo *TRI ) {
124
+ void MachineLateInstrsCleanup::
125
+ clearKillsForDef (Register Reg, MachineBasicBlock *MBB ,
126
+ MachineBasicBlock::iterator I ,
127
+ BitVector &VisitedPreds ) {
109
128
VisitedPreds.set (MBB->getNumber ());
110
- while (I != MBB->begin ()) {
111
- --I;
112
- bool Found = false ;
113
- for (auto &MO : I->operands ())
114
- if (MO.isReg () && TRI->regsOverlap (MO.getReg (), Reg)) {
115
- if (MO.isDef ())
116
- return ;
117
- if (MO.readsReg ()) {
118
- MO.setIsKill (false );
119
- Found = true ; // Keep going for an implicit kill of the super-reg.
120
- }
121
- }
122
- if (Found)
123
- return ;
129
+
130
+ // Kill flag in MBB
131
+ if (MachineInstr *KillMI = RegKills[MBB->getNumber ()].get (Reg)) {
132
+ KillMI->clearRegisterKills (Reg, TRI);
133
+ return ;
124
134
}
125
135
136
+ // Def in MBB (missing kill flag)
137
+ if (MachineInstr *DefMI = RegDefs[MBB->getNumber ()].get (Reg))
138
+ if (DefMI->getParent () == MBB)
139
+ return ;
140
+
126
141
// If an earlier def is not in MBB, continue in predecessors.
127
142
if (!MBB->isLiveIn (Reg))
128
143
MBB->addLiveIn (Reg);
129
144
assert (!MBB->pred_empty () && " Predecessor def not found!" );
130
145
for (MachineBasicBlock *Pred : MBB->predecessors ())
131
146
if (!VisitedPreds.test (Pred->getNumber ()))
132
- clearKillsForDef (Reg, Pred, Pred->end (), VisitedPreds, TRI );
147
+ clearKillsForDef (Reg, Pred, Pred->end (), VisitedPreds);
133
148
}
134
149
135
- static void removeRedundantDef (MachineInstr *MI,
136
- const TargetRegisterInfo *TRI) {
150
+ void MachineLateInstrsCleanup::removeRedundantDef (MachineInstr *MI) {
137
151
Register Reg = MI->getOperand (0 ).getReg ();
138
152
BitVector VisitedPreds (MI->getMF ()->getNumBlockIDs ());
139
- clearKillsForDef (Reg, MI->getParent (), MI->getIterator (), VisitedPreds, TRI );
153
+ clearKillsForDef (Reg, MI->getParent (), MI->getIterator (), VisitedPreds);
140
154
MI->eraseFromParent ();
141
155
++NumRemoved;
142
156
}
@@ -172,7 +186,8 @@ static bool isCandidate(const MachineInstr *MI, Register &DefedReg,
172
186
173
187
bool MachineLateInstrsCleanup::processBlock (MachineBasicBlock *MBB) {
174
188
bool Changed = false ;
175
- Reg2DefMap &MBBDefs = RegDefs[MBB->getNumber ()];
189
+ Reg2MIMap &MBBDefs = RegDefs[MBB->getNumber ()];
190
+ Reg2MIMap &MBBKills = RegKills[MBB->getNumber ()];
176
191
177
192
// Find reusable definitions in the predecessor(s).
178
193
if (!MBB->pred_empty () && !MBB->isEHPad () &&
@@ -182,9 +197,7 @@ bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
182
197
if (llvm::all_of (
183
198
drop_begin (MBB->predecessors ()),
184
199
[&, &Reg = Reg, &DefMI = DefMI](const MachineBasicBlock *Pred) {
185
- auto PredDefI = RegDefs[Pred->getNumber ()].find (Reg);
186
- return PredDefI != RegDefs[Pred->getNumber ()].end () &&
187
- DefMI->isIdenticalTo (*PredDefI->second );
200
+ return RegDefs[Pred->getNumber ()].hasIdentical (Reg, DefMI);
188
201
})) {
189
202
MBBDefs[Reg] = DefMI;
190
203
LLVM_DEBUG (dbgs () << " Reusable instruction from pred(s): in "
@@ -201,38 +214,39 @@ bool MachineLateInstrsCleanup::processBlock(MachineBasicBlock *MBB) {
201
214
// it) are valid.
202
215
if (MI.modifiesRegister (FrameReg, TRI)) {
203
216
MBBDefs.clear ();
217
+ MBBKills.clear ();
204
218
continue ;
205
219
}
206
220
207
221
Register DefedReg;
208
222
bool IsCandidate = isCandidate (&MI, DefedReg, FrameReg);
209
223
210
224
// Check for an earlier identical and reusable instruction.
211
- if (IsCandidate) {
212
- auto DefI = MBBDefs.find (DefedReg);
213
- if (DefI != MBBDefs.end () && MI.isIdenticalTo (*DefI->second )) {
214
- LLVM_DEBUG (dbgs () << " Removing redundant instruction in "
215
- << printMBBReference (*MBB) << " : " << MI;);
216
- removeRedundantDef (&MI, TRI);
217
- Changed = true ;
218
- continue ;
219
- }
225
+ if (IsCandidate && MBBDefs.hasIdentical (DefedReg, &MI)) {
226
+ LLVM_DEBUG (dbgs () << " Removing redundant instruction in "
227
+ << printMBBReference (*MBB) << " : " << MI;);
228
+ removeRedundantDef (&MI);
229
+ Changed = true ;
230
+ continue ;
220
231
}
221
232
222
233
// Clear any entries in map that MI clobbers.
223
- for (auto DefI = MBBDefs.begin (); DefI != MBBDefs.end ();) {
224
- Register Reg = DefI->first ;
225
- if (MI.modifiesRegister (Reg, TRI))
226
- DefI = MBBDefs.erase (DefI);
227
- else
228
- ++DefI;
234
+ for (auto DefI : llvm::make_early_inc_range (MBBDefs)) {
235
+ Register Reg = DefI.first ;
236
+ if (MI.modifiesRegister (Reg, TRI)) {
237
+ MBBDefs.erase (Reg);
238
+ MBBKills.erase (Reg);
239
+ } else if (MI.findRegisterUseOperandIdx (Reg, false /* isKill*/ , TRI) != -1 )
240
+ // Keep track of the last use seen so far.
241
+ MBBKills[Reg] = &MI;
229
242
}
230
243
231
244
// Record this MI for potential later reuse.
232
245
if (IsCandidate) {
233
246
LLVM_DEBUG (dbgs () << " Found interesting instruction in "
234
247
<< printMBBReference (*MBB) << " : " << MI;);
235
248
MBBDefs[DefedReg] = &MI;
249
+ assert (!MBBKills.count (DefedReg) && " Should already have been removed." );
236
250
}
237
251
}
238
252
0 commit comments