@@ -101,7 +101,7 @@ static cl::opt<bool>
101101 cl::init(false ), cl::Hidden);
102102
103103static cl::opt<bool > AggressivelySinkInstsIntoCycle (
104- " aggressively -sink-insts-to-avoid-spills " ,
104+ " aggressive -sink-insts-into-cycles " ,
105105 cl::desc (" Aggressively sink instructions into cycles to avoid "
106106 " register spills" ),
107107 cl::init(false ), cl::Hidden);
@@ -118,6 +118,8 @@ STATISTIC(NumSplit, "Number of critical edges split");
118118STATISTIC (NumCoalesces, " Number of copies coalesced" );
119119STATISTIC (NumPostRACopySink, " Number of copies sunk after RA" );
120120
121+ using RegSubRegPair = TargetInstrInfo::RegSubRegPair;
122+
121123namespace {
122124
123125class MachineSinking : public MachineFunctionPass {
@@ -263,11 +265,10 @@ class MachineSinking : public MachineFunctionPass {
263265 bool SinkIntoCycle (MachineCycle *Cycle, MachineInstr &I);
264266
265267 bool isDead (const MachineInstr *MI) const ;
266- bool AggressivelySinkIntoCycle (
268+ bool aggressivelySinkIntoCycle (
267269 MachineCycle *Cycle, MachineInstr &I,
268- DenseMap<MachineInstr *,
269- std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
270- SunkInstrs);
270+ DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
271+ &SunkInstrs);
271272
272273 bool isProfitableToSinkTo (Register Reg, MachineInstr &MI,
273274 MachineBasicBlock *MBB,
@@ -692,8 +693,8 @@ void MachineSinking::FindCycleSinkCandidates(
692693 SmallVectorImpl<MachineInstr *> &Candidates) {
693694 for (auto &MI : *BB) {
694695 LLVM_DEBUG (dbgs () << " CycleSink: Analysing candidate: " << MI);
695- if (MI.isDebugInstr ()) {
696- LLVM_DEBUG (dbgs () << " CycleSink: Dont sink debug instructions\n " );
696+ if (MI.isMetaInstruction ()) {
697+ LLVM_DEBUG (dbgs () << " CycleSink: Dont sink meta instructions\n " );
697698 continue ;
698699 }
699700 if (!TII->shouldSink (MI)) {
@@ -786,8 +787,11 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
786787 EverMadeChange = true ;
787788 }
788789
789- if (SinkInstsIntoCycle) {
790+ if (SinkInstsIntoCycle || AggressivelySinkInstsIntoCycle ) {
790791 SmallVector<MachineCycle *, 8 > Cycles (CI->toplevel_cycles ());
792+
793+ DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
794+ SunkInstrs;
791795 for (auto *Cycle : Cycles) {
792796 MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
793797 if (!Preheader) {
@@ -801,7 +805,18 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
801805 // of a def-use chain, if there is any.
802806 // TODO: Sort the candidates using a cost-model.
803807 unsigned i = 0 ;
808+
804809 for (MachineInstr *I : llvm::reverse (Candidates)) {
810+ // AggressivelySinkInstsIntoCycle sinks a superset of instructions
811+ // relative to regular cycle sinking. Thus, this option supercedes
812+ // captures all sinking opportunites done
813+ if (AggressivelySinkInstsIntoCycle) {
814+ aggressivelySinkIntoCycle (Cycle, *I, SunkInstrs);
815+ EverMadeChange = true ;
816+ ++NumCycleSunk;
817+ continue ;
818+ }
819+
805820 if (i++ == SinkIntoCycleLimit) {
806821 LLVM_DEBUG (dbgs () << " CycleSink: Limit reached of instructions to "
807822 " be analysed." );
@@ -816,30 +831,6 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
816831 }
817832 }
818833
819- if (AggressivelySinkInstsIntoCycle) {
820- SmallVector<MachineCycle *, 8 > Cycles (CI->toplevel_cycles ());
821- DenseMap<MachineInstr *,
822- std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
823- SunkInstrs;
824- for (auto *Cycle : Cycles) {
825- MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
826- if (!Preheader) {
827- LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Can't find preheader\n " );
828- continue ;
829- }
830- SmallVector<MachineInstr *, 8 > Candidates;
831- FindCycleSinkCandidates (Cycle, Preheader, Candidates);
832-
833- // Walk the candidates in reverse order so that we start with the use
834- // of a def-use chain, if there is any.
835- for (MachineInstr *I : llvm::reverse (Candidates)) {
836- AggressivelySinkIntoCycle (Cycle, *I, SunkInstrs);
837- EverMadeChange = true ;
838- ++NumCycleSunk;
839- }
840- }
841- }
842-
843834 HasStoreCache.clear ();
844835 StoreInstrCache.clear ();
845836
@@ -1615,31 +1606,27 @@ bool MachineSinking::hasStoreBetween(MachineBasicBlock *From,
16151606 return HasAliasedStore;
16161607}
16171608
1618- // / Copy paste from DeadMachineInstructionElimImpl
1619-
16201609bool MachineSinking::isDead (const MachineInstr *MI) const {
16211610 // Instructions without side-effects are dead iff they only define dead regs.
16221611 // This function is hot and this loop returns early in the common case,
16231612 // so only perform additional checks before this if absolutely necessary.
1613+
16241614 for (const MachineOperand &MO : MI->all_defs ()) {
16251615 Register Reg = MO.getReg ();
1626- if (Reg.isPhysical ()) {
1616+ if (Reg.isPhysical ())
16271617 return false ;
1628- } else {
1629- if (MO.isDead ()) {
1618+
1619+ if (MO.isDead ()) {
16301620#ifndef NDEBUG
1631- // Basic check on the register. All of them should be 'undef'.
1632- for (auto &U : MRI->use_nodbg_operands (Reg))
1633- assert (U.isUndef () && " 'Undef' use on a 'dead' register is found!" );
1621+ // Basic check on the register. All of them should be 'undef'.
1622+ for (auto &U : MRI->use_nodbg_operands (Reg))
1623+ assert (U.isUndef () && " 'Undef' use on a 'dead' register is found!" );
16341624#endif
1635- continue ;
1636- }
1637- for (const MachineInstr &Use : MRI->use_nodbg_instructions (Reg)) {
1638- if (&Use != MI)
1639- // This def has a non-debug use. Don't delete the instruction!
1640- return false ;
1641- }
1625+ continue ;
16421626 }
1627+
1628+ if (!(MRI->hasAtMostUserInstrs (Reg, 0 )))
1629+ return false ;
16431630 }
16441631
16451632 // Technically speaking inline asm without side effects and no defs can still
@@ -1661,25 +1648,24 @@ bool MachineSinking::isDead(const MachineInstr *MI) const {
16611648// / In particular, it will sink into multiple successor blocks without limits
16621649// / based on the amount of sinking, or the type of ops being sunk (so long as
16631650// / they are safe to sink).
1664- bool MachineSinking::AggressivelySinkIntoCycle (
1651+ bool MachineSinking::aggressivelySinkIntoCycle (
16651652 MachineCycle *Cycle, MachineInstr &I,
1666- DenseMap<MachineInstr *,
1667- std::list<std::pair<MachineBasicBlock *, MachineInstr *>>>
1668- SunkInstrs) {
1653+ DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
1654+ &SunkInstrs) {
16691655 LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Finding sink block for: " << I);
16701656 MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
16711657 assert (Preheader && " Cycle sink needs a preheader block" );
1672- SmallVector<std::pair<MachineOperand , MachineInstr *>> Uses;
1658+ SmallVector<std::pair<RegSubRegPair , MachineInstr *>> Uses;
16731659 // TODO: support instructions with multiple defs
16741660 if (I.getNumDefs () > 1 )
16751661 return false ;
16761662
1677- MachineOperand DefMO = I.getOperand (0 );
1663+ MachineOperand & DefMO = I.getOperand (0 );
16781664 for (MachineInstr &MI : MRI->use_instructions (DefMO.getReg ())) {
1679- Uses.push_back ({DefMO, &MI});
1665+ Uses.push_back ({{ DefMO. getReg (), DefMO. getSubReg ()} , &MI});
16801666 }
16811667
1682- for (std::pair<MachineOperand , MachineInstr *> Entry : Uses) {
1668+ for (std::pair<RegSubRegPair , MachineInstr *> Entry : Uses) {
16831669 MachineInstr *MI = Entry.second ;
16841670 LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Analysing use: " << MI);
16851671 if (MI->isPHI ()) {
@@ -1701,22 +1687,14 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17011687
17021688 MachineBasicBlock *SinkBlock = MI->getParent ();
17031689 MachineInstr *NewMI = nullptr ;
1690+ std::pair<MachineInstr *, MachineBasicBlock *> MapEntry (&I, SinkBlock);
17041691
17051692 // Check for the case in which we have already sunk a copy of this
17061693 // instruction into the user block.
1707- if (SunkInstrs.contains (&I)) {
1708- auto SunkBlocks = SunkInstrs[&I];
1709- auto Match = std::find_if (
1710- SunkBlocks.begin (), SunkBlocks.end (),
1711- [&SinkBlock](
1712- std::pair<MachineBasicBlock *, MachineInstr *> SunkEntry) {
1713- return SunkEntry.first == SinkBlock;
1714- });
1715- if (Match != SunkBlocks.end ()) {
1716- LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Already sunk to block: "
1717- << printMBBReference (*SinkBlock) << " \n " );
1718- NewMI = Match->second ;
1719- }
1694+ if (SunkInstrs.contains (MapEntry)) {
1695+ LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Already sunk to block: "
1696+ << printMBBReference (*SinkBlock) << " \n " );
1697+ NewMI = SunkInstrs[MapEntry];
17201698 }
17211699
17221700 // Create a copy of the instruction in the use block.
@@ -1733,7 +1711,7 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17331711 }
17341712 SinkBlock->insert (SinkBlock->SkipPHIsAndLabels (SinkBlock->begin ()),
17351713 NewMI);
1736- SunkInstrs[&I]. push_back ({SinkBlock, NewMI}) ;
1714+ SunkInstrs[MapEntry] = NewMI;
17371715 }
17381716
17391717 // Conservatively clear any kill flags on uses of sunk instruction
@@ -1748,9 +1726,9 @@ bool MachineSinking::AggressivelySinkIntoCycle(
17481726 NewMI->setDebugLoc (DebugLoc ());
17491727
17501728 // Replace the use with the newly created virtual register.
1751- MachineOperand UseMO = Entry.first ;
1752- MI->substituteRegister (UseMO. getReg () , NewMI->getOperand (0 ).getReg (),
1753- UseMO. getSubReg () , *TRI);
1729+ RegSubRegPair &UseReg = Entry.first ;
1730+ MI->substituteRegister (UseReg. Reg , NewMI->getOperand (0 ).getReg (),
1731+ UseReg. SubReg , *TRI);
17541732 }
17551733 // If we have replaced all uses, then delete the dead instruction
17561734 if (isDead (&I))
0 commit comments