Skip to content

Commit c9ab6d4

Browse files
[MCP] Optimize copies when src is used during backward propagation
Before this patch, redundant COPY couldn't be removed for the following case: $R0 = OP ... ... // Read of %R0 $R1 = COPY killed $R0 This patch adds support for tracking the users of the source register during backward propagation, so that we can remove the redundant COPY in the above case and optimize it to: $R1 = OP ... ... // Replace all uses of %R0 with $R1 Upstream PR: llvm/llvm-project#111130 Signed-off-by: Vladimir Radosavljevic <[email protected]>
1 parent 6da66c0 commit c9ab6d4

File tree

2 files changed

+94
-5
lines changed

2 files changed

+94
-5
lines changed

llvm/lib/CodeGen/MachineCopyPropagation.cpp

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ class CopyTracker {
109109
struct CopyInfo {
110110
MachineInstr *MI = nullptr;
111111
MachineInstr *LastSeenUseInCopy = nullptr;
112+
// EraVM local begin
113+
SmallPtrSet<MachineInstr *, 4> SrcUsers;
114+
// EraVM local end
112115
SmallVector<MCRegister, 4> DefRegs;
113116
bool Avail = false;
114117
};
@@ -182,6 +185,45 @@ class CopyTracker {
182185
}
183186
}
184187

188+
// EraVM local begin
189+
/// Track copy's src users, and return false if that can't be done.
190+
/// We can only track if we have a COPY instruction which source is
191+
/// the same as the Reg.
192+
bool trackSrcUsers(MCRegister Reg, MachineInstr &MI,
193+
const TargetRegisterInfo &TRI, const TargetInstrInfo &TII,
194+
bool UseCopyInstr) {
195+
MCRegUnit RU = *TRI.regunits(Reg).begin();
196+
MachineInstr *AvailCopy = findCopyDefViaUnit(RU, TRI);
197+
if (!AvailCopy)
198+
return false;
199+
200+
std::optional<DestSourcePair> CopyOperands =
201+
isCopyInstr(*AvailCopy, TII, UseCopyInstr);
202+
Register Src = CopyOperands->Source->getReg();
203+
204+
// Bail out, if the source of the copy is not the same as the Reg.
205+
if (Src != Reg)
206+
return false;
207+
208+
auto I = Copies.find(RU);
209+
if (I == Copies.end())
210+
return false;
211+
212+
I->second.SrcUsers.insert(&MI);
213+
return true;
214+
}
215+
216+
/// Return the users for a given register.
217+
SmallPtrSet<MachineInstr *, 4> getSrcUsers(MCRegister Reg,
218+
const TargetRegisterInfo &TRI) {
219+
MCRegUnit RU = *TRI.regunits(Reg).begin();
220+
auto I = Copies.find(RU);
221+
if (I == Copies.end())
222+
return {};
223+
return I->second.SrcUsers;
224+
}
225+
// EraVM local end
226+
185227
/// Add this copy's registers into the tracker's copy maps.
186228
void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI,
187229
const TargetInstrInfo &TII, bool UseCopyInstr) {
@@ -194,7 +236,9 @@ class CopyTracker {
194236

195237
// Remember Def is defined by the copy.
196238
for (MCRegUnit Unit : TRI.regunits(Def))
197-
Copies[Unit] = {MI, nullptr, {}, true};
239+
// EraVM local begin
240+
Copies[Unit] = {MI, nullptr, {}, {}, true};
241+
// EraVM local end
198242

199243
// Remember source that's copied to Def. Once it's clobbered, then
200244
// it's no longer available for copy propagation.
@@ -385,6 +429,10 @@ class MachineCopyPropagation : public MachineFunctionPass {
385429
bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
386430
bool hasOverlappingMultipleDef(const MachineInstr &MI,
387431
const MachineOperand &MODef, Register Def);
432+
// EraVM local begin
433+
bool canUpdateSrcUsers(const MachineInstr &Copy,
434+
const MachineOperand &CopySrc);
435+
// EraVM local end
388436

389437
/// Candidates for deletion.
390438
SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
@@ -625,6 +673,28 @@ bool MachineCopyPropagation::hasOverlappingMultipleDef(
625673
return false;
626674
}
627675

676+
// EraVM local begin
677+
/// Return true if it is safe to update the users of the source register of the
678+
/// copy.
679+
bool MachineCopyPropagation::canUpdateSrcUsers(const MachineInstr &Copy,
680+
const MachineOperand &CopySrc) {
681+
for (auto *SrcUser : Tracker.getSrcUsers(CopySrc.getReg(), *TRI)) {
682+
if (hasImplicitOverlap(*SrcUser, CopySrc))
683+
return false;
684+
685+
for (MachineOperand &MO : SrcUser->uses()) {
686+
if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.getReg())
687+
continue;
688+
if (MO.isTied() || !MO.isRenamable() ||
689+
!isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
690+
MO.getOperandNo()))
691+
return false;
692+
}
693+
}
694+
return true;
695+
}
696+
// EraVM local end
697+
628698
/// Look for available copies whose destination register is used by \p MI and
629699
/// replace the use in \p MI with the copy's source register.
630700
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
@@ -995,13 +1065,29 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
9951065
if (hasOverlappingMultipleDef(MI, MODef, Def))
9961066
continue;
9971067

1068+
// EraVM local begin
1069+
if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1070+
continue;
1071+
// EraVM local end
1072+
9981073
LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
9991074
<< "\n with " << printReg(Def, TRI) << "\n in "
10001075
<< MI << " from " << *Copy);
10011076

