Skip to content

Commit 665457d

Browse files
vladimirradosavljevicakiramenai
authored andcommitted
[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 8f6c0cf commit 665457d

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
@@ -110,6 +110,9 @@ class CopyTracker {
110110
struct CopyInfo {
111111
MachineInstr *MI = nullptr;
112112
MachineInstr *LastSeenUseInCopy = nullptr;
113+
// EraVM local begin
114+
SmallPtrSet<MachineInstr *, 4> SrcUsers;
115+
// EraVM local end
113116
SmallVector<MCRegister, 4> DefRegs;
114117
bool Avail = false;
115118
};
@@ -224,6 +227,45 @@ class CopyTracker {
224227
}
225228
}
226229

230+
// EraVM local begin
231+
/// Track copy's src users, and return false if that can't be done.
232+
/// We can only track if we have a COPY instruction which source is
233+
/// the same as the Reg.
234+
bool trackSrcUsers(MCRegister Reg, MachineInstr &MI,
235+
const TargetRegisterInfo &TRI, const TargetInstrInfo &TII,
236+
bool UseCopyInstr) {
237+
MCRegUnit RU = *TRI.regunits(Reg).begin();
238+
MachineInstr *AvailCopy = findCopyDefViaUnit(RU, TRI);
239+
if (!AvailCopy)
240+
return false;
241+
242+
std::optional<DestSourcePair> CopyOperands =
243+
isCopyInstr(*AvailCopy, TII, UseCopyInstr);
244+
Register Src = CopyOperands->Source->getReg();
245+
246+
// Bail out, if the source of the copy is not the same as the Reg.
247+
if (Src != Reg)
248+
return false;
249+
250+
auto I = Copies.find(RU);
251+
if (I == Copies.end())
252+
return false;
253+
254+
I->second.SrcUsers.insert(&MI);
255+
return true;
256+
}
257+
258+
/// Return the users for a given register.
259+
SmallPtrSet<MachineInstr *, 4> getSrcUsers(MCRegister Reg,
260+
const TargetRegisterInfo &TRI) {
261+
MCRegUnit RU = *TRI.regunits(Reg).begin();
262+
auto I = Copies.find(RU);
263+
if (I == Copies.end())
264+
return {};
265+
return I->second.SrcUsers;
266+
}
267+
// EraVM local end
268+
227269
/// Add this copy's registers into the tracker's copy maps.
228270
void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI,
229271
const TargetInstrInfo &TII, bool UseCopyInstr) {
@@ -236,7 +278,9 @@ class CopyTracker {
236278

237279
// Remember Def is defined by the copy.
238280
for (MCRegUnit Unit : TRI.regunits(Def))
239-
Copies[Unit] = {MI, nullptr, {}, true};
281+
// EraVM local begin
282+
Copies[Unit] = {MI, nullptr, {}, {}, true};
283+
// EraVM local end
240284

241285
// Remember source that's copied to Def. Once it's clobbered, then
242286
// it's no longer available for copy propagation.
@@ -427,6 +471,10 @@ class MachineCopyPropagation : public MachineFunctionPass {
427471
bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
428472
bool hasOverlappingMultipleDef(const MachineInstr &MI,
429473
const MachineOperand &MODef, Register Def);
474+
// EraVM local begin
475+
bool canUpdateSrcUsers(const MachineInstr &Copy,
476+
const MachineOperand &CopySrc);
477+
// EraVM local end
430478

431479
/// Candidates for deletion.
432480
SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
@@ -667,6 +715,28 @@ bool MachineCopyPropagation::hasOverlappingMultipleDef(
667715
return false;
668716
}
669717

718+
// EraVM local begin
719+
/// Return true if it is safe to update the users of the source register of the
720+
/// copy.
721+
bool MachineCopyPropagation::canUpdateSrcUsers(const MachineInstr &Copy,
722+
const MachineOperand &CopySrc) {
723+
for (auto *SrcUser : Tracker.getSrcUsers(CopySrc.getReg(), *TRI)) {
724+
if (hasImplicitOverlap(*SrcUser, CopySrc))
725+
return false;
726+
727+
for (MachineOperand &MO : SrcUser->uses()) {
728+
if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.getReg())
729+
continue;
730+
if (MO.isTied() || !MO.isRenamable() ||
731+
!isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
732+
MO.getOperandNo()))
733+
return false;
734+
}
735+
}
736+
return true;
737+
}
738+
// EraVM local end
739+
670740
/// Look for available copies whose destination register is used by \p MI and
671741
/// replace the use in \p MI with the copy's source register.
672742
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
@@ -1036,13 +1106,29 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
10361106
if (hasOverlappingMultipleDef(MI, MODef, Def))
10371107
continue;
10381108

1109+
// EraVM local begin
1110+
if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1111+
continue;
1112+
// EraVM local end
1113+
10391114
LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
10401115
<< "\n with " << printReg(Def, TRI) << "\n in "
10411116
<< MI << " from " << *Copy);
10421117

10431118
MODef.setReg(Def);
10441119
MODef.setIsRenamable(CopyOperands->Destination->isRenamable());
10451120

1121+
// EraVM local begin
1122+
for (auto *SrcUser : Tracker.getSrcUsers(Src, *TRI)) {
1123+
for (MachineOperand &MO : SrcUser->uses()) {
1124+
if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
1125+
continue;
1126+
MO.setReg(Def);
1127+
MO.setIsRenamable(CopyOperands->Destination->isRenamable());
1128+
}
1129+
}
1130+
// EraVM local end
1131+
10461132
LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
10471133
MaybeDeadCopies.insert(Copy);
10481134
Changed = true;
@@ -1108,7 +1194,11 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock(
11081194
CopyDbgUsers[Copy].insert(&MI);
11091195
}
11101196
}
1111-
} else {
1197+
// EraVM local begin
1198+
} else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(), MI, *TRI, *TII,
1199+
UseCopyInstr)) {
1200+
// If we can't track the source users, invalidate the register.
1201+
// EraVM local end
11121202
Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
11131203
UseCopyInstr);
11141204
}

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)