Implement a more powerful, simpler, pass system.  This pass system can figure
out how to run a collection of passes optimially given their behaviors and
charactaristics.

Convert code to use it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1507 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/gccas/gccas.cpp b/tools/gccas/gccas.cpp
index 073b248..7e2b6f3 100644
--- a/tools/gccas/gccas.cpp
+++ b/tools/gccas/gccas.cpp
@@ -63,19 +63,19 @@
   // In addition to just parsing the input from GCC, we also want to spiff it up
   // a little bit.  Do this now.
   //
-  std::vector<Pass*> Passes;
-  Passes.push_back(new opt::DeadCodeElimination());  // Remove Dead code/vars
-  Passes.push_back(new CleanupGCCOutput());          // Fix gccisms
-  Passes.push_back(new InductionVariableSimplify()); // Simplify indvars
-  Passes.push_back(new RaisePointerReferences());    // Eliminate casts
-  Passes.push_back(new ConstantMerge());             // Merge dup global consts
-  Passes.push_back(new InstructionCombining());      // Combine silly seq's
-  Passes.push_back(new opt::DeadCodeElimination());  // Remove Dead code/vars
+  PassManager Passes;
+  Passes.add(new opt::DeadCodeElimination());  // Remove Dead code/vars
+  Passes.add(new CleanupGCCOutput());          // Fix gccisms
+  Passes.add(new InductionVariableSimplify()); // Simplify indvars
+  Passes.add(new RaisePointerReferences());    // Eliminate casts
+  Passes.add(new ConstantMerge());             // Merge dup global consts
+  Passes.add(new InstructionCombining());      // Combine silly seq's
+  Passes.add(new opt::DeadCodeElimination());  // Remove Dead code/vars
 
   // Run our queue of passes all at once now, efficiently.  This form of
   // runAllPasses frees the Pass objects after runAllPasses completes.
   //
-  Pass::runAllPassesAndFree(M.get(), Passes);
+  Passes.run(M.get());
 
   WriteBytecodeToFile(M.get(), *Out);
   return 0;
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 6b51f79..3cc8a72 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -52,21 +52,20 @@
 // Native code generation for a specified target.
 //===---------------------------------------------------------------------===//
 
-class GenerateCodeForTarget : public Pass {
+class GenerateCodeForTarget : public MethodPass {
   TargetMachine &Target;
 public:
   inline GenerateCodeForTarget(TargetMachine &T) : Target(T) {}
 
-  // doPerMethodWork - This method does the actual work of generating code for
+  // runOnMethod - This method does the actual work of generating code for
   // the specified method.
   //
-  bool doPerMethodWork(Method *M) {
+  bool runOnMethod(Method *M) {
     if (!M->isExternal() && Target.compileMethod(M)) {
       cerr << "Error compiling " << InputFilename << "!\n";
-      return true;
     }
     
-    return false;
+    return true;
   }
 };
 
@@ -85,8 +84,7 @@
   inline EmitAssembly(const TargetMachine &T, std::ostream *O, bool D)
     : Target(T), Out(O), DeleteStream(D) {}
 
-
-  virtual bool doPassFinalization(Module *M) {
+  virtual bool run(Module *M) {
     Target.emitAssembly(M, *Out);
 
     if (DeleteStream) delete Out;
@@ -95,6 +93,7 @@
 };
 
 
+
 //===---------------------------------------------------------------------===//
 // Function main()
 // 
@@ -119,18 +118,18 @@
   }
 
   // Build up all of the passes that we want to do to the module...
-  std::vector<Pass*> Passes;
+  PassManager Passes;
 
   // Hoist constants out of PHI nodes into predecessor BB's
-  Passes.push_back(new HoistPHIConstants());
+  Passes.add(new HoistPHIConstants());
 
   if (TraceBBValues || TraceMethodValues) {   // If tracing enabled...
     // Insert trace code in all methods in the module
-    Passes.push_back(new InsertTraceCode(TraceBBValues, 
-                                         TraceBBValues ||TraceMethodValues));
+    Passes.add(new InsertTraceCode(TraceBBValues, 
+                                   TraceBBValues ||TraceMethodValues));
 
     // Eliminate duplication in constant pool
-    Passes.push_back(new DynamicConstantMerge());
+    Passes.add(new DynamicConstantMerge());
       
     // Then write out the module with tracing code before code generation 
     assert(InputFilename != "-" &&
@@ -152,20 +151,20 @@
       return 1;
     }
     
-    Passes.push_back(new WriteBytecodePass(os, true));
+    Passes.add(new WriteBytecodePass(os, true));
   }
   
   // Replace malloc and free instructions with library calls.
   // Do this after tracing until lli implements these lib calls.
   // For now, it will emulate malloc and free internally.
-  Passes.push_back(new LowerAllocations(Target.DataLayout));
+  Passes.add(new LowerAllocations(Target.DataLayout));
   
   // If LLVM dumping after transformations is requested, add it to the pipeline
   if (DumpAsm)
-    Passes.push_back(new PrintModulePass("Code after xformations: \n",&cerr));
+    Passes.add(new PrintMethodPass("Code after xformations: \n",&cerr));
 
   // Generate Target code...
-  Passes.push_back(new GenerateCodeForTarget(Target));
+  Passes.add(new GenerateCodeForTarget(Target));
 
   if (!DoNotEmitAssembly) {                // If asm output is enabled...
     // Figure out where we are going to send the output...
@@ -203,12 +202,11 @@
     }
     
     // Output assembly language to the .s file
-    Passes.push_back(new EmitAssembly(Target, Out, Out != &std::cout));
+    Passes.add(new EmitAssembly(Target, Out, Out != &std::cout));
   }
   
-  // Run our queue of passes all at once now, efficiently.  This form of
-  // runAllPasses frees the Pass objects after runAllPasses completes.
-  Pass::runAllPassesAndFree(M.get(), Passes);
+  // Run our queue of passes all at once now, efficiently.
+  Passes.run(M.get());
 
   return 0;
 }
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 8a2208d..7f9acf0 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -34,14 +34,13 @@
   indvars, instcombine, sccp, adce, raise,
 
   // Interprocedural optimizations...
