44
44
#include " llvm/CodeGen/TargetInstrInfo.h"
45
45
#include " llvm/CodeGen/TargetPassConfig.h"
46
46
#include " llvm/CodeGen/TargetRegisterInfo.h"
47
+ #include " llvm/CodeGen/TargetSchedule.h"
47
48
#include " llvm/CodeGen/TargetSubtargetInfo.h"
48
49
#include " llvm/IR/BasicBlock.h"
49
50
#include " llvm/IR/DebugInfoMetadata.h"
@@ -100,12 +101,6 @@ static cl::opt<bool>
100
101
" register spills" ),
101
102
cl::init(false ), cl::Hidden);
102
103
103
- static cl::opt<bool > AggressivelySinkInstsIntoCycle (
104
- " aggressive-sink-insts-into-cycles" ,
105
- cl::desc (" Aggressively sink instructions into cycles to avoid "
106
- " register spills" ),
107
- cl::init(false ), cl::Hidden);
108
-
109
104
static cl::opt<unsigned > SinkIntoCycleLimit (
110
105
" machine-sink-cycle-limit" ,
111
106
cl::desc (
@@ -135,6 +130,7 @@ class MachineSinking : public MachineFunctionPass {
135
130
const MachineBranchProbabilityInfo *MBPI = nullptr ;
136
131
AliasAnalysis *AA = nullptr ;
137
132
RegisterClassInfo RegClassInfo;
133
+ TargetSchedModel SchedModel;
138
134
139
135
// Remember which edges have been considered for breaking.
140
136
SmallSet<std::pair<MachineBasicBlock *, MachineBasicBlock *>, 8 >
@@ -262,7 +258,6 @@ class MachineSinking : public MachineFunctionPass {
262
258
263
259
void FindCycleSinkCandidates (MachineCycle *Cycle, MachineBasicBlock *BB,
264
260
SmallVectorImpl<MachineInstr *> &Candidates);
265
- bool SinkIntoCycle (MachineCycle *Cycle, MachineInstr &I);
266
261
267
262
bool isDead (const MachineInstr *MI) const ;
268
263
bool aggressivelySinkIntoCycle (
@@ -284,11 +279,14 @@ class MachineSinking : public MachineFunctionPass {
284
279
GetAllSortedSuccessors (MachineInstr &MI, MachineBasicBlock *MBB,
285
280
AllSuccsCache &AllSuccessors) const ;
286
281
287
- std::vector<unsigned > &getBBRegisterPressure (const MachineBasicBlock &MBB);
282
+ std::vector<unsigned > &getBBRegisterPressure (const MachineBasicBlock &MBB,
283
+ bool UseCache = true );
288
284
289
285
bool registerPressureSetExceedsLimit (unsigned NRegs,
290
286
const TargetRegisterClass *RC,
291
287
const MachineBasicBlock &MBB);
288
+
289
+ bool registerPressureExceedsLimit (const MachineBasicBlock &MBB);
292
290
};
293
291
294
292
} // end anonymous namespace
@@ -787,48 +785,63 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
787
785
EverMadeChange = true ;
788
786
}
789
787
790
- if (SinkInstsIntoCycle || AggressivelySinkInstsIntoCycle ) {
788
+ if (SinkInstsIntoCycle) {
791
789
SmallVector<MachineCycle *, 8 > Cycles (CI->toplevel_cycles ());
790
+ SchedModel.init (STI);
791
+ enum CycleSinkStage { COPY, LOW_LATENCY, AGGRESSIVE, END };
792
792
793
- DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
794
- SunkInstrs;
795
- for (auto *Cycle : Cycles) {
796
- MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
797
- if (!Preheader) {
798
- LLVM_DEBUG (dbgs () << " CycleSink: Can't find preheader\n " );
799
- continue ;
800
- }
801
- SmallVector<MachineInstr *, 8 > Candidates;
802
- FindCycleSinkCandidates (Cycle, Preheader, Candidates);
803
-
804
- // Walk the candidates in reverse order so that we start with the use
805
- // of a def-use chain, if there is any.
806
- // TODO: Sort the candidates using a cost-model.
807
- unsigned i = 0 ;
808
-
809
- 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;
793
+ CycleSinkStage Stage = CycleSinkStage::COPY;
794
+ bool HasHighPressure;
795
+ do {
796
+ HasHighPressure = false ;
797
+ DenseMap<std::pair<MachineInstr *, MachineBasicBlock *>, MachineInstr *>
798
+ SunkInstrs;
799
+ for (auto *Cycle : Cycles) {
800
+ MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
801
+ if (!Preheader) {
802
+ LLVM_DEBUG (dbgs () << " CycleSink: Can't find preheader\n " );
817
803
continue ;
818
804
}
805
+ SmallVector<MachineInstr *, 8 > Candidates;
806
+ FindCycleSinkCandidates (Cycle, Preheader, Candidates);
807
+
808
+ unsigned i = 0 ;
809
+
810
+ // Walk the candidates in reverse order so that we start with the use
811
+ // of a def-use chain, if there is any.
812
+ // TODO: Sort the candidates using a cost-model.
813
+ for (MachineInstr *I : llvm::reverse (Candidates)) {
814
+ // CycleSinkStage::COPY: Sink a limited number of copies
815
+ if (Stage == CycleSinkStage::COPY) {
816
+ if (i++ == SinkIntoCycleLimit) {
817
+ LLVM_DEBUG (dbgs ()
818
+ << " CycleSink: Limit reached of instructions to "
819
+ " be analysed." );
820
+ break ;
821
+ }
822
+
823
+ if (!I->isCopy ())
824
+ continue ;
825
+ }
819
826
820
- if (i++ == SinkIntoCycleLimit) {
821
- LLVM_DEBUG (dbgs () << " CycleSink: Limit reached of instructions to "
822
- " be analysed." );
823
- break ;
827
+ // CycleSinkStage::LOW_LATENCY: sink unlimited number of instructions
828
+ // which the target specifies as low-latency
829
+ if (Stage == CycleSinkStage::LOW_LATENCY &&
830
+ !TII->hasLowDefLatency (SchedModel, *I, 0 ))
831
+ continue ;
832
+
833
+ if (!aggressivelySinkIntoCycle (Cycle, *I, SunkInstrs))
834
+ break ;
835
+ EverMadeChange = true ;
836
+ ++NumCycleSunk;
824
837
}
825
838
826
- if (!SinkIntoCycle (Cycle, *I))
827
- break ;
828
- EverMadeChange = true ;
829
- ++NumCycleSunk;
839
+ // Recalculate the pressure after sinking
840
+ if (!HasHighPressure)
841
+ HasHighPressure = registerPressureExceedsLimit (*Preheader);
830
842
}
831
- }
843
+ Stage = (CycleSinkStage)(Stage + 1 );
844
+ } while (HasHighPressure && Stage < CycleSinkStage::END);
832
845
}
833
846
834
847
HasStoreCache.clear ();
@@ -1081,13 +1094,15 @@ bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,
1081
1094
}
1082
1095
1083
1096
std::vector<unsigned > &
1084
- MachineSinking::getBBRegisterPressure (const MachineBasicBlock &MBB) {
1097
+ MachineSinking::getBBRegisterPressure (const MachineBasicBlock &MBB,
1098
+ bool UseCache) {
1085
1099
// Currently to save compiling time, MBB's register pressure will not change
1086
1100
// in one ProcessBlock iteration because of CachedRegisterPressure. but MBB's
1087
1101
// register pressure is changed after sinking any instructions into it.
1088
1102
// FIXME: need a accurate and cheap register pressure estiminate model here.
1103
+
1089
1104
auto RP = CachedRegisterPressure.find (&MBB);
1090
- if (RP != CachedRegisterPressure.end ())
1105
+ if (UseCache && RP != CachedRegisterPressure.end ())
1091
1106
return RP->second ;
1092
1107
1093
1108
RegionPressure Pressure;
@@ -1111,6 +1126,12 @@ MachineSinking::getBBRegisterPressure(const MachineBasicBlock &MBB) {
1111
1126
}
1112
1127
1113
1128
RPTracker.closeRegion ();
1129
+
1130
+ if (RP != CachedRegisterPressure.end ()) {
1131
+ CachedRegisterPressure[&MBB] = RPTracker.getPressure ().MaxSetPressure ;
1132
+ return CachedRegisterPressure[&MBB];
1133
+ }
1134
+
1114
1135
auto It = CachedRegisterPressure.insert (
1115
1136
std::make_pair (&MBB, RPTracker.getPressure ().MaxSetPressure ));
1116
1137
return It.first ->second ;
@@ -1129,6 +1150,21 @@ bool MachineSinking::registerPressureSetExceedsLimit(
1129
1150
return false ;
1130
1151
}
1131
1152
1153
+ // Recalculate RP and check if any pressure set exceeds the set limit.
1154
+ bool MachineSinking::registerPressureExceedsLimit (
1155
+ const MachineBasicBlock &MBB) {
1156
+ std::vector<unsigned > BBRegisterPressure = getBBRegisterPressure (MBB, false );
1157
+
1158
+ for (unsigned PS = 0 ; PS < BBRegisterPressure.size (); ++PS) {
1159
+ if (BBRegisterPressure[PS] >=
1160
+ TRI->getRegPressureSetLimit (*MBB.getParent (), PS)) {
1161
+ return true ;
1162
+ }
1163
+ }
1164
+
1165
+ return false ;
1166
+ }
1167
+
1132
1168
// / isProfitableToSinkTo - Return true if it is profitable to sink MI.
1133
1169
bool MachineSinking::isProfitableToSinkTo (Register Reg, MachineInstr &MI,
1134
1170
MachineBasicBlock *MBB,
@@ -1656,10 +1692,6 @@ bool MachineSinking::aggressivelySinkIntoCycle(
1656
1692
if (I.getNumDefs () > 1 )
1657
1693
return false ;
1658
1694
1659
- // Only sink instructions which the target considers to be low latency
1660
- if (!TII->isLowLatencyInstruction (I))
1661
- return false ;
1662
-
1663
1695
LLVM_DEBUG (dbgs () << " AggressiveCycleSink: Finding sink block for: " << I);
1664
1696
MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
1665
1697
assert (Preheader && " Cycle sink needs a preheader block" );
@@ -1741,86 +1773,6 @@ bool MachineSinking::aggressivelySinkIntoCycle(
1741
1773
return true ;
1742
1774
}
1743
1775
1744
- // / Sink instructions into cycles if profitable. This especially tries to
1745
- // / prevent register spills caused by register pressure if there is little to no
1746
- // / overhead moving instructions into cycles.
1747
- bool MachineSinking::SinkIntoCycle (MachineCycle *Cycle, MachineInstr &I) {
1748
- LLVM_DEBUG (dbgs () << " CycleSink: Finding sink block for: " << I);
1749
- MachineBasicBlock *Preheader = Cycle->getCyclePreheader ();
1750
- assert (Preheader && " Cycle sink needs a preheader block" );
1751
- MachineBasicBlock *SinkBlock = nullptr ;
1752
- bool CanSink = true ;
1753
- const MachineOperand &MO = I.getOperand (0 );
1754
-
1755
- for (MachineInstr &MI : MRI->use_instructions (MO.getReg ())) {
1756
- LLVM_DEBUG (dbgs () << " CycleSink: Analysing use: " << MI);
1757
- if (!Cycle->contains (MI.getParent ())) {
1758
- LLVM_DEBUG (dbgs () << " CycleSink: Use not in cycle, can't sink.\n " );
1759
- CanSink = false ;
1760
- break ;
1761
- }
1762
-
1763
- // FIXME: Come up with a proper cost model that estimates whether sinking
1764
- // the instruction (and thus possibly executing it on every cycle
1765
- // iteration) is more expensive than a register.
1766
- // For now assumes that copies are cheap and thus almost always worth it.
1767
- if (!MI.isCopy ()) {
1768
- LLVM_DEBUG (dbgs () << " CycleSink: Use is not a copy\n " );
1769
- CanSink = false ;
1770
- break ;
1771
- }
1772
- if (!SinkBlock) {
1773
- SinkBlock = MI.getParent ();
1774
- LLVM_DEBUG (dbgs () << " CycleSink: Setting sink block to: "
1775
- << printMBBReference (*SinkBlock) << " \n " );
1776
- continue ;
1777
- }
1778
- SinkBlock = DT->findNearestCommonDominator (SinkBlock, MI.getParent ());
1779
- if (!SinkBlock) {
1780
- LLVM_DEBUG (dbgs () << " CycleSink: Can't find nearest dominator\n " );
1781
- CanSink = false ;
1782
- break ;
1783
- }
1784
- LLVM_DEBUG (dbgs () << " CycleSink: Setting nearest common dom block: "
1785
- << printMBBReference (*SinkBlock) << " \n " );
1786
- }
1787
-
1788
- if (!CanSink) {
1789
- LLVM_DEBUG (dbgs () << " CycleSink: Can't sink instruction.\n " );
1790
- return false ;
1791
- }
1792
- if (!SinkBlock) {
1793
- LLVM_DEBUG (dbgs () << " CycleSink: Not sinking, can't find sink block.\n " );
1794
- return false ;
1795
- }
1796
- if (SinkBlock == Preheader) {
1797
- LLVM_DEBUG (
1798
- dbgs () << " CycleSink: Not sinking, sink block is the preheader\n " );
1799
- return false ;
1800
- }
1801
- if (SinkBlock->sizeWithoutDebugLargerThan (SinkLoadInstsPerBlockThreshold)) {
1802
- LLVM_DEBUG (
1803
- dbgs () << " CycleSink: Not Sinking, block too large to analyse.\n " );
1804
- return false ;
1805
- }
1806
-
1807
- LLVM_DEBUG (dbgs () << " CycleSink: Sinking instruction!\n " );
1808
- SinkBlock->splice (SinkBlock->SkipPHIsAndLabels (SinkBlock->begin ()), Preheader,
1809
- I);
1810
-
1811
- // Conservatively clear any kill flags on uses of sunk instruction
1812
- for (MachineOperand &MO : I.operands ()) {
1813
- if (MO.isReg () && MO.readsReg ())
1814
- RegsToClearKillFlags.insert (MO.getReg ());
1815
- }
1816
-
1817
- // The instruction is moved from its basic block, so do not retain the
1818
- // debug information.
1819
- assert (!I.isDebugInstr () && " Should not sink debug inst" );
1820
- I.setDebugLoc (DebugLoc ());
1821
- return true ;
1822
- }
1823
-
1824
1776
// / SinkInstruction - Determine whether it is safe to sink the specified machine
1825
1777
// / instruction out of its current block into a successor.
1826
1778
bool MachineSinking::SinkInstruction (MachineInstr &MI, bool &SawStore,
0 commit comments