@@ -149,11 +149,15 @@ namespace {
149
149
struct IfcvtToken {
150
150
BBInfo &BBI;
151
151
IfcvtKind Kind;
152
- bool NeedSubsumption;
153
152
unsigned NumDups;
154
153
unsigned NumDups2;
155
- IfcvtToken (BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0 )
156
- : BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {}
154
+ bool NeedSubsumption : 1 ;
155
+ bool TClobbersPred : 1 ;
156
+ bool FClobbersPred : 1 ;
157
+ IfcvtToken (BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0 ,
158
+ bool tc = false , bool fc = false )
159
+ : BBI(b), Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
160
+ TClobbersPred (tc), FClobbersPred(fc) {}
157
161
};
158
162
159
163
// / Results of if-conversion feasibility analysis indexed by basic block
@@ -203,23 +207,30 @@ namespace {
203
207
bool FalseBranch, unsigned &Dups,
204
208
BranchProbability Prediction) const ;
205
209
bool ValidDiamond (BBInfo &TrueBBI, BBInfo &FalseBBI,
206
- unsigned &Dups1, unsigned &Dups2) const ;
210
+ unsigned &Dups1, unsigned &Dups2,
211
+ BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const ;
207
212
void AnalyzeBranches (BBInfo &BBI);
208
213
void ScanInstructions (BBInfo &BBI,
209
214
MachineBasicBlock::iterator &Begin,
210
215
MachineBasicBlock::iterator &End) const ;
216
+ bool RescanInstructions (
217
+ MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB,
218
+ MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE,
219
+ BBInfo &TrueBBI, BBInfo &FalseBBI) const ;
211
220
void AnalyzeBlock (MachineBasicBlock &MBB,
212
221
std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
213
222
bool FeasibilityAnalysis (BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond,
214
- bool isTriangle = false , bool RevBranch = false );
223
+ bool isTriangle = false , bool RevBranch = false ,
224
+ bool hasCommonTail = false );
215
225
void AnalyzeBlocks (MachineFunction &MF,
216
226
std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
217
227
void InvalidatePreds (MachineBasicBlock &MBB);
218
228
void RemoveExtraEdges (BBInfo &BBI);
219
229
bool IfConvertSimple (BBInfo &BBI, IfcvtKind Kind);
220
230
bool IfConvertTriangle (BBInfo &BBI, IfcvtKind Kind);
221
231
bool IfConvertDiamond (BBInfo &BBI, IfcvtKind Kind,
222
- unsigned NumDups1, unsigned NumDups2);
232
+ unsigned NumDups1, unsigned NumDups2,
233
+ bool TClobbers, bool FClobbers);
223
234
void PredicateBlock (BBInfo &BBI,
224
235
MachineBasicBlock::iterator E,
225
236
SmallVectorImpl<MachineOperand> &Cond,
@@ -406,7 +417,9 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
406
417
DEBUG (dbgs () << " Ifcvt (Diamond): BB#" << BBI.BB ->getNumber () << " (T:"
407
418
<< BBI.TrueBB ->getNumber () << " ,F:"
408
419
<< BBI.FalseBB ->getNumber () << " ) " );
409
- RetVal = IfConvertDiamond (BBI, Kind, NumDups, NumDups2);
420
+ RetVal = IfConvertDiamond (BBI, Kind, NumDups, NumDups2,
421
+ Token->TClobbersPred ,
422
+ Token->FClobbersPred );
410
423
DEBUG (dbgs () << (RetVal ? " succeeded!" : " failed!" ) << " \n " );
411
424
if (RetVal) ++NumDiamonds;
412
425
break ;
@@ -677,10 +690,36 @@ static void countDuplicatedInstructions(
677
690
}
678
691
}
679
692
693
+ // / RescanInstructions - Run ScanInstructions on a pair of blocks.
694
+ // / @param TIB - True Iterator Begin, points to first non-shared instruction
695
+ // / @param FIB - False Iterator Begin, points to first non-shared instruction
696
+ // / @param TIE - True Iterator End, points past last non-shared instruction
697
+ // / @param FIE - False Iterator End, points past last non-shared instruction
698
+ // / @param TrueBBI - BBInfo to update for the true block.
699
+ // / @param FalseBBI - BBInfo to update for the false block.
700
+ // / @returns - false if either block cannot be predicated or if both blocks end
701
+ // / with a predicate-clobbering instruction.
702
+ bool IfConverter::RescanInstructions (
703
+ MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB,
704
+ MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE,
705
+ BBInfo &TrueBBI, BBInfo &FalseBBI) const {
706
+ ScanInstructions (TrueBBI, TIB, TIE);
707
+ if (TrueBBI.IsUnpredicable )
708
+ return false ;
709
+ ScanInstructions (FalseBBI, FIB, FIE);
710
+ if (FalseBBI.IsUnpredicable )
711
+ return false ;
712
+ if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred )
713
+ return false ;
714
+ return true ;
715
+ }
716
+
680
717
// / ValidDiamond - Returns true if the 'true' and 'false' blocks (along
681
718
// / with their common predecessor) forms a valid diamond shape for ifcvt.
682
- bool IfConverter::ValidDiamond (BBInfo &TrueBBI, BBInfo &FalseBBI,
683
- unsigned &Dups1, unsigned &Dups2) const {
719
+ bool IfConverter::ValidDiamond (
720
+ BBInfo &TrueBBI, BBInfo &FalseBBI,
721
+ unsigned &Dups1, unsigned &Dups2,
722
+ BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const {
684
723
Dups1 = Dups2 = 0 ;
685
724
if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
686
725
FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone )
@@ -701,8 +740,7 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
701
740
return false ;
702
741
703
742
// FIXME: Allow true block to have an early exit?
704
- if (TrueBBI.FalseBB || FalseBBI.FalseBB ||
705
- (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred ))
743
+ if (TrueBBI.FalseBB || FalseBBI.FalseBB )
706
744
return false ;
707
745
708
746
// Count duplicate instructions at the beginning and end of the true and
@@ -714,6 +752,16 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
714
752
countDuplicatedInstructions (TIB, FIB, TIE, FIE, Dups1, Dups2,
715
753
*TrueBBI.BB , *FalseBBI.BB ,
716
754
/* SkipConditionalBranches */ true );
755
+
756
+ TrueBBICalc.BB = TrueBBI.BB ;
757
+ FalseBBICalc.BB = FalseBBI.BB ;
758
+ if (!RescanInstructions (TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
759
+ return false ;
760
+ // The size is used to decide whether to if-convert, and the shared portions
761
+ // are subtracted off. Because of the subtraction, we just use the size that
762
+ // was calculated by the original ScanInstructions, as it is correct.
763
+ TrueBBICalc.NonPredSize = TrueBBI.NonPredSize ;
764
+ FalseBBICalc.NonPredSize = FalseBBI.NonPredSize ;
717
765
return true ;
718
766
}
719
767
@@ -841,11 +889,22 @@ void IfConverter::ScanInstructions(BBInfo &BBI,
841
889
842
890
// / Determine if the block is a suitable candidate to be predicated by the
843
891
// / specified predicate.
892
+ // / @param BBI BBInfo for the block to check
893
+ // / @param Pred Predicate array for the branch that leads to BBI
894
+ // / @param isTriangle true if the Analysis is for a triangle
895
+ // / @param RevBranch true if Reverse(Pred) leads to BBI (e.g. BBI is the false
896
+ // / case
897
+ // / @param hasCommonTail true if BBI shares a tail with a sibling block that
898
+ // / contains any instruction that would make the block unpredicable.
844
899
bool IfConverter::FeasibilityAnalysis (BBInfo &BBI,
845
900
SmallVectorImpl<MachineOperand> &Pred,
846
- bool isTriangle, bool RevBranch) {
901
+ bool isTriangle, bool RevBranch,
902
+ bool hasCommonTail) {
847
903
// If the block is dead or unpredicable, then it cannot be predicated.
848
- if (BBI.IsDone || BBI.IsUnpredicable )
904
+ // Two blocks may share a common unpredicable tail, but this doesn't prevent
905
+ // them from being if-converted. The non-shared portion is assumed to have
906
+ // been checked
907
+ if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
849
908
return false ;
850
909
851
910
// If it is already predicated but we couldn't analyze its terminator, the
@@ -859,7 +918,7 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
859
918
if (BBI.Predicate .size () && !TII->SubsumesPredicate (Pred, BBI.Predicate ))
860
919
return false ;
861
920
862
- if (BBI.BrCond .size ()) {
921
+ if (!hasCommonTail && BBI.BrCond .size ()) {
863
922
if (!isTriangle)
864
923
return false ;
865
924
@@ -966,25 +1025,37 @@ void IfConverter::AnalyzeBlock(
966
1025
967
1026
BranchProbability Prediction = MBPI->getEdgeProbability (BB, TrueBBI.BB );
968
1027
969
- if (CanRevCond && ValidDiamond (TrueBBI, FalseBBI, Dups, Dups2) &&
1028
+ if (CanRevCond) {
1029
+ BBInfo TrueBBICalc, FalseBBICalc;
1030
+ if (ValidDiamond (TrueBBI, FalseBBI, Dups, Dups2,
1031
+ TrueBBICalc, FalseBBICalc) &&
970
1032
MeetIfcvtSizeLimit (*TrueBBI.BB , (TrueBBI.NonPredSize - (Dups + Dups2) +
971
- TrueBBI.ExtraCost ), TrueBBI.ExtraCost2 ,
1033
+ TrueBBICalc.ExtraCost ),
1034
+ TrueBBICalc.ExtraCost2 ,
972
1035
*FalseBBI.BB , (FalseBBI.NonPredSize - (Dups + Dups2) +
973
- FalseBBI.ExtraCost ),FalseBBI.ExtraCost2 ,
974
- Prediction) &&
975
- FeasibilityAnalysis (TrueBBI, BBI.BrCond ) &&
976
- FeasibilityAnalysis (FalseBBI, RevCond)) {
977
- // Diamond:
978
- // EBB
979
- // / \_
980
- // | |
981
- // TBB FBB
982
- // \ /
983
- // TailBB
984
- // Note TailBB can be empty.
985
- Tokens.push_back (llvm::make_unique<IfcvtToken>(
986
- BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2));
987
- Enqueued = true ;
1036
+ FalseBBICalc.ExtraCost ),
1037
+ FalseBBICalc.ExtraCost2 ,
1038
+ Prediction) &&
1039
+ FeasibilityAnalysis (TrueBBI, BBI.BrCond ,
1040
+ /* IsTriangle */ false , /* RevCond */ false ,
1041
+ /* hasCommonTail */ true ) &&
1042
+ FeasibilityAnalysis (FalseBBI, RevCond,
1043
+ /* IsTriangle */ false , /* RevCond */ false ,
1044
+ /* hasCommonTail */ true )) {
1045
+ // Diamond:
1046
+ // EBB
1047
+ // / \_
1048
+ // | |
1049
+ // TBB FBB
1050
+ // \ /
1051
+ // TailBB
1052
+ // Note TailBB can be empty.
1053
+ Tokens.push_back (llvm::make_unique<IfcvtToken>(
1054
+ BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1055
+ (bool ) TrueBBICalc.ClobbersPred ,
1056
+ (bool ) FalseBBICalc.ClobbersPred ));
1057
+ Enqueued = true ;
1058
+ }
988
1059
}
989
1060
990
1061
if (ValidTriangle (TrueBBI, FalseBBI, false , Dups, Prediction) &&
@@ -1429,8 +1500,18 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1429
1500
}
1430
1501
1431
1502
// / If convert a diamond sub-CFG.
1503
+ // / \p BBI is the head of the diamond
1504
+ // / \p NumDups1 - number of shared instructions at the beginning of TrueBBI and
1505
+ // / FalseBBI
1506
+ // / \p NumDups2 - number of shared instructions at the end of TrueBBI and
1507
+ // / FalseBBI
1508
+ // / \p TClobbersPred - True if the true block clobbers the predicate in the
1509
+ // / non-shared portion.
1510
+ // / \p TClobbersPred - True if the false block clobbers the predicate in the
1511
+ // / non-shared portion.
1432
1512
bool IfConverter::IfConvertDiamond (BBInfo &BBI, IfcvtKind Kind,
1433
- unsigned NumDups1, unsigned NumDups2) {
1513
+ unsigned NumDups1, unsigned NumDups2,
1514
+ bool TClobbersPred, bool FClobbersPred) {
1434
1515
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB ->getNumber ()];
1435
1516
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB ->getNumber ()];
1436
1517
MachineBasicBlock *TailBB = TrueBBI.TrueBB ;
@@ -1468,9 +1549,9 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
1468
1549
1469
1550
// Figure out the more profitable ordering.
1470
1551
bool DoSwap = false ;
1471
- if (TrueBBI. ClobbersPred && !FalseBBI. ClobbersPred )
1552
+ if (TClobbersPred && !FClobbersPred )
1472
1553
DoSwap = true ;
1473
- else if (TrueBBI. ClobbersPred == FalseBBI. ClobbersPred ) {
1554
+ else if (TClobbersPred == FClobbersPred ) {
1474
1555
if (TrueBBI.NonPredSize > FalseBBI.NonPredSize )
1475
1556
DoSwap = true ;
1476
1557
}
0 commit comments