Fix warning when assertions disabled.
[oota-llvm.git] / tools / opt / opt.cpp
index 76cede13f6539558ca42473a5edc2eb64be45b8b..19dcb2b782c63f81aac03678a70e2a5918180954 100644 (file)
@@ -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.
 //
 //===----------------------------------------------------------------------===//
 //
 
 #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 <iostream>
@@ -41,13 +43,10 @@ using namespace llvm;
 static cl::list<const PassInfo*, bool, PassNameParser>
 PassList(cl::desc("Optimizations available:"));
 
-static cl::opt<bool> NoCompress("disable-compression", cl::init(true),
-       cl::desc("Don't compress the generated bytecode"));
-
 // Other command line options...
 //
 static cl::opt<std::string>
-InputFilename(cl::Positional, cl::desc("<input bytecode file>"), 
+InputFilename(cl::Positional, cl::desc("<input bitcode file>"), 
     cl::init("-"), cl::value_desc("filename"));
 
 static cl::opt<std::string>
@@ -62,7 +61,7 @@ PrintEachXForm("p", cl::desc("Print module after each transformation"));
 
 static cl::opt<bool>
 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<bool>
 NoVerify("disable-verify", cl::desc("Do not verify result module"), cl::Hidden);
@@ -94,14 +93,44 @@ QuietA("quiet", cl::desc("Alias for -q"), cl::aliasopt(Quiet));
 static cl::opt<bool>
 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<CallGraphNode *>&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<Pass>(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) {
@@ -121,12 +150,15 @@ 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) {
+    if (!Quiet) { 
       cout << "Printing analysis '" << PassToPrint->getPassName()
            << "' for function '" << F.getName() << "':\n";
     }
@@ -143,9 +175,39 @@ 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<Pass>(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) {
@@ -166,6 +228,7 @@ 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);
@@ -178,7 +241,6 @@ void AddStandardCompilePasses(PassManager &PM) {
   PM.add(createVerifierPass());                  // Verify that input is correct
 
   addPass(PM, createLowerSetJmpPass());          // Lower llvm.setjmp/.longjmp
-  addPass(PM, createFunctionResolvingPass());    // Resolve (...) functions
 
   // If the -strip-debug command line option was specified, do it.
   if (StripDebug)
@@ -203,7 +265,9 @@ void AddStandardCompilePasses(PassManager &PM) {
   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
@@ -212,14 +276,18 @@ void AddStandardCompilePasses(PassManager &PM) {
   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, createInstructionCombiningPass()); // Clean up after LICM/reassoc
+  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, createLoadValueNumberingPass());   // GVN for load instructions
-  addPass(PM, createGCSEPass());                 // Remove common subexprs
+  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
@@ -228,9 +296,9 @@ void AddStandardCompilePasses(PassManager &PM) {
   addPass(PM, createCondPropagationPass());      // Propagate conditionals
 
   addPass(PM, createDeadStoreEliminationPass()); // Delete dead stores
-  addPass(PM, createAggressiveDCEPass());        // SSA based 'Aggressive DCE'
+  addPass(PM, createAggressiveDCEPass());        // Delete dead instructions
   addPass(PM, createCFGSimplificationPass());    // Merge & remove BBs
-  addPass(PM, createSimplifyLibCallsPass());     // Library Call Optimizations
+  addPass(PM, createStripDeadPrototypesPass());  // Get rid of dead prototypes
   addPass(PM, createDeadTypeEliminationPass());  // Eliminate dead types
   addPass(PM, createConstantMergePass());        // Merge dup global constants
 }
@@ -245,7 +313,7 @@ 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.
@@ -255,13 +323,19 @@ int main(int argc, char **argv) {
     std::string ErrorMessage;
 
     // Load the input module...
-    std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename, &ErrorMessage));
+    std::auto_ptr<Module> M;
+    if (MemoryBuffer *Buffer
+          = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) {
+      M.reset(ParseBitcodeFile(Buffer, &ErrorMessage));
+      delete Buffer;
+    }
+    
     if (M.get() == 0) {
       cerr << argv[0] << ": ";
       if (ErrorMessage.size())
         cerr << ErrorMessage << "\n";
       else
-        cerr << "bytecode didn't read correctly.\n";
+        cerr << "bitcode didn't read correctly.\n";
       return 1;
     }
 
@@ -293,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;
     }
 
@@ -330,8 +404,12 @@ int main(int argc, char **argv) {
         if (AnalyzeOnly) {
           if (dynamic_cast<BasicBlockPass*>(P))
             Passes.add(new BasicBlockPassPrinter(PassInf));
+          else if (dynamic_cast<LoopPass*>(P))
+            Passes.add(new  LoopPassPrinter(PassInf));
           else if (dynamic_cast<FunctionPass*>(P))
             Passes.add(new FunctionPassPrinter(PassInf));
+          else if (dynamic_cast<CallGraphSCCPass*>(P))
+            Passes.add(new CallGraphSCCPassPrinter(PassInf));
           else
             Passes.add(new ModulePassPrinter(PassInf));
         }
@@ -345,14 +423,16 @@ int main(int argc, char **argv) {
     if (!NoVerify && !VerifyEach)
       Passes.add(createVerifierPass());
 
-    // Write bytecode out to disk or cout as the last step...
-    OStream L(*Out);
+    // Write bitcode out to disk or cout as the last step...
     if (!NoOutput && !AnalyzeOnly)
-      Passes.add(new WriteBytecodePass(&L, false, !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) {