diff options
author | Andrew Trick <atrick@apple.com> | 2012-02-04 02:56:48 +0000 |
---|---|---|
committer | Andrew Trick <atrick@apple.com> | 2012-02-04 02:56:48 +0000 |
commit | d5422654016b3ac7494db1d2ba16bd8febadb0a8 (patch) | |
tree | db0b835884838da774ec6df4bd7477d27a6d7adf /lib/CodeGen | |
parent | 7461334084aa77286b6f9af596fb0f6ba0465685 (diff) | |
download | llvm-d5422654016b3ac7494db1d2ba16bd8febadb0a8.tar.gz llvm-d5422654016b3ac7494db1d2ba16bd8febadb0a8.tar.bz2 llvm-d5422654016b3ac7494db1d2ba16bd8febadb0a8.tar.xz |
Move TargetPassConfig implementation into Passes.cpp
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149753 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 306 | ||||
-rw-r--r-- | lib/CodeGen/Passes.cpp | 311 |
2 files changed, 312 insertions, 305 deletions
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index ff729baf80..b10dab4de8 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -13,80 +13,27 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/PassManager.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/AsmPrinter.h" -#include "llvm/CodeGen/MachineFunctionAnalysis.h" -#include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/GCStrategy.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetOptions.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" -#include "llvm/Target/TargetLowering.h" -#include "llvm/Target/TargetLoweringObjectFile.h" -#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetSubtargetInfo.h" -#include "llvm/Transforms/Scalar.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/TargetRegistry.h" using namespace llvm; -static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden, - cl::desc("Disable Post Regalloc")); -static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden, - cl::desc("Disable branch folding")); -static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden, - cl::desc("Disable tail duplication")); -static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden, - cl::desc("Disable pre-register allocation tail duplication")); -static cl::opt<bool> EnableBlockPlacement("enable-block-placement", - cl::Hidden, cl::desc("Enable probability-driven block placement")); -static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats", - cl::Hidden, cl::desc("Collect probability-driven block placement stats")); -static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden, - cl::desc("Disable code placement")); -static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden, - cl::desc("Disable Stack Slot Coloring")); -static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden, - cl::desc("Disable Machine Dead Code Elimination")); -static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden, - cl::desc("Disable Machine Common Subexpression Elimination")); -static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm", - cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden, - cl::desc("Disable Machine Sinking")); -static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden, - cl::desc("Disable Loop Strength Reduction Pass")); -static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden, - cl::desc("Disable Codegen Prepare")); -static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden, - cl::desc("Disable Copy Propagation pass")); -static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden, - cl::desc("Print LLVM IR produced by the loop-reduce pass")); -static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden, - cl::desc("Print LLVM IR input to isel pass")); -static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, - cl::desc("Dump garbage collector data")); static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden, cl::desc("Show encoding in .s output")); static cl::opt<bool> ShowMCInst("show-mc-inst", cl::Hidden, cl::desc("Show instruction structure in .s output")); -static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, - cl::desc("Verify generated machine code"), - cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); static cl::opt<cl::boolOrDefault> AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), @@ -101,13 +48,6 @@ static bool getVerboseAsm() { llvm_unreachable("Invalid verbose asm state"); } -// Enable or disable FastISel. Both options are needed, because -// FastISel is enabled by default with -fast, and we wish to be -// able to enable or disable fast-isel independently from -O0. -static cl::opt<cl::boolOrDefault> -EnableFastISelOption("fast-isel", cl::Hidden, - cl::desc("Enable the \"fast\" instruction selector")); - LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, StringRef CPU, StringRef FS, TargetOptions Options, @@ -271,245 +211,3 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, return false; // success! } - -void TargetPassConfig::printNoVerify(const char *Banner) const { - if (TM->shouldPrintMachineCode()) - PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); -} - -void TargetPassConfig::printAndVerify(const char *Banner) const { - if (TM->shouldPrintMachineCode()) - PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); - - if (VerifyMachineCode) - PM.add(createMachineVerifierPass(Banner)); -} - -/// addCodeGenPasses - Add standard LLVM codegen passes used for both -/// emitting to assembly files or machine code output. -/// -bool TargetPassConfig::addCodeGenPasses(MCContext *&OutContext) { - // Standard LLVM-Level Passes. - - // Basic AliasAnalysis support. - // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that - // BasicAliasAnalysis wins if they disagree. This is intended to help - // support "obvious" type-punning idioms. - PM.add(createTypeBasedAliasAnalysisPass()); - PM.add(createBasicAliasAnalysisPass()); - - // Before running any passes, run the verifier to determine if the input - // coming from the front-end and/or optimizer is valid. - if (!DisableVerify) - PM.add(createVerifierPass()); - - // Run loop strength reduction before anything else. - if (getOptLevel() != CodeGenOpt::None && !DisableLSR) { - PM.add(createLoopStrengthReducePass(getTargetLowering())); - if (PrintLSR) - PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs())); - } - - PM.add(createGCLoweringPass()); - - // Make sure that no unreachable blocks are instruction selected. - PM.add(createUnreachableBlockEliminationPass()); - - // Turn exception handling constructs into something the code generators can - // handle. - 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, - // catch info can get misplaced when a selector ends up more than one block - // removed from the parent invoke(s). This could happen when a landing - // pad is shared by multiple invokes and is also a target of a normal - // edge from elsewhere. - PM.add(createSjLjEHPass(getTargetLowering())); - // FALLTHROUGH - case ExceptionHandling::DwarfCFI: - case ExceptionHandling::ARM: - case ExceptionHandling::Win64: - PM.add(createDwarfEHPass(TM)); - break; - case ExceptionHandling::None: - PM.add(createLowerInvokePass(getTargetLowering())); - - // The lower invoke pass may create unreachable code. Remove it. - PM.add(createUnreachableBlockEliminationPass()); - break; - } - - if (getOptLevel() != CodeGenOpt::None && !DisableCGP) - PM.add(createCodeGenPreparePass(getTargetLowering())); - - PM.add(createStackProtectorPass(getTargetLowering())); - - addPreISel(); - - if (PrintISelInput) - PM.add(createPrintFunctionPass("\n\n" - "*** Final LLVM Code input to ISel ***\n", - &dbgs())); - - // All passes which modify the LLVM IR are now complete; run the verifier - // to ensure that the IR is valid. - if (!DisableVerify) - PM.add(createVerifierPass()); - - // Standard Lower-Level Passes. - - // 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(*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(*TM)); - - // Enable FastISel with -fast, but allow that to be overridden. - if (EnableFastISelOption == cl::BOU_TRUE || - (getOptLevel() == CodeGenOpt::None && - EnableFastISelOption != cl::BOU_FALSE)) - TM->setFastISel(true); - - // Ask the target for an isel. - if (addInstSelector()) - return true; - - // Print the instruction selected machine code... - printAndVerify("After Instruction Selection"); - - // Expand pseudo-instructions emitted by ISel. - PM.add(createExpandISelPseudosPass()); - - // Pre-ra tail duplication. - if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { - PM.add(createTailDuplicatePass(true)); - printAndVerify("After Pre-RegAlloc TailDuplicate"); - } - - // Optimize PHIs before DCE: removing dead PHI cycles may make more - // instructions dead. - if (getOptLevel() != CodeGenOpt::None) - PM.add(createOptimizePHIsPass()); - - // If the target requests it, assign local variables to stack slots relative - // to one another and simplify frame index references where possible. - PM.add(createLocalStackSlotAllocationPass()); - - if (getOptLevel() != CodeGenOpt::None) { - // With optimization, dead code should already be eliminated. However - // there is one known exception: lowered code for arguments that are only - // used by tail calls, where the tail calls reuse the incoming stack - // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). - if (!DisableMachineDCE) - PM.add(createDeadMachineInstructionElimPass()); - printAndVerify("After codegen DCE pass"); - - if (!DisableMachineLICM) - PM.add(createMachineLICMPass()); - if (!DisableMachineCSE) - PM.add(createMachineCSEPass()); - if (!DisableMachineSink) - PM.add(createMachineSinkingPass()); - printAndVerify("After Machine LICM, CSE and Sinking passes"); - - PM.add(createPeepholeOptimizerPass()); - printAndVerify("After codegen peephole optimization pass"); - } - - // Run pre-ra passes. - if (addPreRegAlloc()) - printAndVerify("After PreRegAlloc passes"); - - // Perform register allocation. - PM.add(createRegisterAllocator(getOptLevel())); - printAndVerify("After Register Allocation"); - - // Perform stack slot coloring and post-ra machine LICM. - if (getOptLevel() != CodeGenOpt::None) { - // FIXME: Re-enable coloring with register when it's capable of adding - // kill markers. - if (!DisableSSC) - PM.add(createStackSlotColoringPass(false)); - - // Run post-ra machine LICM to hoist reloads / remats. - if (!DisablePostRAMachineLICM) - PM.add(createMachineLICMPass(false)); - - printAndVerify("After StackSlotColoring and postra Machine LICM"); - } - - // Run post-ra passes. - if (addPostRegAlloc()) - printAndVerify("After PostRegAlloc passes"); - - // Insert prolog/epilog code. Eliminate abstract frame index references... - PM.add(createPrologEpilogCodeInserter()); - printAndVerify("After PrologEpilogCodeInserter"); - - // Branch folding must be run after regalloc and prolog/epilog insertion. - if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - printNoVerify("After BranchFolding"); - } - - // Tail duplication. - if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { - PM.add(createTailDuplicatePass(false)); - printNoVerify("After TailDuplicate"); - } - - // Copy propagation. - if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { - PM.add(createMachineCopyPropagationPass()); - printNoVerify("After copy propagation pass"); - } - - // Expand pseudo instructions before second scheduling pass. - PM.add(createExpandPostRAPseudosPass()); - printNoVerify("After ExpandPostRAPseudos"); - - // Run pre-sched2 passes. - if (addPreSched2()) - printNoVerify("After PreSched2 passes"); - - // Second pass scheduler. - if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { - PM.add(createPostRAScheduler(getOptLevel())); - printNoVerify("After PostRAScheduler"); - } - - PM.add(createGCMachineCodeAnalysisPass()); - - if (PrintGCInfo) - PM.add(createGCInfoPrinter(dbgs())); - - if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) { - if (EnableBlockPlacement) { - // MachineBlockPlacement is an experimental pass which is disabled by - // default currently. Eventually it should subsume CodePlacementOpt, so - // when enabled, the other is disabled. - PM.add(createMachineBlockPlacementPass()); - printNoVerify("After MachineBlockPlacement"); - } else { - PM.add(createCodePlacementOptPass()); - printNoVerify("After CodePlacementOpt"); - } - - // Run a separate pass to collect block placement statistics. - if (EnableBlockPlacementStats) { - PM.add(createMachineBlockPlacementStatsPass()); - printNoVerify("After MachineBlockPlacementStats"); - } - } - - if (addPreEmitPass()) - printNoVerify("After PreEmit passes"); - - return false; -} diff --git a/lib/CodeGen/Passes.cpp b/lib/CodeGen/Passes.cpp index f2618282c3..739ff60d3a 100644 --- a/lib/CodeGen/Passes.cpp +++ b/lib/CodeGen/Passes.cpp @@ -12,12 +12,78 @@ // //===---------------------------------------------------------------------===// -#include "llvm/CodeGen/RegAllocRegistry.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/PassManager.h" +#include "llvm/CodeGen/GCStrategy.h" +#include "llvm/CodeGen/MachineFunctionAnalysis.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/CodeGen/Passes.h" +#include "llvm/CodeGen/RegAllocRegistry.h" +#include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Assembly/PrintModulePass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; +static cl::opt<bool> DisablePostRA("disable-post-ra", cl::Hidden, + cl::desc("Disable Post Regalloc")); +static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden, + cl::desc("Disable branch folding")); +static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden, + cl::desc("Disable tail duplication")); +static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden, + cl::desc("Disable pre-register allocation tail duplication")); +static cl::opt<bool> EnableBlockPlacement("enable-block-placement", + cl::Hidden, cl::desc("Enable probability-driven block placement")); +static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats", + cl::Hidden, cl::desc("Collect probability-driven block placement stats")); +static cl::opt<bool> DisableCodePlace("disable-code-place", cl::Hidden, + cl::desc("Disable code placement")); +static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden, + cl::desc("Disable Stack Slot Coloring")); +static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden, + cl::desc("Disable Machine Dead Code Elimination")); +static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden, + cl::desc("Disable Machine LICM")); +static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden, + cl::desc("Disable Machine Common Subexpression Elimination")); +static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm", + cl::Hidden, + cl::desc("Disable Machine LICM")); +static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden, + cl::desc("Disable Machine Sinking")); +static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden, + cl::desc("Disable Loop Strength Reduction Pass")); +static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden, + cl::desc("Disable Codegen Prepare")); +static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden, + cl::desc("Disable Copy Propagation pass")); +static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden, + cl::desc("Print LLVM IR produced by the loop-reduce pass")); +static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden, + cl::desc("Print LLVM IR input to isel pass")); +static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, + cl::desc("Dump garbage collector data")); +static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, + cl::desc("Verify generated machine code"), + cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); + +// Enable or disable FastISel. Both options are needed, because +// FastISel is enabled by default with -fast, and we wish to be +// able to enable or disable fast-isel independently from -O0. +static cl::opt<cl::boolOrDefault> +EnableFastISelOption("fast-isel", cl::Hidden, + cl::desc("Enable the \"fast\" instruction selector")); + //===---------------------------------------------------------------------===// /// TargetPassConfig //===---------------------------------------------------------------------===// @@ -51,6 +117,249 @@ TargetPassConfig::TargetPassConfig() llvm_unreachable("TargetPassConfig should not be constructed on-the-fly"); } + +void TargetPassConfig::printNoVerify(const char *Banner) const { + if (TM->shouldPrintMachineCode()) + PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); +} + +void TargetPassConfig::printAndVerify(const char *Banner) const { + if (TM->shouldPrintMachineCode()) + PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); + + if (VerifyMachineCode) + PM.add(createMachineVerifierPass(Banner)); +} + +/// addCodeGenPasses - Add standard LLVM codegen passes used for both +/// emitting to assembly files or machine code output. +/// +bool TargetPassConfig::addCodeGenPasses(MCContext *&OutContext) { + // Standard LLVM-Level Passes. + + // Basic AliasAnalysis support. + // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that + // BasicAliasAnalysis wins if they disagree. This is intended to help + // support "obvious" type-punning idioms. + PM.add(createTypeBasedAliasAnalysisPass()); + PM.add(createBasicAliasAnalysisPass()); + + // Before running any passes, run the verifier to determine if the input + // coming from the front-end and/or optimizer is valid. + if (!DisableVerify) + PM.add(createVerifierPass()); + + // Run loop strength reduction before anything else. + if (getOptLevel() != CodeGenOpt::None && !DisableLSR) { + PM.add(createLoopStrengthReducePass(getTargetLowering())); + if (PrintLSR) + PM.add(createPrintFunctionPass("\n\n*** Code after LSR ***\n", &dbgs())); + } + + PM.add(createGCLoweringPass()); + + // Make sure that no unreachable blocks are instruction selected. + PM.add(createUnreachableBlockEliminationPass()); + + // Turn exception handling constructs into something the code generators can + // handle. + 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, + // catch info can get misplaced when a selector ends up more than one block + // removed from the parent invoke(s). This could happen when a landing + // pad is shared by multiple invokes and is also a target of a normal + // edge from elsewhere. + PM.add(createSjLjEHPass(getTargetLowering())); + // FALLTHROUGH + case ExceptionHandling::DwarfCFI: + case ExceptionHandling::ARM: + case ExceptionHandling::Win64: + PM.add(createDwarfEHPass(TM)); + break; + case ExceptionHandling::None: + PM.add(createLowerInvokePass(getTargetLowering())); + + // The lower invoke pass may create unreachable code. Remove it. + PM.add(createUnreachableBlockEliminationPass()); + break; + } + + if (getOptLevel() != CodeGenOpt::None && !DisableCGP) + PM.add(createCodeGenPreparePass(getTargetLowering())); + + PM.add(createStackProtectorPass(getTargetLowering())); + + addPreISel(); + + if (PrintISelInput) + PM.add(createPrintFunctionPass("\n\n" + "*** Final LLVM Code input to ISel ***\n", + &dbgs())); + + // All passes which modify the LLVM IR are now complete; run the verifier + // to ensure that the IR is valid. + if (!DisableVerify) + PM.add(createVerifierPass()); + + // Standard Lower-Level Passes. + + // 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(*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(*TM)); + + // Enable FastISel with -fast, but allow that to be overridden. + if (EnableFastISelOption == cl::BOU_TRUE || + (getOptLevel() == CodeGenOpt::None && + EnableFastISelOption != cl::BOU_FALSE)) + TM->setFastISel(true); + + // Ask the target for an isel. + if (addInstSelector()) + return true; + + // Print the instruction selected machine code... + printAndVerify("After Instruction Selection"); + + // Expand pseudo-instructions emitted by ISel. + PM.add(createExpandISelPseudosPass()); + + // Pre-ra tail duplication. + if (getOptLevel() != CodeGenOpt::None && !DisableEarlyTailDup) { + PM.add(createTailDuplicatePass(true)); + printAndVerify("After Pre-RegAlloc TailDuplicate"); + } + + // Optimize PHIs before DCE: removing dead PHI cycles may make more + // instructions dead. + if (getOptLevel() != CodeGenOpt::None) + PM.add(createOptimizePHIsPass()); + + // If the target requests it, assign local variables to stack slots relative + // to one another and simplify frame index references where possible. + PM.add(createLocalStackSlotAllocationPass()); + + if (getOptLevel() != CodeGenOpt::None) { + // With optimization, dead code should already be eliminated. However + // there is one known exception: lowered code for arguments that are only + // used by tail calls, where the tail calls reuse the incoming stack + // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll). + if (!DisableMachineDCE) + PM.add(createDeadMachineInstructionElimPass()); + printAndVerify("After codegen DCE pass"); + + if (!DisableMachineLICM) + PM.add(createMachineLICMPass()); + if (!DisableMachineCSE) + PM.add(createMachineCSEPass()); + if (!DisableMachineSink) + PM.add(createMachineSinkingPass()); + printAndVerify("After Machine LICM, CSE and Sinking passes"); + + PM.add(createPeepholeOptimizerPass()); + printAndVerify("After codegen peephole optimization pass"); + } + + // Run pre-ra passes. + if (addPreRegAlloc()) + printAndVerify("After PreRegAlloc passes"); + + // Perform register allocation. + PM.add(createRegisterAllocator(getOptLevel())); + printAndVerify("After Register Allocation"); + + // Perform stack slot coloring and post-ra machine LICM. + if (getOptLevel() != CodeGenOpt::None) { + // FIXME: Re-enable coloring with register when it's capable of adding + // kill markers. + if (!DisableSSC) + PM.add(createStackSlotColoringPass(false)); + + // Run post-ra machine LICM to hoist reloads / remats. + if (!DisablePostRAMachineLICM) + PM.add(createMachineLICMPass(false)); + + printAndVerify("After StackSlotColoring and postra Machine LICM"); + } + + // Run post-ra passes. + if (addPostRegAlloc()) + printAndVerify("After PostRegAlloc passes"); + + // Insert prolog/epilog code. Eliminate abstract frame index references... + PM.add(createPrologEpilogCodeInserter()); + printAndVerify("After PrologEpilogCodeInserter"); + + // Branch folding must be run after regalloc and prolog/epilog insertion. + if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { + PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); + printNoVerify("After BranchFolding"); + } + + // Tail duplication. + if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { + PM.add(createTailDuplicatePass(false)); + printNoVerify("After TailDuplicate"); + } + + // Copy propagation. + if (getOptLevel() != CodeGenOpt::None && !DisableCopyProp) { + PM.add(createMachineCopyPropagationPass()); + printNoVerify("After copy propagation pass"); + } + + // Expand pseudo instructions before second scheduling pass. + PM.add(createExpandPostRAPseudosPass()); + printNoVerify("After ExpandPostRAPseudos"); + + // Run pre-sched2 passes. + if (addPreSched2()) + printNoVerify("After PreSched2 passes"); + + // Second pass scheduler. + if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { + PM.add(createPostRAScheduler(getOptLevel())); + printNoVerify("After PostRAScheduler"); + } + + PM.add(createGCMachineCodeAnalysisPass()); + + if (PrintGCInfo) + PM.add(createGCInfoPrinter(dbgs())); + + if (getOptLevel() != CodeGenOpt::None && !DisableCodePlace) { + if (EnableBlockPlacement) { + // MachineBlockPlacement is an experimental pass which is disabled by + // default currently. Eventually it should subsume CodePlacementOpt, so + // when enabled, the other is disabled. + PM.add(createMachineBlockPlacementPass()); + printNoVerify("After MachineBlockPlacement"); + } else { + PM.add(createCodePlacementOptPass()); + printNoVerify("After CodePlacementOpt"); + } + + // Run a separate pass to collect block placement statistics. + if (EnableBlockPlacementStats) { + PM.add(createMachineBlockPlacementStatsPass()); + printNoVerify("After MachineBlockPlacementStats"); + } + } + + if (addPreEmitPass()) + printNoVerify("After PreEmit passes"); + + return false; +} + //===---------------------------------------------------------------------===// /// /// RegisterRegAlloc class - Track the registration of register allocators. |