X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fopt%2Fopt.cpp;h=dcff891bcd07aad428b87cec554e8f52d179db14;hb=56e1394c8861ecdc551815ae875d2c3db2fa9cdb;hp=251edc482000fbeefd7097b0b997324a4463f64b;hpb=52b28896c8dfaa36f4b577b99fa57c5c412a5853;p=oota-llvm.git diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 251edc48200..dcff891bcd0 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -12,37 +12,44 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" -#include "llvm/PassManager.h" -#include "llvm/CallGraphSCCPass.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Assembly/PrintModulePass.h" -#include "llvm/Analysis/DebugInfo.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Analysis/LoopPass.h" -#include "llvm/Analysis/RegionPass.h" -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Target/TargetData.h" -#include "llvm/Target/TargetLibraryInfo.h" -#include "llvm/Target/TargetMachine.h" +#include "NewPMDriver.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" -#include "llvm/Support/PassNameParser.h" -#include "llvm/Support/Signals.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/CallGraphSCCPass.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/RegionPass.h" +#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/CodeGen/CommandFlags.h" +#include "llvm/DebugInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Verifier.h" +#include "llvm/IRReader/IRReader.h" +#include "llvm/LinkAllIR.h" +#include "llvm/LinkAllPasses.h" +#include "llvm/MC/SubtargetFeature.h" +#include "llvm/PassManager.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PassNameParser.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/PassManagerBuilder.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" -#include "llvm/LinkAllPasses.h" -#include "llvm/LinkAllVMCore.h" -#include +#include "llvm/Target/TargetLibraryInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" #include +#include using namespace llvm; +using namespace opt_tool; // The OptimizationList is automatically populated with registered Passes by the // PassNameParser. @@ -50,6 +57,15 @@ using namespace llvm; static cl::list PassList(cl::desc("Optimizations available:")); +// This flag specifies a textual description of the optimization pass pipeline +// to run over the module. This flag switches opt to use the new pass manager +// infrastructure, completely disabling all of the flags specific to the old +// pass management. +static cl::opt PassPipeline( + "passes", + cl::desc("A textual description of the pass pipeline for optimizing"), + cl::Hidden); + // Other command line options... // static cl::opt @@ -104,21 +120,47 @@ StandardLinkOpts("std-link-opts", static cl::opt OptLevelO1("O1", - cl::desc("Optimization level 1. Similar to llvm-gcc -O1")); + cl::desc("Optimization level 1. Similar to clang -O1")); static cl::opt OptLevelO2("O2", - cl::desc("Optimization level 2. Similar to llvm-gcc -O2")); + cl::desc("Optimization level 2. Similar to clang -O2")); + +static cl::opt +OptLevelOs("Os", + cl::desc("Like -O2 with extra optimizations for size. Similar to clang -Os")); + +static cl::opt +OptLevelOz("Oz", + cl::desc("Like -Os but reduces code size further. Similar to clang -Oz")); static cl::opt OptLevelO3("O3", - cl::desc("Optimization level 3. Similar to llvm-gcc -O3")); + cl::desc("Optimization level 3. Similar to clang -O3")); + +static cl::opt +TargetTriple("mtriple", cl::desc("Override target triple for module")); static cl::opt UnitAtATime("funit-at-a-time", cl::desc("Enable IPO. This is same as llvm-gcc's -funit-at-a-time"), cl::init(true)); +static cl::opt +DisableLoopUnrolling("disable-loop-unrolling", + cl::desc("Disable loop unrolling in all relevant passes"), + cl::init(false)); +static cl::opt +DisableLoopVectorization("disable-loop-vectorization", + cl::desc("Disable the loop vectorization pass"), + cl::init(false)); + +static cl::opt +DisableSLPVectorization("disable-slp-vectorization", + cl::desc("Disable the slp vectorization pass"), + cl::init(false)); + + static cl::opt DisableSimplifyLibCalls("disable-simplify-libcalls", cl::desc("Disable simplify-libcalls")); @@ -291,8 +333,8 @@ struct RegionPassPrinter : public RegionPass { virtual bool runOnRegion(Region *R, RGPassManager &RGM) { if (!Quiet) { Out << "Printing analysis '" << PassToPrint->getPassName() << "' for " - << "region: '" << R->getNameStr() << "' in function '" - << R->getEntry()->getParent()->getNameStr() << "':\n"; + << "region: '" << R->getNameStr() << "' in function '" + << R->getEntry()->getParent()->getName() << "':\n"; } // Get and print pass... getAnalysisID(PassToPrint->getTypeInfo()).print(Out, @@ -346,6 +388,7 @@ char BasicBlockPassPrinter::ID = 0; struct BreakpointPrinter : public ModulePass { raw_ostream &Out; static char ID; + DITypeIdentifierMap TypeIdentifierMap; BreakpointPrinter(raw_ostream &out) : ModulePass(ID), Out(out) { @@ -361,20 +404,28 @@ struct BreakpointPrinter : public ModulePass { } else if (Context.isType()) { DIType TY(Context); if (!TY.getName().empty()) { - getContextName(TY.getContext(), N); + getContextName(TY.getContext().resolve(TypeIdentifierMap), N); N = N + TY.getName().str() + "::"; } } } virtual bool runOnModule(Module &M) { + TypeIdentifierMap.clear(); + NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); + if (CU_Nodes) + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); + StringSet<> Processed; if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { std::string Name; DISubprogram SP(NMD->getOperand(i)); - if (SP.Verify()) - getContextName(SP.getContext(), Name); + assert((!SP || SP.isSubprogram()) && + "A MDNode in llvm.dbg.sp should be null or a DISubprogram."); + if (!SP) + continue; + getContextName(SP.getContext().resolve(TypeIdentifierMap), Name); Name = Name + SP.getDisplayName().str(); if (!Name.empty() && Processed.insert(Name)) { Out << Name << "\n"; @@ -387,7 +438,7 @@ struct BreakpointPrinter : public ModulePass { AU.setPreservesAll(); } }; - + } // anonymous namespace char BreakpointPrinter::ID = 0; @@ -406,14 +457,21 @@ static inline void addPass(PassManagerBase &PM, Pass *P) { /// /// OptLevel - Optimization Level static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, - unsigned OptLevel) { + unsigned OptLevel, unsigned SizeLevel) { + FPM.add(createVerifierPass()); // Verify that input is correct + PassManagerBuilder Builder; Builder.OptLevel = OptLevel; + Builder.SizeLevel = SizeLevel; if (DisableInline) { // No inlining pass - } else if (OptLevel) { + } else if (OptLevel > 1) { unsigned Threshold = 225; + if (SizeLevel == 1) // -Os + Threshold = 75; + else if (SizeLevel == 2) // -Oz + Threshold = 25; if (OptLevel > 2) Threshold = 275; Builder.Inliner = createFunctionInliningPass(Threshold); @@ -421,9 +479,20 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; - Builder.DisableUnrollLoops = OptLevel == 0; - Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; - + Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? + DisableLoopUnrolling : OptLevel == 0; + + // This is final, unless there is a #pragma vectorize enable + if (DisableLoopVectorization) + Builder.LoopVectorize = false; + // If option wasn't forced via cmd line (-vectorize-loops, -loop-vectorize) + else if (!Builder.LoopVectorize) + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; + + // When #pragma vectorize is on for SLP, do the same as above + Builder.SLPVectorize = + DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); } @@ -431,8 +500,6 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, static void AddStandardCompilePasses(PassManagerBase &PM) { PM.add(createVerifierPass()); // Verify that input is correct - addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp - // If the -strip-debug command line option was specified, do it. if (StripDebug) addPass(PM, createStripSymbolsPass(true)); @@ -444,7 +511,6 @@ static void AddStandardCompilePasses(PassManagerBase &PM) { if (!DisableInline) Builder.Inliner = createFunctionInliningPass(); Builder.OptLevel = 3; - Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; Builder.populateModulePassManager(PM); } @@ -462,6 +528,67 @@ static void AddStandardLinkPasses(PassManagerBase &PM) { /*RunInliner=*/ !DisableInline); } +//===----------------------------------------------------------------------===// +// CodeGen-related helper functions. +// +static TargetOptions GetTargetOptions() { + TargetOptions Options; + Options.LessPreciseFPMADOption = EnableFPMAD; + Options.NoFramePointerElim = DisableFPElim; + Options.AllowFPOpFusion = FuseFPOps; + Options.UnsafeFPMath = EnableUnsafeFPMath; + Options.NoInfsFPMath = EnableNoInfsFPMath; + Options.NoNaNsFPMath = EnableNoNaNsFPMath; + Options.HonorSignDependentRoundingFPMathOption = + EnableHonorSignDependentRoundingFPMath; + Options.UseSoftFloat = GenerateSoftFloatCalls; + if (FloatABIForCalls != FloatABI::Default) + Options.FloatABIType = FloatABIForCalls; + Options.NoZerosInBSS = DontPlaceZerosInBSS; + Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; + Options.DisableTailCalls = DisableTailCalls; + Options.StackAlignmentOverride = OverrideStackAlignment; + Options.TrapFuncName = TrapFuncName; + Options.PositionIndependentExecutable = EnablePIE; + Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; + return Options; +} + +CodeGenOpt::Level GetCodeGenOptLevel() { + if (OptLevelO1) + return CodeGenOpt::Less; + if (OptLevelO2) + return CodeGenOpt::Default; + if (OptLevelO3) + return CodeGenOpt::Aggressive; + return CodeGenOpt::None; +} + +// Returns the TargetMachine instance or zero if no triple is provided. +static TargetMachine* GetTargetMachine(Triple TheTriple) { + std::string Error; + const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, + Error); + // Some modules don't specify a triple, and this is okay. + if (!TheTarget) { + return 0; + } + + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (MAttrs.size()) { + SubtargetFeatures Features; + for (unsigned i = 0; i != MAttrs.size(); ++i) + Features.AddFeature(MAttrs[i]); + FeaturesStr = Features.getString(); + } + + return TheTarget->createTargetMachine(TheTriple.getTriple(), + MCPU, FeaturesStr, GetTargetOptions(), + RelocModel, CMModel, + GetCodeGenOptLevel()); +} //===----------------------------------------------------------------------===// // main for opt @@ -476,10 +603,16 @@ int main(int argc, char **argv) { llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); + InitializeAllTargets(); + InitializeAllTargetMCs(); + // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); + initializeDebugIRPass(Registry); initializeScalarOpts(Registry); + initializeObjCARCOpts(Registry); + initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); @@ -496,21 +629,21 @@ int main(int argc, char **argv) { return 1; } - // Allocate a full target machine description only if necessary. - // FIXME: The choice of target should be controllable on the command line. - std::auto_ptr target; - SMDiagnostic Err; // Load the input module... - std::auto_ptr M; + OwningPtr M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { - Err.Print(argv[0], errs()); + Err.print(argv[0], errs()); return 1; } + // If we are supposed to override the target triple, do so now. + if (!TargetTriple.empty()) + M->setTargetTriple(Triple::normalize(TargetTriple)); + // Figure out what stream we are supposed to write to... OwningPtr Out; if (NoOutput) { @@ -524,7 +657,7 @@ int main(int argc, char **argv) { std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); + sys::fs::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; @@ -538,6 +671,20 @@ int main(int argc, char **argv) { if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; + if (PassPipeline.getNumOccurrences() > 0) { + OutputKind OK = OK_NoOutput; + if (!NoOutput) + OK = OutputAssembly ? OK_OutputAssembly : OK_OutputBitcode; + + // The user has asked to use the new pass manager and provided a pipeline + // string. Hand off the rest of the functionality to the new code for that + // layer. + return runPassPipeline(argv[0], Context, *M.get(), Out.get(), PassPipeline, + OK) + ? 0 + : 1; + } + // Create a PassManager to hold and optimize the collection of passes we are // about to build. // @@ -551,22 +698,35 @@ int main(int argc, char **argv) { TLI->disableAllFunctions(); Passes.add(TLI); - // Add an appropriate TargetData instance for this module. - TargetData *TD = 0; + // Add an appropriate DataLayout instance for this module. + DataLayout *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) - TD = new TargetData(ModuleDataLayout); + TD = new DataLayout(ModuleDataLayout); else if (!DefaultDataLayout.empty()) - TD = new TargetData(DefaultDataLayout); + TD = new DataLayout(DefaultDataLayout); if (TD) Passes.add(TD); + Triple ModuleTriple(M->getTargetTriple()); + TargetMachine *Machine = 0; + if (ModuleTriple.getArch()) + Machine = GetTargetMachine(Triple(ModuleTriple)); + OwningPtr TM(Machine); + + // Add internal analysis passes from the target machine. + if (TM.get()) + TM->addAnalysisPasses(Passes); + OwningPtr FPasses; - if (OptLevelO1 || OptLevelO2 || OptLevelO3) { + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (TD) - FPasses->add(new TargetData(*TD)); + FPasses->add(new DataLayout(*TD)); + if (TM.get()) + TM->addAnalysisPasses(*FPasses); + } if (PrintBreakpoints) { @@ -577,7 +737,7 @@ int main(int argc, char **argv) { std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); + sys::fs::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; @@ -609,17 +769,27 @@ int main(int argc, char **argv) { } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } + if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 1); + OptLevelOs = false; + } + + if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { + AddOptimizationPasses(Passes, *FPasses, 2, 2); + OptLevelOz = false; + } + if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } @@ -659,7 +829,7 @@ int main(int argc, char **argv) { } if (PrintEachXForm) - Passes.add(createPrintModulePass(&errs())); + Passes.add(createPrintModulePass(errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. @@ -674,17 +844,26 @@ int main(int argc, char **argv) { } if (OptLevelO1) - AddOptimizationPasses(Passes, *FPasses, 1); + AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) - AddOptimizationPasses(Passes, *FPasses, 2); + AddOptimizationPasses(Passes, *FPasses, 2, 0); + + if (OptLevelOs) + AddOptimizationPasses(Passes, *FPasses, 2, 1); + + if (OptLevelOz) + AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) - AddOptimizationPasses(Passes, *FPasses, 3); + AddOptimizationPasses(Passes, *FPasses, 3, 0); - if (OptLevelO1 || OptLevelO2 || OptLevelO3) + if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { + FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F); + FPasses->doFinalization(); + } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) @@ -693,7 +872,7 @@ int main(int argc, char **argv) { // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) - Passes.add(createPrintModulePass(&Out->os())); + Passes.add(createPrintModulePass(Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); }