X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FIfConversion.cpp;h=9dbd6d1241caabd354e4b2fb2c571bc43946ba86;hb=9390cd0e86cb3b79f6836acab2a27b275e5bde9e;hp=fb53377b98ba0959468d0a9fca07bb1f77f003c0;hpb=303595942502f17c087fa28874c2b89117148c45;p=oota-llvm.git diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index fb53377b98b..9dbd6d1241c 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -21,6 +21,8 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/DepthFirstIterator.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -56,7 +58,7 @@ STATISTIC(NumIfConvBBs, "Number of if-converted blocks"); STATISTIC(NumDupBBs, "Number of duplicated blocks"); namespace { - class IfConverter : public MachineFunctionPass { + class VISIBILITY_HIDDEN IfConverter : public MachineFunctionPass { enum IfcvtKind { ICNotClassfied, // BB data valid, but not classified. ICSimpleFalse, // Same as ICSimple, but on the false path. @@ -103,8 +105,8 @@ namespace { MachineBasicBlock *BB; MachineBasicBlock *TrueBB; MachineBasicBlock *FalseBB; - std::vector BrCond; - std::vector Predicate; + SmallVector BrCond; + SmallVector Predicate; BBInfo() : IsDone(false), IsBeingAnalyzed(false), IsAnalyzed(false), IsEnqueued(false), IsBrAnalyzable(false), HasFallThrough(false), IsUnpredicable(false), @@ -115,7 +117,7 @@ namespace { /// IfcvtToken - Record information about pending if-conversions to attemp: /// BBI - Corresponding BBInfo. /// Kind - Type of block. See IfcvtKind. - /// NeedSubsumsion - True if the to be predicated BB has already been + /// NeedSubsumption - True if the to-be-predicated BB has already been /// predicated. /// NumDups - Number of instructions that would be duplicated due /// to this if-conversion. (For diamonds, the number of @@ -126,11 +128,11 @@ namespace { struct IfcvtToken { BBInfo &BBI; IfcvtKind Kind; - bool NeedSubsumsion; + bool NeedSubsumption; unsigned NumDups; unsigned NumDups2; IfcvtToken(BBInfo &b, IfcvtKind k, bool s, unsigned d, unsigned d2 = 0) - : BBI(b), Kind(k), NeedSubsumsion(s), NumDups(d), NumDups2(d2) {} + : BBI(b), Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {} }; /// Roots - Basic blocks that do not have successors. These are the starting @@ -144,12 +146,13 @@ namespace { const TargetLowering *TLI; const TargetInstrInfo *TII; bool MadeChange; + int FnNum; public: static char ID; - IfConverter() : MachineFunctionPass((intptr_t)&ID) {} + IfConverter() : MachineFunctionPass(&ID), FnNum(-1) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "If converter"; } + virtual const char *getPassName() const { return "If Converter"; } private: bool ReverseBranchCondition(BBInfo &BBI); @@ -161,7 +164,7 @@ namespace { void ScanInstructions(BBInfo &BBI); BBInfo &AnalyzeBlock(MachineBasicBlock *BB, std::vector &Tokens); - bool FeasibilityAnalysis(BBInfo &BBI, std::vector &Cond, + bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl &Cond, bool isTriangle = false, bool RevBranch = false); bool AnalyzeBlocks(MachineFunction &MF, std::vector &Tokens); @@ -173,9 +176,9 @@ namespace { unsigned NumDups1, unsigned NumDups2); void PredicateBlock(BBInfo &BBI, MachineBasicBlock::iterator E, - std::vector &Cond); + SmallVectorImpl &Cond); void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, - std::vector &Cond, + SmallVectorImpl &Cond, bool IgnoreBr = false); void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI); @@ -197,10 +200,10 @@ namespace { if (Incr1 > Incr2) return true; else if (Incr1 == Incr2) { - // Favors subsumsion. - if (C1->NeedSubsumsion == false && C2->NeedSubsumsion == true) + // Favors subsumption. + if (C1->NeedSubsumption == false && C2->NeedSubsumption == true) return true; - else if (C1->NeedSubsumsion == C2->NeedSubsumsion) { + else if (C1->NeedSubsumption == C2->NeedSubsumption) { // Favors diamond over triangle, etc. if ((unsigned)C1->Kind < (unsigned)C2->Kind) return true; @@ -215,6 +218,9 @@ namespace { char IfConverter::ID = 0; } +static RegisterPass +X("if-converter", "If Converter"); + FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); } bool IfConverter::runOnMachineFunction(MachineFunction &MF) { @@ -222,9 +228,8 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); if (!TII) return false; - static int FnNum = -1; - DOUT << "\nIfcvt: function (" << ++FnNum << ") \'" - << MF.getFunction()->getName() << "\'"; + DEBUG(errs() << "\nIfcvt: function (" << ++FnNum << ") \'" + << MF.getFunction()->getName() << "\'"); if (FnNum < IfCvtFnStart || (IfCvtFnStop != -1 && FnNum > IfCvtFnStop)) { DOUT << " skipped\n"; @@ -245,14 +250,18 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds; while (IfCvtLimit == -1 || (int)NumIfCvts < IfCvtLimit) { - // Do an intial analysis for each basic block and finding all the potential - // candidates to perform if-convesion. + // Do an initial analysis for each basic block and find all the potential + // candidates to perform if-conversion. bool Change = AnalyzeBlocks(MF, Tokens); while (!Tokens.empty()) { IfcvtToken *Token = Tokens.back(); Tokens.pop_back(); BBInfo &BBI = Token->BBI; IfcvtKind Kind = Token->Kind; + unsigned NumDups = Token->NumDups; + unsigned NumDups2 = Token->NumDups2; + + delete Token; // If the block has been evicted out of the queue or it has already been // marked dead (due to it being predicated), then skip it. @@ -278,9 +287,10 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { : BBI.TrueBB->getNumber()) << ") "; RetVal = IfConvertSimple(BBI, Kind); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; - if (RetVal) + if (RetVal) { if (isFalse) NumSimpleFalse++; else NumSimple++; + } break; } case ICTriangle: @@ -319,7 +329,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { DOUT << "Ifcvt (Diamond): BB#" << BBI.BB->getNumber() << " (T:" << BBI.TrueBB->getNumber() << ",F:" << BBI.FalseBB->getNumber() << ") "; - RetVal = IfConvertDiamond(BBI, Kind, Token->NumDups, Token->NumDups2); + RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2); DOUT << (RetVal ? "succeeded!" : "failed!") << "\n"; if (RetVal) NumDiamonds++; break; @@ -367,7 +377,7 @@ static MachineBasicBlock *findFalseBlock(MachineBasicBlock *BB, } /// ReverseBranchCondition - Reverse the condition of the end of the block -/// branchs. Swap block's 'true' and 'false' successors. +/// branch. Swap block's 'true' and 'false' successors. bool IfConverter::ReverseBranchCondition(BBInfo &BBI) { if (!TII->ReverseBranchCondition(BBI.BrCond)) { TII->RemoveBranch(*BBI.BB); @@ -429,7 +439,7 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, unsigned Size = TrueBBI.NonPredSize; if (TrueBBI.IsBrAnalyzable) { if (TrueBBI.TrueBB && TrueBBI.BrCond.empty()) - // End with an unconditional branch. It will be removed. + // Ends with an unconditional branch. It will be removed. --Size; else { MachineBasicBlock *FExit = FalseBranch @@ -539,13 +549,16 @@ void IfConverter::ScanInstructions(BBInfo &BBI) { // fallthrough. if (!BBI.FalseBB) BBI.FalseBB = findFalseBlock(BBI.BB, BBI.TrueBB); - assert(BBI.FalseBB && "Expected to find the fallthrough block!"); + if (!BBI.FalseBB) { + // Malformed bcc? True and false blocks are the same? + BBI.IsUnpredicable = true; + return; + } } // Then scan all the instructions. BBI.NonPredSize = 0; BBI.ClobbersPred = false; - bool SeenCondBr = false; for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); I != E; ++I) { const TargetInstrDesc &TID = I->getDesc(); @@ -565,16 +578,13 @@ void IfConverter::ScanInstructions(BBInfo &BBI) { BBI.IsUnpredicable = true; return; } - } if (BBI.ClobbersPred && !isPredicated) { // Predicate modification instruction should end the block (except for // already predicated instructions and end of block branches). if (isCondBr) { - SeenCondBr = true; - - // Conditional branches is not predicable. But it may be eliminated. + // A conditional branch is not predicable, but it may be eliminated. continue; } @@ -600,7 +610,7 @@ void IfConverter::ScanInstructions(BBInfo &BBI) { /// FeasibilityAnalysis - Determine if the block is a suitable candidate to be /// predicated by the specified predicate. bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, - std::vector &Pred, + SmallVectorImpl &Pred, bool isTriangle, bool RevBranch) { // If the block is dead or unpredicable, then it cannot be predicated. if (BBI.IsDone || BBI.IsUnpredicable) @@ -615,9 +625,9 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, if (!isTriangle) return false; - // Test predicate subsumsion. - std::vector RevPred(Pred); - std::vector Cond(BBI.BrCond); + // Test predicate subsumption. + SmallVector RevPred(Pred.begin(), Pred.end()); + SmallVector Cond(BBI.BrCond.begin(), BBI.BrCond.end()); if (RevBranch) { if (TII->ReverseBranchCondition(Cond)) return false; @@ -645,7 +655,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, ScanInstructions(BBI); - // Unanalyable or ends with fallthrough or unconditional branch. + // Unanalyzable or ends with fallthrough or unconditional branch. if (!BBI.IsBrAnalyzable || BBI.BrCond.empty()) { BBI.IsBeingAnalyzed = false; BBI.IsAnalyzed = true; @@ -659,6 +669,13 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, return BBI; } + // Do not ifcvt if true and false fallthrough blocks are the same. + if (!BBI.FalseBB) { + BBI.IsBeingAnalyzed = false; + BBI.IsAnalyzed = true; + return BBI; + } + BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens); BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens); @@ -668,7 +685,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, return BBI; } - std::vector RevCond(BBI.BrCond); + SmallVector RevCond(BBI.BrCond.begin(), BBI.BrCond.end()); bool CanRevCond = !TII->ReverseBranchCondition(RevCond); unsigned Dups = 0; @@ -811,7 +828,7 @@ void IfConverter::InvalidatePreds(MachineBasicBlock *BB) { /// static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB, const TargetInstrInfo *TII) { - std::vector NoCond; + SmallVector NoCond; TII->InsertBranch(*BB, ToBB, NULL, NoCond); } @@ -819,7 +836,7 @@ static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB, /// successors. void IfConverter::RemoveExtraEdges(BBInfo &BBI) { MachineBasicBlock *TBB = NULL, *FBB = NULL; - std::vector Cond; + SmallVector Cond; if (!TII->AnalyzeBranch(*BBI.BB, TBB, FBB, Cond)) BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); } @@ -832,7 +849,7 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) { BBInfo *CvtBBI = &TrueBBI; BBInfo *NextBBI = &FalseBBI; - std::vector Cond(BBI.BrCond); + SmallVector Cond(BBI.BrCond.begin(), BBI.BrCond.end()); if (Kind == ICSimpleFalse) std::swap(CvtBBI, NextBBI); @@ -845,11 +862,12 @@ bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) { } if (Kind == ICSimpleFalse) - TII->ReverseBranchCondition(Cond); + if (TII->ReverseBranchCondition(Cond)) + assert(false && "Unable to reverse branch condition!"); if (CvtBBI->BB->pred_size() > 1) { BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); - // Copy instructions in the true block, predicate them add them to + // Copy instructions in the true block, predicate them, and add them to // the entry block. CopyAndPredicateBlock(BBI, *CvtBBI, Cond); } else { @@ -897,7 +915,7 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { BBInfo *CvtBBI = &TrueBBI; BBInfo *NextBBI = &FalseBBI; - std::vector Cond(BBI.BrCond); + SmallVector Cond(BBI.BrCond.begin(), BBI.BrCond.end()); if (Kind == ICTriangleFalse || Kind == ICTriangleFRev) std::swap(CvtBBI, NextBBI); @@ -910,21 +928,23 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { } if (Kind == ICTriangleFalse || Kind == ICTriangleFRev) - TII->ReverseBranchCondition(Cond); + if (TII->ReverseBranchCondition(Cond)) + assert(false && "Unable to reverse branch condition!"); if (Kind == ICTriangleRev || Kind == ICTriangleFRev) { - ReverseBranchCondition(*CvtBBI); - // BB has been changed, modify its predecessors (except for this - // one) so they don't get ifcvt'ed based on bad intel. - for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(), - E = CvtBBI->BB->pred_end(); PI != E; ++PI) { - MachineBasicBlock *PBB = *PI; - if (PBB == BBI.BB) - continue; - BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; - if (PBBI.IsEnqueued) { - PBBI.IsAnalyzed = false; - PBBI.IsEnqueued = false; + if (ReverseBranchCondition(*CvtBBI)) { + // BB has been changed, modify its predecessors (except for this + // one) so they don't get ifcvt'ed based on bad intel. + for (MachineBasicBlock::pred_iterator PI = CvtBBI->BB->pred_begin(), + E = CvtBBI->BB->pred_end(); PI != E; ++PI) { + MachineBasicBlock *PBB = *PI; + if (PBB == BBI.BB) + continue; + BBInfo &PBBI = BBAnalysis[PBB->getNumber()]; + if (PBBI.IsEnqueued) { + PBBI.IsAnalyzed = false; + PBBI.IsEnqueued = false; + } } } } @@ -933,16 +953,14 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { bool DupBB = CvtBBI->BB->pred_size() > 1; if (DupBB) { BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); - // Copy instructions in the true block, predicate them add them to + // Copy instructions in the true block, predicate them, and add them to // the entry block. CopyAndPredicateBlock(BBI, *CvtBBI, Cond, true); } else { // Predicate the 'true' block after removing its branch. CvtBBI->NonPredSize -= TII->RemoveBranch(*CvtBBI->BB); PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond); - } - if (!DupBB) { // Now merge the entry of the triangle with the true block. BBI.NonPredSize -= TII->RemoveBranch(*BBI.BB); MergeBlocks(BBI, *CvtBBI); @@ -950,7 +968,8 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { // If 'true' block has a 'false' successor, add an exit branch to it. if (HasEarlyExit) { - std::vector RevCond(CvtBBI->BrCond); + SmallVector RevCond(CvtBBI->BrCond.begin(), + CvtBBI->BrCond.end()); if (TII->ReverseBranchCondition(RevCond)) assert(false && "Unable to reverse branch condition!"); TII->InsertBranch(*BBI.BB, CvtBBI->FalseBB, NULL, RevCond); @@ -958,7 +977,7 @@ bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) { } // Merge in the 'false' block if the 'false' block has no other - // predecessors. Otherwise, add a unconditional branch from to 'false'. + // predecessors. Otherwise, add an unconditional branch to 'false'. bool FalseBBDead = false; bool IterIfcvt = true; bool isFallThrough = canFallThroughTo(BBI.BB, NextBBI->BB); @@ -1000,7 +1019,7 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()]; BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()]; MachineBasicBlock *TailBB = TrueBBI.TrueBB; - // True block must fall through or ended with unanalyzable terminator. + // True block must fall through or end with an unanalyzable terminator. if (!TailBB) { if (blockAlwaysFallThrough(TrueBBI)) TailBB = FalseBBI.TrueBB; @@ -1022,10 +1041,11 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, // block would clobber the predicate, in that case, do the opposite. BBInfo *BBI1 = &TrueBBI; BBInfo *BBI2 = &FalseBBI; - std::vector RevCond(BBI.BrCond); - TII->ReverseBranchCondition(RevCond); - std::vector *Cond1 = &BBI.BrCond; - std::vector *Cond2 = &RevCond; + SmallVector RevCond(BBI.BrCond.begin(), BBI.BrCond.end()); + if (TII->ReverseBranchCondition(RevCond)) + assert(false && "Unable to reverse branch condition!"); + SmallVector *Cond1 = &BBI.BrCond; + SmallVector *Cond2 = &RevCond; // Figure out the more profitable ordering. bool DoSwap = false; @@ -1077,8 +1097,8 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, MergeBlocks(BBI, *BBI1); MergeBlocks(BBI, *BBI2); - // If the if-converted block fallthrough or unconditionally branch into the - // tail block, and the tail block does not have other predecessors, then + // If the if-converted block falls through or unconditionally branches into + // the tail block, and the tail block does not have other predecessors, then // fold the tail block in as well. Otherwise, unless it falls through to the // tail, add a unconditional branch to it. if (TailBB) { @@ -1107,13 +1127,15 @@ bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind, /// specified end with the specified condition. void IfConverter::PredicateBlock(BBInfo &BBI, MachineBasicBlock::iterator E, - std::vector &Cond) { + SmallVectorImpl &Cond) { for (MachineBasicBlock::iterator I = BBI.BB->begin(); I != E; ++I) { if (TII->isPredicated(I)) continue; if (!TII->PredicateInstruction(I, Cond)) { +#ifndef NDEBUG cerr << "Unable to predicate " << *I << "!\n"; - abort(); +#endif + llvm_unreachable(0); } } @@ -1128,8 +1150,10 @@ void IfConverter::PredicateBlock(BBInfo &BBI, /// CopyAndPredicateBlock - Copy and predicate instructions from source BB to /// the destination block. Skip end of block branches if IgnoreBr is true. void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, - std::vector &Cond, + SmallVectorImpl &Cond, bool IgnoreBr) { + MachineFunction &MF = *ToBBI.BB->getParent(); + for (MachineBasicBlock::iterator I = FromBBI.BB->begin(), E = FromBBI.BB->end(); I != E; ++I) { const TargetInstrDesc &TID = I->getDesc(); @@ -1138,14 +1162,16 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, if (IgnoreBr && !isPredicated && TID.isBranch()) break; - MachineInstr *MI = I->clone(); + MachineInstr *MI = MF.CloneMachineInstr(I); ToBBI.BB->insert(ToBBI.BB->end(), MI); ToBBI.NonPredSize++; if (!isPredicated) if (!TII->PredicateInstruction(MI, Cond)) { - cerr << "Unable to predicate " << *MI << "!\n"; - abort(); +#ifndef NDEBUG + cerr << "Unable to predicate " << *I << "!\n"; +#endif + llvm_unreachable(0); } } @@ -1159,8 +1185,7 @@ void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI, // Fallthrough edge can't be transferred. if (Succ == FallThrough) continue; - if (!ToBBI.BB->isSuccessor(Succ)) - ToBBI.BB->addSuccessor(Succ); + ToBBI.BB->addSuccessor(Succ); } std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(), @@ -1200,11 +1225,10 @@ void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI) { if (Succ == FallThrough) continue; FromBBI.BB->removeSuccessor(Succ); - if (!ToBBI.BB->isSuccessor(Succ)) - ToBBI.BB->addSuccessor(Succ); + ToBBI.BB->addSuccessor(Succ); } - // Now FromBBI always fall through to the next block! + // Now FromBBI always falls through to the next block! if (NBB && !FromBBI.BB->isSuccessor(NBB)) FromBBI.BB->addSuccessor(NBB);