@@ -164,91 +164,67 @@ class CopyTracker {
164
164
Copies.erase (Unit);
165
165
}
166
166
167
- // / Clobber a single register unit, removing it from the tracker's copy maps.
168
- void clobberRegUnit (MCRegUnit Unit, const TargetRegisterInfo &TRI,
169
- const TargetInstrInfo &TII, bool UseCopyInstr) {
170
- auto I = Copies.find (Unit);
171
- if (I != Copies.end ()) {
172
- // When we clobber the source of a copy, we need to clobber everything
173
- // it defined.
174
- markRegsUnavailable (I->second .DefRegs , TRI);
175
- // When we clobber the destination of a copy, we need to clobber the
176
- // whole register it defined.
177
- if (MachineInstr *MI = I->second .MI ) {
178
- std::optional<DestSourcePair> CopyOperands =
179
- isCopyInstr (*MI, TII, UseCopyInstr);
180
-
181
- MCRegister Def = CopyOperands->Destination ->getReg ().asMCReg ();
182
- MCRegister Src = CopyOperands->Source ->getReg ().asMCReg ();
183
-
184
- markRegsUnavailable (Def, TRI);
185
-
186
- // Since we clobber the destination of a copy, the semantic of Src's
187
- // "DefRegs" to contain Def is no longer effectual. We will also need
188
- // to remove the record from the copy maps that indicates Src defined
189
- // Def. Failing to do so might cause the target to miss some
190
- // opportunities to further eliminate redundant copy instructions.
191
- // Consider the following sequence during the
192
- // ForwardCopyPropagateBlock procedure:
193
- // L1: r0 = COPY r9 <- TrackMI
194
- // L2: r0 = COPY r8 <- TrackMI (Remove r9 defined r0 from tracker)
195
- // L3: use r0 <- Remove L2 from MaybeDeadCopies
196
- // L4: early-clobber r9 <- Clobber r9 (L2 is still valid in tracker)
197
- // L5: r0 = COPY r8 <- Remove NopCopy
198
- for (MCRegUnit SrcUnit : TRI.regunits (Src)) {
199
- auto SrcCopy = Copies.find (SrcUnit);
200
- if (SrcCopy != Copies.end () && SrcCopy->second .LastSeenUseInCopy ) {
201
- // If SrcCopy defines multiple values, we only need
202
- // to erase the record for Def in DefRegs.
203
- for (auto itr = SrcCopy->second .DefRegs .begin ();
204
- itr != SrcCopy->second .DefRegs .end (); itr++) {
205
- if (*itr == Def) {
206
- SrcCopy->second .DefRegs .erase (itr);
207
- // If DefReg becomes empty after removal, we can remove the
208
- // SrcCopy from the tracker's copy maps. We only remove those
209
- // entries solely record the Def is defined by Src. If an
210
- // entry also contains the definition record of other Def'
211
- // registers, it cannot be cleared.
212
- if (SrcCopy->second .DefRegs .empty () && !SrcCopy->second .MI ) {
213
- Copies.erase (SrcCopy);
167
+ // / Clobber a single register, removing it from the tracker's copy maps.
168
+ void clobberRegister (MCRegister Reg, const TargetRegisterInfo &TRI,
169
+ const TargetInstrInfo &TII, bool UseCopyInstr) {
170
+ for (MCRegUnit Unit : TRI.regunits (Reg)) {
171
+ auto I = Copies.find (Unit);
172
+ if (I != Copies.end ()) {
173
+ // When we clobber the source of a copy, we need to clobber everything
174
+ // it defined.
175
+ markRegsUnavailable (I->second .DefRegs , TRI);
176
+ // When we clobber the destination of a copy, we need to clobber the
177
+ // whole register it defined.
178
+ if (MachineInstr *MI = I->second .MI ) {
179
+ std::optional<DestSourcePair> CopyOperands =
180
+ isCopyInstr (*MI, TII, UseCopyInstr);
181
+
182
+ MCRegister Def = CopyOperands->Destination ->getReg ().asMCReg ();
183
+ MCRegister Src = CopyOperands->Source ->getReg ().asMCReg ();
184
+
185
+ markRegsUnavailable (Def, TRI);
186
+
187
+ // Since we clobber the destination of a copy, the semantic of Src's
188
+ // "DefRegs" to contain Def is no longer effectual. We will also need
189
+ // to remove the record from the copy maps that indicates Src defined
190
+ // Def. Failing to do so might cause the target to miss some
191
+ // opportunities to further eliminate redundant copy instructions.
192
+ // Consider the following sequence during the
193
+ // ForwardCopyPropagateBlock procedure:
194
+ // L1: r0 = COPY r9 <- TrackMI
195
+ // L2: r0 = COPY r8 <- TrackMI (Remove r9 defined r0 from tracker)
196
+ // L3: use r0 <- Remove L2 from MaybeDeadCopies
197
+ // L4: early-clobber r9 <- Clobber r9 (L2 is still valid in tracker)
198
+ // L5: r0 = COPY r8 <- Remove NopCopy
199
+ for (MCRegUnit SrcUnit : TRI.regunits (Src)) {
200
+ auto SrcCopy = Copies.find (SrcUnit);
201
+ if (SrcCopy != Copies.end () && SrcCopy->second .LastSeenUseInCopy ) {
202
+ // If SrcCopy defines multiple values, we only need
203
+ // to erase the record for Def in DefRegs.
204
+ for (auto itr = SrcCopy->second .DefRegs .begin ();
205
+ itr != SrcCopy->second .DefRegs .end (); itr++) {
206
+ if (*itr == Def) {
207
+ SrcCopy->second .DefRegs .erase (itr);
208
+ // If DefReg becomes empty after removal, we can remove the
209
+ // SrcCopy from the tracker's copy maps. We only remove those
210
+ // entries solely record the Def is defined by Src. If an
211
+ // entry also contains the definition record of other Def'
212
+ // registers, it cannot be cleared.
213
+ if (SrcCopy->second .DefRegs .empty () && !SrcCopy->second .MI ) {
214
+ Copies.erase (SrcCopy);
215
+ }
216
+ break ;
214
217
}
215
- break ;
216
218
}
217
219
}
218
220
}
219
221
}
222
+ // Now we can erase the copy.
223
+ Copies.erase (I);
220
224
}
221
- // Now we can erase the copy.
222
- Copies.erase (I);
223
225
}
224
226
}
225
227
226
- // / Clobber a single register, removing it from the tracker's copy maps.
227
- void clobberRegister (MCRegister Reg, const TargetRegisterInfo &TRI,
228
- const TargetInstrInfo &TII, bool UseCopyInstr) {
229
- for (MCRegUnit Unit : TRI.regunits (Reg)) {
230
- clobberRegUnit (Unit, TRI, TII, UseCopyInstr);
231
- }
232
- }
233
-
234
- // / Clobber all registers which are not preserved by RegMask, removing them
235
- // / from the tracker's copy maps.
236
- void clobberRegistersExceptMask (const MachineOperand *RegMask,
237
- const TargetRegisterInfo &TRI,
238
- const TargetInstrInfo &TII,
239
- bool UseCopyInstr) {
240
- BitVector SafeRegUnits (TRI.getNumRegUnits ());
241
-
242
- for (unsigned SafeReg = 0 , E = TRI.getNumRegs (); SafeReg < E; ++SafeReg)
243
- if (!RegMask->clobbersPhysReg (SafeReg))
244
- for (auto SafeUnit : TRI.regunits (SafeReg))
245
- SafeRegUnits.set (SafeUnit);
246
-
247
- for (unsigned Unit = 0 , E = TRI.getNumRegUnits (); Unit < E; ++Unit)
248
- if (!SafeRegUnits.test (Unit))
249
- clobberRegUnit (Unit, TRI, TII, UseCopyInstr);
250
- }
251
-
252
228
// / Track copy's src users, and return false if that can't be done.
253
229
// / We can only track if we have a COPY instruction which source is
254
230
// / the same as the Reg.
@@ -984,10 +960,6 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
984
960
// a large set of registers. Treat clobbered registers the same way as
985
961
// defined registers.
986
962
if (RegMask) {
987
- // Invalidate all entries in the copy map which are not preserved by this
988
- // register mask.
989
- Tracker.clobberRegistersExceptMask (RegMask, *TRI, *TII, UseCopyInstr);
990
-
991
963
// Erase any MaybeDeadCopies whose destination register is clobbered.
992
964
for (SmallSetVector<MachineInstr *, 8 >::iterator DI =
993
965
MaybeDeadCopies.begin ();
@@ -1006,6 +978,10 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
1006
978
LLVM_DEBUG (dbgs () << " MCP: Removing copy due to regmask clobbering: " ;
1007
979
MaybeDead->dump ());
1008
980
981
+ // Make sure we invalidate any entries in the copy maps before erasing
982
+ // the instruction.
983
+ Tracker.clobberRegister (Reg, *TRI, *TII, UseCopyInstr);
984
+
1009
985
// erase() will return the next valid iterator pointing to the next
1010
986
// element after the erased one.
1011
987
DI = MaybeDeadCopies.erase (DI);
0 commit comments