diff options
author | Diana Picus <diana.picus@linaro.org> | 2016-08-14 02:10:18 +0000 |
---|---|---|
committer | Diana Picus <diana.picus@linaro.org> | 2016-08-14 02:10:18 +0000 |
commit | 68be1eb885dd7cc47f534d5608cb9ddff5d722c3 (patch) | |
tree | 5c72a35880db33e152224a63165e7b4bd312b052 /llvm/lib/CodeGen/IfConversion.cpp | |
parent | 35ccf53e753fab6b1b0221502cd4fcee1de6a2e9 (diff) | |
download | bcm5719-llvm-68be1eb885dd7cc47f534d5608cb9ddff5d722c3.tar.gz bcm5719-llvm-68be1eb885dd7cc47f534d5608cb9ddff5d722c3.zip |
Revert "CodeGen: If Convert blocks that would form a diamond when tail-merged."
This reverts commit r278287.
This commit broke the clang-cmake-thumbv7-a15-full-sh bot.
See https://llvm.org/bugs/show_bug.cgi?id=28949
llvm-svn: 278621
Diffstat (limited to 'llvm/lib/CodeGen/IfConversion.cpp')
-rw-r--r-- | llvm/lib/CodeGen/IfConversion.cpp | 416 |
1 files changed, 65 insertions, 351 deletions
diff --git a/llvm/lib/CodeGen/IfConversion.cpp b/llvm/lib/CodeGen/IfConversion.cpp index 80d170689bf..5394b081aff 100644 --- a/llvm/lib/CodeGen/IfConversion.cpp +++ b/llvm/lib/CodeGen/IfConversion.cpp @@ -15,7 +15,6 @@ #include "llvm/CodeGen/Passes.h" #include "BranchFolding.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/LivePhysRegs.h" @@ -59,8 +58,6 @@ static cl::opt<bool> DisableTriangleFR("disable-ifcvt-triangle-false-rev", cl::init(false), cl::Hidden); static cl::opt<bool> DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden); -static cl::opt<bool> DisableForkedDiamond("disable-ifcvt-forked-diamond", - cl::init(false), cl::Hidden); static cl::opt<bool> IfCvtBranchFold("ifcvt-branch-fold", cl::init(true), cl::Hidden); @@ -71,7 +68,6 @@ STATISTIC(NumTriangleRev, "Number of triangle (R) if-conversions performed"); STATISTIC(NumTriangleFalse,"Number of triangle (F) if-conversions performed"); STATISTIC(NumTriangleFRev, "Number of triangle (F/R) if-conversions performed"); STATISTIC(NumDiamonds, "Number of diamond if-conversions performed"); -STATISTIC(NumForkedDiamonds, "Number of forked-diamond if-conversions performed"); STATISTIC(NumIfConvBBs, "Number of if-converted blocks"); STATISTIC(NumDupBBs, "Number of duplicated blocks"); STATISTIC(NumUnpred, "Number of true blocks of diamonds unpredicated"); @@ -86,9 +82,7 @@ namespace { ICTriangleRev, // Same as ICTriangle, but true path rev condition. ICTriangleFalse, // Same as ICTriangle, but on the false path. ICTriangle, // BB is entry of a triangle sub-CFG. - ICDiamond, // BB is entry of a diamond sub-CFG. - ICForkedDiamond // BB is entry of an almost diamond sub-CFG, with a - // common tail that can be shared. + ICDiamond // BB is entry of a diamond sub-CFG. }; /// BBInfo - One per MachineBasicBlock, this is used to cache the result @@ -120,7 +114,6 @@ namespace { bool IsAnalyzed : 1; bool IsEnqueued : 1; bool IsBrAnalyzable : 1; - bool IsBrReversible : 1; bool HasFallThrough : 1; bool IsUnpredicable : 1; bool CannotBeCopied : 1; @@ -135,10 +128,9 @@ namespace { SmallVector<MachineOperand, 4> Predicate; BBInfo() : IsDone(false), IsBeingAnalyzed(false), IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false), - IsBrReversible(false), HasFallThrough(false), - IsUnpredicable(false), CannotBeCopied(false), - ClobbersPred(false), NonPredSize(0), ExtraCost(0), - ExtraCost2(0), BB(nullptr), TrueBB(nullptr), + HasFallThrough(false), IsUnpredicable(false), + CannotBeCopied(false), ClobbersPred(false), NonPredSize(0), + ExtraCost(0), ExtraCost2(0), BB(nullptr), TrueBB(nullptr), FalseBB(nullptr) {} }; @@ -156,15 +148,11 @@ namespace { struct IfcvtToken { BBInfo &BBI; IfcvtKind Kind; + bool NeedSubsumption; unsigned NumDups; unsigned NumDups2; - bool NeedSubsumption : 1; - bool TClobbersPred : 1; - bool FClobbersPred : 1; - IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0, - bool tc = false, bool fc = false) - : BBI(b), Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s), - TClobbersPred(tc), FClobbersPred(fc) {} + IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0) + : BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {} }; /// BBAnalysis - Results of if-conversion feasibility analysis indexed by @@ -214,40 +202,23 @@ namespace { bool FalseBranch, unsigned &Dups, BranchProbability Prediction) const; bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned &Dups1, unsigned &Dups2, - BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const; - bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned &Dups1, unsigned &Dups2, - BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const; + unsigned &Dups1, unsigned &Dups2) const; void AnalyzeBranches(BBInfo &BBI); void ScanInstructions(BBInfo &BBI, MachineBasicBlock::iterator &Begin, MachineBasicBlock::iterator &End) const; - bool RescanInstructions( - MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB, - MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE, - BBInfo &TrueBBI, BBInfo &FalseBBI) const; void AnalyzeBlock(MachineBasicBlock *MBB, std::vector<std::unique_ptr<IfcvtToken>> &Tokens); bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Cond, - bool isTriangle = false, bool RevBranch = false, - bool hasCommonTail = false); + bool isTriangle = false, bool RevBranch = false); void AnalyzeBlocks(MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens); void InvalidatePreds(MachineBasicBlock *BB); void RemoveExtraEdges(BBInfo &BBI); bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind); bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind); - bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned NumDups1, unsigned NumDups2, - bool TClobbersPred, bool FClobbersPred, - bool RemoveTrueBranch, bool RemoveFalseBranch, - bool MergeAddEdges); bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, unsigned NumDups1, unsigned NumDups2); - bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind, - unsigned NumDups1, unsigned NumDups2, - bool TClobbers, bool FClobbers); void PredicateBlock(BBInfo &BBI, MachineBasicBlock::iterator E, SmallVectorImpl<MachineOperand> &Cond, @@ -439,19 +410,6 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { if (RetVal) ++NumDiamonds; break; } - case ICForkedDiamond: { - if (DisableForkedDiamond) break; - DEBUG(dbgs() << "Ifcvt (Forked Diamond): BB#" - << BBI.BB->getNumber() << " (T:" - << BBI.TrueBB->getNumber() << ",F:" - << BBI.FalseBB->getNumber() << ") "); - RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2, - Token->TClobbersPred, - Token->FClobbersPred); - DEBUG(dbgs() << (RetVal ? "succeeded!" : "failed!") << "\n"); - if (RetVal) ++NumForkedDiamonds; - break; - } } Change |= RetVal; @@ -653,13 +611,6 @@ static void countDuplicatedInstructions( return; --TIE; --FIE; - // Upon exit TIE and FIE will both point at the last non-shared instruction, - // they need to be moved forward to point past the last non-shared - // instruction. - auto IncrementEndIteratorsOnExit = make_scope_exit([&]() { - ++TIE; ++FIE; - }); - if (!TBB.succ_empty() || !FBB.succ_empty()) { if (SkipConditionalBranches) { while (TIE != TIB && TIE->isBranch()) @@ -697,125 +648,10 @@ static void countDuplicatedInstructions( } } -/// RescanInstructions - Run ScanInstructions on a pair of blocks. -/// @param TIB - True Iterator Begin, points to first non-shared instruction -/// @param FIB - False Iterator Begin, points to first non-shared instruction -/// @param TIE - True Iterator End, points past last non-shared instruction -/// @param FIE - False Iterator End, points past last non-shared instruction -/// @param TrueBBI - BBInfo to update for the true block. -/// @param FalseBBI - BBInfo to update for the false block. -/// @returns - false if either block cannot be predicated or if both blocks end -/// with a predicate-clobbering instruction. -bool IfConverter::RescanInstructions( - MachineBasicBlock::iterator &TIB, MachineBasicBlock::iterator &FIB, - MachineBasicBlock::iterator &TIE, MachineBasicBlock::iterator &FIE, - BBInfo &TrueBBI, BBInfo &FalseBBI) const { - ScanInstructions(TrueBBI, TIB, TIE); - if (TrueBBI.IsUnpredicable) - return false; - ScanInstructions(FalseBBI, FIB, FIE); - if (FalseBBI.IsUnpredicable) - return false; - if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred) - return false; - return true; -} - -/// ValidForkedDiamond - Returns true if the 'true' and 'false' blocks (along -/// with their common predecessor) form a diamond if a common tail block is -/// extracted. -/// While not strictly a diamond, this pattern would form a diamond if -/// tail-merging had merged the shared tails. -/// EBB -/// _/ \_ -/// | | -/// TBB FBB -/// / \ / \ -/// FalseBB TrueBB FalseBB -/// Currently only handles analyzable branches. -/// Specifically excludes actual diamonds to avoid overlap. -bool IfConverter::ValidForkedDiamond( - BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned &Dups1, unsigned &Dups2, - BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const { - Dups1 = Dups2 = 0; - if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone || - FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone) - return false; - - if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable) - return false; - // Don't IfConvert blocks that can't be folded into their predecessor. - if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) - return false; - - // This function is specifically looking for conditional tails, as - // unconditional tails are already handled by the standard diamond case. - if (TrueBBI.BrCond.size() == 0 || - FalseBBI.BrCond.size() == 0) - return false; - - MachineBasicBlock *TT = TrueBBI.TrueBB; - MachineBasicBlock *TF = TrueBBI.FalseBB; - MachineBasicBlock *FT = FalseBBI.TrueBB; - MachineBasicBlock *FF = FalseBBI.FalseBB; - - if (!TT) - TT = getNextBlock(TrueBBI.BB); - if (!TF) - TF = getNextBlock(TrueBBI.BB); - if (!FT) - FT = getNextBlock(FalseBBI.BB); - if (!FF) - FF = getNextBlock(FalseBBI.BB); - - if (!TT || !TF) - return false; - - // Check successors. If they don't match, bail. - if (!((TT == FT && TF == FF) || (TF == FT && TT == FF))) - return false; - - bool FalseReversed = false; - if (TF == FT && TT == FF) { - // If the branches are opposing, but we can't reverse, don't do it. - if (!FalseBBI.IsBrReversible) - return false; - FalseReversed = true; - ReverseBranchCondition(FalseBBI); - } - auto UnReverseOnExit = make_scope_exit([&]() { - if (FalseReversed) - ReverseBranchCondition(FalseBBI); - }); - - // Count duplicate instructions at the beginning of the true and false blocks. - MachineBasicBlock::iterator TIB = TrueBBI.BB->begin(); - MachineBasicBlock::iterator FIB = FalseBBI.BB->begin(); - MachineBasicBlock::iterator TIE = TrueBBI.BB->end(); - MachineBasicBlock::iterator FIE = FalseBBI.BB->end(); - countDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2, - *TrueBBI.BB, *FalseBBI.BB, - /* SkipConditionalBranches */ false); - - TrueBBICalc.BB = TrueBBI.BB; - FalseBBICalc.BB = FalseBBI.BB; - if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc)) - return false; - // The size is used to decide whether to if-convert, and the shared portions - // are subtracted off. Because of the subtraction, we just use the size that - // was calculated by the original ScanInstructions, as it is correct. - TrueBBICalc.NonPredSize = TrueBBI.NonPredSize; - FalseBBICalc.NonPredSize = FalseBBI.NonPredSize; - return true; -} - /// ValidDiamond - Returns true if the 'true' and 'false' blocks (along /// with their common predecessor) forms a valid diamond shape for ifcvt. -bool IfConverter::ValidDiamond( - BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned &Dups1, unsigned &Dups2, - BBInfo &TrueBBICalc, BBInfo &FalseBBICalc) const { +bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, + unsigned &Dups1, unsigned &Dups2) const { Dups1 = Dups2 = 0; if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone || FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone) @@ -836,7 +672,8 @@ bool IfConverter::ValidDiamond( return false; // FIXME: Allow true block to have an early exit? - if (TrueBBI.FalseBB || FalseBBI.FalseBB) + if (TrueBBI.FalseBB || FalseBBI.FalseBB || + (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)) return false; // Count duplicate instructions at the beginning and end of the true and @@ -848,16 +685,6 @@ bool IfConverter::ValidDiamond( countDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2, *TrueBBI.BB, *FalseBBI.BB, /* SkipConditionalBranches */ true); - - TrueBBICalc.BB = TrueBBI.BB; - FalseBBICalc.BB = FalseBBI.BB; - if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc)) - return false; - // The size is used to decide whether to if-convert, and the shared portions - // are subtracted off. Because of the subtraction, we just use the size that - // was calculated by the original ScanInstructions, as it is correct. - TrueBBICalc.NonPredSize = TrueBBI.NonPredSize; - FalseBBICalc.NonPredSize = FalseBBI.NonPredSize; return true; } @@ -871,9 +698,6 @@ void IfConverter::AnalyzeBranches(BBInfo &BBI) { BBI.BrCond.clear(); BBI.IsBrAnalyzable = !TII->analyzeBranch(*BBI.BB, BBI.TrueBB, BBI.FalseBB, BBI.BrCond); - SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end()); - BBI.IsBrReversible = (RevCond.size() == 0) || - !TII->ReverseBranchCondition(RevCond); BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == nullptr; if (BBI.BrCond.size()) { @@ -989,22 +813,11 @@ void IfConverter::ScanInstructions(BBInfo &BBI, /// FeasibilityAnalysis - Determine if the block is a suitable candidate to be /// predicated by the specified predicate. -/// @param BBI BBInfo for the block to check -/// @param Pred Predicate array for the branch that leads to BBI -/// @param isTriangle true if the Analysis is for a triangle -/// @param RevBranch true if Reverse(Pred) leads to BBI (e.g. BBI is the false -/// case -/// @param hasCommonTail true if BBI shares a tail with a sibling block that -/// contains any instruction that would make the block unpredicable. bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Pred, - bool isTriangle, bool RevBranch, - bool hasCommonTail) { + bool isTriangle, bool RevBranch) { // If the block is dead or unpredicable, then it cannot be predicated. - // Two blocks may share a common unpredicable tail, but this doesn't prevent - // them from being if-converted. The non-shared portion is assumed to have - // been checked - if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail)) + if (BBI.IsDone || BBI.IsUnpredicable) return false; // If it is already predicated but we couldn't analyze its terminator, the @@ -1018,7 +831,7 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, if (BBI.Predicate.size() && !TII->SubsumesPredicate(Pred, BBI.Predicate)) return false; - if (!hasCommonTail && BBI.BrCond.size()) { + if (BBI.BrCond.size()) { if (!isTriangle) return false; @@ -1126,58 +939,25 @@ void IfConverter::AnalyzeBlock( BranchProbability Prediction = MBPI->getEdgeProbability(BB, TrueBBI.BB); - if (CanRevCond) { - BBInfo TrueBBICalc, FalseBBICalc; - auto feasibleDiamond = [&]() { - return ( - MeetIfcvtSizeLimit( - *TrueBBI.BB, (TrueBBICalc.NonPredSize - (Dups + Dups2) + - TrueBBICalc.ExtraCost), TrueBBICalc.ExtraCost2, - *FalseBBI.BB, (FalseBBICalc.NonPredSize - (Dups + Dups2) + - FalseBBICalc.ExtraCost), FalseBBICalc.ExtraCost2, - Prediction) && - FeasibilityAnalysis(TrueBBI, BBI.BrCond, - /* IsTriangle */ false, /* RevCond */ false, - /* hasCommonTail */ true) && - FeasibilityAnalysis(FalseBBI, RevCond, - /* IsTriangle */ false, /* RevCond */ false, - /* hasCommonTail */ true)); - }; - - if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2, - TrueBBICalc, FalseBBICalc)) { - if (feasibleDiamond()) { - // Diamond: - // EBB - // / \_ - // | | - // TBB FBB - // \ / - // TailBB - // Note TailBB can be empty. - Tokens.push_back(llvm::make_unique<IfcvtToken>( - BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2)); - Enqueued = true; - } - } else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2, - TrueBBICalc, FalseBBICalc)) { - if (feasibleDiamond()) { - // ForkedDiamond: - // if TBB and FBB have a common tail that includes their conditional - // branch instructions, then we can If Convert this pattern. - // EBB - // _/ \_ - // | | - // TBB FBB - // / \ / \ - // FalseBB TrueBB FalseBB - // - Tokens.push_back(llvm::make_unique<IfcvtToken>( - BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2, - (bool) TrueBBICalc.ClobbersPred, (bool) FalseBBICalc.ClobbersPred)); - Enqueued = true; - } - } + if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) && + MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) + + TrueBBI.ExtraCost), TrueBBI.ExtraCost2, + *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) + + FalseBBI.ExtraCost),FalseBBI.ExtraCost2, + Prediction) && + FeasibilityAnalysis(TrueBBI, BBI.BrCond) && + FeasibilityAnalysis(FalseBBI, RevCond)) { + // Diamond: + // EBB + // / \_ + // | | + // TBB FBB + // \ / + // TailBB + // Note TailBB can be empty. + Tokens.push_back(llvm::make_unique<IfcvtToken>( + BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2)); + Enqueued = true; } if (ValidTriangle(TrueBBI, FalseBBI, false, Dups, Prediction) && @@ -1629,26 +1409,23 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { return true; } -/// IfConvertDiamondCommon - Common code shared between diamond conversions. -/// BBI, TrueBBI, and FalseBBI form the diamond shape. -/// NumDups1 - number of shared instructions at the beginning of TrueBBI and -/// FalseBBI -/// NumDups2 - number of shared instructions at the end of TrueBBI and FalseBBI -/// RemoveTrueBranch - Remove the branch of the true block before predicating -/// Only false for unanalyzable fallthrough cases. -/// RemoveFalseBranch - Remove the branch of the false block before predicating -/// Only false for unanalyzable fallthrough cases. -/// MergeAddEdges - Add successor edges when merging blocks. Only false for -/// unanalyzable fallthrough -bool IfConverter::IfConvertDiamondCommon( - BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI, - unsigned NumDups1, unsigned NumDups2, - bool TClobbersPred, bool FClobbersPred, - bool RemoveTrueBranch, bool RemoveFalseBranch, - bool MergeAddEdges) { +/// IfConvertDiamond - If convert a diamond sub-CFG. +/// +bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, + unsigned NumDups1, unsigned NumDups2) { + BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; + BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; + MachineBasicBlock *TailBB = TrueBBI.TrueBB; + // True block must fall through or end with an unanalyzable terminator. + if (!TailBB) { + if (blockAlwaysFallThrough(TrueBBI)) + TailBB = FalseBBI.TrueBB; + assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!"); + } if (TrueBBI.IsDone || FalseBBI.IsDone || - TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) { + TrueBBI.BB->pred_size() > 1 || + FalseBBI.BB->pred_size() > 1) { // Something has changed. It's no longer safe to predicate these blocks. BBI.IsAnalyzed = false; TrueBBI.IsAnalyzed = false; @@ -1673,16 +1450,15 @@ bool IfConverter::IfConvertDiamondCommon( // Figure out the more profitable ordering. bool DoSwap = false; - if (TClobbersPred && !FClobbersPred) + if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred) DoSwap = true; - else if (TClobbersPred == FClobbersPred) { + else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) { if (TrueBBI.NonPredSize > FalseBBI.NonPredSize) DoSwap = true; } if (DoSwap) { std::swap(BBI1, BBI2); std::swap(Cond1, Cond2); - std::swap(RemoveTrueBranch, RemoveFalseBranch); } // Remove the conditional branch from entry to the blocks. @@ -1734,7 +1510,11 @@ bool IfConverter::IfConvertDiamondCommon( BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1); BBI2->BB->erase(BBI2->BB->begin(), DI2); - if (RemoveTrueBranch) + // Remove branch from the 'true' block, unless it was not analyzable. + // Non-analyzable branches need to be preserved, since in such cases, + // the CFG structure is not an actual diamond (the join block may not + // be present). + if (BBI1->IsBrAnalyzable) BBI1->NonPredSize -= TII->RemoveBranch(*BBI1->BB); // Remove duplicated instructions. DI1 = BBI1->BB->end(); @@ -1753,9 +1533,9 @@ bool IfConverter::IfConvertDiamondCommon( // must be removed. RemoveKills(BBI1->BB->begin(), BBI1->BB->end(), DontKill, *TRI); - // Remove 'false' block branch, and find the last instruction to predicate. - // Save the debug location. - if (RemoveFalseBranch) + // Remove 'false' block branch (unless it was not analyzable), and find + // the last instruction to predicate. + if (BBI2->IsBrAnalyzable) BBI2->NonPredSize -= TII->RemoveBranch(*BBI2->BB); DI2 = BBI2->BB->end(); while (NumDups2 != 0) { @@ -1831,74 +1611,8 @@ bool IfConverter::IfConvertDiamondCommon( PredicateBlock(*BBI2, DI2, *Cond2); // Merge the true block into the entry of the diamond. - MergeBlocks(BBI, *BBI1, MergeAddEdges); - MergeBlocks(BBI, *BBI2, MergeAddEdges); - return true; -} - -/// IfConvertForkedDiamond - If convert an almost-diamond sub-CFG where the true -/// and false blocks share a common tail. -bool IfConverter::IfConvertForkedDiamond( - BBInfo &BBI, IfcvtKind Kind, - unsigned NumDups1, unsigned NumDups2, - bool TClobbersPred, bool FClobbersPred) { - BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; - BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; - - // Save the debug location for later. - DebugLoc dl; - MachineBasicBlock::iterator TIE = TrueBBI.BB->getFirstTerminator(); - if (TIE != TrueBBI.BB->end()) - dl = TIE->getDebugLoc(); - // Removing branches from both blocks is safe, because we have already - // determined that both blocks have the same branch instructions. The branch - // will be added back at the end, unpredicated. - if (!IfConvertDiamondCommon( - BBI, TrueBBI, FalseBBI, - NumDups1, NumDups2, - TClobbersPred, FClobbersPred, - /* RemoveTrueBranch */ true, /* RemoveFalseBranch */ true, - /* MergeAddEdges */ true)) - return false; - - // Add back the branch. - // Debug location saved above when removing the branch from BBI2 - TII->InsertBranch(*BBI.BB, TrueBBI.TrueBB, TrueBBI.FalseBB, - TrueBBI.BrCond, dl); - - RemoveExtraEdges(BBI); - - // Update block info. - BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone = true; - InvalidatePreds(BBI.BB); - - // FIXME: Must maintain LiveIns. - return true; -} - -/// IfConvertDiamond - If convert a diamond sub-CFG. -/// -bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, - unsigned NumDups1, unsigned NumDups2) { - BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; - BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; - MachineBasicBlock *TailBB = TrueBBI.TrueBB; - - // True block must fall through or end with an unanalyzable terminator. - if (!TailBB) { - if (blockAlwaysFallThrough(TrueBBI)) - TailBB = FalseBBI.TrueBB; - assert((TailBB || !TrueBBI.IsBrAnalyzable) && "Unexpected!"); - } - - if (!IfConvertDiamondCommon( - BBI, TrueBBI, FalseBBI, - NumDups1, NumDups2, - TrueBBI.ClobbersPred, FalseBBI.ClobbersPred, - /* RemoveTrueBranch */ TrueBBI.IsBrAnalyzable, - /* RemoveFalseBranch */ FalseBBI.IsBrAnalyzable, - /* MergeAddEdges */ TailBB == nullptr)) - return false; + MergeBlocks(BBI, *BBI1, TailBB == nullptr); + MergeBlocks(BBI, *BBI2, TailBB == nullptr); // If the if-converted block falls through or unconditionally branches into // the tail block, and the tail block does not have other predecessors, then @@ -1921,7 +1635,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, CanMergeTail = false; else if (NumPreds == 1 && CanMergeTail) { MachineBasicBlock::pred_iterator PI = TailBB->pred_begin(); - if (*PI != TrueBBI.BB && *PI != FalseBBI.BB) + if (*PI != BBI1->BB && *PI != BBI2->BB) CanMergeTail = false; } if (CanMergeTail) { @@ -1937,8 +1651,8 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, // RemoveExtraEdges won't work if the block has an unanalyzable branch, // which can happen here if TailBB is unanalyzable and is merged, so // explicitly remove BBI1 and BBI2 as successors. - BBI.BB->removeSuccessor(TrueBBI.BB); - BBI.BB->removeSuccessor(FalseBBI.BB, /* NormalizeSuccessProbs */ true); + BBI.BB->removeSuccessor(BBI1->BB); + BBI.BB->removeSuccessor(BBI2->BB, true); RemoveExtraEdges(BBI); // Update block info. |