10021077
MODef.setReg(Def);
10031078
MODef.setIsRenamable(CopyOperands->Destination->isRenamable());
10041079

1080+
// EraVM local begin
1081+
for (auto *SrcUser : Tracker.getSrcUsers(Src, *TRI)) {
1082+
for (MachineOperand &MO : SrcUser->uses()) {
1083+
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
1084+
continue;
1085+
MO.setReg(Def);
1086+
MO.setIsRenamable(CopyOperands->Destination->isRenamable());
1087+
}
1088+
}
1089+
// EraVM local end
1090+
10051091
LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
10061092
MaybeDeadCopies.insert(Copy);
10071093
Changed = true;
@@ -1067,7 +1153,11 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
10671153
CopyDbgUsers[Copy].insert(&MI);
10681154
}
10691155
}
1070-
} else {
1156+
// EraVM local begin
1157+
} else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(), MI, *TRI, *TII,
1158+
UseCopyInstr)) {
1159+
// If we can't track the source users, invalidate the register.
1160+
// EraVM local end
10711161
Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
10721162
UseCopyInstr);
10731163
}

llvm/test/CodeGen/EraVM/machine-cp-backward-users.mir

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,8 @@ body: |
1818
; CHECK-LABEL: name: test
1919
; CHECK: liveins: $r1, $r2, $r4
2020
; CHECK-NEXT: {{ $}}
21-
; CHECK-NEXT: renamable $r3 = ADDirr_s i256 1, killed renamable $r1, i256 0
22-
; CHECK-NEXT: dead $r0 = SUBrrr_v renamable $r3, renamable $r2, i256 0, implicit-def $flags
23-
; CHECK-NEXT: renamable $r1 = COPY killed renamable $r3
21+
; CHECK-NEXT: renamable $r1 = ADDirr_s i256 1, killed renamable $r1, i256 0
22+
; CHECK-NEXT: dead $r0 = SUBrrr_v renamable $r1, renamable $r2, i256 0, implicit-def $flags
2423
; CHECK-NEXT: RET 0, implicit $r1
2524
renamable $r3 = ADDirr_s i256 1, killed renamable $r1, i256 0
2625
dead $r0 = SUBrrr_v renamable $r3, renamable $r2, i256 0, implicit-def $flags

0 commit comments

Comments
 (0)