diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 7bc93114d6d..14dcd2ce19c 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -42,9 +42,13 @@ protected: bool Initialized; // Flagged after all passes are configured. // Target Pass Options + // Targets provide a default setting, user flags override. // bool DisableVerify; + /// Default setting for -enable-tail-merge on this target. + bool EnableTailMerge; + public: TargetPassConfig(TargetMachine *tm, PassManagerBase &pm); // Dummy constructor. @@ -67,7 +71,10 @@ public: CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } - void setDisableVerify(bool disable) { DisableVerify = disable; } + void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); } + + bool getEnableTailMerge() const { return EnableTailMerge; } + void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); } /// Add common target configurable passes that perform LLVM IR to IR /// transforms following machine independent optimization. @@ -118,10 +125,6 @@ protected: return false; } - /// getEnableTailMergeDefault - the default setting for -enable-tail-merge - /// on this target. User flag overrides. - virtual bool getEnableTailMergeDefault() const { return true; } - /// addPreSched2 - This method may be implemented by targets that want to /// run passes after prolog-epilog insertion and before the second instruction /// scheduling pass. This should return true if -print-machineinstrs should @@ -274,7 +277,7 @@ namespace llvm { /// optimizations to delete branches to branches, eliminate branches to /// successor blocks (creating fall throughs), and eliminating branches over /// branches. - FunctionPass *createBranchFoldingPass(bool DefaultEnableTailMerge); + extern char &BranchFolderPassID; /// TailDuplicate Pass - Duplicate blocks with unconditional branches /// into tails of their predecessors. diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index c1940d6aa77..f11b0244b7c 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -71,6 +71,7 @@ void initializeBasicCallGraphPass(PassRegistry&); void initializeBlockExtractorPassPass(PassRegistry&); void initializeBlockFrequencyInfoPass(PassRegistry&); void initializeBlockPlacementPass(PassRegistry&); +void initializeBranchFolderPassPass(PassRegistry&); void initializeBranchProbabilityInfoPass(PassRegistry&); void initializeBreakCriticalEdgesPass(PassRegistry&); void initializeCFGOnlyPrinterPass(PassRegistry&); diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index af37742c4b5..4929e388900 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -61,29 +61,33 @@ TailMergeSize("tail-merge-size", namespace { /// BranchFolderPass - Wrap branch folder in a machine function pass. - class BranchFolderPass : public MachineFunctionPass, - public BranchFolder { + class BranchFolderPass : public MachineFunctionPass { public: static char ID; - explicit BranchFolderPass(bool defaultEnableTailMerge) - : MachineFunctionPass(ID), BranchFolder(defaultEnableTailMerge, true) {} + explicit BranchFolderPass(): MachineFunctionPass(ID) {} virtual bool runOnMachineFunction(MachineFunction &MF); - virtual const char *getPassName() const { return "Control Flow Optimizer"; } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + MachineFunctionPass::getAnalysisUsage(AU); + } }; } char BranchFolderPass::ID = 0; +char &llvm::BranchFolderPassID = BranchFolderPass::ID; -FunctionPass *llvm::createBranchFoldingPass(bool DefaultEnableTailMerge) { - return new BranchFolderPass(DefaultEnableTailMerge); -} +INITIALIZE_PASS(BranchFolderPass, "branch-folder", + "Control Flow Optimizer", false, false) bool BranchFolderPass::runOnMachineFunction(MachineFunction &MF) { - return OptimizeFunction(MF, - MF.getTarget().getInstrInfo(), - MF.getTarget().getRegisterInfo(), - getAnalysisIfAvailable()); + TargetPassConfig *PassConfig = &getAnalysis(); + BranchFolder Folder(PassConfig->getEnableTailMerge(), /*CommonHoist=*/true); + return Folder.OptimizeFunction(MF, + MF.getTarget().getInstrInfo(), + MF.getTarget().getRegisterInfo(), + getAnalysisIfAvailable()); } diff --git a/lib/CodeGen/CodeGen.cpp b/lib/CodeGen/CodeGen.cpp index 7651e221fd5..c838e6fb31b 100644 --- a/lib/CodeGen/CodeGen.cpp +++ b/lib/CodeGen/CodeGen.cpp @@ -19,6 +19,7 @@ using namespace llvm; /// initializeCodeGen - Initialize all passes linked into the CodeGen library. void llvm::initializeCodeGen(PassRegistry &Registry) { + initializeBranchFolderPassPass(Registry); initializeCalculateSpillWeightsPass(Registry); initializeDeadMachineInstructionElimPass(Registry); initializeGCModuleInfoPass(Registry); diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index 6d12dd839c3..0a4d4d754ad 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -83,6 +83,8 @@ char TargetPassConfig::ID = 0; // Out of line virtual method. TargetPassConfig::~TargetPassConfig() {} +// Out of line constructor provides default values for pass options and +// registers all common codegen passes. TargetPassConfig::TargetPassConfig(TargetMachine *tm, PassManagerBase &pm) : ImmutablePass(ID), TM(tm), PM(pm), Initialized(false), DisableVerify(false), @@ -257,7 +259,7 @@ void TargetPassConfig::addMachinePasses() { // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + addPass(BranchFolderPassID); printNoVerify("After BranchFolding"); } diff --git a/lib/Target/PTX/PTXTargetMachine.cpp b/lib/Target/PTX/PTXTargetMachine.cpp index 41bcfd564d1..38cc005c815 100644 --- a/lib/Target/PTX/PTXTargetMachine.cpp +++ b/lib/Target/PTX/PTXTargetMachine.cpp @@ -359,7 +359,7 @@ bool PTXPassConfig::addCodeGenPasses(MCContext *&OutContext) { // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + addPass(BranchFolderPassID); printNoVerify("After BranchFolding"); } diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index f5be1483999..da202747375 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -78,13 +78,18 @@ public: } virtual bool addInstSelector(); - virtual bool getEnableTailMergeDefault() const; virtual bool addPreEmitPass(); }; } // namespace TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM) { - return new PPCPassConfig(this, PM); + TargetPassConfig *PassConfig = new PPCPassConfig(this, PM); + + // Override this for PowerPC. Tail merging happily breaks up instruction issue + // groups, which typically degrades performance. + PassConfig->setEnableTailMerge(false); + + return PassConfig; } bool PPCPassConfig::addInstSelector() { @@ -93,10 +98,6 @@ bool PPCPassConfig::addInstSelector() { return false; } -/// Override this for PowerPC. Tail merging happily breaks up instruction issue -/// groups, which typically degrades performance. -bool PPCPassConfig::getEnableTailMergeDefault() const { return false; } - bool PPCPassConfig::addPreEmitPass() { // Must run branch selection immediately preceding the asm printer. PM.add(createPPCBranchSelectionPass());