X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FIfConversion.cpp;h=8d212a606fdf305012b13e8e20decadcb19923c0;hb=b0000c376cf13ed63306622ab9642cfae49f074a;hp=8702bb30802bf74009423d5d650576f3c7d2cf84;hpb=c4047a8e96408a6149c2b64c953774fa578769fd;p=oota-llvm.git diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 8702bb30802..8d212a606fd 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the Evan Cheng and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -26,26 +26,24 @@ #include "llvm/ADT/STLExtras.h" using namespace llvm; -namespace { - // Hidden options for help debugging. - cl::opt IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden); - cl::opt IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden); - cl::opt IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden); - cl::opt DisableSimple("disable-ifcvt-simple", - cl::init(false), cl::Hidden); - cl::opt DisableSimpleF("disable-ifcvt-simple-false", - cl::init(false), cl::Hidden); - cl::opt DisableTriangle("disable-ifcvt-triangle", - cl::init(false), cl::Hidden); - cl::opt DisableTriangleR("disable-ifcvt-triangle-rev", - cl::init(false), cl::Hidden); - cl::opt DisableTriangleF("disable-ifcvt-triangle-false", - cl::init(false), cl::Hidden); - cl::opt DisableTriangleFR("disable-ifcvt-triangle-false-rev", - cl::init(false), cl::Hidden); - cl::opt DisableDiamond("disable-ifcvt-diamond", - cl::init(false), cl::Hidden); -} +// Hidden options for help debugging. +static cl::opt IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden); +static cl::opt IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden); +static cl::opt IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden); +static cl::opt DisableSimple("disable-ifcvt-simple", + cl::init(false), cl::Hidden); +static cl::opt DisableSimpleF("disable-ifcvt-simple-false", + cl::init(false), cl::Hidden); +static cl::opt DisableTriangle("disable-ifcvt-triangle", + cl::init(false), cl::Hidden); +static cl::opt DisableTriangleR("disable-ifcvt-triangle-rev", + cl::init(false), cl::Hidden); +static cl::opt DisableTriangleF("disable-ifcvt-triangle-false", + cl::init(false), cl::Hidden); +static cl::opt DisableTriangleFR("disable-ifcvt-triangle-false-rev", + cl::init(false), cl::Hidden); +static cl::opt DisableDiamond("disable-ifcvt-diamond", + cl::init(false), cl::Hidden); STATISTIC(NumSimple, "Number of simple if-conversions performed"); STATISTIC(NumSimpleFalse, "Number of simple (F) if-conversions performed"); @@ -58,7 +56,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. @@ -84,7 +82,7 @@ namespace { /// IsBrAnalyzable - True if AnalyzeBranch() returns false. /// HasFallThrough - True if BB may fallthrough to the following BB. /// IsUnpredicable - True if BB is known to be unpredicable. - /// ClobbersPredicate- True if BB would modify the predicate (e.g. has + /// ClobbersPred - True if BB could modify predicates (e.g. has /// cmp, call, etc.) /// NonPredSize - Number of non-predicated instructions. /// BB - Corresponding MachineBasicBlock. @@ -105,8 +103,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), @@ -148,10 +146,10 @@ namespace { bool MadeChange; public: static char ID; - IfConverter() : MachineFunctionPass((intptr_t)&ID) {} + IfConverter() : MachineFunctionPass(&ID) {} 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); @@ -163,7 +161,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); @@ -175,9 +173,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); @@ -217,6 +215,9 @@ namespace { char IfConverter::ID = 0; } +static RegisterPass +X("if-converter", "If Converter"); + FunctionPass *llvm::createIfConverterPass() { return new IfConverter(); } bool IfConverter::runOnMachineFunction(MachineFunction &MF) { @@ -239,7 +240,7 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { // Look for root nodes, i.e. blocks without successors. for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) - if (I->succ_size() == 0) + if (I->succ_empty()) Roots.push_back(I); std::vector Tokens; @@ -255,6 +256,10 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { 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. @@ -280,9 +285,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: @@ -321,7 +327,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; @@ -399,6 +405,9 @@ bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups) const { if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone) return false; + if (TrueBBI.IsBrAnalyzable) + return false; + if (TrueBBI.BB->pred_size() > 1) { if (TrueBBI.CannotBeCopied || TrueBBI.NonPredSize > TLI->getIfCvtDupBlockSizeLimit()) @@ -406,7 +415,7 @@ bool IfConverter::ValidSimple(BBInfo &TrueBBI, unsigned &Dups) const { Dups = TrueBBI.NonPredSize; } - return !blockAlwaysFallThrough(TrueBBI) && TrueBBI.BrCond.size() == 0; + return true; } /// ValidTriangle - Returns true if the 'true' and 'false' blocks (along @@ -427,7 +436,7 @@ bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI, unsigned Size = TrueBBI.NonPredSize; if (TrueBBI.IsBrAnalyzable) { - if (TrueBBI.TrueBB && TrueBBI.BrCond.size() == 0) + if (TrueBBI.TrueBB && TrueBBI.BrCond.empty()) // End with an unconditional branch. It will be removed. --Size; else { @@ -459,8 +468,7 @@ MachineBasicBlock::iterator firstNonBranchInst(MachineBasicBlock *BB, MachineBasicBlock::iterator I = BB->end(); while (I != BB->begin()) { --I; - const TargetInstrDescriptor *TID = I->getInstrDescriptor(); - if ((TID->Flags & M_BRANCH_FLAG) == 0) + if (!I->getDesc().isBranch()) break; } return I; @@ -519,13 +527,14 @@ bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI, /// ScanInstructions - Scan all the instructions in the block to determine if /// the block is predicable. In most cases, that means all the instructions -/// in the block has M_PREDICABLE flag. Also checks if the block contains any +/// in the block are isPredicable(). Also checks if the block contains any /// instruction which can clobber a predicate (e.g. condition code register). /// If so, the block is not predicable unless it's the last instruction. void IfConverter::ScanInstructions(BBInfo &BBI) { if (BBI.IsDone) return; + bool AlreadyPredicated = BBI.Predicate.size() > 0; // First analyze the end of BB branches. BBI.TrueBB = BBI.FalseBB = NULL; BBI.BrCond.clear(); @@ -547,16 +556,25 @@ void IfConverter::ScanInstructions(BBInfo &BBI) { bool SeenCondBr = false; for (MachineBasicBlock::iterator I = BBI.BB->begin(), E = BBI.BB->end(); I != E; ++I) { - if (!BBI.CannotBeCopied && !TII->CanBeDuplicated(I)) + const TargetInstrDesc &TID = I->getDesc(); + if (TID.isNotDuplicable()) BBI.CannotBeCopied = true; - const TargetInstrDescriptor *TID = I->getInstrDescriptor(); bool isPredicated = TII->isPredicated(I); - bool isCondBr = BBI.IsBrAnalyzable && - (TID->Flags & M_BRANCH_FLAG) != 0 && (TID->Flags & M_BARRIER_FLAG) == 0; - - if (!isPredicated && !isCondBr) - BBI.NonPredSize++; + bool isCondBr = BBI.IsBrAnalyzable && TID.isConditionalBranch(); + + if (!isCondBr) { + if (!isPredicated) + BBI.NonPredSize++; + else if (!AlreadyPredicated) { + // FIXME: This instruction is already predicated before the + // if-conversion pass. It's probably something like a conditional move. + // Mark this block unpredicable for now. + BBI.IsUnpredicable = true; + return; + } + + } if (BBI.ClobbersPred && !isPredicated) { // Predicate modification instruction should end the block (except for @@ -569,15 +587,18 @@ void IfConverter::ScanInstructions(BBInfo &BBI) { } // Predicate may have been modified, the subsequent (currently) - // unpredocated instructions cannot be correctly predicated. + // unpredicated instructions cannot be correctly predicated. BBI.IsUnpredicable = true; return; } - if (TID->Flags & M_CLOBBERS_PRED) + // FIXME: Make use of PredDefs? e.g. ADDC, SUBC sets predicates but are + // still potentially predicable. + std::vector PredDefs; + if (TII->DefinesPredicate(I, PredDefs)) BBI.ClobbersPred = true; - if ((TID->Flags & M_PREDICABLE) == 0) { + if (!TID.isPredicable()) { BBI.IsUnpredicable = true; return; } @@ -587,7 +608,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) @@ -603,8 +624,8 @@ bool IfConverter::FeasibilityAnalysis(BBInfo &BBI, return false; // Test predicate subsumsion. - std::vector RevPred(Pred); - std::vector Cond(BBI.BrCond); + SmallVector RevPred(Pred.begin(), Pred.end()); + SmallVector Cond(BBI.BrCond.begin(), BBI.BrCond.end()); if (RevBranch) { if (TII->ReverseBranchCondition(Cond)) return false; @@ -633,7 +654,7 @@ IfConverter::BBInfo &IfConverter::AnalyzeBlock(MachineBasicBlock *BB, ScanInstructions(BBI); // Unanalyable or ends with fallthrough or unconditional branch. - if (!BBI.IsBrAnalyzable || BBI.BrCond.size() == 0) { + if (!BBI.IsBrAnalyzable || BBI.BrCond.empty()) { BBI.IsBeingAnalyzed = false; BBI.IsAnalyzed = true; return BBI; @@ -655,7 +676,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; @@ -798,7 +819,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); } @@ -806,7 +827,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()); } @@ -819,7 +840,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); @@ -832,7 +853,8 @@ 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); @@ -884,7 +906,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); @@ -897,21 +919,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; + } } } } @@ -937,7 +961,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); @@ -1009,10 +1034,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; @@ -1094,7 +1120,7 @@ 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; @@ -1115,17 +1141,19 @@ 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 TargetInstrDescriptor *TID = I->getInstrDescriptor(); + const TargetInstrDesc &TID = I->getDesc(); bool isPredicated = TII->isPredicated(I); // Do not copy the end of the block branches. - if (IgnoreBr && !isPredicated && (TID->Flags & M_BRANCH_FLAG) != 0) + if (IgnoreBr && !isPredicated && TID.isBranch()) break; - MachineInstr *MI = I->clone(); + MachineInstr *MI = MF.CloneMachineInstr(I); ToBBI.BB->insert(ToBBI.BB->end(), MI); ToBBI.NonPredSize++;