@@ -106,7 +106,13 @@ static cl::opt<bool>
106
106
SinkInstsIntoCycle (" sink-insts-to-avoid-spills" ,
107
107
cl::desc (" Sink instructions into cycles to avoid "
108
108
" 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);
110
116
111
117
static cl::opt<unsigned > SinkIntoCycleLimit (
112
118
" machine-sink-cycle-limit" ,
@@ -263,6 +269,8 @@ class MachineSinking {
263
269
aggressivelySinkIntoCycle (MachineCycle *Cycle, MachineInstr &I,
264
270
DenseMap<SinkItem, MachineInstr *> &SunkInstrs);
265
271
272
+ bool rematerializeIntoCycle (MachineCycle *Cycle, MachineInstr &I);
273
+
266
274
bool isProfitableToSinkTo (Register Reg, MachineInstr &MI,
267
275
MachineBasicBlock *MBB,
268
276
MachineBasicBlock *SuccToSinkTo,
@@ -815,21 +823,28 @@ bool MachineSinking::run(MachineFunction &MF) {
815
823
if (SinkInstsIntoCycle) {
816
824
SmallVector<MachineCycle *, 8 > Cycles (CI->toplevel_cycles ());
817
825
SchedModel.init (STI);
818
- bool HasHighPressure;
819
826
820
827
DenseMap<SinkItem, MachineInstr *> SunkInstrs;
821
828
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 ()) {
826
847
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
- }
833
848
SmallVector<MachineInstr *, 8 > Candidates;
834
849
for (auto &MI : *Preheader)
835
850
if (isSinkIntoCycleCandidate (MI, Cycle, MRI, TII))
@@ -860,18 +875,23 @@ bool MachineSinking::run(MachineFunction &MF) {
860
875
!TII->hasLowDefLatency (SchedModel, *I, 0 ))
861
876
continue ;
862
877
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
+ }
865
886
EverMadeChange = true ;
866
887
++NumCycleSunk;
867
888
}
868
889
869
890
// Recalculate the pressure after sinking
891
+ HasHighPressure = registerPressureExceedsLimit (*Preheader);
870
892
if (!HasHighPressure)
871
- HasHighPressure = registerPressureExceedsLimit (*Preheader) ;
893
+ break ;
872
894
}
873
- if (!HasHighPressure)
874
- break ;
875
895
}
876
896
}
877
897
@@ -1771,6 +1791,86 @@ bool MachineSinking::aggressivelySinkIntoCycle(
1771
1791
return true ;
1772
1792
}
1773
1793
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
+
1774
1874
// / SinkInstruction - Determine whether it is safe to sink the specified machine
1775
1875
// / instruction out of its current block into a successor.
1776
1876
bool MachineSinking::SinkInstruction (MachineInstr &MI, bool &SawStore,
0 commit comments