@@ -98,6 +98,12 @@ DisableHoistingToHotterBlocks("disable-hoisting-to-hotter-blocks",
9898 clEnumValN(UseBFI::All, " all" ,
9999 " enable the feature with/wo profile data" )));
100100
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+
101107STATISTIC (NumHoisted,
102108 " Number of machine instructions hoisted out of loops" );
103109STATISTIC (NumLowRP,
@@ -287,6 +293,8 @@ namespace {
287293 bool isTgtHotterThanSrc (MachineBasicBlock *SrcBlock,
288294 MachineBasicBlock *TgtBlock);
289295 MachineBasicBlock *getOrCreatePreheader (MachineLoop *CurLoop);
296+
297+ bool rematerializeIntoCycle (MachineCycle *Cycle, MachineInstr &I);
290298 };
291299
292300 class MachineLICMBase : public MachineFunctionPass {
@@ -304,7 +312,11 @@ namespace {
304312 AU.addRequired <MachineBlockFrequencyInfoWrapperPass>();
305313 AU.addRequired <MachineDominatorTreeWrapperPass>();
306314 AU.addRequired <AAResultsWrapperPass>();
315+ if (PreRegAlloc)
316+ AU.addRequired <MachineCycleInfoWrapperPass>();
307317 AU.addPreserved <MachineLoopInfoWrapperPass>();
318+ if (PreRegAlloc)
319+ AU.addPreserved <MachineCycleInfoWrapperPass>();
308320 MachineFunctionPass::getAnalysisUsage (AU);
309321 }
310322 };
@@ -348,6 +360,7 @@ INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass)
348360INITIALIZE_PASS_DEPENDENCY(MachineBlockFrequencyInfoWrapperPass)
349361INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
350362INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
363+ INITIALIZE_PASS_DEPENDENCY(MachineCycleInfoWrapperPass)
351364INITIALIZE_PASS_END(EarlyMachineLICM, " early-machinelicm" ,
352365 " Early Machine Loop Invariant Code Motion" , false , false )
353366
@@ -396,6 +409,26 @@ bool MachineLICMImpl::run(MachineFunction &MF) {
396409 LLVM_DEBUG (dbgs () << MF.getName () << " ********\n " );
397410
398411 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+ }
399432 // Estimate register pressure during pre-regalloc pass.
400433 unsigned NumRPS = TRI->getNumRegPressureSets ();
401434 RegPressure.resize (NumRPS);
@@ -1005,24 +1038,6 @@ MachineLICMImpl::calcRegisterCost(const MachineInstr *MI, bool ConsiderSeen,
10051038 return Cost;
10061039}
10071040
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-
10261041// This function iterates through all the operands of the input store MI and
10271042// checks that each register operand statisfies isCallerPreservedPhysReg.
10281043// This means, the value being stored and the address where it is being stored
@@ -1744,13 +1759,97 @@ bool MachineLICMImpl::isTgtHotterThanSrc(MachineBasicBlock *SrcBlock,
17441759 return Ratio > BlockFrequencyRatioThreshold;
17451760}
17461761
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+
17471844template <typename DerivedT, bool PreRegAlloc>
17481845PreservedAnalyses MachineLICMBasePass<DerivedT, PreRegAlloc>::run(
17491846 MachineFunction &MF, MachineFunctionAnalysisManager &MFAM) {
17501847 bool Changed = MachineLICMImpl (PreRegAlloc, nullptr , &MFAM).run (MF);
17511848 if (!Changed)
17521849 return PreservedAnalyses::all ();
17531850 auto PA = getMachineFunctionPassPreservedAnalyses ();
1851+ if (PreRegAlloc)
1852+ PA.preserve <MachineCycleAnalysis>();
17541853 PA.preserve <MachineLoopAnalysis>();
17551854 return PA;
17561855}
0 commit comments