Skip to content

Commit 9ffa46a

Browse files
committed
[MachineSink][Experiment] Rematerialize instructions that may be hoisted in LICM
1 parent 8cb8bb0 commit 9ffa46a

File tree

2 files changed

+118
-18
lines changed

2 files changed

+118
-18
lines changed

llvm/lib/CodeGen/MachineLICM.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static cl::opt<bool> SinkInstsIntoCycleBeforeLICM(
102102
"sink-insts-before-licm",
103103
cl::desc("Sink instructions into cycles to avoid "
104104
"register spills"),
105-
cl::init(true), cl::Hidden);
105+
cl::init(false), cl::Hidden);
106106

107107
STATISTIC(NumHoisted,
108108
"Number of machine instructions hoisted out of loops");

llvm/lib/CodeGen/MachineSink.cpp

Lines changed: 117 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,13 @@ static cl::opt<bool>
106106
SinkInstsIntoCycle("sink-insts-to-avoid-spills",
107107
cl::desc("Sink instructions into cycles to avoid "
108108
"register spills"),
109-
cl::init(false), cl::Hidden);
109+
cl::init(true), cl::Hidden);
110+
111+
static cl::opt<bool> AggressivelySinkInstsIntoCycle(
112+
"aggressively-sink-insts-to-avoid-spills",
113+
cl::desc("Aggressively sink instructions into cycles to avoid "
114+
"register spills"),
115+
cl::init(false), cl::Hidden);
110116

