diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2009-10-14 17:57:32 +0000 |
commit | cd749a9c07f1de2fb8affde90537efa4bc3e7c54 (patch) | |
tree | b21f6de4e08b89bb7931806bab798fc2a5e3a686 /lib/CodeGen/LLVMTargetMachine.cpp | |
parent | 72621d11de5b873f1695f391eb95f0b336c3d2d4 (diff) | |
download | FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.zip FreeBSD-src-cd749a9c07f1de2fb8affde90537efa4bc3e7c54.tar.gz |
Update llvm to r84119.
Diffstat (limited to 'lib/CodeGen/LLVMTargetMachine.cpp')
-rw-r--r-- | lib/CodeGen/LLVMTargetMachine.cpp | 136 |
1 files changed, 95 insertions, 41 deletions
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index a163cac..4e713a6 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -15,14 +15,16 @@ #include "llvm/PassManager.h" #include "llvm/Pass.h" #include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Analysis/LoopPass.h" +#include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/GCStrategy.h" +#include "llvm/CodeGen/MachineFunctionAnalysis.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetAsmInfo.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/Target/TargetRegistry.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" using namespace llvm; namespace llvm { @@ -37,26 +39,31 @@ static cl::opt<bool> PrintEmittedAsm("print-emitted-asm", cl::Hidden, cl::desc("Dump emitter generated instructions as assembly")); static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden, cl::desc("Dump garbage collector data")); +static cl::opt<bool> HoistConstants("hoist-constants", cl::Hidden, + cl::desc("Hoist constants out of loops")); static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, cl::desc("Verify generated machine code"), cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); -// When this works it will be on by default. -static cl::opt<bool> -DisablePostRAScheduler("disable-post-RA-scheduler", - cl::desc("Disable scheduling after register allocation"), - cl::init(true)); - // 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 -fast. +// able to enable or disable fast-isel independently from -O0. static cl::opt<cl::boolOrDefault> EnableFastISelOption("fast-isel", cl::Hidden, - cl::desc("Enable the experimental \"fast\" instruction selector")); + cl::desc("Enable the \"fast\" instruction selector")); + + +LLVMTargetMachine::LLVMTargetMachine(const Target &T, + const std::string &TargetTriple) + : TargetMachine(T) { + AsmInfo = T.createAsmInfo(TargetTriple); +} + + FileModel::Model LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, - raw_ostream &Out, + formatted_raw_ostream &Out, CodeGenFileType FileType, CodeGenOpt::Level OptLevel) { // Add common CodeGen passes. @@ -67,10 +74,10 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, PM.add(createDebugLabelFoldingPass()); if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + PM.add(createMachineFunctionPrinterPass(errs())); if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + PM.add(createMachineFunctionPrinterPass(errs())); if (OptLevel != CodeGenOpt::None) PM.add(createCodePlacementOptPass()); @@ -92,6 +99,19 @@ LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM, return FileModel::Error; } +bool LLVMTargetMachine::addAssemblyEmitter(PassManagerBase &PM, + CodeGenOpt::Level OptLevel, + bool Verbose, + formatted_raw_ostream &Out) { + FunctionPass *Printer = + getTarget().createAsmPrinter(Out, *this, getMCAsmInfo(), Verbose); + if (!Printer) + return true; + + PM.add(Printer); + return false; +} + /// addPassesToEmitFileFinish - If the passes to emit the specified file had to /// be split up (e.g., to add an object writer pass), this method can be used to /// finish up adding passes to emit the file, if necessary. @@ -99,13 +119,12 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM, MachineCodeEmitter *MCE, CodeGenOpt::Level OptLevel) { if (MCE) - addSimpleCodeEmitter(PM, OptLevel, PrintEmittedAsm, *MCE); + addSimpleCodeEmitter(PM, OptLevel, *MCE); + if (PrintEmittedAsm) + addAssemblyEmitter(PM, OptLevel, true, ferrs()); PM.add(createGCInfoDeleter()); - // Delete machine code for this function - PM.add(createMachineCodeDeleter()); - return false; // success! } @@ -116,12 +135,27 @@ bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM, JITCodeEmitter *JCE, CodeGenOpt::Level OptLevel) { if (JCE) - addSimpleCodeEmitter(PM, OptLevel, PrintEmittedAsm, *JCE); + addSimpleCodeEmitter(PM, OptLevel, *JCE); + if (PrintEmittedAsm) + addAssemblyEmitter(PM, OptLevel, true, ferrs()); PM.add(createGCInfoDeleter()); - // Delete machine code for this function - PM.add(createMachineCodeDeleter()); + return false; // success! +} + +/// addPassesToEmitFileFinish - If the passes to emit the specified file had to +/// be split up (e.g., to add an object writer pass), this method can be used to +/// finish up adding passes to emit the file, if necessary. +bool LLVMTargetMachine::addPassesToEmitFileFinish(PassManagerBase &PM, + ObjectCodeEmitter *OCE, + CodeGenOpt::Level OptLevel) { + if (OCE) + addSimpleCodeEmitter(PM, OptLevel, *OCE); + if (PrintEmittedAsm) + addAssemblyEmitter(PM, OptLevel, true, ferrs()); + + PM.add(createGCInfoDeleter()); return false; // success! } @@ -140,15 +174,14 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, return true; if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + PM.add(createMachineFunctionPrinterPass(errs())); - addCodeEmitter(PM, OptLevel, PrintEmittedAsm, MCE); + addCodeEmitter(PM, OptLevel, MCE); + if (PrintEmittedAsm) + addAssemblyEmitter(PM, OptLevel, true, ferrs()); PM.add(createGCInfoDeleter()); - // Delete machine code for this function - PM.add(createMachineCodeDeleter()); - return false; // success! } @@ -166,22 +199,21 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM, return true; if (addPreEmitPass(PM, OptLevel) && PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + PM.add(createMachineFunctionPrinterPass(errs())); - addCodeEmitter(PM, OptLevel, PrintEmittedAsm, JCE); + addCodeEmitter(PM, OptLevel, JCE); + if (PrintEmittedAsm) + addAssemblyEmitter(PM, OptLevel, true, ferrs()); PM.add(createGCInfoDeleter()); - // Delete machine code for this function - PM.add(createMachineCodeDeleter()); - return false; // success! } static void printAndVerify(PassManagerBase &PM, bool allowDoubleDefs = false) { if (PrintMachineCode) - PM.add(createMachineFunctionPrinterPass(cerr)); + PM.add(createMachineFunctionPrinterPass(errs())); if (VerifyMachineCode) PM.add(createMachineVerifierPass(allowDoubleDefs)); @@ -203,18 +235,31 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Turn exception handling constructs into something the code generators can // handle. - if (!getTargetAsmInfo()->doesSupportExceptionHandling()) - PM.add(createLowerInvokePass(getTargetLowering())); - else + switch (getMCAsmInfo()->getExceptionHandlingType()) + { + case ExceptionHandling::SjLj: + // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None)); + PM.add(createSjLjEHPass(getTargetLowering())); + break; + case ExceptionHandling::Dwarf: + PM.add(createDwarfEHPass(getTargetLowering(), OptLevel==CodeGenOpt::None)); + break; + case ExceptionHandling::None: + PM.add(createLowerInvokePass(getTargetLowering())); + break; + } PM.add(createGCLoweringPass()); // Make sure that no unreachable blocks are instruction selected. PM.add(createUnreachableBlockEliminationPass()); - if (OptLevel != CodeGenOpt::None) + if (OptLevel != CodeGenOpt::None) { + if (HoistConstants) + PM.add(createCodeGenLICMPass()); PM.add(createCodeGenPreparePass(getTargetLowering())); + } PM.add(createStackProtectorPass(getTargetLowering())); @@ -225,6 +270,9 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, // Standard Lower-Level Passes. + // Set up a MachineFunction for the rest of CodeGen to work on. + PM.add(new MachineFunctionAnalysis(*this, OptLevel)); + // Enable FastISel with -fast, but allow that to be overridden. if (EnableFastISelOption == cl::BOU_TRUE || (OptLevel == CodeGenOpt::None && EnableFastISelOption != cl::BOU_FALSE)) @@ -240,19 +288,21 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, if (OptLevel != CodeGenOpt::None) { PM.add(createMachineLICMPass()); PM.add(createMachineSinkingPass()); - printAndVerify(PM, /* allowDoubleDefs= */ false); + printAndVerify(PM, /* allowDoubleDefs= */ true); } // Run pre-ra passes. if (addPreRegAlloc(PM, OptLevel)) - printAndVerify(PM); + printAndVerify(PM, /* allowDoubleDefs= */ true); // Perform register allocation. PM.add(createRegisterAllocator()); // Perform stack slot coloring. if (OptLevel != CodeGenOpt::None) - PM.add(createStackSlotColoringPass(OptLevel >= CodeGenOpt::Aggressive)); + // FIXME: Re-enable coloring with register when it's capable of adding + // kill markers. + PM.add(createStackSlotColoringPass(false)); printAndVerify(PM); // Print the register-allocated code @@ -267,8 +317,12 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, PM.add(createPrologEpilogCodeInserter()); printAndVerify(PM); + // Run pre-sched2 passes. + if (addPreSched2(PM, OptLevel)) + printAndVerify(PM); + // Second pass scheduler. - if (OptLevel != CodeGenOpt::None && !DisablePostRAScheduler) { + if (OptLevel != CodeGenOpt::None) { PM.add(createPostRAScheduler()); printAndVerify(PM); } @@ -283,7 +337,7 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, printAndVerify(PM); if (PrintGCInfo) - PM.add(createGCInfoPrinter(*cerr)); + PM.add(createGCInfoPrinter(errs())); return false; } |