@@ -130,6 +130,14 @@ namespace {
130
130
// Remember which edges have been considered for breaking.
131
131
SmallSet<std::pair<MachineBasicBlock*, MachineBasicBlock*>, 8 >
132
132
CEBCandidates;
133
+ // Memorize the register that also wanted to sink into the same block along
134
+ // a different critical edge.
135
+ // {register to sink, sink-to block} -> the first sink-from block.
136
+ // We're recording the first sink-from block because that (critical) edge
137
+ // was deferred until we see another register that's going to sink into the
138
+ // same block.
139
+ DenseMap<std::pair<Register, MachineBasicBlock *>, MachineBasicBlock *>
140
+ CEMergeCandidates;
133
141
// Remember which edges we are about to split.
134
142
// This is different from CEBCandidates since those edges
135
143
// will be split.
@@ -197,14 +205,17 @@ namespace {
197
205
198
206
void releaseMemory () override {
199
207
CEBCandidates.clear ();
208
+ CEMergeCandidates.clear ();
200
209
}
201
210
202
211
private:
203
212
bool ProcessBlock (MachineBasicBlock &MBB);
204
213
void ProcessDbgInst (MachineInstr &MI);
205
- bool isWorthBreakingCriticalEdge (MachineInstr &MI,
206
- MachineBasicBlock *From,
207
- MachineBasicBlock *To);
214
+ bool isLegalToBreakCriticalEdge (MachineInstr &MI, MachineBasicBlock *From,
215
+ MachineBasicBlock *To, bool BreakPHIEdge);
216
+ bool isWorthBreakingCriticalEdge (MachineInstr &MI, MachineBasicBlock *From,
217
+ MachineBasicBlock *To,
218
+ MachineBasicBlock *&DeferredFromBlock);
208
219
209
220
bool hasStoreBetween (MachineBasicBlock *From, MachineBasicBlock *To,
210
221
MachineInstr &MI);
@@ -725,6 +736,7 @@ bool MachineSinking::runOnMachineFunction(MachineFunction &MF) {
725
736
726
737
// Process all basic blocks.
727
738
CEBCandidates.clear ();
739
+ CEMergeCandidates.clear ();
728
740
ToSplit.clear ();
729
741
for (auto &MBB: MF)
730
742
MadeChange |= ProcessBlock (MBB);
@@ -873,9 +885,9 @@ void MachineSinking::ProcessDbgInst(MachineInstr &MI) {
873
885
SeenDbgVars.insert (Var);
874
886
}
875
887
876
- bool MachineSinking::isWorthBreakingCriticalEdge (MachineInstr &MI,
877
- MachineBasicBlock *From ,
878
- MachineBasicBlock *To ) {
888
+ bool MachineSinking::isWorthBreakingCriticalEdge (
889
+ MachineInstr &MI, MachineBasicBlock *From, MachineBasicBlock *To ,
890
+ MachineBasicBlock *&DeferredFromBlock ) {
879
891
// FIXME: Need much better heuristics.
880
892
881
893
// If the pass has already considered breaking this edge (during this pass
@@ -887,6 +899,27 @@ bool MachineSinking::isWorthBreakingCriticalEdge(MachineInstr &MI,
887
899
if (!MI.isCopy () && !TII->isAsCheapAsAMove (MI))
888
900
return true ;
889
901
902
+ // Check and record the register and the destination block we want to sink
903
+ // into. Note that we want to do the following before the next check on branch
904
+ // probability. Because we want to record the initial candidate even if it's
905
+ // on hot edge, so that other candidates that might not on hot edges can be
906
+ // sinked as well.
907
+ for (const auto &MO : MI.all_defs ()) {
908
+ Register Reg = MO.getReg ();
909
+ if (!Reg)
910
+ continue ;
911
+ Register SrcReg = Reg.isVirtual () ? TRI->lookThruCopyLike (Reg, MRI) : Reg;
912
+ auto Key = std::make_pair (SrcReg, To);
913
+ auto Res = CEMergeCandidates.try_emplace (Key, From);
914
+ // We wanted to sink the same register into the same block, consider it to
915
+ // be profitable.
916
+ if (!Res.second ) {
917
+ // Return the source block that was previously held off.
918
+ DeferredFromBlock = Res.first ->second ;
919
+ return true ;
920
+ }
921
+ }
922
+
890
923
if (From->isSuccessor (To) && MBPI->getEdgeProbability (From, To) <=
891
924
BranchProbability (SplitEdgeProbabilityThreshold, 100 ))
892
925
return true ;
@@ -921,13 +954,10 @@ bool MachineSinking::isWorthBreakingCriticalEdge(MachineInstr &MI,
921
954
return false ;
922
955
}
923
956
924
- bool MachineSinking::PostponeSplitCriticalEdge (MachineInstr &MI,
925
- MachineBasicBlock *FromBB,
926
- MachineBasicBlock *ToBB,
927
- bool BreakPHIEdge) {
928
- if (!isWorthBreakingCriticalEdge (MI, FromBB, ToBB))
929
- return false ;
930
-
957
+ bool MachineSinking::isLegalToBreakCriticalEdge (MachineInstr &MI,
958
+ MachineBasicBlock *FromBB,
959
+ MachineBasicBlock *ToBB,
960
+ bool BreakPHIEdge) {
931
961
// Avoid breaking back edge. From == To means backedge for single BB cycle.
932
962
if (!SplitEdges || FromBB == ToBB)
933
963
return false ;
@@ -985,11 +1015,32 @@ bool MachineSinking::PostponeSplitCriticalEdge(MachineInstr &MI,
985
1015
return false ;
986
1016
}
987
1017
988
- ToSplit.insert (std::make_pair (FromBB, ToBB));
989
-
990
1018
return true ;
991
1019
}
992
1020
1021
+ bool MachineSinking::PostponeSplitCriticalEdge (MachineInstr &MI,
1022
+ MachineBasicBlock *FromBB,
1023
+ MachineBasicBlock *ToBB,
1024
+ bool BreakPHIEdge) {
1025
+ bool Status = false ;
1026
+ MachineBasicBlock *DeferredFromBB = nullptr ;
1027
+ if (isWorthBreakingCriticalEdge (MI, FromBB, ToBB, DeferredFromBB)) {
1028
+ // If there is a DeferredFromBB, we consider FromBB only if _both_
1029
+ // of them are legal to split.
1030
+ if ((!DeferredFromBB ||
1031
+ ToSplit.count (std::make_pair (DeferredFromBB, ToBB)) ||
1032
+ isLegalToBreakCriticalEdge (MI, DeferredFromBB, ToBB, BreakPHIEdge)) &&
1033
+ isLegalToBreakCriticalEdge (MI, FromBB, ToBB, BreakPHIEdge)) {
1034
+ ToSplit.insert (std::make_pair (FromBB, ToBB));
1035
+ if (DeferredFromBB)
1036
+ ToSplit.insert (std::make_pair (DeferredFromBB, ToBB));
1037
+ Status = true ;
1038
+ }
1039
+ }
1040
+
1041
+ return Status;
1042
+ }
1043
+
993
1044
std::vector<unsigned > &
994
1045
MachineSinking::getBBRegisterPressure (const MachineBasicBlock &MBB) {
995
1046
// Currently to save compiling time, MBB's register pressure will not change
0 commit comments