@@ -164,91 +164,67 @@ class CopyTracker {
164164 Copies.erase (Unit);
165165 }
166166
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 ;
214217 }
215- break ;
216218 }
217219 }
218220 }
219221 }
222+ // Now we can erase the copy.
223+ Copies.erase (I);
220224 }
221- // Now we can erase the copy.
222- Copies.erase (I);
223225 }
224226 }
225227
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-
252228 // / Track copy's src users, and return false if that can't be done.
253229 // / We can only track if we have a COPY instruction which source is
254230 // / the same as the Reg.
@@ -984,10 +960,6 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
984960 // a large set of registers. Treat clobbered registers the same way as
985961 // defined registers.
986962 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-
991963 // Erase any MaybeDeadCopies whose destination register is clobbered.
992964 for (SmallSetVector<MachineInstr *, 8 >::iterator DI =
993965 MaybeDeadCopies.begin ();
@@ -1006,6 +978,10 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
1006978 LLVM_DEBUG (dbgs () << " MCP: Removing copy due to regmask clobbering: " ;
1007979 MaybeDead->dump ());
1008980
981+ // Make sure we invalidate any entries in the copy maps before erasing
982+ // the instruction.
983+ Tracker.clobberRegister (Reg, *TRI, *TII, UseCopyInstr);
984+
1009985 // erase() will return the next valid iterator pointing to the next
1010986 // element after the erased one.
1011987 DI = MaybeDeadCopies.erase (DI);
0 commit comments