-  globaldce, swapstructs,
+  globaldce, swapstructs, sortstructs,
 };
 
 struct {
   enum Opts OptID;
   Pass *ThePass;
 } OptTable[] = {
-  { swapstructs, 0 },
   { dce        , new opt::DeadCodeElimination() },
   { constprop  , new opt::ConstantPropogation() }, 
   { inlining   , new opt::MethodInlining() },
@@ -55,8 +54,11 @@
   { raise      , new RaisePointerReferences() },
   { trace      , new InsertTraceCode(true, true) },
   { tracem     , new InsertTraceCode(false, true) },
-  { print      , new PrintModulePass("Current Method: \n",&cerr) },
+  { print      , new PrintMethodPass("Current Method: \n",&cerr) },
   { cleangcc   , new CleanupGCCOutput() },
+  { globaldce  , new GlobalDCE() },
+  { swapstructs, new SimpleStructMutation(SimpleStructMutation::SwapElements) },
+  { sortstructs, new SimpleStructMutation(SimpleStructMutation::SortElements) },
 };
 
 cl::String InputFilename ("", "Load <arg> file to optimize", cl::NoFlags, "-");
@@ -78,6 +80,7 @@
 
   clEnumVal(globaldce  , "Remove unreachable globals"),
   clEnumVal(swapstructs, "Swap structure types around"),
+  clEnumVal(sortstructs, "Sort structure elements"),
 
   clEnumVal(cleangcc   , "Cleanup GCC Output"),
   clEnumVal(raise      , "Raise to Higher Level"),
@@ -95,18 +98,7 @@
       return;
     }
   
-  // Special cases that haven't been fit into a consistent framework yet...
-  switch (Opt) {
-  case globaldce: {
-    GlobalDCE GDCE; GDCE.run(M); return;
-  }
-  case swapstructs: {
-    PrebuiltStructMutation SM(M, PrebuiltStructMutation::SortElements);
-    SM.run(M); return;
-  }
-  default:
-    cerr << "Optimization tables inconsistent!!\n";
-  }
+  cerr << "Optimization tables inconsistent!!\n";
 }
 
 int main(int argc, char **argv) {
@@ -118,6 +110,8 @@
     return 1;
   }
 
+  PassManager Passes;
+
   // Run all of the optimizations specified on the command line
   for (unsigned i = 0; i < OptimizationList.size(); ++i)
     RunOptimization(M.get(), OptimizationList[i]);