@@ -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
111117static 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.
17761876bool MachineSinking::SinkInstruction (MachineInstr &MI, bool &SawStore,
0 commit comments