summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MachineCopyPropagation.cpp
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2018-10-22 19:51:31 +0000
committerJustin Bogner <mail@justinbogner.com>2018-10-22 19:51:31 +0000
commit912adfba7ed39fbf1fe2342cb8938f817e9b0915 (patch)
tree2464e4780435c41a97d70a98be140c4baca727a8 /llvm/lib/CodeGen/MachineCopyPropagation.cpp
parent11dadac247e677de124328077d080fe086f14d47 (diff)
downloadbcm5719-llvm-912adfba7ed39fbf1fe2342cb8938f817e9b0915.tar.gz
bcm5719-llvm-912adfba7ed39fbf1fe2342cb8938f817e9b0915.zip
Reapply "[MachineCopyPropagation] Reimplement CopyTracker in terms of register units"
Recommits r342942, which was reverted in r343189, with a fix for an issue where we would propagate unsafely if we defined only the upper part of a register. Original message: Change the copy tracker to keep a single map of register units instead of 3 maps of registers. This gives a very significant compile time performance improvement to the pass. I measured a 30-40% decrease in time spent in MCP on x86 and AArch64 and much more significant improvements on out of tree targets with more registers. llvm-svn: 344942
Diffstat (limited to 'llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r--llvm/lib/CodeGen/MachineCopyPropagation.cpp127
1 files changed, 69 insertions, 58 deletions
diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
index dfaa946c913..19879fe8900 100644
--- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp
+++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp
@@ -75,98 +75,109 @@ DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
namespace {
class CopyTracker {
- using RegList = SmallVector<unsigned, 4>;
- using SourceMap = DenseMap<unsigned, RegList>;
- using Reg2MIMap = DenseMap<unsigned, MachineInstr *>;
+ struct CopyInfo {
+ MachineInstr *MI;
+ SmallVector<unsigned, 4> DefRegs;
+ bool Avail;
+ };
- /// Def -> available copies map.
- Reg2MIMap AvailCopyMap;
-
- /// Def -> copies map.
- Reg2MIMap CopyMap;
-
- /// Src -> Def map
- SourceMap SrcMap;
+ DenseMap<unsigned, CopyInfo> Copies;
public:
/// Mark all of the given registers and their subregisters as unavailable for
/// copying.
- void markRegsUnavailable(const RegList &Regs, const TargetRegisterInfo &TRI) {
+ void markRegsUnavailable(ArrayRef<unsigned> Regs,
+ const TargetRegisterInfo &TRI) {
for (unsigned Reg : Regs) {
// Source of copy is no longer available for propagation.
- for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR)
- AvailCopyMap.erase(*SR);
+ for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
+ auto CI = Copies.find(*RUI);
+ if (CI != Copies.end())
+ CI->second.Avail = false;
+ }
}
}
/// Clobber a single register, removing it from the tracker's copy maps.
void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) {
- for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) {
- CopyMap.erase(*AI);
- AvailCopyMap.erase(*AI);
-
- SourceMap::iterator SI = SrcMap.find(*AI);
- if (SI != SrcMap.end()) {
- markRegsUnavailable(SI->second, TRI);
- SrcMap.erase(SI);
+ for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
+ auto I = Copies.find(*RUI);
+ if (I != Copies.end()) {
+ // When we clobber the source of a copy, we need to clobber everything
+ // it defined.
+ markRegsUnavailable(I->second.DefRegs, TRI);
+ // When we clobber the destination of a copy, we need to clobber the
+ // whole register it defined.
+ if (MachineInstr *MI = I->second.MI)
+ markRegsUnavailable({MI->getOperand(0).getReg()}, TRI);
+ // Now we can erase the copy.
+ Copies.erase(I);
}
}
}
/// Add this copy's registers into the tracker's copy maps.
- void trackCopy(MachineInstr *Copy, const TargetRegisterInfo &TRI) {
- assert(Copy->isCopy() && "Tracking non-copy?");
+ void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) {
+ assert(MI->isCopy() && "Tracking non-copy?");
- unsigned Def = Copy->getOperand(0).getReg();
- unsigned Src = Copy->getOperand(1).getReg();
+ unsigned Def = MI->getOperand(0).getReg();
+ unsigned Src = MI->getOperand(1).getReg();
// Remember Def is defined by the copy.
- for (MCSubRegIterator SR(Def, &TRI, /*IncludeSelf=*/true); SR.isValid();
- ++SR) {
- CopyMap[*SR] = Copy;
- AvailCopyMap[*SR] = Copy;
- }
+ for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI)
+ Copies[*RUI] = {MI, {}, true};
// Remember source that's copied to Def. Once it's clobbered, then
// it's no longer available for copy propagation.
- RegList &DestList = SrcMap[Src];
- if (!is_contained(DestList, Def))
- DestList.push_back(Def);
+ for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) {
+ auto I = Copies.insert({*RUI, {nullptr, {}, false}});
+ auto &Copy = I.first->second;
+ if (!is_contained(Copy.DefRegs, Def))
+ Copy.DefRegs.push_back(Def);
+ }
+ }
+
+ bool hasAnyCopies() {
+ return !Copies.empty();
}
- bool hasAvailableCopies() { return !AvailCopyMap.empty(); }
+ MachineInstr *findCopyForUnit(unsigned RegUnit, const TargetRegisterInfo &TRI,
+ bool MustBeAvailable = false) {
+ auto CI = Copies.find(RegUnit);
+ if (CI == Copies.end())
+ return nullptr;
+ if (MustBeAvailable && !CI->second.Avail)
+ return nullptr;
+ return CI->second.MI;
+ }
- MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg) {
- auto CI = AvailCopyMap.find(Reg);
- if (CI == AvailCopyMap.end())
+ MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg,
+ const TargetRegisterInfo &TRI) {
+ // We check the first RegUnit here, since we'll only be interested in the
+ // copy if it copies the entire register anyway.
+ MCRegUnitIterator RUI(Reg, &TRI);
+ MachineInstr *AvailCopy =
+ findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true);
+ if (!AvailCopy ||
+ !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg))
return nullptr;
- MachineInstr &AvailCopy = *CI->second;
// Check that the available copy isn't clobbered by any regmasks between
// itself and the destination.
- unsigned AvailSrc = AvailCopy.getOperand(1).getReg();
- unsigned AvailDef = AvailCopy.getOperand(0).getReg();
+ unsigned AvailSrc = AvailCopy->getOperand(1).getReg();
+ unsigned AvailDef = AvailCopy->getOperand(0).getReg();
for (const MachineInstr &MI :
- make_range(AvailCopy.getIterator(), DestCopy.getIterator()))
+ make_range(AvailCopy->getIterator(), DestCopy.getIterator()))
for (const MachineOperand &MO : MI.operands())
if (MO.isRegMask())
if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
return nullptr;
- return &AvailCopy;
- }
-
- MachineInstr *findCopy(unsigned Reg) {
- auto CI = CopyMap.find(Reg);
- if (CI != CopyMap.end())
- return CI->second;
- return nullptr;
+ return AvailCopy;
}
void clear() {
- AvailCopyMap.clear();
- CopyMap.clear();
- SrcMap.clear();
+ Copies.clear();
}
};
@@ -224,8 +235,8 @@ INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
void MachineCopyPropagation::ReadRegister(unsigned Reg) {
// If 'Reg' is defined by a copy, the copy is no longer a candidate
// for elimination.
- for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
- if (MachineInstr *Copy = Tracker.findCopy(*AI)) {
+ for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
+ if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) {
LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
MaybeDeadCopies.remove(Copy);
}
@@ -263,7 +274,7 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
return false;
// Search for an existing copy.
- MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def);
+ MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI);
if (!PrevCopy)
return false;
@@ -357,7 +368,7 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
/// Look for available copies whose destination register is used by \p MI and
/// replace the use in \p MI with the copy's source register.
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
- if (!Tracker.hasAvailableCopies())
+ if (!Tracker.hasAnyCopies())
return;
// Look for non-tied explicit vreg uses that have an active COPY
@@ -384,7 +395,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
if (!MOUse.isRenamable())
continue;
- MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg());
+ MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg(), *TRI);
if (!Copy)
continue;
OpenPOWER on IntegriCloud