X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fopt%2Fopt.cpp;h=19dcb2b782c63f81aac03678a70e2a5918180954;hb=629c1a3f78494d0dd769fe82bd2bd17df0555843;hp=502118e65885707a94070a41737cd647b4d46986;hpb=a5b31ca85686062408bca0f0a8aa43f9fe58e644;p=oota-llvm.git diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 502118e6588..19dcb2b782c 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -14,20 +14,24 @@ #include "llvm/Module.h" #include "llvm/PassManager.h" -#include "llvm/Bytecode/Reader.h" -#include "llvm/Bytecode/WriteBytecodePass.h" +#include "llvm/CallGraphSCCPass.h" +#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Analysis/Verifier.h" +#include "llvm/Analysis/LoopPass.h" +#include "llvm/Analysis/CallGraph.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/PassNameParser.h" #include "llvm/System/Signals.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/Streams.h" #include "llvm/Support/SystemUtils.h" -#include "llvm/Support/Timer.h" #include "llvm/LinkAllPasses.h" #include "llvm/LinkAllVMCore.h" +#include #include #include #include @@ -39,13 +43,10 @@ using namespace llvm; static cl::list PassList(cl::desc("Optimizations available:")); -static cl::opt NoCompress("disable-compression", cl::init(false), - cl::desc("Don't compress the generated bytecode")); - // Other command line options... // static cl::opt -InputFilename(cl::Positional, cl::desc(""), +InputFilename(cl::Positional, cl::desc(""), cl::init("-"), cl::value_desc("filename")); static cl::opt @@ -60,11 +61,29 @@ PrintEachXForm("p", cl::desc("Print module after each transformation")); static cl::opt NoOutput("disable-output", - cl::desc("Do not write result bytecode file"), cl::Hidden); + cl::desc("Do not write result bitcode file"), cl::Hidden); static cl::opt NoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden); +static cl::opt +VerifyEach("verify-each", cl::desc("Verify after each transform")); + +static cl::opt +StripDebug("strip-debug", + cl::desc("Strip debugger symbol info from translation unit")); + +static cl::opt +DisableInline("disable-inlining", cl::desc("Do not run the inliner pass")); + +static cl::opt +DisableOptimizations("disable-opt", + cl::desc("Do not run any optimization passes")); + +static cl::opt +StandardCompileOpts("std-compile-opts", + cl::desc("Include the standard compile time optimizations")); + static cl::opt Quiet("q", cl::desc("Obsolete option"), cl::Hidden); @@ -74,20 +93,49 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet)); static cl::opt AnalyzeOnly("analyze", cl::desc("Only perform analysis, no optimization")); -static Timer BytecodeLoadTimer("Bytecode Loader"); - // ---------- Define Printers for module and function passes ------------ namespace { +struct CallGraphSCCPassPrinter : public CallGraphSCCPass { + static char ID; + const PassInfo *PassToPrint; + CallGraphSCCPassPrinter(const PassInfo *PI) : + CallGraphSCCPass((intptr_t)&ID), PassToPrint(PI) {} + + virtual bool runOnSCC(const std::vector&SCC) { + if (!Quiet) { + cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + + for (unsigned i = 0, e = SCC.size(); i != e; ++i) { + Function *F = SCC[i]->getFunction(); + if (F) + getAnalysisID(PassToPrint).print(cout, F->getParent()); + } + } + // Get and print pass... + return false; + } + + virtual const char *getPassName() const { return "'Pass' Printer"; } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredID(PassToPrint); + AU.setPreservesAll(); + } +}; + +char CallGraphSCCPassPrinter::ID = 0; + struct ModulePassPrinter : public ModulePass { + static char ID; const PassInfo *PassToPrint; - ModulePassPrinter(const PassInfo *PI) : PassToPrint(PI) {} + ModulePassPrinter(const PassInfo *PI) : ModulePass((intptr_t)&ID), + PassToPrint(PI) {} virtual bool runOnModule(Module &M) { if (!Quiet) { - llvm_cout << "Printing analysis '" << PassToPrint->getPassName() - << "':\n"; - getAnalysisID(PassToPrint).print(llvm_cout, &M); + cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + getAnalysisID(PassToPrint).print(cout, &M); } // Get and print pass... @@ -102,17 +150,20 @@ struct ModulePassPrinter : public ModulePass { } }; +char ModulePassPrinter::ID = 0; struct FunctionPassPrinter : public FunctionPass { const PassInfo *PassToPrint; - FunctionPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} + static char ID; + FunctionPassPrinter(const PassInfo *PI) : FunctionPass((intptr_t)&ID), + PassToPrint(PI) {} virtual bool runOnFunction(Function &F) { - if (!Quiet) { - llvm_cout << "Printing analysis '" << PassToPrint->getPassName() - << "' for function '" << F.getName() << "':\n"; + if (!Quiet) { + cout << "Printing analysis '" << PassToPrint->getPassName() + << "' for function '" << F.getName() << "':\n"; } // Get and print pass... - getAnalysisID(PassToPrint).print(llvm_cout, F.getParent()); + getAnalysisID(PassToPrint).print(cout, F.getParent()); return false; } @@ -124,19 +175,48 @@ struct FunctionPassPrinter : public FunctionPass { } }; +char FunctionPassPrinter::ID = 0; + +struct LoopPassPrinter : public LoopPass { + static char ID; + const PassInfo *PassToPrint; + LoopPassPrinter(const PassInfo *PI) : + LoopPass((intptr_t)&ID), PassToPrint(PI) {} + + virtual bool runOnLoop(Loop *L, LPPassManager &LPM) { + if (!Quiet) { + cout << "Printing analysis '" << PassToPrint->getPassName() << "':\n"; + getAnalysisID(PassToPrint).print(cout, + L->getHeader()->getParent()->getParent()); + } + // Get and print pass... + return false; + } + + virtual const char *getPassName() const { return "'Pass' Printer"; } + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequiredID(PassToPrint); + AU.setPreservesAll(); + } +}; + +char LoopPassPrinter::ID = 0; + struct BasicBlockPassPrinter : public BasicBlockPass { const PassInfo *PassToPrint; - BasicBlockPassPrinter(const PassInfo *PI) : PassToPrint(PI) {} + static char ID; + BasicBlockPassPrinter(const PassInfo *PI) + : BasicBlockPass((intptr_t)&ID), PassToPrint(PI) {} virtual bool runOnBasicBlock(BasicBlock &BB) { if (!Quiet) { - llvm_cout << "Printing Analysis info for BasicBlock '" << BB.getName() - << "': Pass " << PassToPrint->getPassName() << ":\n"; + cout << "Printing Analysis info for BasicBlock '" << BB.getName() + << "': Pass " << PassToPrint->getPassName() << ":\n"; } // Get and print pass... - getAnalysisID(PassToPrint).print( - llvm_cout, BB.getParent()->getParent()); + getAnalysisID(PassToPrint).print(cout, BB.getParent()->getParent()); return false; } @@ -148,6 +228,81 @@ struct BasicBlockPassPrinter : public BasicBlockPass { } }; +char BasicBlockPassPrinter::ID = 0; +inline void addPass(PassManager &PM, Pass *P) { + // Add the pass to the pass manager... + PM.add(P); + + // If we are verifying all of the intermediate steps, add the verifier... + if (VerifyEach) PM.add(createVerifierPass()); +} + +void AddStandardCompilePasses(PassManager &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)); + + if (DisableOptimizations) return; + + addPass(PM, createRaiseAllocationsPass()); // call %malloc -> malloc inst + addPass(PM, createCFGSimplificationPass()); // Clean up disgusting code + addPass(PM, createPromoteMemoryToRegisterPass());// Kill useless allocas + addPass(PM, createGlobalOptimizerPass()); // Optimize out global vars + addPass(PM, createGlobalDCEPass()); // Remove unused fns and globs + addPass(PM, createIPConstantPropagationPass());// IP Constant Propagation + addPass(PM, createDeadArgEliminationPass()); // Dead argument elimination + addPass(PM, createInstructionCombiningPass()); // Clean up after IPCP & DAE + addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE + + addPass(PM, createPruneEHPass()); // Remove dead EH info + + if (!DisableInline) + addPass(PM, createFunctionInliningPass()); // Inline small functions + addPass(PM, createArgumentPromotionPass()); // Scalarize uninlined fn args + + addPass(PM, createTailDuplicationPass()); // Simplify cfg by copying code + addPass(PM, createSimplifyLibCallsPass()); // Library Call Optimizations + addPass(PM, createInstructionCombiningPass()); // Cleanup for scalarrepl. + addPass(PM, createJumpThreadingPass()); // Thread jumps. + addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs + addPass(PM, createScalarReplAggregatesPass()); // Break up aggregate allocas + addPass(PM, createInstructionCombiningPass()); // Combine silly seq's + addPass(PM, createCondPropagationPass()); // Propagate conditionals + + addPass(PM, createTailCallEliminationPass()); // Eliminate tail calls + addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs + addPass(PM, createReassociatePass()); // Reassociate expressions + addPass(PM, createLoopRotatePass()); + addPass(PM, createLICMPass()); // Hoist loop invariants + addPass(PM, createLoopUnswitchPass()); // Unswitch loops. + addPass(PM, createLoopIndexSplitPass()); // Index split loops. + // FIXME : Removing instcombine causes nestedloop regression. + addPass(PM, createInstructionCombiningPass()); + addPass(PM, createIndVarSimplifyPass()); // Canonicalize indvars + addPass(PM, createLoopDeletionPass()); // Delete dead loops + addPass(PM, createLoopUnrollPass()); // Unroll small loops + addPass(PM, createInstructionCombiningPass()); // Clean up after the unroller + addPass(PM, createGVNPass()); // Remove redundancies + addPass(PM, createMemCpyOptPass()); // Remove memcpy / form memset + addPass(PM, createSCCPPass()); // Constant prop with SCCP + + // Run instcombine after redundancy elimination to exploit opportunities + // opened up by them. + addPass(PM, createInstructionCombiningPass()); + addPass(PM, createCondPropagationPass()); // Propagate conditionals + + addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores + addPass(PM, createAggressiveDCEPass()); // Delete dead instructions + addPass(PM, createCFGSimplificationPass()); // Merge & remove BBs + addPass(PM, createStripDeadPrototypesPass()); // Get rid of dead prototypes + addPass(PM, createDeadTypeEliminationPass()); // Eliminate dead types + addPass(PM, createConstantMergePass()); // Merge dup global constants +} + } // anonymous namespace @@ -155,9 +310,10 @@ struct BasicBlockPassPrinter : public BasicBlockPass { // main for opt // int main(int argc, char **argv) { + llvm_shutdown_obj X; // Call llvm_shutdown() on exit. try { cl::ParseCommandLineOptions(argc, argv, - " llvm .bc -> .bc modular optimizer and analysis printer \n"); + "llvm .bc -> .bc modular optimizer and analysis printer\n"); sys::PrintStackTraceOnErrorSignal(); // Allocate a full target machine description only if necessary. @@ -167,13 +323,19 @@ int main(int argc, char **argv) { std::string ErrorMessage; // Load the input module... - std::auto_ptr M(ParseBytecodeFile(InputFilename, &ErrorMessage)); + std::auto_ptr M; + if (MemoryBuffer *Buffer + = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { + M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); + delete Buffer; + } + if (M.get() == 0) { - llvm_cerr << argv[0] << ": "; + cerr << argv[0] << ": "; if (ErrorMessage.size()) - llvm_cerr << ErrorMessage << "\n"; + cerr << ErrorMessage << "\n"; else - llvm_cerr << "bytecode didn't read correctly.\n"; + cerr << "bitcode didn't read correctly.\n"; return 1; } @@ -183,9 +345,9 @@ int main(int argc, char **argv) { if (OutputFilename != "-") { if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! - llvm_cerr << argv[0] << ": error opening '" << OutputFilename - << "': file exists!\n" - << "Use -f command line argument to force output\n"; + cerr << argv[0] << ": error opening '" << OutputFilename + << "': file exists!\n" + << "Use -f command line argument to force output\n"; return 1; } std::ios::openmode io_mode = std::ios::out | std::ios::trunc | @@ -193,7 +355,7 @@ int main(int argc, char **argv) { Out = new std::ofstream(OutputFilename.c_str(), io_mode); if (!Out->good()) { - llvm_cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; + cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; return 1; } @@ -205,7 +367,7 @@ int main(int argc, char **argv) { // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. - if (!Force && !NoOutput && CheckBytecodeOutputToConsole(Out,!Quiet)) { + if (!Force && !NoOutput && CheckBitcodeOutputToConsole(Out,!Quiet)) { NoOutput = true; } @@ -217,52 +379,67 @@ int main(int argc, char **argv) { // Add an appropriate TargetData instance for this module... Passes.add(new TargetData(M.get())); + // If -std-compile-opts is given, add in all the standard compilation + // optimizations first. This will handle -strip-debug, -disable-inline, + // and -disable-opt as well. + if (StandardCompileOpts) + AddStandardCompilePasses(Passes); + + // otherwise if the -strip-debug command line option was specified, add it. + else if (StripDebug) + addPass(Passes, createStripSymbolsPass(true)); + // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); - else if (PassInf->getTargetCtor()) { - assert(target.get() && "Could not allocate target machine!"); - P = PassInf->getTargetCtor()(*target.get()); - } else - llvm_cerr << argv[0] << ": cannot create pass: " - << PassInf->getPassName() << "\n"; + else + cerr << argv[0] << ": cannot create pass: " + << PassInf->getPassName() << "\n"; if (P) { - Passes.add(P); + addPass(Passes, P); if (AnalyzeOnly) { if (dynamic_cast(P)) Passes.add(new BasicBlockPassPrinter(PassInf)); + else if (dynamic_cast(P)) + Passes.add(new LoopPassPrinter(PassInf)); else if (dynamic_cast(P)) Passes.add(new FunctionPassPrinter(PassInf)); + else if (dynamic_cast(P)) + Passes.add(new CallGraphSCCPassPrinter(PassInf)); else Passes.add(new ModulePassPrinter(PassInf)); } } if (PrintEachXForm) - Passes.add(new PrintModulePass(&llvm_cerr)); + Passes.add(new PrintModulePass(&cerr)); } // Check that the module is well formed on completion of optimization - if (!NoVerify) + if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); - // Write bytecode out to disk or cout as the last step... + // Write bitcode out to disk or cout as the last step... if (!NoOutput && !AnalyzeOnly) - Passes.add(new WriteBytecodePass(Out, Out != &std::cout, !NoCompress)); + Passes.add(CreateBitcodeWriterPass(*Out)); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); + // Delete the ofstream. + if (Out != &std::cout) + delete Out; return 0; } catch (const std::string& msg) { - llvm_cerr << argv[0] << ": " << msg << "\n"; + cerr << argv[0] << ": " << msg << "\n"; } catch (...) { - llvm_cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; + cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; } + llvm_shutdown(); return 1; }