Skip to content

Commit b2cbc3c

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 08f682e commit b2cbc3c

File tree

1 file changed

+92
-2
lines changed

1 file changed

+92
-2
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+
// EVM local begin
114+
SmallPtrSet<MachineInstr *, 4> SrcUsers;
115+
// EVM local end
113116
SmallVector<MCRegister, 4> DefRegs;
114117
bool Avail = false;
115118
};
@@ -224,6 +227,45 @@ class CopyTracker {
224227
}
225228
}
226229

230+
// EVM 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+
// EVM 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+
// EVM local begin
282+
Copies[Unit] = {MI, nullptr, {}, {}, true};
283+
// EVM 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+
// EVM local begin
475+
bool canUpdateSrcUsers(const MachineInstr &Copy,
476+
const MachineOperand &CopySrc);
477+
// EVM 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+
// EVM 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+
// EVM 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+
// EVM local begin
1110+
if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1111+
continue;
1112+
// EVM 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+
// EVM 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+
// EVM 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+
// EVM 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+
// EVM local end
11121202
Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
11131203
UseCopyInstr);
11141204
}

0 commit comments

Comments
 (0)