Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit bfd62a4

Browse files
author
Kyle Butt
committed
IfConversion: Rescan diamonds.
The cost of predicating a diamond is only the instructions that are not shared between the two branches. Additionally If a predicate clobbering instruction occurs in the shared portion of the branches (e.g. a cond move), it may still be possible to if convert the sub-cfg. This change handles these two facts by rescanning the non-shared portion of a diamond sub-cfg to recalculate both the predication cost and whether both blocks are pred-clobbering. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@279167 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 1eee0ec commit bfd62a4

File tree

1 file changed

+115
-34
lines changed

1 file changed

+115
-34
lines changed

lib/CodeGen/IfConversion.cpp

Lines changed: 115 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -149,11 +149,15 @@ namespace {
149149
struct IfcvtToken {
150150
BBInfo &BBI;
151151
IfcvtKind Kind;
152-
bool NeedSubsumption;
153152
unsigned NumDups;
154153
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) {}
157161
};
158162

159163
/// Results of if-conversion feasibility analysis indexed by basic block
@@ -203,23 +207,30 @@ namespace {
203207
bool FalseBranch, unsigned &Dups,
204208
BranchProbability Prediction) const;
205209
bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
206-
unsigned &Dups1, unsigned &Dups2) const;
210+
unsigned &Dups1, unsigned &Dups2,
211+
BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const;
207212
void AnalyzeBranches(BBInfo &BBI);
208213
void ScanInstructions(BBInfo &BBI,
209214
MachineBasicBlock::iterator &Begin,
210215
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;
211220
void AnalyzeBlock(MachineBasicBlock &MBB,
212221
std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
213222
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);
215225
void AnalyzeBlocks(MachineFunction &MF,
216226
std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
217227
void InvalidatePreds(MachineBasicBlock &MBB);
218228
void RemoveExtraEdges(BBInfo &BBI);
219229
bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
220230
bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
221231
bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
222-
unsigned NumDups1, unsigned NumDups2);
232+
unsigned NumDups1, unsigned NumDups2,
233+
bool TClobbers, bool FClobbers);
223234
void PredicateBlock(BBInfo &BBI,
224235
MachineBasicBlock::iterator E,
225236
SmallVectorImpl<MachineOperand> &Cond,
@@ -406,7 +417,9 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
406417
DEBUG(dbgs() << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:"
407418
<< BBI.TrueBB->getNumber() << ",F:"
408419
<< BBI.FalseBB->getNumber() << ") ");
409-
RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
420+
RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
421+
Token->TClobbersPred,
422+
Token->FClobbersPred);
410423
DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n");
411424
if (RetVal) ++NumDiamonds;
412425
break;
@@ -677,10 +690,36 @@ static void countDuplicatedInstructions(
677690
}
678691
}
679692

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+
680717
/// ValidDiamond - Returns true if the 'true' and 'false' blocks (along
681718
/// 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 {
684723
Dups1 = Dups2 = 0;
685724
if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
686725
FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
@@ -701,8 +740,7 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
701740
return false;
702741

703742
// 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)
706744
return false;
707745

708746
// Count duplicate instructions at the beginning and end of the true and
@@ -714,6 +752,16 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
714752
countDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
715753
*TrueBBI.BB, *FalseBBI.BB,
716754
/* 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;
717765
return true;
718766
}
719767

@@ -841,11 +889,22 @@ void IfConverter::ScanInstructions(BBInfo &BBI,
841889

842890
/// Determine if the block is a suitable candidate to be predicated by the
843891
/// 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.
844899
bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
845900
SmallVectorImpl<MachineOperand> &Pred,
846-
bool isTriangle, bool RevBranch) {
901+
bool isTriangle, bool RevBranch,
902+
bool hasCommonTail) {
847903
// 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))
849908
return false;
850909

851910
// If it is already predicated but we couldn't analyze its terminator, the
@@ -859,7 +918,7 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
859918
if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate))
860919
return false;
861920

862-
if (BBI.BrCond.size()) {
921+
if (!hasCommonTail && BBI.BrCond.size()) {
863922
if (!isTriangle)
864923
return false;
865924

@@ -966,25 +1025,37 @@ void IfConverter::AnalyzeBlock(
9661025

9671026
BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB);
9681027

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) &&
9701032
MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
971-
TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
1033+
TrueBBICalc.ExtraCost),
1034+
TrueBBICalc.ExtraCost2,
9721035
*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+
}
9881059
}
9891060

9901061
if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) &&
@@ -1429,8 +1500,18 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
14291500
}
14301501

14311502
/// 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.
14321512
bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
1433-
unsigned NumDups1, unsigned NumDups2) {
1513+
unsigned NumDups1, unsigned NumDups2,
1514+
bool TClobbersPred, bool FClobbersPred) {
14341515
BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
14351516
BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
14361517
MachineBasicBlock *TailBB = TrueBBI.TrueBB;
@@ -1468,9 +1549,9 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
14681549

14691550
// Figure out the more profitable ordering.
14701551
bool DoSwap = false;
1471-
if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)
1552+
if (TClobbersPred && !FClobbersPred)
14721553
DoSwap = true;
1473-
else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {
1554+
else if (TClobbersPred == FClobbersPred) {
14741555
if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
14751556
DoSwap = true;
14761557
}

0 commit comments

Comments
 (0)