diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index 2259ebffc27..082bada1c38 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -26,7 +26,111 @@ namespace llvm { class TargetLowering; class TargetRegisterClass; class raw_ostream; +} +namespace llvm { + +/// Target-Independent Code Generator Pass Configuration Options. +/// +/// FIXME: Why are we passing the DisableVerify flags around instead of setting +/// an options in the target machine, like all the other driver options? +class TargetPassConfig { +protected: + TargetMachine *TM; + PassManagerBase ± + bool DisableVerify; + +public: + TargetPassConfig(TargetMachine *tm, PassManagerBase &pm, + bool DisableVerifyFlag) + : TM(tm), PM(pm), DisableVerify(DisableVerifyFlag) {} + + virtual ~TargetPassConfig() {} + + /// Get the right type of TargetMachine for this target. + template TMC &getTM() const { + return *static_cast(TM); + } + + CodeGenOpt::Level getOptLevel() const { return TM->getOptLevel(); } + + const TargetLowering *getTargetLowering() const { return TM->getTargetLowering(); } + + /// Add the complete, standard set of LLVM CodeGen passes. + /// Fully developed targets will not generally override this. + virtual bool addCodeGenPasses(MCContext *&OutContext); + +protected: + /// Convenient points in the common codegen pass pipeline for inserting + /// passes, and major CodeGen stages that some targets may override. + /// + + /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM + /// passes (which are run just before instruction selector). + virtual bool addPreISel() { + return true; + } + + /// addInstSelector - This method should install an instruction selector pass, + /// which converts from LLVM code to machine instructions. + virtual bool addInstSelector() { + return true; + } + + /// addPreRegAlloc - This method may be implemented by targets that want to + /// run passes immediately before register allocation. This should return + /// true if -print-machineinstrs should print after these passes. + virtual bool addPreRegAlloc() { + return false; + } + + /// addPostRegAlloc - This method may be implemented by targets that want + /// to run passes after register allocation but before prolog-epilog + /// insertion. This should return true if -print-machineinstrs should print + /// after these passes. + virtual bool addPostRegAlloc() { + 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 + /// print after these passes. + virtual bool addPreSched2() { + return false; + } + + /// addPreEmitPass - This pass may be implemented by targets that want to run + /// passes immediately before machine code is emitted. This should return + /// true if -print-machineinstrs should print out the code after the passes. + virtual bool addPreEmitPass() { + return false; + } + + /// Utilities for targets to add passes to the pass manager. + /// + + /// Add a target-independent CodeGen pass at this point in the pipeline. + void addCommonPass(char &ID); + + /// printNoVerify - Add a pass to dump the machine function, if debugging is + /// enabled. + /// + void printNoVerify(const char *Banner) const; + + /// printAndVerify - Add a pass to dump then verify the machine function, if + /// those steps are enabled. + /// + void printAndVerify(const char *Banner) const; +}; +} // namespace llvm + +/// List of target independent CodeGen pass IDs. +namespace llvm { /// createUnreachableBlockEliminationPass - The LLVM code generator does not /// work well with unreachable basic blocks (what live ranges make sense for a /// block that cannot be reached?). As such, a code generator should either diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 61c60c5c73f..afb15c08951 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -38,6 +38,7 @@ class TargetInstrInfo; class TargetIntrinsicInfo; class TargetJITInfo; class TargetLowering; +class TargetPassConfig; class TargetRegisterInfo; class TargetSelectionDAGInfo; class TargetSubtargetInfo; @@ -200,6 +201,10 @@ public: /// Default, or Aggressive. CodeGenOpt::Level getOptLevel() const; + void setFastISel(bool Enable) { Options.EnableFastISel = Enable; } + + bool shouldPrintMachineCode() const { return Options.PrintMachineCode; } + /// getAsmVerbosityDefault - Returns the default value of asm verbosity. /// static bool getAsmVerbosityDefault(); @@ -232,10 +237,6 @@ public: CGFT_Null // Do not emit any output. }; - /// getEnableTailMergeDefault - the default setting for -enable-tail-merge - /// on this target. User flag overrides. - virtual bool getEnableTailMergeDefault() const { return true; } - /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. This method should return true if emission of this file type @@ -282,24 +283,12 @@ protected: // Can only create subclasses. Reloc::Model RM, CodeModel::Model CM, CodeGenOpt::Level OL); - /// printNoVerify - Add a pass to dump the machine function, if debugging is - /// enabled. - /// - void printNoVerify(PassManagerBase &PM, const char *Banner) const; - - /// printAndVerify - Add a pass to dump then verify the machine function, if - /// those steps are enabled. - /// - void printAndVerify(PassManagerBase &PM, const char *Banner) const; - -private: - /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for - /// both emitting to assembly files or machine code output. - /// - bool addCommonCodeGenPasses(PassManagerBase &, - bool DisableVerify, MCContext *&OutCtx); - public: + /// createPassConfig - Create a pass configuration object to be used by + /// addPassToEmitX methods for generating a pipeline of CodeGen passes. + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); + /// addPassesToEmitFile - Add passes to the specified pass manager to get the /// specified file emitted. Typically this will involve several steps of code /// generation. @@ -328,51 +317,6 @@ public: raw_ostream &OS, bool DisableVerify = true); - /// Target-Independent Code Generator Pass Configuration Options. - - /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM - /// passes (which are run just before instruction selector). - virtual bool addPreISel(PassManagerBase &) { - return true; - } - - /// addInstSelector - This method should install an instruction selector pass, - /// which converts from LLVM code to machine instructions. - virtual bool addInstSelector(PassManagerBase &) { - return true; - } - - /// addPreRegAlloc - This method may be implemented by targets that want to - /// run passes immediately before register allocation. This should return - /// true if -print-machineinstrs should print after these passes. - virtual bool addPreRegAlloc(PassManagerBase &) { - return false; - } - - /// addPostRegAlloc - This method may be implemented by targets that want - /// to run passes after register allocation but before prolog-epilog - /// insertion. This should return true if -print-machineinstrs should print - /// after these passes. - virtual bool addPostRegAlloc(PassManagerBase &) { - return false; - } - - /// 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 - /// print after these passes. - virtual bool addPreSched2(PassManagerBase &) { - return false; - } - - /// addPreEmitPass - This pass may be implemented by targets that want to run - /// passes immediately before machine code is emitted. This should return - /// true if -print-machineinstrs should print out the code after the passes. - virtual bool addPreEmitPass(PassManagerBase &) { - return false; - } - - /// addCodeEmitter - This pass should be overridden by the target to add a /// code emitter, if supported. If this is not supported, 'true' should be /// returned. @@ -380,10 +324,6 @@ public: JITCodeEmitter &) { return true; } - - /// getEnableTailMergeDefault - the default setting for -enable-tail-merge - /// on this target. User flag overrides. - virtual bool getEnableTailMergeDefault() const { return true; } }; } // End llvm namespace diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 3a9f0f013b1..34bf77b7901 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -125,13 +125,21 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, "and that InitializeAllTargetMCs() is being invoked!"); } +/// createPassConfig - Create a pass configuration object to be used by +/// addPassToEmitX methods for generating a pipeline of CodeGen passes. +TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new TargetPassConfig(this, PM, DisableVerify); +} + bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, formatted_raw_ostream &Out, CodeGenFileType FileType, bool DisableVerify) { // Add common CodeGen passes. MCContext *Context = 0; - if (addCommonCodeGenPasses(PM, DisableVerify, Context)) + OwningPtr PassConfig(createPassConfig(PM, DisableVerify)); + if (PassConfig->addCodeGenPasses(Context)) return true; assert(Context != 0 && "Failed to get MCContext"); @@ -215,7 +223,8 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, bool DisableVerify) { // Add common CodeGen passes. MCContext *Ctx = 0; - if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) + OwningPtr PassConfig(createPassConfig(PM, DisableVerify)); + if (PassConfig->addCodeGenPasses(Ctx)) return true; addCodeEmitter(PM, JCE); @@ -234,7 +243,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, raw_ostream &Out, bool DisableVerify) { // Add common CodeGen passes. - if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) + OwningPtr PassConfig(createPassConfig(PM, DisableVerify)); + if (PassConfig->addCodeGenPasses(Ctx)) return true; if (hasMCSaveTempLabels()) @@ -268,27 +278,23 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, return false; // success! } -void LLVMTargetMachine::printNoVerify(PassManagerBase &PM, - const char *Banner) const { - if (Options.PrintMachineCode) +void TargetPassConfig::printNoVerify(const char *Banner) const { + if (TM->shouldPrintMachineCode()) PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); } -void LLVMTargetMachine::printAndVerify(PassManagerBase &PM, - const char *Banner) const { - if (Options.PrintMachineCode) +void TargetPassConfig::printAndVerify(const char *Banner) const { + if (TM->shouldPrintMachineCode()) PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); if (VerifyMachineCode) PM.add(createMachineVerifierPass(Banner)); } -/// addCommonCodeGenPasses - Add standard LLVM codegen passes used for both +/// addCodeGenPasses - Add standard LLVM codegen passes used for both /// emitting to assembly files or machine code output. /// -bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, - bool DisableVerify, - MCContext *&OutContext) { +bool TargetPassConfig::addCodeGenPasses(MCContext *&OutContext) { // Standard LLVM-Level Passes. // Basic AliasAnalysis support. @@ -317,7 +323,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Turn exception handling constructs into something the code generators can // handle. - switch (getMCAsmInfo()->getExceptionHandlingType()) { + switch (TM->getMCAsmInfo()->getExceptionHandlingType()) { case ExceptionHandling::SjLj: // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise, @@ -330,7 +336,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, case ExceptionHandling::DwarfCFI: case ExceptionHandling::ARM: case ExceptionHandling::Win64: - PM.add(createDwarfEHPass(this)); + PM.add(createDwarfEHPass(TM)); break; case ExceptionHandling::None: PM.add(createLowerInvokePass(getTargetLowering())); @@ -345,7 +351,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, PM.add(createStackProtectorPass(getTargetLowering())); - addPreISel(PM); + addPreISel(); if (PrintISelInput) PM.add(createPrintFunctionPass("\n\n" @@ -362,26 +368,26 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Install a MachineModuleInfo class, which is an immutable pass that holds // all the per-module stuff we're generating, including MCContext. MachineModuleInfo *MMI = - new MachineModuleInfo(*getMCAsmInfo(), *getRegisterInfo(), + new MachineModuleInfo(*TM->getMCAsmInfo(), *TM->getRegisterInfo(), &getTargetLowering()->getObjFileLowering()); PM.add(MMI); OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref. // Set up a MachineFunction for the rest of CodeGen to work on. - PM.add(new MachineFunctionAnalysis(*this)); + PM.add(new MachineFunctionAnalysis(*TM)); // Enable FastISel with -fast, but allow that to be overridden. if (EnableFastISelOption == cl::BOU_TRUE || (getOptLevel() == CodeGenOpt::None && EnableFastISelOption != cl::BOU_FALSE)) - Options.EnableFastISel = true; + TM->setFastISel(true); // Ask the target for an isel. - if (addInstSelector(PM)) + if (addInstSelector()) return true; // Print the instruction selected machine code... - printAndVerify(PM, "After Instruction Selection"); + printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. PM.add(createExpandISelPseudosPass()); @@ -389,7 +395,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { PM.add(createTailDuplicatePass(true)); - printAndVerify(PM, "After Pre-RegAlloc TailDuplicate"); + printAndVerify("After Pre-RegAlloc TailDuplicate"); } // Optimize PHIs before DCE: removing dead PHI cycles may make more @@ -408,7 +414,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). if (!DisableMachineDCE) PM.add(createDeadMachineInstructionElimPass()); - printAndVerify(PM, "After codegen DCE pass"); + printAndVerify("After codegen DCE pass"); if (!DisableMachineLICM) PM.add(createMachineLICMPass()); @@ -416,19 +422,19 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, PM.add(createMachineCSEPass()); if (!DisableMachineSink) PM.add(createMachineSinkingPass()); - printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); + printAndVerify("After Machine LICM, CSE and Sinking passes"); PM.add(createPeepholeOptimizerPass()); - printAndVerify(PM, "After codegen peephole optimization pass"); + printAndVerify("After codegen peephole optimization pass"); } // Run pre-ra passes. - if (addPreRegAlloc(PM)) - printAndVerify(PM, "After PreRegAlloc passes"); + if (addPreRegAlloc()) + printAndVerify("After PreRegAlloc passes"); // Perform register allocation. PM.add(createRegisterAllocator(getOptLevel())); - printAndVerify(PM, "After Register Allocation"); + printAndVerify("After Register Allocation"); // Perform stack slot coloring and post-ra machine LICM. if (getOptLevel() != CodeGenOpt::None) { @@ -441,47 +447,47 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (!DisablePostRAMachineLICM) PM.add(createMachineLICMPass(false)); - printAndVerify(PM, "After StackSlotColoring and postra Machine LICM"); + printAndVerify("After StackSlotColoring and postra Machine LICM"); } // Run post-ra passes. - if (addPostRegAlloc(PM)) - printAndVerify(PM, "After PostRegAlloc passes"); + if (addPostRegAlloc()) + printAndVerify("After PostRegAlloc passes"); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - printAndVerify(PM, "After PrologEpilogCodeInserter"); + printAndVerify("After PrologEpilogCodeInserter"); // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - printNoVerify(PM, "After BranchFolding"); + printNoVerify("After BranchFolding"); } // Tail duplication. if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { PM.add(createTailDuplicatePass(false)); - printNoVerify(PM, "After TailDuplicate"); + printNoVerify("After TailDuplicate"); } // Copy propagation. if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { PM.add(createMachineCopyPropagationPass()); - printNoVerify(PM, "After copy propagation pass"); + printNoVerify("After copy propagation pass"); } // Expand pseudo instructions before second scheduling pass. PM.add(createExpandPostRAPseudosPass()); - printNoVerify(PM, "After ExpandPostRAPseudos"); + printNoVerify("After ExpandPostRAPseudos"); // Run pre-sched2 passes. - if (addPreSched2(PM)) - printNoVerify(PM, "After PreSched2 passes"); + if (addPreSched2()) + printNoVerify("After PreSched2 passes"); // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { PM.add(createPostRAScheduler(getOptLevel())); - printNoVerify(PM, "After PostRAScheduler"); + printNoVerify("After PostRAScheduler"); } PM.add(createGCMachineCodeAnalysisPass()); @@ -495,21 +501,21 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // default currently. Eventually it should subsume CodePlacementOpt, so // when enabled, the other is disabled. PM.add(createMachineBlockPlacementPass()); - printNoVerify(PM, "After MachineBlockPlacement"); + printNoVerify("After MachineBlockPlacement"); } else { PM.add(createCodePlacementOptPass()); - printNoVerify(PM, "After CodePlacementOpt"); + printNoVerify("After CodePlacementOpt"); } // Run a separate pass to collect block placement statistics. if (EnableBlockPlacementStats) { PM.add(createMachineBlockPlacementStatsPass()); - printNoVerify(PM, "After MachineBlockPlacementStats"); + printNoVerify("After MachineBlockPlacementStats"); } } - if (addPreEmitPass(PM)) - printNoVerify(PM, "After PreEmit passes"); + if (addPreEmitPass()) + printNoVerify("After PreEmit passes"); return false; } diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp index 9d6f9bd47a7..cfe45584ed9 100644 --- a/lib/Target/ARM/ARMTargetMachine.cpp +++ b/lib/Target/ARM/ARMTargetMachine.cpp @@ -107,33 +107,62 @@ ThumbTargetMachine::ThumbTargetMachine(const Target &T, StringRef TT, : (ARMFrameLowering*)new Thumb1FrameLowering(Subtarget)) { } -bool ARMBaseTargetMachine::addPreISel(PassManagerBase &PM) { - if (getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) - PM.add(createGlobalMergePass(getTargetLowering())); +namespace { +/// ARM Code Generator Pass Configuration Options. +class ARMPassConfig : public TargetPassConfig { +public: + ARMPassConfig(ARMBaseTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + ARMBaseTargetMachine &getARMTargetMachine() const { + return getTM(); + } + + const ARMSubtarget &getARMSubtarget() const { + return *getARMTargetMachine().getSubtargetImpl(); + } + + virtual bool addPreISel(); + virtual bool addInstSelector(); + virtual bool addPreRegAlloc(); + virtual bool addPreSched2(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *ARMBaseTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new ARMPassConfig(this, PM, DisableVerify); +} + +bool ARMPassConfig::addPreISel() { + if (TM->getOptLevel() != CodeGenOpt::None && EnableGlobalMerge) + PM.add(createGlobalMergePass(TM->getTargetLowering())); return false; } -bool ARMBaseTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createARMISelDag(*this, getOptLevel())); +bool ARMPassConfig::addInstSelector() { + PM.add(createARMISelDag(getARMTargetMachine(), getOptLevel())); return false; } -bool ARMBaseTargetMachine::addPreRegAlloc(PassManagerBase &PM) { +bool ARMPassConfig::addPreRegAlloc() { // FIXME: temporarily disabling load / store optimization pass for Thumb1. - if (getOptLevel() != CodeGenOpt::None && !Subtarget.isThumb1Only()) + if (getOptLevel() != CodeGenOpt::None && !getARMSubtarget().isThumb1Only()) PM.add(createARMLoadStoreOptimizationPass(true)); - if (getOptLevel() != CodeGenOpt::None && Subtarget.isCortexA9()) + if (getOptLevel() != CodeGenOpt::None && getARMSubtarget().isCortexA9()) PM.add(createMLxExpansionPass()); return true; } -bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM) { +bool ARMPassConfig::addPreSched2() { // FIXME: temporarily disabling load / store optimization pass for Thumb1. if (getOptLevel() != CodeGenOpt::None) { - if (!Subtarget.isThumb1Only()) + if (!getARMSubtarget().isThumb1Only()) PM.add(createARMLoadStoreOptimizationPass()); - if (Subtarget.hasNEON()) + if (getARMSubtarget().hasNEON()) PM.add(createExecutionDependencyFixPass(&ARM::DPRRegClass)); } @@ -142,18 +171,18 @@ bool ARMBaseTargetMachine::addPreSched2(PassManagerBase &PM) { PM.add(createARMExpandPseudoPass()); if (getOptLevel() != CodeGenOpt::None) { - if (!Subtarget.isThumb1Only()) + if (!getARMSubtarget().isThumb1Only()) PM.add(createIfConverterPass()); } - if (Subtarget.isThumb2()) + if (getARMSubtarget().isThumb2()) PM.add(createThumb2ITBlockPass()); return true; } -bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM) { - if (Subtarget.isThumb2()) { - if (!Subtarget.prefers32BitThumb()) +bool ARMPassConfig::addPreEmitPass() { + if (getARMSubtarget().isThumb2()) { + if (!getARMSubtarget().prefers32BitThumb()) PM.add(createThumb2SizeReductionPass()); // Constant island pass work on unbundled instructions. @@ -165,8 +194,7 @@ bool ARMBaseTargetMachine::addPreEmitPass(PassManagerBase &PM) { return true; } -bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, - JITCodeEmitter &JCE) { +bool ARMBaseTargetMachine::addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE) { // Machine code emitter pass for ARM. PM.add(createARMJITCodeEmitterPass(*this, JCE)); return false; diff --git a/lib/Target/ARM/ARMTargetMachine.h b/lib/Target/ARM/ARMTargetMachine.h index b8a384928f5..5e70b7186d8 100644 --- a/lib/Target/ARM/ARMTargetMachine.h +++ b/lib/Target/ARM/ARMTargetMachine.h @@ -52,11 +52,8 @@ public: } // Pass Pipeline Configuration - virtual bool addPreISel(PassManagerBase &PM); - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreRegAlloc(PassManagerBase &PM); - virtual bool addPreSched2(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, bool DisableVerify); + virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &MCE); }; diff --git a/lib/Target/CellSPU/SPUTargetMachine.cpp b/lib/Target/CellSPU/SPUTargetMachine.cpp index 1e922a4efd1..83e22f624c4 100644 --- a/lib/Target/CellSPU/SPUTargetMachine.cpp +++ b/lib/Target/CellSPU/SPUTargetMachine.cpp @@ -21,7 +21,7 @@ using namespace llvm; -extern "C" void LLVMInitializeCellSPUTarget() { +extern "C" void LLVMInitializeCellSPUTarget() { // Register the target. RegisterTargetMachine X(TheCellSPUTarget); } @@ -51,15 +51,36 @@ SPUTargetMachine::SPUTargetMachine(const Target &T, StringRef TT, // Pass Pipeline Configuration //===----------------------------------------------------------------------===// -bool SPUTargetMachine::addInstSelector(PassManagerBase &PM) { +namespace { +/// SPU Code Generator Pass Configuration Options. +class SPUPassConfig : public TargetPassConfig { +public: + SPUPassConfig(SPUTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + SPUTargetMachine &getSPUTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *SPUTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new SPUPassConfig(this, PM, DisableVerify); +} + +bool SPUPassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createSPUISelDag(*this)); + PM.add(createSPUISelDag(getSPUTargetMachine())); return false; } // passes to run just before printing the assembly -bool SPUTargetMachine:: -addPreEmitPass(PassManagerBase &PM) { +bool SPUPassConfig::addPreEmitPass() { // load the TCE instruction scheduler, if available via // loaded plugins typedef llvm::FunctionPass* (*BuilderFunc)(const char*); @@ -70,6 +91,6 @@ addPreEmitPass(PassManagerBase &PM) { PM.add(schedulerCreator("cellspu")); //align instructions with nops/lnops for dual issue - PM.add(createSPUNopFillerPass(*this)); + PM.add(createSPUNopFillerPass(getSPUTargetMachine())); return true; } diff --git a/lib/Target/CellSPU/SPUTargetMachine.h b/lib/Target/CellSPU/SPUTargetMachine.h index 0841feef32b..7eeb128aca5 100644 --- a/lib/Target/CellSPU/SPUTargetMachine.h +++ b/lib/Target/CellSPU/SPUTargetMachine.h @@ -61,7 +61,7 @@ public: return NULL; } - virtual const SPUTargetLowering *getTargetLowering() const { + virtual const SPUTargetLowering *getTargetLowering() const { return &TLInfo; } @@ -72,7 +72,7 @@ public: virtual const SPURegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } - + virtual const TargetData *getTargetData() const { return &DataLayout; } @@ -80,10 +80,10 @@ public: virtual const InstrItineraryData *getInstrItineraryData() const { return &InstrItins; } - + // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; } // end namespace llvm diff --git a/lib/Target/Hexagon/HexagonTargetMachine.cpp b/lib/Target/Hexagon/HexagonTargetMachine.cpp index ee09dafd2b1..83f0b40af6d 100644 --- a/lib/Target/Hexagon/HexagonTargetMachine.cpp +++ b/lib/Target/Hexagon/HexagonTargetMachine.cpp @@ -76,14 +76,39 @@ bool HexagonTargetMachine::addPassesForOptimizations(PassManagerBase &PM) { return true; } -bool HexagonTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createHexagonRemoveExtendOps(*this)); - PM.add(createHexagonISelDag(*this)); +namespace { +/// Hexagon Code Generator Pass Configuration Options. +class HexagonPassConfig : public TargetPassConfig { +public: + HexagonPassConfig(HexagonTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + HexagonTargetMachine &getHexagonTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool addPreRegAlloc(); + virtual bool addPostRegAlloc(); + virtual bool addPreSched2(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *HexagonTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new HexagonPassConfig(this, PM, DisableVerify); +} + +bool HexagonPassConfig::addInstSelector() { + PM.add(createHexagonRemoveExtendOps(getHexagonTargetMachine())); + PM.add(createHexagonISelDag(getHexagonTargetMachine())); return false; } -bool HexagonTargetMachine::addPreRegAlloc(PassManagerBase &PM) { +bool HexagonPassConfig::addPreRegAlloc() { if (!DisableHardwareLoops) { PM.add(createHexagonHardwareLoops()); } @@ -91,28 +116,28 @@ bool HexagonTargetMachine::addPreRegAlloc(PassManagerBase &PM) { return false; } -bool HexagonTargetMachine::addPostRegAlloc(PassManagerBase &PM) { - PM.add(createHexagonCFGOptimizer(*this)); +bool HexagonPassConfig::addPostRegAlloc() { + PM.add(createHexagonCFGOptimizer(getHexagonTargetMachine())); return true; } -bool HexagonTargetMachine::addPreSched2(PassManagerBase &PM) { +bool HexagonPassConfig::addPreSched2() { PM.add(createIfConverterPass()); return true; } -bool HexagonTargetMachine::addPreEmitPass(PassManagerBase &PM) { +bool HexagonPassConfig::addPreEmitPass() { if (!DisableHardwareLoops) { PM.add(createHexagonFixupHwLoops()); } // Expand Spill code for predicate registers. - PM.add(createHexagonExpandPredSpillCode(*this)); + PM.add(createHexagonExpandPredSpillCode(getHexagonTargetMachine())); // Split up TFRcondsets into conditional transfers. - PM.add(createHexagonSplitTFRCondSets(*this)); + PM.add(createHexagonSplitTFRCondSets(getHexagonTargetMachine())); return false; } diff --git a/lib/Target/Hexagon/HexagonTargetMachine.h b/lib/Target/Hexagon/HexagonTargetMachine.h index 712cf3d5eae..d1c76db30ba 100644 --- a/lib/Target/Hexagon/HexagonTargetMachine.h +++ b/lib/Target/Hexagon/HexagonTargetMachine.h @@ -72,11 +72,8 @@ public: // Pass Pipeline Configuration. virtual bool addPassesForOptimizations(PassManagerBase &PM); - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); - virtual bool addPreRegAlloc(llvm::PassManagerBase &PM); - virtual bool addPostRegAlloc(PassManagerBase &PM); - virtual bool addPreSched2(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; extern bool flag_aligned_memcpy; diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp index 5ed81dd28be..aad3500ffde 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp +++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp @@ -45,17 +45,39 @@ MBlazeTargetMachine(const Target &T, StringRef TT, InstrItins(Subtarget.getInstrItineraryData()) { } +namespace { +/// MBlaze Code Generator Pass Configuration Options. +class MBlazePassConfig : public TargetPassConfig { +public: + MBlazePassConfig(MBlazeTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + MBlazeTargetMachine &getMBlazeTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *MBlazeTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new MBlazePassConfig(this, PM, DisableVerify); +} + // Install an instruction selector pass using // the ISelDag to gen MBlaze code. -bool MBlazeTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createMBlazeISelDag(*this)); +bool MBlazePassConfig::addInstSelector() { + PM.add(createMBlazeISelDag(getMBlazeTargetMachine())); return false; } // Implemented by targets that want to run passes immediately before // machine code is emitted. return true if -print-machineinstrs should // print out the code after the passes. -bool MBlazeTargetMachine::addPreEmitPass(PassManagerBase &PM) { - PM.add(createMBlazeDelaySlotFillerPass(*this)); +bool MBlazePassConfig::addPreEmitPass() { + PM.add(createMBlazeDelaySlotFillerPass(getMBlazeTargetMachine())); return true; } diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.h b/lib/Target/MBlaze/MBlazeTargetMachine.h index 036f1b6cf52..58fcbfd6719 100644 --- a/lib/Target/MBlaze/MBlazeTargetMachine.h +++ b/lib/Target/MBlaze/MBlazeTargetMachine.h @@ -79,8 +79,8 @@ namespace llvm { } // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; } // End llvm namespace diff --git a/lib/Target/MSP430/MSP430TargetMachine.cpp b/lib/Target/MSP430/MSP430TargetMachine.cpp index a0fc3daa3c8..a2e97f11e50 100644 --- a/lib/Target/MSP430/MSP430TargetMachine.cpp +++ b/lib/Target/MSP430/MSP430TargetMachine.cpp @@ -38,14 +38,35 @@ MSP430TargetMachine::MSP430TargetMachine(const Target &T, InstrInfo(*this), TLInfo(*this), TSInfo(*this), FrameLowering(Subtarget) { } +namespace { +/// MSP430 Code Generator Pass Configuration Options. +class MSP430PassConfig : public TargetPassConfig { +public: + MSP430PassConfig(MSP430TargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} -bool MSP430TargetMachine::addInstSelector(PassManagerBase &PM) { + MSP430TargetMachine &getMSP430TargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *MSP430TargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new MSP430PassConfig(this, PM, DisableVerify); +} + +bool MSP430PassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createMSP430ISelDag(*this, getOptLevel())); + PM.add(createMSP430ISelDag(getMSP430TargetMachine(), getOptLevel())); return false; } -bool MSP430TargetMachine::addPreEmitPass(PassManagerBase &PM) { +bool MSP430PassConfig::addPreEmitPass() { // Must run branch selection immediately preceding the asm printer. PM.add(createMSP430BranchSelectionPass()); return false; diff --git a/lib/Target/MSP430/MSP430TargetMachine.h b/lib/Target/MSP430/MSP430TargetMachine.h index 28d482a28f0..19b7bf1b717 100644 --- a/lib/Target/MSP430/MSP430TargetMachine.h +++ b/lib/Target/MSP430/MSP430TargetMachine.h @@ -62,8 +62,8 @@ public: return &TSInfo; } - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; // MSP430TargetMachine. } // end namespace llvm diff --git a/lib/Target/Mips/MipsTargetMachine.cpp b/lib/Target/Mips/MipsTargetMachine.cpp index 6088ceedcc0..e48c3745f61 100644 --- a/lib/Target/Mips/MipsTargetMachine.cpp +++ b/lib/Target/Mips/MipsTargetMachine.cpp @@ -14,6 +14,7 @@ #include "Mips.h" #include "MipsTargetMachine.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -88,37 +89,61 @@ Mips64elTargetMachine(const Target &T, StringRef TT, CodeGenOpt::Level OL) : MipsTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) {} +namespace { +/// Mips Code Generator Pass Configuration Options. +class MipsPassConfig : public TargetPassConfig { +public: + MipsPassConfig(MipsTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + MipsTargetMachine &getMipsTargetMachine() const { + return getTM(); + } + + const MipsSubtarget &getMipsSubtarget() const { + return *getMipsTargetMachine().getSubtargetImpl(); + } + + virtual bool addInstSelector(); + virtual bool addPreRegAlloc(); + virtual bool addPostRegAlloc(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *MipsTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new MipsPassConfig(this, PM, DisableVerify); +} + // Install an instruction selector pass using // the ISelDag to gen Mips code. -bool MipsTargetMachine:: -addInstSelector(PassManagerBase &PM) +bool MipsPassConfig::addInstSelector() { - PM.add(createMipsISelDag(*this)); + PM.add(createMipsISelDag(getMipsTargetMachine())); return false; } // Implemented by targets that want to run passes immediately before // machine code is emitted. return true if -print-machineinstrs should // print out the code after the passes. -bool MipsTargetMachine:: -addPreEmitPass(PassManagerBase &PM) +bool MipsPassConfig::addPreEmitPass() { - PM.add(createMipsDelaySlotFillerPass(*this)); + PM.add(createMipsDelaySlotFillerPass(getMipsTargetMachine())); return true; } -bool MipsTargetMachine:: -addPreRegAlloc(PassManagerBase &PM) { +bool MipsPassConfig::addPreRegAlloc() { // Do not restore $gp if target is Mips64. // In N32/64, $gp is a callee-saved register. - if (!Subtarget.hasMips64()) - PM.add(createMipsEmitGPRestorePass(*this)); + if (!getMipsSubtarget().hasMips64()) + PM.add(createMipsEmitGPRestorePass(getMipsTargetMachine())); return true; } -bool MipsTargetMachine:: -addPostRegAlloc(PassManagerBase &PM) { - PM.add(createMipsExpandPseudoPass(*this)); +bool MipsPassConfig::addPostRegAlloc() { + PM.add(createMipsExpandPseudoPass(getMipsTargetMachine())); return true; } diff --git a/lib/Target/Mips/MipsTargetMachine.h b/lib/Target/Mips/MipsTargetMachine.h index 6e88956f655..b2a609c5c52 100644 --- a/lib/Target/Mips/MipsTargetMachine.h +++ b/lib/Target/Mips/MipsTargetMachine.h @@ -68,10 +68,8 @@ namespace llvm { } // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); - virtual bool addPreRegAlloc(PassManagerBase &PM); - virtual bool addPostRegAlloc(PassManagerBase &); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE); diff --git a/lib/Target/PTX/PTXTargetMachine.cpp b/lib/Target/PTX/PTXTargetMachine.cpp index f8787a7cd5b..cf45c8fe47b 100644 --- a/lib/Target/PTX/PTXTargetMachine.cpp +++ b/lib/Target/PTX/PTXTargetMachine.cpp @@ -105,14 +105,36 @@ PTX64TargetMachine::PTX64TargetMachine(const Target &T, StringRef TT, : PTXTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL, true) { } -bool PTXTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createPTXISelDag(*this, getOptLevel())); +namespace { +/// PTX Code Generator Pass Configuration Options. +class PTXPassConfig : public TargetPassConfig { +public: + PTXPassConfig(PTXTargetMachine *TM, PassManagerBase &PM, bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + PTXTargetMachine &getPTXTargetMachine() const { + return getTM(); + } + + bool addInstSelector(); + bool addPostRegAlloc(); + bool addCodeGenPasses(MCContext *&OutContext); +}; +} // namespace + +TargetPassConfig *PTXTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new PTXPassConfig(this, PM, DisableVerify); +} + +bool PTXPassConfig::addInstSelector() { + PM.add(createPTXISelDag(getPTXTargetMachine(), getOptLevel())); return false; } -bool PTXTargetMachine::addPostRegAlloc(PassManagerBase &PM) { +bool PTXPassConfig::addPostRegAlloc() { // PTXMFInfoExtract must after register allocation! - //PM.add(createPTXMFInfoExtract(*this)); + //PM.add(createPTXMFInfoExtract(getPTXTargetMachine())); return false; } @@ -124,7 +146,8 @@ bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM, // Add common CodeGen passes. MCContext *Context = 0; - if (addCommonCodeGenPasses(PM, DisableVerify, Context)) + OwningPtr PassConfig(createPassConfig(PM, DisableVerify)); + if (PassConfig->addCodeGenPasses(Context)) return true; assert(Context != 0 && "Failed to get MCContext"); @@ -179,9 +202,7 @@ bool PTXTargetMachine::addPassesToEmitFile(PassManagerBase &PM, return false; } -bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, - bool DisableVerify, - MCContext *&OutContext) { +bool PTXPassConfig::addCodeGenPasses(MCContext *&OutContext) { // Add standard LLVM codegen passes. // This is derived from LLVMTargetMachine::addCommonCodeGenPasses, with some // modifications for the PTX target. @@ -220,7 +241,7 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, PM.add(createStackProtectorPass(getTargetLowering())); - addPreISel(PM); + addPreISel(); //PM.add(createPrintFunctionPass("\n\n" // "*** Final LLVM Code input to ISel ***\n", @@ -235,21 +256,21 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Install a MachineModuleInfo class, which is an immutable pass that holds // all the per-module stuff we're generating, including MCContext. - MachineModuleInfo *MMI = new MachineModuleInfo(*getMCAsmInfo(), - *getRegisterInfo(), + MachineModuleInfo *MMI = new MachineModuleInfo(*TM->getMCAsmInfo(), + *TM->getRegisterInfo(), &getTargetLowering()->getObjFileLowering()); PM.add(MMI); OutContext = &MMI->getContext(); // Return the MCContext specifically by-ref. // Set up a MachineFunction for the rest of CodeGen to work on. - PM.add(new MachineFunctionAnalysis(*this)); + PM.add(new MachineFunctionAnalysis(*TM)); // Ask the target for an isel. - if (addInstSelector(PM)) + if (addInstSelector()) return true; // Print the instruction selected machine code... - printAndVerify(PM, "After Instruction Selection"); + printAndVerify("After Instruction Selection"); // Expand pseudo-instructions emitted by ISel. PM.add(createExpandISelPseudosPass()); @@ -257,7 +278,7 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Pre-ra tail duplication. if (getOptLevel() != CodeGenOpt::None) { PM.add(createTailDuplicatePass(true)); - printAndVerify(PM, "After Pre-RegAlloc TailDuplicate"); + printAndVerify("After Pre-RegAlloc TailDuplicate"); } // Optimize PHIs before DCE: removing dead PHI cycles may make more @@ -275,24 +296,24 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // used by tail calls, where the tail calls reuse the incoming stack // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). PM.add(createDeadMachineInstructionElimPass()); - printAndVerify(PM, "After codegen DCE pass"); + printAndVerify("After codegen DCE pass"); PM.add(createMachineLICMPass()); PM.add(createMachineCSEPass()); PM.add(createMachineSinkingPass()); - printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); + printAndVerify("After Machine LICM, CSE and Sinking passes"); PM.add(createPeepholeOptimizerPass()); - printAndVerify(PM, "After codegen peephole optimization pass"); + printAndVerify("After codegen peephole optimization pass"); } // Run pre-ra passes. - if (addPreRegAlloc(PM)) - printAndVerify(PM, "After PreRegAlloc passes"); + if (addPreRegAlloc()) + printAndVerify("After PreRegAlloc passes"); // Perform register allocation. PM.add(createPTXRegisterAllocator()); - printAndVerify(PM, "After Register Allocation"); + printAndVerify("After Register Allocation"); // Perform stack slot coloring and post-ra machine LICM. if (getOptLevel() != CodeGenOpt::None) { @@ -305,40 +326,40 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, //if (!DisablePostRAMachineLICM) // PM.add(createMachineLICMPass(false)); - printAndVerify(PM, "After StackSlotColoring and postra Machine LICM"); + printAndVerify("After StackSlotColoring and postra Machine LICM"); } // Run post-ra passes. - if (addPostRegAlloc(PM)) - printAndVerify(PM, "After PostRegAlloc passes"); + if (addPostRegAlloc()) + printAndVerify("After PostRegAlloc passes"); PM.add(createExpandPostRAPseudosPass()); - printAndVerify(PM, "After ExpandPostRAPseudos"); + printAndVerify("After ExpandPostRAPseudos"); // Insert prolog/epilog code. Eliminate abstract frame index references... PM.add(createPrologEpilogCodeInserter()); - printAndVerify(PM, "After PrologEpilogCodeInserter"); + printAndVerify("After PrologEpilogCodeInserter"); // Run pre-sched2 passes. - if (addPreSched2(PM)) - printAndVerify(PM, "After PreSched2 passes"); + if (addPreSched2()) + printAndVerify("After PreSched2 passes"); // Second pass scheduler. if (getOptLevel() != CodeGenOpt::None) { PM.add(createPostRAScheduler(getOptLevel())); - printAndVerify(PM, "After PostRAScheduler"); + printAndVerify("After PostRAScheduler"); } // Branch folding must be run after regalloc and prolog/epilog insertion. if (getOptLevel() != CodeGenOpt::None) { PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - printNoVerify(PM, "After BranchFolding"); + printNoVerify("After BranchFolding"); } // Tail duplication. if (getOptLevel() != CodeGenOpt::None) { PM.add(createTailDuplicatePass(false)); - printNoVerify(PM, "After TailDuplicate"); + printNoVerify("After TailDuplicate"); } PM.add(createGCMachineCodeAnalysisPass()); @@ -348,14 +369,14 @@ bool PTXTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (getOptLevel() != CodeGenOpt::None) { PM.add(createCodePlacementOptPass()); - printNoVerify(PM, "After CodePlacementOpt"); + printNoVerify("After CodePlacementOpt"); } - if (addPreEmitPass(PM)) - printNoVerify(PM, "After PreEmit passes"); + if (addPreEmitPass()) + printNoVerify("After PreEmit passes"); - PM.add(createPTXMFInfoExtract(*this, getOptLevel())); - PM.add(createPTXFPRoundingModePass(*this, getOptLevel())); + PM.add(createPTXMFInfoExtract(getPTXTargetMachine(), getOptLevel())); + PM.add(createPTXFPRoundingModePass(getPTXTargetMachine(), getOptLevel())); return false; } diff --git a/lib/Target/PTX/PTXTargetMachine.h b/lib/Target/PTX/PTXTargetMachine.h index b051348781c..3e991399ab7 100644 --- a/lib/Target/PTX/PTXTargetMachine.h +++ b/lib/Target/PTX/PTXTargetMachine.h @@ -59,9 +59,6 @@ class PTXTargetMachine : public LLVMTargetMachine { virtual const PTXSubtarget *getSubtargetImpl() const { return &Subtarget; } - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPostRegAlloc(PassManagerBase &PM); - // We override this method to supply our own set of codegen passes. virtual bool addPassesToEmitFile(PassManagerBase &, formatted_raw_ostream &, @@ -83,10 +80,9 @@ class PTXTargetMachine : public LLVMTargetMachine { return true; } - private: - - bool addCommonCodeGenPasses(PassManagerBase &, - bool DisableVerify, MCContext *&OutCtx); + // Pass Pipeline Configuration + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; // class PTXTargetMachine diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index 0bbbb0608ce..92986613776 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -15,6 +15,7 @@ #include "PPCTargetMachine.h" #include "llvm/PassManager.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/TargetRegistry.h" @@ -40,10 +41,6 @@ PPCTargetMachine::PPCTargetMachine(const Target &T, StringRef TT, InstrItins(Subtarget.getInstrItineraryData()) { } -/// Override this for PowerPC. Tail merging happily breaks up instruction issue -/// groups, which typically degrades performance. -bool PPCTargetMachine::getEnableTailMergeDefault() const { return false; } - void PPC32TargetMachine::anchor() { } PPC32TargetMachine::PPC32TargetMachine(const Target &T, StringRef TT, @@ -69,13 +66,40 @@ PPC64TargetMachine::PPC64TargetMachine(const Target &T, StringRef TT, // Pass Pipeline Configuration //===----------------------------------------------------------------------===// -bool PPCTargetMachine::addInstSelector(PassManagerBase &PM) { +namespace { +/// PPC Code Generator Pass Configuration Options. +class PPCPassConfig : public TargetPassConfig { +public: + PPCPassConfig(PPCTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + PPCTargetMachine &getPPCTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool getEnableTailMergeDefault() const; + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *PPCTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new PPCPassConfig(this, PM, DisableVerify); +} + +bool PPCPassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createPPCISelDag(*this)); + PM.add(createPPCISelDag(getPPCTargetMachine())); return false; } -bool PPCTargetMachine::addPreEmitPass(PassManagerBase &PM) { +/// 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()); return false; diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h index 03147eb0c4c..2877201ed7c 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.h +++ b/lib/Target/PowerPC/PPCTargetMachine.h @@ -67,11 +67,10 @@ public: } // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE); - virtual bool getEnableTailMergeDefault() const; }; /// PPC32TargetMachine - PowerPC 32-bit target machine. diff --git a/lib/Target/Sparc/SparcTargetMachine.cpp b/lib/Target/Sparc/SparcTargetMachine.cpp index cfb23438bd4..f45de4b1454 100644 --- a/lib/Target/Sparc/SparcTargetMachine.cpp +++ b/lib/Target/Sparc/SparcTargetMachine.cpp @@ -13,6 +13,7 @@ #include "Sparc.h" #include "SparcTargetMachine.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -24,7 +25,7 @@ extern "C" void LLVMInitializeSparcTarget() { /// SparcTargetMachine ctor - Create an ILP32 architecture model /// -SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT, +SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, @@ -37,17 +38,39 @@ SparcTargetMachine::SparcTargetMachine(const Target &T, StringRef TT, FrameLowering(Subtarget) { } -bool SparcTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createSparcISelDag(*this)); +namespace { +/// Sparc Code Generator Pass Configuration Options. +class SparcPassConfig : public TargetPassConfig { +public: + SparcPassConfig(SparcTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + SparcTargetMachine &getSparcTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *SparcTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new SparcPassConfig(this, PM, DisableVerify); +} + +bool SparcPassConfig::addInstSelector() { + PM.add(createSparcISelDag(getSparcTargetMachine())); return false; } /// addPreEmitPass - This pass may be implemented by targets that want to run /// passes immediately before machine code is emitted. This should return /// true if -print-machineinstrs should print out the code after the passes. -bool SparcTargetMachine::addPreEmitPass(PassManagerBase &PM){ - PM.add(createSparcFPMoverPass(*this)); - PM.add(createSparcDelaySlotFillerPass(*this)); +bool SparcPassConfig::addPreEmitPass(){ + PM.add(createSparcFPMoverPass(getSparcTargetMachine())); + PM.add(createSparcDelaySlotFillerPass(getSparcTargetMachine())); return true; } @@ -65,7 +88,7 @@ SparcV8TargetMachine::SparcV8TargetMachine(const Target &T, void SparcV9TargetMachine::anchor() { } -SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, +SparcV9TargetMachine::SparcV9TargetMachine(const Target &T, StringRef TT, StringRef CPU, StringRef FS, const TargetOptions &Options, diff --git a/lib/Target/Sparc/SparcTargetMachine.h b/lib/Target/Sparc/SparcTargetMachine.h index 62843459c4f..2622af25e50 100644 --- a/lib/Target/Sparc/SparcTargetMachine.h +++ b/lib/Target/Sparc/SparcTargetMachine.h @@ -55,8 +55,8 @@ public: virtual const TargetData *getTargetData() const { return &DataLayout; } // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; /// SparcV8TargetMachine - Sparc 32-bit target machine diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 2a6f4a6a7f7..08817351376 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -117,35 +117,63 @@ UseVZeroUpper("x86-use-vzeroupper", // Pass Pipeline Configuration //===----------------------------------------------------------------------===// -bool X86TargetMachine::addInstSelector(PassManagerBase &PM) { +namespace { +/// X86 Code Generator Pass Configuration Options. +class X86PassConfig : public TargetPassConfig { +public: + X86PassConfig(X86TargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + X86TargetMachine &getX86TargetMachine() const { + return getTM(); + } + + const X86Subtarget &getX86Subtarget() const { + return *getX86TargetMachine().getSubtargetImpl(); + } + + virtual bool addInstSelector(); + virtual bool addPreRegAlloc(); + virtual bool addPostRegAlloc(); + virtual bool addPreEmitPass(); +}; +} // namespace + +TargetPassConfig *X86TargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new X86PassConfig(this, PM, DisableVerify); +} + +bool X86PassConfig::addInstSelector() { // Install an instruction selector. - PM.add(createX86ISelDag(*this, getOptLevel())); + PM.add(createX86ISelDag(getX86TargetMachine(), getOptLevel())); // For 32-bit, prepend instructions to set the "global base reg" for PIC. - if (!Subtarget.is64Bit()) + if (!getX86Subtarget().is64Bit()) PM.add(createGlobalBaseRegPass()); return false; } -bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM) { +bool X86PassConfig::addPreRegAlloc() { PM.add(createX86MaxStackAlignmentHeuristicPass()); return false; // -print-machineinstr shouldn't print after this. } -bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM) { +bool X86PassConfig::addPostRegAlloc() { PM.add(createX86FloatingPointStackifierPass()); return true; // -print-machineinstr should print after this. } -bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM) { +bool X86PassConfig::addPreEmitPass() { bool ShouldPrint = false; - if (getOptLevel() != CodeGenOpt::None && Subtarget.hasSSE2()) { + if (getOptLevel() != CodeGenOpt::None && getX86Subtarget().hasSSE2()) { PM.add(createExecutionDependencyFixPass(&X86::VR128RegClass)); ShouldPrint = true; } - if (Subtarget.hasAVX() && UseVZeroUpper) { + if (getX86Subtarget().hasAVX() && UseVZeroUpper) { PM.add(createX86IssueVZeroUpperPass()); ShouldPrint = true; } diff --git a/lib/Target/X86/X86TargetMachine.h b/lib/Target/X86/X86TargetMachine.h index 2bd32b626ba..9450706f75e 100644 --- a/lib/Target/X86/X86TargetMachine.h +++ b/lib/Target/X86/X86TargetMachine.h @@ -71,10 +71,9 @@ public: } // Set up the pass pipeline. - virtual bool addInstSelector(PassManagerBase &PM); - virtual bool addPreRegAlloc(PassManagerBase &PM); - virtual bool addPostRegAlloc(PassManagerBase &PM); - virtual bool addPreEmitPass(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); + virtual bool addCodeEmitter(PassManagerBase &PM, JITCodeEmitter &JCE); }; diff --git a/lib/Target/XCore/XCoreTargetMachine.cpp b/lib/Target/XCore/XCoreTargetMachine.cpp index 7e1e0354220..a42acf18808 100644 --- a/lib/Target/XCore/XCoreTargetMachine.cpp +++ b/lib/Target/XCore/XCoreTargetMachine.cpp @@ -14,6 +14,7 @@ #include "XCore.h" #include "llvm/Module.h" #include "llvm/PassManager.h" +#include "llvm/CodeGen/Passes.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; @@ -34,8 +35,29 @@ XCoreTargetMachine::XCoreTargetMachine(const Target &T, StringRef TT, TSInfo(*this) { } -bool XCoreTargetMachine::addInstSelector(PassManagerBase &PM) { - PM.add(createXCoreISelDag(*this, getOptLevel())); +namespace { +/// XCore Code Generator Pass Configuration Options. +class XCorePassConfig : public TargetPassConfig { +public: + XCorePassConfig(XCoreTargetMachine *TM, PassManagerBase &PM, + bool DisableVerifyFlag) + : TargetPassConfig(TM, PM, DisableVerifyFlag) {} + + XCoreTargetMachine &getXCoreTargetMachine() const { + return getTM(); + } + + virtual bool addInstSelector(); +}; +} // namespace + +TargetPassConfig *XCoreTargetMachine::createPassConfig(PassManagerBase &PM, + bool DisableVerify) { + return new XCorePassConfig(this, PM, DisableVerify); +} + +bool XCorePassConfig::addInstSelector() { + PM.add(createXCoreISelDag(getXCoreTargetMachine(), getOptLevel())); return false; } diff --git a/lib/Target/XCore/XCoreTargetMachine.h b/lib/Target/XCore/XCoreTargetMachine.h index 0159b1e6b71..aafd86e90a6 100644 --- a/lib/Target/XCore/XCoreTargetMachine.h +++ b/lib/Target/XCore/XCoreTargetMachine.h @@ -56,7 +56,8 @@ public: virtual const TargetData *getTargetData() const { return &DataLayout; } // Pass Pipeline Configuration - virtual bool addInstSelector(PassManagerBase &PM); + virtual TargetPassConfig *createPassConfig(PassManagerBase &PM, + bool DisableVerify); }; } // end namespace llvm