111117
static cl::opt<unsigned> SinkIntoCycleLimit(
112118
"machine-sink-cycle-limit",
@@ -263,6 +269,8 @@ class MachineSinking {
263269
aggressivelySinkIntoCycle(MachineCycle *Cycle, MachineInstr &I,
264270
DenseMap<SinkItem, MachineInstr *> &SunkInstrs);
265271

272+
bool rematerializeIntoCycle(MachineCycle *Cycle, MachineInstr &I);
273+
266274
bool isProfitableToSinkTo(Register Reg, MachineInstr &MI,
267275
MachineBasicBlock *MBB,
268276
MachineBasicBlock *SuccToSinkTo,
@@ -815,21 +823,28 @@ bool MachineSinking::run(MachineFunction &MF) {
815823
if (SinkInstsIntoCycle) {
816824
SmallVector<MachineCycle *, 8> Cycles(CI->toplevel_cycles());
817825
SchedModel.init(STI);
818-
bool HasHighPressure;
819826

820827
DenseMap<SinkItem, MachineInstr *> SunkInstrs;
821828

822-
enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };
823-
for (unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;
824-
++Stage, SunkInstrs.clear()) {
825-
HasHighPressure = false;
829+
enum CycleSinkStage {
830+
COPY,
831+
LOW_LATENCY,
832+
REMATERIALIZATION,
833+
AGGRESSIVE,
834+
END
835+
};
836+
for (auto *Cycle : Cycles) {
837+
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
838+
if (!Preheader) {
839+
LLVM_DEBUG(dbgs() << "CycleSink: Can't find preheader\n");
840+
continue;
841+
}
842+
bool HasHighPressure = registerPressureExceedsLimit(*Preheader);
843+
if (!HasHighPressure)
844+
continue;
845+
for (unsigned Stage = CycleSinkStage::COPY; Stage != CycleSinkStage::END;
846+
++Stage, SunkInstrs.clear()) {
826847

827-
for (auto *Cycle : Cycles) {
828-
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
829-
if (!Preheader) {
830-
LLVM_DEBUG(dbgs() << "CycleSink: Can't find preheader\n");
831-
continue;
832-
}
833848
SmallVector<MachineInstr *, 8> Candidates;
834849
for (auto &MI : *Preheader)
835850
if (isSinkIntoCycleCandidate(MI, Cycle, MRI, TII))
@@ -860,18 +875,23 @@ bool MachineSinking::run(MachineFunction &MF) {
860875
!TII->hasLowDefLatency(SchedModel, *I, 0))
861876
continue;
862877

863-
if (!aggressivelySinkIntoCycle(Cycle, *I, SunkInstrs))
864-
continue;
878+
if (Stage == CycleSinkStage::AGGRESSIVE &&
879+
AggressivelySinkInstsIntoCycle) {
880+
if (!aggressivelySinkIntoCycle(Cycle, *I, SunkInstrs))
881+
continue;
882+
} else {
883+
if (!rematerializeIntoCycle(Cycle, *I))
884+
continue;
885+
}
865886
EverMadeChange = true;
866887
++NumCycleSunk;
867888
}
868889

869890
// Recalculate the pressure after sinking
891+
HasHighPressure = registerPressureExceedsLimit(*Preheader);
870892
if (!HasHighPressure)
871-
HasHighPressure = registerPressureExceedsLimit(*Preheader);
893+
break;
872894
}
873-
if (!HasHighPressure)
874-
break;
875895
}
876896
}
877897

@@ -1771,6 +1791,86 @@ bool MachineSinking::aggressivelySinkIntoCycle(
17711791
return true;
17721792
}
17731793

1794+
/// Rematerialize instructions into cycles,
1795+
/// since LICM in the middle-end hoisted every instructions without considering
1796+
/// register pressure.
1797+
bool MachineSinking::rematerializeIntoCycle(MachineCycle *Cycle,
1798+
MachineInstr &I) {
1799+
LLVM_DEBUG(dbgs() << "Rematerialization: Finding sink block for: " << I);
1800+
MachineBasicBlock *Preheader = Cycle->getCyclePreheader();
1801+
assert(Preheader && "Cycle sink needs a preheader block");
1802+
MachineBasicBlock *SinkBlock = nullptr;
1803+
const MachineOperand &MO = I.getOperand(0);
1804+
for (MachineInstr &MI : MRI->use_instructions(MO.getReg())) {
1805+
LLVM_DEBUG(dbgs() << "Rematerialization: Analysing use: " << MI);
1806+
if (!Cycle->contains(MI.getParent())) {
1807+
LLVM_DEBUG(
1808+
dbgs() << "Rematerialization: Use not in cycle, can't sink.\n");
1809+
return false;
1810+
}
1811+
if (!SinkBlock) {
1812+
SinkBlock = MI.getParent();
1813+
LLVM_DEBUG(dbgs() << "Rematerialization: Setting sink block to: "
1814+
<< printMBBReference(*SinkBlock) << "\n");
1815+
continue;
1816+
}
1817+
if (MI.isPHI()) {
1818+
for (unsigned I = 1; I != MI.getNumOperands(); I += 2) {
1819+
Register SrcReg = MI.getOperand(I).getReg();
1820+
if (TRI->regsOverlap(SrcReg, MO.getReg())) {
1821+
MachineBasicBlock *SrcBB = MI.getOperand(I + 1).getMBB();
1822+
if (SrcBB != SinkBlock) {
1823+
SinkBlock = DT->findNearestCommonDominator(SinkBlock, SrcBB);
1824+
if (!SinkBlock)
1825+
break;
1826+
}
1827+
}
1828+
}
1829+
} else {
1830+
SinkBlock = DT->findNearestCommonDominator(SinkBlock, MI.getParent());
1831+
}
1832+
if (!SinkBlock) {
1833+
LLVM_DEBUG(
1834+
dbgs() << "Rematerialization: Can't find nearest dominator\n");
1835+
return false;
1836+
}
1837+
LLVM_DEBUG(
1838+
dbgs() << "Rematerialization: Setting nearest common dom block: "
1839+
<< printMBBReference(*SinkBlock) << "\n");
1840+
}
1841+
if (!SinkBlock) {
1842+
LLVM_DEBUG(
1843+
dbgs() << "Rematerialization: Not sinking, can't find sink block.\n");
1844+
return false;
1845+
}
1846+
if (SinkBlock == Preheader) {
1847+
LLVM_DEBUG(
1848+
dbgs()
1849+
<< "Rematerialization: Not sinking, sink block is the preheader\n");
1850+
return false;
1851+
}
1852+
for (MachineInstr &MI : MRI->use_instructions(MO.getReg())) {
1853+
if (MI.isPHI() && MI.getParent() == SinkBlock) {
1854+
LLVM_DEBUG(dbgs() << "Rematerialization: Not sinking, sink block is "
1855+
"using it on PHI.\n");
1856+
return false;
1857+
}
1858+
}
1859+
LLVM_DEBUG(dbgs() << "Rematerialization: Sinking instruction!\n");
1860+
SinkBlock->splice(SinkBlock->SkipPHIsAndLabels(SinkBlock->begin()), Preheader,
1861+
I);
1862+
// Conservatively clear any kill flags on uses of sunk instruction
1863+
for (MachineOperand &MO : I.operands()) {
1864+
if (MO.isReg() && MO.readsReg())
1865+
MRI->clearKillFlags(MO.getReg());
1866+
}
1867+
// The instruction is moved from its basic block, so do not retain the
1868+
// debug information.
1869+
assert(!I.isDebugInstr() && "Should not sink debug inst");
1870+
I.setDebugLoc(DebugLoc());
1871+
return true;
1872+
}
1873+
17741874
/// SinkInstruction - Determine whether it is safe to sink the specified machine
17751875
/// instruction out of its current block into a successor.
17761876
bool MachineSinking::SinkInstruction(MachineInstr &MI, bool &SawStore,

0 commit comments

Comments
 (0)