Skip to content

Commit 0813b87

Browse files
committed
Address review comments
Change-Id: I975fab6cf7dba21788fb5677a5484916ef29d959
1 parent b32aa25 commit 0813b87

File tree

4 files changed

+297
-76
lines changed

4 files changed

+297
-76
lines changed

llvm/lib/CodeGen/MachineSink.cpp

Lines changed: 50 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ static cl::opt<bool>
101101
cl::init(false), cl::Hidden);
102102

103103
static cl::opt<bool> AggressivelySinkInstsIntoCycle(
104-
"aggressively-sink-insts-to-avoid-spills",
104+
"aggressive-sink-insts-into-cycles",
105105
cl::desc("Aggressively sink instructions into cycles to avoid "
106106
"register spills"),
107107
cl::init(false), cl::Hidden);
@@ -118,6 +118,8 @@ STATISTIC(NumSplit, "Number of critical edges split");
118118
STATISTIC(NumCoalesces, "Number of copies coalesced");
119119
STATISTIC(NumPostRACopySink, "Number of copies sunk after RA");
120120

121+
using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
122+
121123
namespace {
122124

123125
class MachineSinking : public MachineFunctionPass {
@@ -263,11 +265,10 @@ class MachineSinking : public MachineFunctionPass {
263265
bool SinkIntoCycle(MachineCycle *Cycle, MachineInstr &I);
264266

265267
bool isDead(const MachineInstr *MI) const;
266-
bool AggressivelySinkIntoCycle(
268+
bool aggressivelySinkIntoCycle(
267269
MachineCycle *Cycle, MachineInstr &I,
268-
DenseMap<MachineInstr *,
269-
std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
270-
SunkInstrs);
270+
DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
271+
&SunkInstrs);
271272

272273
bool isProfitableToSinkTo(Register Reg, MachineInstr &MI,
273274
MachineBasicBlock *MBB,
@@ -692,8 +693,8 @@ void MachineSinking::FindCycleSinkCandidates(
692693
SmallVectorImpl<MachineInstr *> &Candidates) {
693694
for (auto &MI : *BB) {
694695
LLVM_DEBUG(dbgs() << "CycleSink: Analysing candidate: " << MI);
695-
if (MI.isDebugInstr()) {
696-
LLVM_DEBUG(dbgs() << "CycleSink: Dont sink debug instructions\n");
696+
if (MI.isMetaInstruction()) {
697+
LLVM_DEBUG(dbgs() << "CycleSink: Dont sink meta instructions\n");
697698
continue;
698699
}
699700
if (!TII->shouldSink(MI)) {
@@ -786,8 +787,11 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
786787
EverMadeChange = true;
787788
}
788789

789-
if (SinkInstsIntoCycle) {
790+
if (SinkInstsIntoCycle || AggressivelySinkInstsIntoCycle) {
790791
SmallVector<MachineCycle *, 8> Cycles(CI->toplevel_cycles());
792+
793+
DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
794+
SunkInstrs;
791795
for (auto *Cycle : Cycles) {
792796
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
793797
if (!Preheader) {
@@ -801,7 +805,18 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
801805
// of a def-use chain, if there is any.
802806
// TODO: Sort the candidates using a cost-model.
803807
unsigned i = 0;
808+
804809
for (MachineInstr *I : llvm::reverse(Candidates)) {
810+
// AggressivelySinkInstsIntoCycle sinks a superset of instructions
811+
// relative to regular cycle sinking. Thus, this option supercedes
812+
// captures all sinking opportunites done
813+
if (AggressivelySinkInstsIntoCycle) {
814+
aggressivelySinkIntoCycle(Cycle, *I, SunkInstrs);
815+
EverMadeChange = true;
816+
++NumCycleSunk;
817+
continue;
818+
}
819+
805820
if (i++ == SinkIntoCycleLimit) {
806821
LLVM_DEBUG(dbgs() << "CycleSink: Limit reached of instructions to "
807822
"be analysed.");
@@ -816,30 +831,6 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
816831
}
817832
}
818833

819-
if (AggressivelySinkInstsIntoCycle) {
820-
SmallVector<MachineCycle *, 8> Cycles(CI->toplevel_cycles());
821-
DenseMap<MachineInstr *,
822-
std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
823-
SunkInstrs;
824-
for (auto *Cycle : Cycles) {
825-
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
826-
if (!Preheader) {
827-
LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Can't find preheader\n");
828-
continue;
829-
}
830-
SmallVector<MachineInstr *, 8> Candidates;
831-
FindCycleSinkCandidates(Cycle, Preheader, Candidates);
832-
833-
// Walk the candidates in reverse order so that we start with the use
834-
// of a def-use chain, if there is any.
835-
for (MachineInstr *I : llvm::reverse(Candidates)) {
836-
AggressivelySinkIntoCycle(Cycle, *I, SunkInstrs);
837-
EverMadeChange = true;
838-
++NumCycleSunk;
839-
}
840-
}
841-
}
842-
843834
HasStoreCache.clear();
844835
StoreInstrCache.clear();
845836

@@ -1615,31 +1606,27 @@ bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
16151606
return HasAliasedStore;
16161607
}
16171608

1618-
/// Copy paste from DeadMachineInstructionElimImpl
1619-
16201609
bool MachineSinking::isDead(const MachineInstr *MI) const {
16211610
// Instructions without side-effects are dead iff they only define dead regs.
16221611
// This function is hot and this loop returns early in the common case,
16231612
// so only perform additional checks before this if absolutely necessary.
1613+
16241614
for (const MachineOperand &MO : MI->all_defs()) {
16251615
Register Reg = MO.getReg();
1626-
if (Reg.isPhysical()) {
1616+
if (Reg.isPhysical())
16271617
return false;
1628-
} else {
1629-
if (MO.isDead()) {
1618+
1619+
if (MO.isDead()) {
16301620
#ifndef NDEBUG
1631-
// Basic check on the register. All of them should be 'undef'.
1632-
for (auto &U : MRI->use_nodbg_operands(Reg))
1633-
assert(U.isUndef() && "'Undef' use on a 'dead' register is found!");
1621+
// Basic check on the register. All of them should be 'undef'.
1622+
for (auto &U : MRI->use_nodbg_operands(Reg))
1623+
assert(U.isUndef() && "'Undef' use on a 'dead' register is found!");
16341624
#endif
1635-
continue;
1636-
}
1637-
for (const MachineInstr &Use : MRI->use_nodbg_instructions(Reg)) {
1638-
if (&Use != MI)
1639-
// This def has a non-debug use. Don't delete the instruction!
1640-
return false;
1641-
}
1625+
continue;
16421626
}
1627+
1628+
if (!(MRI->hasAtMostUserInstrs(Reg, 0)))
1629+
return false;
16431630
}
16441631

16451632
// Technically speaking inline asm without side effects and no defs can still
@@ -1661,25 +1648,24 @@ bool MachineSinking::isDead(const MachineInstr *MI) const {
16611648
/// In particular, it will sink into multiple successor blocks without limits
16621649
/// based on the amount of sinking, or the type of ops being sunk (so long as
16631650
/// they are safe to sink).
1664-
bool MachineSinking::AggressivelySinkIntoCycle(
1651+
bool MachineSinking::aggressivelySinkIntoCycle(
16651652
MachineCycle *Cycle, MachineInstr &I,
1666-
DenseMap<MachineInstr *,
1667-
std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
1668-
SunkInstrs) {
1653+
DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
1654+
&SunkInstrs) {
16691655
LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Finding sink block for: " << I);
16701656
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
16711657
assert(Preheader && "Cycle sink needs a preheader block");
1672-
SmallVector<std::pair<MachineOperand, MachineInstr *>> Uses;
1658+
SmallVector<std::pair<RegSubRegPair, MachineInstr *>> Uses;
16731659
// TODO: support instructions with multiple defs
16741660
if (I.getNumDefs() > 1)
16751661
return false;
16761662

1677-
MachineOperand DefMO = I.getOperand(0);
1663+
MachineOperand &DefMO = I.getOperand(0);
16781664
for (MachineInstr &MI : MRI->use_instructions(DefMO.getReg())) {
1679-
Uses.push_back({DefMO, &MI});
1665+
Uses.push_back({{DefMO.getReg(), DefMO.getSubReg()}, &MI});
16801666
}
16811667

1682-
for (std::pair<MachineOperand, MachineInstr *> Entry : Uses) {
1668+
for (std::pair<RegSubRegPair, MachineInstr *> Entry : Uses) {
16831669
MachineInstr *MI = Entry.second;
16841670
LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Analysing use: " << MI);
16851671
if (MI->isPHI()) {
@@ -1701,22 +1687,14 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17011687

17021688
MachineBasicBlock *SinkBlock = MI->getParent();
17031689
MachineInstr *NewMI = nullptr;
1690+
std::pair<MachineInstr *, MachineBasicBlock *> MapEntry(&I, SinkBlock);
17041691

17051692
// Check for the case in which we have already sunk a copy of this
17061693
// instruction into the user block.
1707-
if (SunkInstrs.contains(&I)) {
1708-
auto SunkBlocks = SunkInstrs[&I];
1709-
auto Match = std::find_if(
1710-
SunkBlocks.begin(), SunkBlocks.end(),
1711-
[&SinkBlock](
1712-
std::pair<MachineBasicBlock *, MachineInstr *> SunkEntry) {
1713-
return SunkEntry.first == SinkBlock;
1714-
});
1715-
if (Match != SunkBlocks.end()) {
1716-
LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Already sunk to block: "
1717-
<< printMBBReference(*SinkBlock) << "\n");
1718-
NewMI = Match->second;
1719-
}
1694+
if (SunkInstrs.contains(MapEntry)) {
1695+
LLVM_DEBUG(dbgs() << "AggressiveCycleSink: Already sunk to block: "
1696+
<< printMBBReference(*SinkBlock) << "\n");
1697+
NewMI = SunkInstrs[MapEntry];
17201698
}
17211699

17221700
// Create a copy of the instruction in the use block.
@@ -1733,7 +1711,7 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17331711
}
17341712
SinkBlock->insert(SinkBlock->SkipPHIsAndLabels(SinkBlock->begin()),
17351713
NewMI);
1736-
SunkInstrs[&I].push_back({SinkBlock, NewMI});
1714+
SunkInstrs[MapEntry] = NewMI;
17371715
}
17381716

17391717
// Conservatively clear any kill flags on uses of sunk instruction
@@ -1748,9 +1726,9 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17481726
NewMI->setDebugLoc(DebugLoc());
17491727

17501728
// Replace the use with the newly created virtual register.
1751-
MachineOperand UseMO = Entry.first;
1752-
MI->substituteRegister(UseMO.getReg(), NewMI->getOperand(0).getReg(),
1753-
UseMO.getSubReg(), *TRI);
1729+
RegSubRegPair &UseReg = Entry.first;
1730+
MI->substituteRegister(UseReg.Reg, NewMI->getOperand(0).getReg(),
1731+
UseReg.SubReg, *TRI);
17541732
}
17551733
// If we have replaced all uses, then delete the dead instruction
17561734
if (isDead(&I))

0 commit comments

Comments
 (0)