X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FBranchFolding.cpp;h=66c5aa5ff784e84b6a2648276ac9d63b52dd9ec3;hb=91203cf87b8a72227c78a9eeae8bb744dfcc4ef0;hp=c97f176d74b1c5bac6e5b82b83ad33d39728e2b7;hpb=44eb65cf58e3ab9b5621ce72256d1621a18aeed7;p=oota-llvm.git diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index c97f176d74b..66c5aa5ff78 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -17,6 +17,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "branchfolding" +#include "BranchFolding.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -27,6 +28,8 @@ #include "llvm/Target/TargetRegisterInfo.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/SmallSet.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/STLExtras.h" @@ -42,72 +45,37 @@ static cl::opt FlagEnableTailMerge("enable-tail-merge", static cl::opt TailMergeThreshold("tail-merge-threshold", cl::desc("Max number of predecessors to consider tail merging"), - cl::init(100), cl::Hidden); - -namespace { - struct VISIBILITY_HIDDEN BranchFolder : public MachineFunctionPass { - static char ID; - explicit BranchFolder(bool defaultEnableTailMerge) : - MachineFunctionPass((intptr_t)&ID) { - switch (FlagEnableTailMerge) { - case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; - case cl::BOU_TRUE: EnableTailMerge = true; break; - case cl::BOU_FALSE: EnableTailMerge = false; break; - } - } + cl::init(150), cl::Hidden); - virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Control Flow Optimizer"; } - const TargetInstrInfo *TII; - MachineModuleInfo *MMI; - bool MadeChange; - private: - // Tail Merging. - bool EnableTailMerge; - bool TailMergeBlocks(MachineFunction &MF); - bool TryMergeBlocks(MachineBasicBlock* SuccBB, - MachineBasicBlock* PredBB); - void ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, - MachineBasicBlock *NewDest); - MachineBasicBlock *SplitMBBAt(MachineBasicBlock &CurMBB, - MachineBasicBlock::iterator BBI1); - unsigned ComputeSameTails(unsigned CurHash, unsigned minCommonTailLength); - void RemoveBlocksWithHash(unsigned CurHash, MachineBasicBlock* SuccBB, - MachineBasicBlock* PredBB); - unsigned CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, - unsigned maxCommonTailLength); - - typedef std::pair MergePotentialsElt; - typedef std::vector::iterator MPIterator; - std::vector MergePotentials; - - typedef std::pair SameTailElt; - std::vector SameTails; - - const TargetRegisterInfo *RegInfo; - RegScavenger *RS; - // Branch optzn. - bool OptimizeBranches(MachineFunction &MF); - void OptimizeBlock(MachineBasicBlock *MBB); - void RemoveDeadBlock(MachineBasicBlock *MBB); - bool OptimizeImpDefsBlock(MachineBasicBlock *MBB); - - bool CanFallThrough(MachineBasicBlock *CurBB); - bool CanFallThrough(MachineBasicBlock *CurBB, bool BranchUnAnalyzable, - MachineBasicBlock *TBB, MachineBasicBlock *FBB, - const SmallVectorImpl &Cond); - }; - char BranchFolder::ID = 0; -} + +char BranchFolderPass::ID = 0; FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { - return new BranchFolder(DefaultEnableTailMerge); } + return new BranchFolderPass(DefaultEnableTailMerge); +} + +bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { + return OptimizeFunction(MF, + MF.getTarget().getInstrInfo(), + MF.getTarget().getRegisterInfo(), + getAnalysisIfAvailable()); +} + + + +BranchFolder::BranchFolder(bool defaultEnableTailMerge) { + switch (FlagEnableTailMerge) { + case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; + case cl::BOU_TRUE: EnableTailMerge = true; break; + case cl::BOU_FALSE: EnableTailMerge = false; break; + } +} /// RemoveDeadBlock - Remove the specified dead machine basic block from the /// function, updating the CFG. void BranchFolder::RemoveDeadBlock(MachineBasicBlock *MBB) { assert(MBB->pred_empty() && "MBB must be dead!"); - DOUT << "\nRemoving MBB: " << *MBB; + DEBUG(errs() << "\nRemoving MBB: " << *MBB); MachineFunction *MF = MBB->getParent(); // drop all successors. @@ -146,7 +114,7 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) { break; unsigned Reg = I->getOperand(0).getReg(); ImpDefRegs.insert(Reg); - for (const unsigned *SubRegs = RegInfo->getSubRegisters(Reg); + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); unsigned SubReg = *SubRegs; ++SubRegs) ImpDefRegs.insert(SubReg); ++I; @@ -180,32 +148,37 @@ bool BranchFolder::OptimizeImpDefsBlock(MachineBasicBlock *MBB) { return true; } -bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { - TII = MF.getTarget().getInstrInfo(); - if (!TII) return false; +/// OptimizeFunction - Perhaps branch folding, tail merging and other +/// CFG optimizations on the given function. +bool BranchFolder::OptimizeFunction(MachineFunction &MF, + const TargetInstrInfo *tii, + const TargetRegisterInfo *tri, + MachineModuleInfo *mmi) { + if (!tii) return false; + + TII = tii; + TRI = tri; + MMI = mmi; - RegInfo = MF.getTarget().getRegisterInfo(); + RS = TRI->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL; // Fix CFG. The later algorithms expect it to be right. - bool EverMadeChange = false; + bool MadeChange = false; for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; I++) { MachineBasicBlock *MBB = I, *TBB = 0, *FBB = 0; SmallVector Cond; - if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond)) - EverMadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); - EverMadeChange |= OptimizeImpDefsBlock(MBB); + if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, true)) + MadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); + MadeChange |= OptimizeImpDefsBlock(MBB); } - RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL; - - MMI = getAnalysisToUpdate(); bool MadeChangeThisIteration = true; while (MadeChangeThisIteration) { MadeChangeThisIteration = false; MadeChangeThisIteration |= TailMergeBlocks(MF); MadeChangeThisIteration |= OptimizeBranches(MF); - EverMadeChange |= MadeChangeThisIteration; + MadeChange |= MadeChangeThisIteration; } // See if any jump tables have become mergable or dead as the code generator @@ -222,8 +195,12 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { // Scan the jump tables, seeing if there are any duplicates. Note that this // is N^2, which should be fixed someday. - for (unsigned i = 1, e = JTs.size(); i != e; ++i) - JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs)); + for (unsigned i = 1, e = JTs.size(); i != e; ++i) { + if (JTs[i].MBBs.empty()) + JTMapping.push_back(i); + else + JTMapping.push_back(JTI->getJumpTableIndex(JTs[i].MBBs)); + } // If a jump table was merge with another one, walk the function rewriting // references to jump tables to reference the new JT ID's. Keep track of @@ -235,7 +212,7 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { I != E; ++I) for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) { MachineOperand &Op = I->getOperand(op); - if (!Op.isJumpTableIndex()) continue; + if (!Op.isJTI()) continue; unsigned NewIdx = JTMapping[Op.getIndex()]; Op.setIndex(NewIdx); @@ -250,12 +227,12 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) { for (unsigned i = 0, e = JTIsLive.size(); i != e; ++i) if (!JTIsLive.test(i)) { JTI->RemoveJumpTable(i); - EverMadeChange = true; + MadeChange = true; } } - + delete RS; - return EverMadeChange; + return MadeChange; } //===----------------------------------------------------------------------===// @@ -364,7 +341,7 @@ void BranchFolder::ReplaceTailWithBranchTo(MachineBasicBlock::iterator OldInst, // If OldBB isn't immediately before OldBB, insert a branch to it. if (++MachineFunction::iterator(OldBB) != MachineFunction::iterator(NewDest)) - TII->InsertBranch(*OldBB, NewDest, 0, SmallVector()); + TII->InsertBranch(*OldBB, NewDest, 0, SmallVector()); OldBB->addSuccessor(NewDest); ++NumTailMerge; } @@ -395,9 +372,9 @@ MachineBasicBlock *BranchFolder::SplitMBBAt(MachineBasicBlock &CurMBB, RS->enterBasicBlock(&CurMBB); if (!CurMBB.empty()) RS->forward(prior(CurMBB.end())); - BitVector RegsLiveAtExit(RegInfo->getNumRegs()); + BitVector RegsLiveAtExit(TRI->getNumRegs()); RS->getRegsUsed(RegsLiveAtExit, false); - for (unsigned int i=0, e=RegInfo->getNumRegs(); i!=e; i++) + for (unsigned int i=0, e=TRI->getNumRegs(); i!=e; i++) if (RegsLiveAtExit[i]) NewMBB->addLiveIn(i); } @@ -414,7 +391,7 @@ static unsigned EstimateRuntime(MachineBasicBlock::iterator I, const TargetInstrDesc &TID = I->getDesc(); if (TID.isCall()) Time += 10; - else if (TID.isSimpleLoad() || TID.mayStore()) + else if (TID.mayLoad() || TID.mayStore()) Time += 2; else ++Time; @@ -434,7 +411,7 @@ static void FixTail(MachineBasicBlock* CurMBB, MachineBasicBlock *SuccBB, MachineBasicBlock *TBB = 0, *FBB = 0; SmallVector Cond; if (I != MF->end() && - !TII->AnalyzeBranch(*CurMBB, TBB, FBB, Cond)) { + !TII->AnalyzeBranch(*CurMBB, TBB, FBB, Cond, true)) { MachineBasicBlock *NextBB = I; if (TBB == NextBB && !Cond.empty() && !FBB) { if (!TII->ReverseBranchCondition(Cond)) { @@ -444,7 +421,7 @@ static void FixTail(MachineBasicBlock* CurMBB, MachineBasicBlock *SuccBB, } } } - TII->InsertBranch(*CurMBB, SuccBB, NULL, SmallVector()); + TII->InsertBranch(*CurMBB, SuccBB, NULL, SmallVector()); } static bool MergeCompare(const std::pair &p, @@ -461,9 +438,9 @@ static bool MergeCompare(const std::pair &p, // _GLIBCXX_DEBUG checks strict weak ordering, which involves comparing // an object with itself. #ifndef _GLIBCXX_DEBUG - assert(0 && "Predecessor appears twice"); + llvm_unreachable("Predecessor appears twice"); #endif - return(false); + return false; } } @@ -567,8 +544,8 @@ unsigned BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, MachineBasicBlock::iterator BBI = SameTails[commonTailIndex].second; MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; - DOUT << "\nSplitting " << MBB->getNumber() << ", size " << - maxCommonTailLength; + DEBUG(errs() << "\nSplitting " << MBB->getNumber() << ", size " + << maxCommonTailLength); MachineBasicBlock *newMBB = SplitMBBAt(*MBB, BBI); SameTails[commonTailIndex].first->second = newMBB; @@ -590,13 +567,14 @@ unsigned BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB, MachineBasicBlock* PredBB) { + bool MadeChange = false; + // It doesn't make sense to save a single instruction since tail merging // will add a jump. // FIXME: Ask the target to provide the threshold? unsigned minCommonTailLength = (SuccBB ? 1 : 2) + 1; - MadeChange = false; - DOUT << "\nTryMergeBlocks " << MergePotentials.size(); + DEBUG(errs() << "\nTryMergeBlocks " << MergePotentials.size() << '\n'); // Sort by hash value so that blocks with identical end sequences sort // together. @@ -643,17 +621,17 @@ bool BranchFolder::TryMergeBlocks(MachineBasicBlock *SuccBB, MachineBasicBlock *MBB = SameTails[commonTailIndex].first->second; // MBB is common tail. Adjust all other BB's to jump to this one. // Traversal must be forwards so erases work. - DOUT << "\nUsing common tail " << MBB->getNumber() << " for "; + DEBUG(errs() << "\nUsing common tail " << MBB->getNumber() << " for "); for (unsigned int i=0; isecond->getNumber() << ","; + DEBUG(errs() << SameTails[i].first->second->getNumber() << ","); // Hack the end off BB i, making it jump to BB commonTailIndex instead. ReplaceTailWithBranchTo(SameTails[i].second, MBB); // BB i is no longer a predecessor of SuccBB; remove it from the worklist. MergePotentials.erase(SameTails[i].first); } - DOUT << "\n"; + DEBUG(errs() << "\n"); // We leave commonTailIndex in the worklist in case there are other blocks // that match it with a smaller number of instructions. MadeChange = true; @@ -665,7 +643,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { if (!EnableTailMerge) return false; - MadeChange = false; + bool MadeChange = false; // First find blocks with no successors. MergePotentials.clear(); @@ -699,6 +677,7 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { if (I->pred_size() >= 2 && I->pred_size() < TailMergeThreshold) { + SmallPtrSet UniquePreds; MachineBasicBlock *IBB = I; MachineBasicBlock *PredBB = prior(I); MergePotentials.clear(); @@ -709,9 +688,12 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { // Skip blocks that loop to themselves, can't tail merge these. if (PBB==IBB) continue; + // Visit each predecessor only once. + if (!UniquePreds.insert(PBB)) + continue; MachineBasicBlock *TBB = 0, *FBB = 0; SmallVector Cond; - if (!TII->AnalyzeBranch(*PBB, TBB, FBB, Cond)) { + if (!TII->AnalyzeBranch(*PBB, TBB, FBB, Cond, true)) { // Failing case: IBB is the target of a cbr, and // we cannot reverse the branch. SmallVector NewCond(Cond); @@ -772,14 +754,14 @@ bool BranchFolder::TailMergeBlocks(MachineFunction &MF) { //===----------------------------------------------------------------------===// bool BranchFolder::OptimizeBranches(MachineFunction &MF) { - MadeChange = false; + bool MadeChange = false; // Make sure blocks are numbered in order MF.RenumberBlocks(); for (MachineFunction::iterator I = ++MF.begin(), E = MF.end(); I != E; ) { MachineBasicBlock *MBB = I++; - OptimizeBlock(MBB); + MadeChange |= OptimizeBlock(MBB); // If it is dead, remove it. if (MBB->pred_empty()) { @@ -845,7 +827,7 @@ bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB, bool BranchFolder::CanFallThrough(MachineBasicBlock *CurBB) { MachineBasicBlock *TBB = 0, *FBB = 0; SmallVector Cond; - bool CurUnAnalyzable = TII->AnalyzeBranch(*CurBB, TBB, FBB, Cond); + bool CurUnAnalyzable = TII->AnalyzeBranch(*CurBB, TBB, FBB, Cond, true); return CanFallThrough(CurBB, CurUnAnalyzable, TBB, FBB, Cond); } @@ -873,7 +855,9 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1, /// OptimizeBlock - Analyze and optimize control flow related to the specified /// block. This is never called on the entry block. -void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { +bool BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { + bool MadeChange = false; + MachineFunction::iterator FallThrough = MBB; ++FallThrough; @@ -882,7 +866,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // points to this block. if (MBB->empty() && !MBB->isLandingPad()) { // Dead block? Leave for cleanup later. - if (MBB->pred_empty()) return; + if (MBB->pred_empty()) return MadeChange; if (FallThrough == MBB->getParent()->end()) { // TODO: Simplify preds to not branch here if possible! @@ -893,14 +877,13 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { MachineBasicBlock *Pred = *(MBB->pred_end()-1); Pred->ReplaceUsesOfBlockWith(MBB, FallThrough); } - // If MBB was the target of a jump table, update jump tables to go to the // fallthrough instead. MBB->getParent()->getJumpTableInfo()-> ReplaceMBBInJumpTables(MBB, FallThrough); MadeChange = true; } - return; + return MadeChange; } // Check to see if we can simplify the terminator of the block before this @@ -910,7 +893,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { MachineBasicBlock *PriorTBB = 0, *PriorFBB = 0; SmallVector PriorCond; bool PriorUnAnalyzable = - TII->AnalyzeBranch(PrevBB, PriorTBB, PriorFBB, PriorCond); + TII->AnalyzeBranch(PrevBB, PriorTBB, PriorFBB, PriorCond, true); if (!PriorUnAnalyzable) { // If the CFG for the prior block has extra edges, remove them. MadeChange |= PrevBB.CorrectExtraCFGEdges(PriorTBB, PriorFBB, @@ -962,15 +945,15 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { } } - // If this block doesn't fall through (e.g. it ends with an uncond branch or - // has no successors) and if the pred falls through into this block, and if - // it would otherwise fall through into the block after this, move this - // block to the end of the function. + // If this block has no successors (e.g. it is a return block or ends with + // a call to a no-return function like abort or __cxa_throw) and if the pred + // falls through into this block, and if it would otherwise fall through + // into the block after this, move this block to the end of the function. // // We consider it more likely that execution will stay in the function (e.g. // due to loops) than it is to exit it. This asserts in loops etc, moving // the assert condition out of the loop body. - if (!PriorCond.empty() && PriorFBB == 0 && + if (MBB->succ_empty() && !PriorCond.empty() && PriorFBB == 0 && MachineFunction::iterator(PriorTBB) == FallThrough && !CanFallThrough(MBB)) { bool DoTransform = true; @@ -1004,8 +987,8 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // Reverse the branch so we will fall through on the previous true cond. SmallVector NewPriorCond(PriorCond); if (!TII->ReverseBranchCondition(NewPriorCond)) { - DOUT << "\nMoving MBB: " << *MBB; - DOUT << "To make fallthrough to: " << *PriorTBB << "\n"; + DEBUG(errs() << "\nMoving MBB: " << *MBB + << "To make fallthrough to: " << *PriorTBB << "\n"); TII->RemoveBranch(PrevBB); TII->InsertBranch(PrevBB, MBB, 0, NewPriorCond); @@ -1014,7 +997,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { MBB->moveAfter(--MBB->getParent()->end()); MadeChange = true; ++NumBranchOpts; - return; + return MadeChange; } } } @@ -1023,7 +1006,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { // Analyze the branch in the current block. MachineBasicBlock *CurTBB = 0, *CurFBB = 0; SmallVector CurCond; - bool CurUnAnalyzable = TII->AnalyzeBranch(*MBB, CurTBB, CurFBB, CurCond); + bool CurUnAnalyzable= TII->AnalyzeBranch(*MBB, CurTBB, CurFBB, CurCond, true); if (!CurUnAnalyzable) { // If the CFG for the prior block has extra edges, remove them. MadeChange |= MBB->CorrectExtraCFGEdges(CurTBB, CurFBB, !CurCond.empty()); @@ -1092,6 +1075,21 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { } else { DidChange = true; PMBB->ReplaceUsesOfBlockWith(MBB, CurTBB); + // If this change resulted in PMBB ending in a conditional + // branch where both conditions go to the same destination, + // change this to an unconditional branch (and fix the CFG). + MachineBasicBlock *NewCurTBB = 0, *NewCurFBB = 0; + SmallVector NewCurCond; + bool NewCurUnAnalyzable = TII->AnalyzeBranch(*PMBB, NewCurTBB, + NewCurFBB, NewCurCond, true); + if (!NewCurUnAnalyzable && NewCurTBB && NewCurTBB == NewCurFBB) { + TII->RemoveBranch(*PMBB); + NewCurCond.clear(); + TII->InsertBranch(*PMBB, NewCurTBB, 0, NewCurCond); + MadeChange = true; + ++NumBranchOpts; + PMBB->CorrectExtraCFGEdges(NewCurTBB, NewCurFBB, false); + } } } @@ -1101,7 +1099,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { if (DidChange) { ++NumBranchOpts; MadeChange = true; - if (!HasBranchToSelf) return; + if (!HasBranchToSelf) return MadeChange; } } } @@ -1182,8 +1180,10 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { PrevBB.isSuccessor(FallThrough)) { MBB->moveAfter(--MBB->getParent()->end()); MadeChange = true; - return; + return MadeChange; } } } + + return MadeChange; }