diff options
author | Evan Cheng <evan.cheng@apple.com> | 2009-09-04 07:47:40 +0000 |
---|---|---|
committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-04 07:47:40 +0000 |
commit | 030a0a0cdb38924e55773a8e0b5fe7347aa664aa (patch) | |
tree | 7dffa62ef1bf0eb250d871fdc39d25cf5f776924 /lib | |
parent | e93909185fb61ae1b2fd045572d7d51209a39d1c (diff) | |
download | external_llvm-030a0a0cdb38924e55773a8e0b5fe7347aa664aa.zip external_llvm-030a0a0cdb38924e55773a8e0b5fe7347aa664aa.tar.gz external_llvm-030a0a0cdb38924e55773a8e0b5fe7347aa664aa.tar.bz2 |
Run branch folding if if-converter make some transformations.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@80994 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/CodeGen/BranchFolding.cpp | 147 | ||||
-rw-r--r-- | lib/CodeGen/BranchFolding.h | 84 | ||||
-rw-r--r-- | lib/CodeGen/IfConversion.cpp | 8 |
3 files changed, 155 insertions, 84 deletions
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index dd51d5f..f9abeac 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" @@ -46,64 +47,28 @@ TailMergeThreshold("tail-merge-threshold", cl::desc("Max number of predecessors to consider tail merging"), cl::init(150), cl::Hidden); -namespace { - struct VISIBILITY_HIDDEN BranchFolder : public MachineFunctionPass { - static char ID; - explicit BranchFolder(bool defaultEnableTailMerge) : - MachineFunctionPass(&ID) { - switch (FlagEnableTailMerge) { - case cl::BOU_UNSET: EnableTailMerge = defaultEnableTailMerge; break; - case cl::BOU_TRUE: EnableTailMerge = true; break; - case cl::BOU_FALSE: EnableTailMerge = false; break; - } - } - 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<unsigned,MachineBasicBlock*> MergePotentialsElt; - typedef std::vector<MergePotentialsElt>::iterator MPIterator; - std::vector<MergePotentialsElt> MergePotentials; - - typedef std::pair<MPIterator, MachineBasicBlock::iterator> SameTailElt; - std::vector<SameTailElt> 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<MachineOperand> &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<MachineModuleInfo>()); +} + + + +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 @@ -149,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; @@ -183,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<MachineOperand, 4> Cond; if (!TII->AnalyzeBranch(*MBB, TBB, FBB, Cond, true)) - EverMadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); - EverMadeChange |= OptimizeImpDefsBlock(MBB); + MadeChange |= MBB->CorrectExtraCFGEdges(TBB, FBB, !Cond.empty()); + MadeChange |= OptimizeImpDefsBlock(MBB); } - RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL; - - MMI = getAnalysisIfAvailable<MachineModuleInfo>(); 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 @@ -225,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 @@ -253,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; } //===----------------------------------------------------------------------===// @@ -398,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); } @@ -593,11 +567,12 @@ 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; DEBUG(errs() << "\nTryMergeBlocks " << MergePotentials.size() << '\n'); @@ -668,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(); @@ -779,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()) { @@ -880,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; @@ -889,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! @@ -906,7 +883,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { ReplaceMBBInJumpTables(MBB, FallThrough); MadeChange = true; } - return; + return MadeChange; } // Check to see if we can simplify the terminator of the block before this @@ -1020,7 +997,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { MBB->moveAfter(--MBB->getParent()->end()); MadeChange = true; ++NumBranchOpts; - return; + return MadeChange; } } } @@ -1122,7 +1099,7 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { if (DidChange) { ++NumBranchOpts; MadeChange = true; - if (!HasBranchToSelf) return; + if (!HasBranchToSelf) return MadeChange; } } } @@ -1203,8 +1180,10 @@ void BranchFolder::OptimizeBlock(MachineBasicBlock *MBB) { PrevBB.isSuccessor(FallThrough)) { MBB->moveAfter(--MBB->getParent()->end()); MadeChange = true; - return; + return MadeChange; } } } + + return MadeChange; } diff --git a/lib/CodeGen/BranchFolding.h b/lib/CodeGen/BranchFolding.h new file mode 100644 index 0000000..9763e33 --- /dev/null +++ b/lib/CodeGen/BranchFolding.h @@ -0,0 +1,84 @@ +//===-- BranchFolding.h - Fold machine code branch instructions --*- C++ -*===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_BRANCHFOLDING_HPP +#define LLVM_CODEGEN_BRANCHFOLDING_HPP + +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include <vector> + +namespace llvm { + class MachineFunction; + class MachineModuleInfo; + class RegScavenger; + class TargetInstrInfo; + class TargetRegisterInfo; + + class BranchFolder { + public: + explicit BranchFolder(bool defaultEnableTailMerge); + + bool OptimizeFunction(MachineFunction &MF, + const TargetInstrInfo *tii, + const TargetRegisterInfo *tri, + MachineModuleInfo *mmi); + private: + typedef std::pair<unsigned,MachineBasicBlock*> MergePotentialsElt; + typedef std::vector<MergePotentialsElt>::iterator MPIterator; + std::vector<MergePotentialsElt> MergePotentials; + + typedef std::pair<MPIterator, MachineBasicBlock::iterator> SameTailElt; + std::vector<SameTailElt> SameTails; + + bool EnableTailMerge; + const TargetInstrInfo *TII; + const TargetRegisterInfo *TRI; + MachineModuleInfo *MMI; + RegScavenger *RS; + + 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); + + bool OptimizeBranches(MachineFunction &MF); + bool 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<MachineOperand> &Cond); + }; + + + /// BranchFolderPass - Wrap branch folder in a machine function pass. + class BranchFolderPass : public MachineFunctionPass, + public BranchFolder { + public: + static char ID; + explicit BranchFolderPass(bool defaultEnableTailMerge) + : MachineFunctionPass(&ID), BranchFolder(defaultEnableTailMerge) {} + + virtual bool runOnMachineFunction(MachineFunction &MF); + virtual const char *getPassName() const { return "Control Flow Optimizer"; } + }; +} + +#endif /* LLVM_CODEGEN_BRANCHFOLDING_HPP */ diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp index 62bde60..7b613ff 100644 --- a/lib/CodeGen/IfConversion.cpp +++ b/lib/CodeGen/IfConversion.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "ifcvt" +#include "BranchFolding.h" #include "llvm/Function.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -360,6 +361,13 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) { Roots.clear(); BBAnalysis.clear(); + if (MadeChange) { + BranchFolder BF(false); + BF.OptimizeFunction(MF, TII, + MF.getTarget().getRegisterInfo(), + getAnalysisIfAvailable<MachineModuleInfo>()); + } + return MadeChange; } |