@@ -98,6 +98,12 @@ DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks",
98
98
clEnumValN(UseBFI::All, " all" ,
99
99
" enable the feature with/wo profile data" )));
100
100
101
+ static cl::opt<bool > SinkInstsIntoCycleBeforeLICM (
102
+ " sink-insts-before-licm" ,
103
+ cl::desc (" Sink instructions into cycles to avoid "
104
+ " register spills" ),
105
+ cl::init(true ), cl::Hidden);
106
+
101
107
STATISTIC (NumHoisted,
102
108
" Number of machine instructions hoisted out of loops" );
103
109
STATISTIC (NumLowRP,
@@ -287,6 +293,8 @@ namespace {
287
293
bool isTgtHotterThanSrc (MachineBasicBlock *SrcBlock,
288
294
MachineBasicBlock *TgtBlock);
289
295
MachineBasicBlock *getOrCreatePreheader (MachineLoop *CurLoop);
296
+
297
+ bool rematerializeIntoCycle (MachineCycle *Cycle, MachineInstr &I);
290
298
};
291
299
292
300
class MachineLICMBase : public MachineFunctionPass {
@@ -304,7 +312,11 @@ namespace {
304
312
AU.addRequired <MachineBlockFrequencyInfoWrapperPass>();
305
313
AU.addRequired <MachineDominatorTreeWrapperPass>();
306
314
AU.addRequired <AAResultsWrapperPass>();
315
+ if (PreRegAlloc)
316
+ AU.addRequired <MachineCycleInfoWrapperPass>();
307
317
AU.addPreserved <MachineLoopInfoWrapperPass>();
318
+ if (PreRegAlloc)
319
+ AU.addPreserved <MachineCycleInfoWrapperPass>();
308
320
MachineFunctionPass::getAnalysisUsage (AU);
309
321
}
310
322
};
@@ -348,6 +360,7 @@ INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
348
360
INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
349
361
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
350
362
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
363
+ INITIALIZE_PASS_DEPENDENCY(MachineCycleInfoWrapperPass)
351
364
INITIALIZE_PASS_END(EarlyMachineLICM, " early-machinelicm" ,
352
365
" Early Machine Loop Invariant Code Motion" , false , false )
353
366
@@ -396,6 +409,26 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
396
409
LLVM_DEBUG (dbgs () << MF.getName () << " ********\n " );
397
410
398
411
if (PreRegAlloc) {
412
+ if (SinkInstsIntoCycleBeforeLICM) {
413
+ auto *CI = GET_RESULT (MachineCycle, getCycleInfo, Info);
414
+ SmallVector<MachineCycle *, 8 > Cycles (CI->toplevel_cycles ());
415
+ for (auto *Cycle : Cycles) {
416
+ MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
417
+ if (!Preheader) {
418
+ LLVM_DEBUG (dbgs () << " Rematerialization: Can't find preheader\n " );
419
+ continue ;
420
+ }
421
+ SmallVector<MachineInstr *, 8 > Candidates;
422
+ for (auto &MI : *Preheader)
423
+ if (isSinkIntoCycleCandidate (MI, Cycle, MRI, TII))
424
+ Candidates.push_back (&MI);
425
+ // Walk the candidates in reverse order so that we start with the use
426
+ // of a def-use chain, if there is any.
427
+ for (MachineInstr *I : llvm::reverse (Candidates))
428
+ if (rematerializeIntoCycle (Cycle, *I))
429
+ Changed = true ;
430
+ }
431
+ }
399
432
// Estimate register pressure during pre-regalloc pass.
400
433
unsigned NumRPS = TRI->getNumRegPressureSets ();
401
434
RegPressure.resize (NumRPS);
@@ -1005,24 +1038,6 @@ MachineLICMImpl::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
1005
1038
return Cost;
1006
1039
}
1007
1040
1008
- // / Return true if this machine instruction loads from global offset table or
1009
- // / constant pool.
1010
- static bool mayLoadFromGOTOrConstantPool (MachineInstr &MI) {
1011
- assert (MI.mayLoad () && " Expected MI that loads!" );
1012
-
1013
- // If we lost memory operands, conservatively assume that the instruction
1014
- // reads from everything..
1015
- if (MI.memoperands_empty ())
1016
- return true ;
1017
-
1018
- for (MachineMemOperand *MemOp : MI.memoperands ())
1019
- if (const PseudoSourceValue *PSV = MemOp->getPseudoValue ())
1020
- if (PSV->isGOT () || PSV->isConstantPool ())
1021
- return true ;
1022
-
1023
- return false ;
1024
- }
1025
-
1026
1041
// This function iterates through all the operands of the input store MI and
1027
1042
// checks that each register operand statisfies isCallerPreservedPhysReg.
1028
1043
// This means, the value being stored and the address where it is being stored
@@ -1744,13 +1759,97 @@ bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
1744
1759
return Ratio > BlockFrequencyRatioThreshold;
1745
1760
}
1746
1761
1762
+ // / Rematerialize instructions into cycles before Machine LICM,
1763
+ // / since LICM in the middle-end hoisted every instructions without considering
1764
+ // / register pressure.
1765
+ bool MachineLICMImpl::rematerializeIntoCycle (MachineCycle *Cycle,
1766
+ MachineInstr &I) {
1767
+ LLVM_DEBUG (dbgs () << " Rematerialization: Finding sink block for: " << I);
1768
+ MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
1769
+ assert (Preheader && " Cycle sink needs a preheader block" );
1770
+ MachineBasicBlock *SinkBlock = nullptr ;
1771
+ const MachineOperand &MO = I.getOperand (0 );
1772
+ for (MachineInstr &MI : MRI->use_instructions (MO.getReg ())) {
1773
+ LLVM_DEBUG (dbgs () << " Rematerialization: Analysing use: " << MI);
1774
+ if (!Cycle->contains (MI.getParent ())) {
1775
+ LLVM_DEBUG (
1776
+ dbgs () << " Rematerialization: Use not in cycle, can't sink.\n " );
1777
+ return false ;
1778
+ }
1779
+ if (!SinkBlock) {
1780
+ SinkBlock = MI.getParent ();
1781
+ LLVM_DEBUG (dbgs () << " Rematerialization: Setting sink block to: "
1782
+ << printMBBReference (*SinkBlock) << " \n " );
1783
+ continue ;
1784
+ }
1785
+ if (MI.isPHI ()) {
1786
+ for (unsigned I = 1 ; I != MI.getNumOperands (); I += 2 ) {
1787
+ Register SrcReg = MI.getOperand (I).getReg ();
1788
+ if (TRI->regsOverlap (SrcReg, MO.getReg ())) {
1789
+ MachineBasicBlock *SrcBB = MI.getOperand (I + 1 ).getMBB ();
1790
+ if (SrcBB != SinkBlock) {
1791
+ SinkBlock =
1792
+ MDTU->getDomTree ().findNearestCommonDominator (SinkBlock, SrcBB);
1793
+ if (!SinkBlock)
1794
+ break ;
1795
+ }
1796
+ }
1797
+ }
1798
+ } else {
1799
+ SinkBlock = MDTU->getDomTree ().findNearestCommonDominator (SinkBlock,
1800
+ MI.getParent ());
1801
+ }
1802
+ if (!SinkBlock) {
1803
+ LLVM_DEBUG (
1804
+ dbgs () << " Rematerialization: Can't find nearest dominator\n " );
1805
+ return false ;
1806
+ }
1807
+ LLVM_DEBUG (
1808
+ dbgs () << " Rematerialization: Setting nearest common dom block: "
1809
+ << printMBBReference (*SinkBlock) << " \n " );
1810
+ }
1811
+ if (!SinkBlock) {
1812
+ LLVM_DEBUG (
1813
+ dbgs () << " Rematerialization: Not sinking, can't find sink block.\n " );
1814
+ return false ;
1815
+ }
1816
+ if (SinkBlock == Preheader) {
1817
+ LLVM_DEBUG (
1818
+ dbgs ()
1819
+ << " Rematerialization: Not sinking, sink block is the preheader\n " );
1820
+ return false ;
1821
+ }
1822
+ for (MachineInstr &MI : MRI->use_instructions (MO.getReg ())) {
1823
+ if (MI.isPHI () && MI.getParent () == SinkBlock) {
1824
+ LLVM_DEBUG (dbgs () << " Rematerialization: Not sinking, sink block is "
1825
+ " using it on PHI.\n " );
1826
+ return false ;
1827
+ }
1828
+ }
1829
+ LLVM_DEBUG (dbgs () << " Rematerialization: Sinking instruction!\n " );
1830
+ SinkBlock->splice (SinkBlock->SkipPHIsAndLabels (SinkBlock->begin ()), Preheader,
1831
+ I);
1832
+ // Conservatively clear any kill flags on uses of sunk instruction
1833
+ for (MachineOperand &MO : I.operands ()) {
1834
+ if (MO.isReg () && MO.readsReg ())
1835
+ MRI->clearKillFlags (MO.getReg ());
1836
+ }
1837
+ // The instruction is moved from its basic block, so do not retain the
1838
+ // debug information.
1839
+ assert (!I.isDebugInstr () && " Should not sink debug inst" );
1840
+ I.setDebugLoc (DebugLoc ());
1841
+ return true ;
1842
+ }
1843
+
1747
1844
template <typename DerivedT, bool PreRegAlloc>
1748
1845
PreservedAnalyses MachineLICMBasePass<DerivedT, PreRegAlloc>::run(
1749
1846
MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) {
1750
1847
bool Changed = MachineLICMImpl (PreRegAlloc, nullptr , &MFAM).run (MF);
1751
1848
if (!Changed)
1752
1849
return PreservedAnalyses::all ();
1753
1850
auto PA = getMachineFunctionPassPreservedAnalyses ();
1851
+ if (PreRegAlloc)
1852
+ PA.preserve <MachineCycleAnalysis>();
1754
1853
PA.preserve <MachineLoopAnalysis>();
1755
1854
return PA;
1756
1855
}
0 commit comments