X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FLLVMTargetMachine.cpp;h=97e654775a22f6677b39273fac06a7bddcce46af;hb=eabae1d07bffac60d9f4f2473cf6736d6a1c372d;hp=62227fd4d65005ad3126d06a2fe3e3e89bdfd876;hpb=8a8d479214745c82ef00f08d4e4f1c173b5f9ce2;p=oota-llvm.git diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 62227fd4d65..97e654775a2 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -11,82 +11,42 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/Scalar.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/Passes.h" #include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/GCStrategy.h" -#include "llvm/CodeGen/Passes.h" +#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetLoweringObjectFile.h" +#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#include "llvm/Target/TargetSubtargetInfo.h" +#include "llvm/Target/TargetRegisterInfo.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 DisablePostRA("disable-post-ra", cl::Hidden, - cl::desc("Disable Post Regalloc")); -static cl::opt DisableBranchFold("disable-branch-fold", cl::Hidden, - cl::desc("Disable branch folding")); -static cl::opt DisableTailDuplicate("disable-tail-duplicate", cl::Hidden, - cl::desc("Disable tail duplication")); -static cl::opt DisableEarlyTailDup("disable-early-taildup", cl::Hidden, - cl::desc("Disable pre-register allocation tail duplication")); -static cl::opt EnableBlockPlacement("enable-block-placement", - cl::Hidden, cl::desc("Enable probability-driven block placement")); -static cl::opt EnableBlockPlacementStats("enable-block-placement-stats", - cl::Hidden, cl::desc("Collect probability-driven block placement stats")); -static cl::opt DisableCodePlace("disable-code-place", cl::Hidden, - cl::desc("Disable code placement")); -static cl::opt DisableSSC("disable-ssc", cl::Hidden, - cl::desc("Disable Stack Slot Coloring")); -static cl::opt DisableMachineDCE("disable-machine-dce", cl::Hidden, - cl::desc("Disable Machine Dead Code Elimination")); -static cl::opt DisableMachineLICM("disable-machine-licm", cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt DisableMachineCSE("disable-machine-cse", cl::Hidden, - cl::desc("Disable Machine Common Subexpression Elimination")); -static cl::opt DisablePostRAMachineLICM("disable-postra-machine-licm", - cl::Hidden, - cl::desc("Disable Machine LICM")); -static cl::opt DisableMachineSink("disable-machine-sink", cl::Hidden, - cl::desc("Disable Machine Sinking")); -static cl::opt DisableLSR("disable-lsr", cl::Hidden, - cl::desc("Disable Loop Strength Reduction Pass")); -static cl::opt DisableCGP("disable-cgp", cl::Hidden, - cl::desc("Disable Codegen Prepare")); -static cl::opt PrintLSR("print-lsr-output", cl::Hidden, - cl::desc("Print LLVM IR produced by the loop-reduce pass")); -static cl::opt PrintISelInput("print-isel-input", cl::Hidden, - cl::desc("Print LLVM IR input to isel pass")); -static cl::opt PrintGCInfo("print-gc", cl::Hidden, - cl::desc("Dump garbage collector data")); +// 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 +EnableFastISelOption("fast-isel", cl::Hidden, + cl::desc("Enable the \"fast\" instruction selector")); + static cl::opt ShowMCEncoding("show-mc-encoding", cl::Hidden, cl::desc("Show encoding in .s output")); static cl::opt ShowMCInst("show-mc-inst", cl::Hidden, cl::desc("Show instruction structure in .s output")); -static cl::opt EnableMCLogging("enable-mc-api-logging", cl::Hidden, - cl::desc("Enable MC API logging")); -static cl::opt VerifyMachineCode("verify-machineinstrs", cl::Hidden, - cl::desc("Verify generated machine code"), - cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); static cl::opt AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), @@ -94,20 +54,13 @@ AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), static bool getVerboseAsm() { switch (AsmVerbose) { - default: case cl::BOU_UNSET: return TargetMachine::getAsmVerbosityDefault(); case cl::BOU_TRUE: return true; case cl::BOU_FALSE: return false; } + 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 -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, @@ -125,15 +78,88 @@ LLVMTargetMachine::LLVMTargetMachine(const Target &T, StringRef Triple, "and that InitializeAllTargetMCs() is being invoked!"); } +/// Turn exception handling constructs into something the code generators can +/// handle. +static void addPassesToHandleExceptions(TargetMachine *TM, + PassManagerBase &PM) { + 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(createSjLjEHPreparePass(TM->getTargetLowering())); + // FALLTHROUGH + case ExceptionHandling::DwarfCFI: + case ExceptionHandling::ARM: + case ExceptionHandling::Win64: + PM.add(createDwarfEHPass(TM)); + break; + case ExceptionHandling::None: + PM.add(createLowerInvokePass(TM->getTargetLowering())); + + // The lower invoke pass may create unreachable code. Remove it. + PM.add(createUnreachableBlockEliminationPass()); + break; + } +} + +/// addPassesToX helper drives creation and initialization of TargetPassConfig. +static MCContext *addPassesToGenerateCode(LLVMTargetMachine *TM, + PassManagerBase &PM, + bool DisableVerify) { + // Targets may override createPassConfig to provide a target-specific sublass. + TargetPassConfig *PassConfig = TM->createPassConfig(PM); + + // Set PassConfig options provided by TargetMachine. + PassConfig->setDisableVerify(DisableVerify); + + PM.add(PassConfig); + + PassConfig->addIRPasses(); + + addPassesToHandleExceptions(TM, PM); + + PassConfig->addISelPrepare(); + + // 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(), + &TM->getTargetLowering()->getObjFileLowering()); + PM.add(MMI); + MCContext *Context = &MMI->getContext(); // Return the MCContext 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 || + (TM->getOptLevel() == CodeGenOpt::None && + EnableFastISelOption != cl::BOU_FALSE)) + TM->setFastISel(true); + + // Ask the target for an isel. + if (PassConfig->addInstSelector()) + return NULL; + + PassConfig->addMachinePasses(); + + PassConfig->setInitialized(); + + return Context; +} + 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)) + MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify); + if (!Context) return true; - assert(Context != 0 && "Failed to get MCContext"); if (hasMCSaveTempLabels()) Context->setAllowTemporaryLabels(false); @@ -143,10 +169,10 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, OwningPtr AsmStreamer; switch (FileType) { - default: return true; case CGFT_AssemblyFile: { MCInstPrinter *InstPrinter = - getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, STI); + getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, + Context->getRegisterInfo(), STI); // Create a code emitter if asked to show the encoding. MCCodeEmitter *MCE = 0; @@ -191,9 +217,6 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, break; } - if (EnableMCLogging) - AsmStreamer.reset(createLoggingStreamer(AsmStreamer.take(), errs())); - // Create the AsmPrinter, which takes ownership of AsmStreamer if successful. FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer); if (Printer == 0) @@ -218,8 +241,8 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, JITCodeEmitter &JCE, bool DisableVerify) { // Add common CodeGen passes. - MCContext *Ctx = 0; - if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) + MCContext *Context = addPassesToGenerateCode(this, PM, DisableVerify); + if (!Context) return true; addCodeEmitter(PM, JCE); @@ -238,7 +261,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, raw_ostream &Out, bool DisableVerify) { // Add common CodeGen passes. - if (addCommonCodeGenPasses(PM, DisableVerify, Ctx)) + Ctx = addPassesToGenerateCode(this, PM, DisableVerify); + if (!Ctx) return true; if (hasMCSaveTempLabels()) @@ -247,7 +271,8 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, // Create the code emitter for the target if it exists. If not, .o file // emission fails. const MCSubtargetInfo &STI = getSubtarget(); - MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI, *Ctx); + MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(*getInstrInfo(),STI, + *Ctx); MCAsmBackend *MAB = getTarget().createMCAsmBackend(getTargetTriple()); if (MCE == 0 || MAB == 0) return true; @@ -271,242 +296,3 @@ bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM, return false; // success! } - -void LLVMTargetMachine::printNoVerify(PassManagerBase &PM, - const char *Banner) const { - if (Options.PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); -} - -void LLVMTargetMachine::printAndVerify(PassManagerBase &PM, - const char *Banner) const { - if (Options.PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(dbgs(), Banner)); - - if (VerifyMachineCode) - PM.add(createMachineVerifierPass(Banner)); -} - -/// addCommonCodeGenPasses - 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) { - // 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 (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(this)); - 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(PM); - - 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(*getMCAsmInfo(), - *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)); - - // 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; - - // Ask the target for an isel. - if (addInstSelector(PM)) - return true; - - // Print the instruction selected machine code... - printAndVerify(PM, "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(PM, "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(PM, "After codegen DCE pass"); - - if (!DisableMachineLICM) - PM.add(createMachineLICMPass()); - if (!DisableMachineCSE) - PM.add(createMachineCSEPass()); - if (!DisableMachineSink) - PM.add(createMachineSinkingPass()); - printAndVerify(PM, "After Machine LICM, CSE and Sinking passes"); - - PM.add(createPeepholeOptimizerPass()); - printAndVerify(PM, "After codegen peephole optimization pass"); - } - - // Run pre-ra passes. - if (addPreRegAlloc(PM)) - printAndVerify(PM, "After PreRegAlloc passes"); - - // Perform register allocation. - PM.add(createRegisterAllocator(getOptLevel())); - printAndVerify(PM, "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(PM, "After StackSlotColoring and postra Machine LICM"); - } - - // Run post-ra passes. - if (addPostRegAlloc(PM)) - printAndVerify(PM, "After PostRegAlloc passes"); - - PM.add(createExpandPostRAPseudosPass()); - printAndVerify(PM, "After ExpandPostRAPseudos"); - - // Insert prolog/epilog code. Eliminate abstract frame index references... - PM.add(createPrologEpilogCodeInserter()); - printAndVerify(PM, "After PrologEpilogCodeInserter"); - - // Run pre-sched2 passes. - if (addPreSched2(PM)) - printAndVerify(PM, "After PreSched2 passes"); - - // Second pass scheduler. - if (getOptLevel() != CodeGenOpt::None && !DisablePostRA) { - PM.add(createPostRAScheduler(getOptLevel())); - printAndVerify(PM, "After PostRAScheduler"); - } - - // Branch folding must be run after regalloc and prolog/epilog insertion. - if (getOptLevel() != CodeGenOpt::None && !DisableBranchFold) { - PM.add(createBranchFoldingPass(getEnableTailMergeDefault())); - printNoVerify(PM, "After BranchFolding"); - } - - // Tail duplication. - if (getOptLevel() != CodeGenOpt::None && !DisableTailDuplicate) { - PM.add(createTailDuplicatePass(false)); - printNoVerify(PM, "After TailDuplicate"); - } - - 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(PM, "After MachineBlockPlacement"); - } else { - PM.add(createCodePlacementOptPass()); - printNoVerify(PM, "After CodePlacementOpt"); - } - - // Run a separate pass to collect block placement statistics. - if (EnableBlockPlacementStats) { - PM.add(createMachineBlockPlacementStatsPass()); - printNoVerify(PM, "After MachineBlockPlacementStats"); - } - } - - if (addPreEmitPass(PM)) - printNoVerify(PM, "After PreEmit passes"); - - return false; -}