@@ -74,9 +74,115 @@ DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
74
74
75
75
namespace {
76
76
77
- using RegList = SmallVector<unsigned , 4 >;
78
- using SourceMap = DenseMap<unsigned , RegList>;
79
- using Reg2MIMap = DenseMap<unsigned , MachineInstr *>;
77
+ class CopyTracker {
78
+ using RegList = SmallVector<unsigned , 4 >;
79
+ using SourceMap = DenseMap<unsigned , RegList>;
80
+ using Reg2MIMap = DenseMap<unsigned , MachineInstr *>;
81
+
82
+ // / Def -> available copies map.
83
+ Reg2MIMap AvailCopyMap;
84
+
85
+ // / Def -> copies map.
86
+ Reg2MIMap CopyMap;
87
+
88
+ // / Src -> Def map
89
+ SourceMap SrcMap;
90
+
91
+ public:
92
+ // / Mark all of the given registers and their subregisters as unavailable for
93
+ // / copying.
94
+ void markRegsUnavailable (const RegList &Regs, const TargetRegisterInfo &TRI) {
95
+ for (unsigned Reg : Regs) {
96
+ // Source of copy is no longer available for propagation.
97
+ for (MCSubRegIterator SR (Reg, &TRI, true ); SR.isValid (); ++SR)
98
+ AvailCopyMap.erase (*SR);
99
+ }
100
+ }
101
+
102
+ // / Remove any entry in the tracker's copy maps that is marked clobbered in \p
103
+ // / RegMask. The map will typically have a lot fewer entries than the regmask
104
+ // / clobbers, so this is more efficient than iterating the clobbered registers
105
+ // / and calling ClobberRegister() on them.
106
+ void removeClobberedRegs (const MachineOperand &RegMask,
107
+ const TargetRegisterInfo &TRI) {
108
+ auto RemoveFromMap = [&RegMask](Reg2MIMap &Map) {
109
+ for (Reg2MIMap::iterator I = Map.begin (), E = Map.end (), Next; I != E;
110
+ I = Next) {
111
+ Next = std::next (I);
112
+ if (RegMask.clobbersPhysReg (I->first ))
113
+ Map.erase (I);
114
+ }
115
+ };
116
+ RemoveFromMap (AvailCopyMap);
117
+ RemoveFromMap (CopyMap);
118
+
119
+ for (SourceMap::iterator I = SrcMap.begin (), E = SrcMap.end (), Next; I != E;
120
+ I = Next) {
121
+ Next = std::next (I);
122
+ if (RegMask.clobbersPhysReg (I->first )) {
123
+ markRegsUnavailable (I->second , TRI);
124
+ SrcMap.erase (I);
125
+ }
126
+ }
127
+ }
128
+
129
+ // / Clobber a single register, removing it from the tracker's copy maps.
130
+ void clobberRegister (unsigned Reg, const TargetRegisterInfo &TRI) {
131
+ for (MCRegAliasIterator AI (Reg, &TRI, true ); AI.isValid (); ++AI) {
132
+ CopyMap.erase (*AI);
133
+ AvailCopyMap.erase (*AI);
134
+
135
+ SourceMap::iterator SI = SrcMap.find (*AI);
136
+ if (SI != SrcMap.end ()) {
137
+ markRegsUnavailable (SI->second , TRI);
138
+ SrcMap.erase (SI);
139
+ }
140
+ }
141
+ }
142
+
143
+ // / Add this copy's registers into the tracker's copy maps.
144
+ void trackCopy (MachineInstr *Copy, const TargetRegisterInfo &TRI) {
145
+ assert (Copy->isCopy () && " Tracking non-copy?" );
146
+
147
+ unsigned Def = Copy->getOperand (0 ).getReg ();
148
+ unsigned Src = Copy->getOperand (1 ).getReg ();
149
+
150
+ // Remember Def is defined by the copy.
151
+ for (MCSubRegIterator SR (Def, &TRI, /* IncludeSelf=*/ true ); SR.isValid ();
152
+ ++SR) {
153
+ CopyMap[*SR] = Copy;
154
+ AvailCopyMap[*SR] = Copy;
155
+ }
156
+
157
+ // Remember source that's copied to Def. Once it's clobbered, then
158
+ // it's no longer available for copy propagation.
159
+ RegList &DestList = SrcMap[Src];
160
+ if (!is_contained (DestList, Def))
161
+ DestList.push_back (Def);
162
+ }
163
+
164
+ bool hasAvailableCopies () { return !AvailCopyMap.empty (); }
165
+
166
+ MachineInstr *findAvailCopy (unsigned Reg) {
167
+ auto CI = AvailCopyMap.find (Reg);
168
+ if (CI != AvailCopyMap.end ())
169
+ return CI->second ;
170
+ return nullptr ;
171
+ }
172
+
173
+ MachineInstr *findCopy (unsigned Reg) {
174
+ auto CI = CopyMap.find (Reg);
175
+ if (CI != CopyMap.end ())
176
+ return CI->second ;
177
+ return nullptr ;
178
+ }
179
+
180
+ void clear () {
181
+ AvailCopyMap.clear ();
182
+ CopyMap.clear ();
183
+ SrcMap.clear ();
184
+ }
185
+ };
80
186
81
187
class MachineCopyPropagation : public MachineFunctionPass {
82
188
const TargetRegisterInfo *TRI;
@@ -115,14 +221,7 @@ class MachineCopyPropagation : public MachineFunctionPass {
115
221
// / Candidates for deletion.
116
222
SmallSetVector<MachineInstr *, 8 > MaybeDeadCopies;
117
223
118
- // / Def -> available copies map.
119
- Reg2MIMap AvailCopyMap;
120
-
121
- // / Def -> copies map.
122
- Reg2MIMap CopyMap;
123
-
124
- // / Src -> Def map
125
- SourceMap SrcMap;
224
+ CopyTracker Tracker;
126
225
127
226
bool Changed;
128
227
};
@@ -136,54 +235,13 @@ char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
136
235
INITIALIZE_PASS (MachineCopyPropagation, DEBUG_TYPE,
137
236
" Machine Copy Propagation Pass" , false , false )
138
237
139
- // / Remove any entry in \p Map where the register is a subregister or equal to
140
- // / a register contained in \p Regs.
141
- static void removeRegsFromMap(Reg2MIMap &Map, const RegList &Regs,
142
- const TargetRegisterInfo &TRI) {
143
- for (unsigned Reg : Regs) {
144
- // Source of copy is no longer available for propagation.
145
- for (MCSubRegIterator SR (Reg, &TRI, true ); SR.isValid (); ++SR)
146
- Map.erase (*SR);
147
- }
148
- }
149
-
150
- // / Remove any entry in \p Map that is marked clobbered in \p RegMask.
151
- // / The map will typically have a lot fewer entries than the regmask clobbers,
152
- // / so this is more efficient than iterating the clobbered registers and calling
153
- // / ClobberRegister() on them.
154
- static void removeClobberedRegsFromMap (Reg2MIMap &Map,
155
- const MachineOperand &RegMask) {
156
- for (Reg2MIMap::iterator I = Map.begin (), E = Map.end (), Next; I != E;
157
- I = Next) {
158
- Next = std::next (I);
159
- unsigned Reg = I->first ;
160
- if (RegMask.clobbersPhysReg (Reg))
161
- Map.erase (I);
162
- }
163
- }
164
-
165
- void MachineCopyPropagation::ClobberRegister (unsigned Reg) {
166
- for (MCRegAliasIterator AI (Reg, TRI, true ); AI.isValid (); ++AI) {
167
- CopyMap.erase (*AI);
168
- AvailCopyMap.erase (*AI);
169
-
170
- SourceMap::iterator SI = SrcMap.find (*AI);
171
- if (SI != SrcMap.end ()) {
172
- removeRegsFromMap (AvailCopyMap, SI->second , *TRI);
173
- SrcMap.erase (SI);
174
- }
175
- }
176
- }
177
-
178
238
void MachineCopyPropagation::ReadRegister(unsigned Reg) {
179
239
// If 'Reg' is defined by a copy, the copy is no longer a candidate
180
240
// for elimination.
181
241
for (MCRegAliasIterator AI (Reg, TRI, true ); AI.isValid (); ++AI) {
182
- Reg2MIMap::iterator CI = CopyMap.find (*AI);
183
- if (CI != CopyMap.end ()) {
184
- LLVM_DEBUG (dbgs () << " MCP: Copy is used - not dead: " ;
185
- CI->second ->dump ());
186
- MaybeDeadCopies.remove (CI->second );
242
+ if (MachineInstr *Copy = Tracker.findCopy (*AI)) {
243
+ LLVM_DEBUG (dbgs () << " MCP: Copy is used - not dead: " ; Copy->dump ());
244
+ MaybeDeadCopies.remove (Copy);
187
245
}
188
246
}
189
247
}
@@ -219,15 +277,14 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
219
277
return false ;
220
278
221
279
// Search for an existing copy.
222
- Reg2MIMap::iterator CI = AvailCopyMap. find (Def);
223
- if (CI == AvailCopyMap. end () )
280
+ MachineInstr *PrevCopy = Tracker. findAvailCopy (Def);
281
+ if (!PrevCopy )
224
282
return false ;
225
283
226
284
// Check that the existing copy uses the correct sub registers.
227
- MachineInstr &PrevCopy = *CI->second ;
228
- if (PrevCopy.getOperand (0 ).isDead ())
285
+ if (PrevCopy->getOperand (0 ).isDead ())
229
286
return false ;
230
- if (!isNopCopy (PrevCopy, Src, Def, TRI))
287
+ if (!isNopCopy (* PrevCopy, Src, Def, TRI))
231
288
return false ;
232
289
233
290
LLVM_DEBUG (dbgs () << " MCP: copy is a NOP, removing: " ; Copy.dump ());
@@ -238,7 +295,7 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
238
295
unsigned CopyDef = Copy.getOperand (0 ).getReg ();
239
296
assert (CopyDef == Src || CopyDef == Def);
240
297
for (MachineInstr &MI :
241
- make_range (PrevCopy. getIterator (), Copy.getIterator ()))
298
+ make_range (PrevCopy-> getIterator (), Copy.getIterator ()))
242
299
MI.clearRegisterKills (CopyDef, TRI);
243
300
244
301
Copy.eraseFromParent ();
@@ -314,7 +371,7 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
314
371
// / Look for available copies whose destination register is used by \p MI and
315
372
// / replace the use in \p MI with the copy's source register.
316
373
void MachineCopyPropagation::forwardUses (MachineInstr &MI) {
317
- if (AvailCopyMap. empty ())
374
+ if (!Tracker. hasAvailableCopies ())
318
375
return ;
319
376
320
377
// Look for non-tied explicit vreg uses that have an active COPY
@@ -341,13 +398,12 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
341
398
if (!MOUse.isRenamable ())
342
399
continue ;
343
400
344
- auto CI = AvailCopyMap. find (MOUse.getReg ());
345
- if (CI == AvailCopyMap. end () )
401
+ MachineInstr *Copy = Tracker. findAvailCopy (MOUse.getReg ());
402
+ if (!Copy )
346
403
continue ;
347
404
348
- MachineInstr &Copy = *CI->second ;
349
- unsigned CopyDstReg = Copy.getOperand (0 ).getReg ();
350
- const MachineOperand &CopySrc = Copy.getOperand (1 );
405
+ unsigned CopyDstReg = Copy->getOperand (0 ).getReg ();
406
+ const MachineOperand &CopySrc = Copy->getOperand (1 );
351
407
unsigned CopySrcReg = CopySrc.getReg ();
352
408
353
409
// FIXME: Don't handle partial uses of wider COPYs yet.
@@ -362,7 +418,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
362
418
if (MRI->isReserved (CopySrcReg) && !MRI->isConstantPhysReg (CopySrcReg))
363
419
continue ;
364
420
365
- if (!isForwardableRegClassCopy (Copy, MI, OpIdx))
421
+ if (!isForwardableRegClassCopy (* Copy, MI, OpIdx))
366
422
continue ;
367
423
368
424
if (hasImplicitOverlap (MI, MOUse))
@@ -376,7 +432,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
376
432
377
433
LLVM_DEBUG (dbgs () << " MCP: Replacing " << printReg (MOUse.getReg (), TRI)
378
434
<< " \n with " << printReg (CopySrcReg, TRI)
379
- << " \n in " << MI << " from " << Copy);
435
+ << " \n in " << MI << " from " << * Copy);
380
436
381
437
MOUse.setReg (CopySrcReg);
382
438
if (!CopySrc.isRenamable ())
@@ -386,7 +442,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
386
442
387
443
// Clear kill markers that may have been invalidated.
388
444
for (MachineInstr &KMI :
389
- make_range (Copy. getIterator (), std::next (MI.getIterator ())))
445
+ make_range (Copy-> getIterator (), std::next (MI.getIterator ())))
390
446
KMI.clearRegisterKills (CopySrcReg, TRI);
391
447
392
448
++NumCopyForwards;
@@ -459,28 +515,17 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
459
515
// %xmm2 = copy %xmm0
460
516
// ...
461
517
// %xmm2 = copy %xmm9
462
- ClobberRegister (Def);
518
+ Tracker. clobberRegister (Def, *TRI );
463
519
for (const MachineOperand &MO : MI->implicit_operands ()) {
464
520
if (!MO.isReg () || !MO.isDef ())
465
521
continue ;
466
522
unsigned Reg = MO.getReg ();
467
523
if (!Reg)
468
524
continue ;
469
- ClobberRegister (Reg);
470
- }
471
-
472
- // Remember Def is defined by the copy.
473
- for (MCSubRegIterator SR (Def, TRI, /* IncludeSelf=*/ true ); SR.isValid ();
474
- ++SR) {
475
- CopyMap[*SR] = MI;
476
- AvailCopyMap[*SR] = MI;
525
+ Tracker.clobberRegister (Reg, *TRI);
477
526
}
478
527
479
- // Remember source that's copied to Def. Once it's clobbered, then
480
- // it's no longer available for copy propagation.
481
- RegList &DestList = SrcMap[Src];
482
- if (!is_contained (DestList, Def))
483
- DestList.push_back (Def);
528
+ Tracker.trackCopy (MI, *TRI);
484
529
485
530
continue ;
486
531
}
@@ -494,7 +539,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
494
539
// later.
495
540
if (MO.isTied ())
496
541
ReadRegister (Reg);
497
- ClobberRegister (Reg);
542
+ Tracker. clobberRegister (Reg, *TRI );
498
543
}
499
544
500
545
forwardUses (*MI);
@@ -549,21 +594,12 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
549
594
++NumDeletes;
550
595
}
551
596
552
- removeClobberedRegsFromMap (AvailCopyMap, *RegMask);
553
- removeClobberedRegsFromMap (CopyMap, *RegMask);
554
- for (SourceMap::iterator I = SrcMap.begin (), E = SrcMap.end (), Next;
555
- I != E; I = Next) {
556
- Next = std::next (I);
557
- if (RegMask->clobbersPhysReg (I->first )) {
558
- removeRegsFromMap (AvailCopyMap, I->second , *TRI);
559
- SrcMap.erase (I);
560
- }
561
- }
597
+ Tracker.removeClobberedRegs (*RegMask, *TRI);
562
598
}
563
599
564
600
// Any previous copy definition or reading the Defs is no longer available.
565
601
for (unsigned Reg : Defs)
566
- ClobberRegister (Reg);
602
+ Tracker. clobberRegister (Reg, *TRI );
567
603
}
568
604
569
605
// If MBB doesn't have successors, delete the copies whose defs are not used.
@@ -581,9 +617,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
581
617
}
582
618
583
619
MaybeDeadCopies.clear ();
584
- AvailCopyMap.clear ();
585
- CopyMap.clear ();
586
- SrcMap.clear ();
620
+ Tracker.clear ();
587
621
}
588
622
589
623
bool MachineCopyPropagation::runOnMachineFunction (MachineFunction &MF) {
0 commit comments