Implement a more powerful, simpler, pass system. This pass system can figure
authorChris Lattner <sabre@nondot.org>
Mon, 21 Jan 2002 07:31:50 +0000 (07:31 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 21 Jan 2002 07:31:50 +0000 (07:31 +0000)
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

32 files changed:
include/llvm/Analysis/FindUnsafePointerTypes.h
include/llvm/Analysis/FindUsedTypes.h
include/llvm/Assembly/PrintModulePass.h
include/llvm/Bytecode/WriteBytecodePass.h
include/llvm/Transforms/ChangeAllocations.h
include/llvm/Transforms/FunctionInlining.h
include/llvm/Transforms/HoistPHIConstants.h
include/llvm/Transforms/IPO.h
include/llvm/Transforms/IPO/ConstantMerge.h
include/llvm/Transforms/IPO/GlobalDCE.h
include/llvm/Transforms/IPO/SimpleStructMutation.h
include/llvm/Transforms/Instrumentation/TraceValues.h
include/llvm/Transforms/MutateStructTypes.h
include/llvm/Transforms/RaisePointerReferences.h
include/llvm/Transforms/Scalar/ConstantProp.h
include/llvm/Transforms/Scalar/DCE.h
include/llvm/Transforms/Scalar/IndVarSimplify.h
include/llvm/Transforms/Scalar/InductionVars.h
include/llvm/Transforms/Scalar/InstructionCombining.h
include/llvm/Transforms/Scalar/SymbolStripping.h
lib/Analysis/IPA/FindUnsafePointerTypes.cpp
lib/Analysis/IPA/FindUsedTypes.cpp
lib/Transforms/IPO/ConstantMerge.cpp
lib/Transforms/IPO/DeadTypeElimination.cpp
lib/Transforms/IPO/GlobalDCE.cpp
lib/Transforms/IPO/MutateStructTypes.cpp
lib/Transforms/IPO/SimpleStructMutation.cpp
lib/Transforms/Instrumentation/TraceValues.cpp
lib/Transforms/Utils/LowerAllocations.cpp
tools/gccas/gccas.cpp
tools/llc/llc.cpp
tools/opt/opt.cpp

index c52ca2fbbb511fc8704e6df715df578fc2cdba89..4b2251d90529eb6e58bdfd03a353a8bb8eb2c323 100644 (file)
@@ -22,7 +22,7 @@
 
 class PointerType;
 
-struct FindUnsafePointerTypes : public Pass {
+struct FindUnsafePointerTypes : public MethodPass {
   // UnsafeTypes - Set of types that are not safe to transform.
   std::set<PointerType*> UnsafeTypes;
 public:
@@ -32,11 +32,11 @@ public:
     return UnsafeTypes;
   }
 
-  // doPerMethodWork - Inspect the operations that the specified method does on
+  // runOnMethod - Inspect the operations that the specified method does on
   // values of various types.  If they are deemed to be 'unsafe' note that the
   // type is not safe to transform.
   //
-  virtual bool doPerMethodWork(Method *M);
+  virtual bool runOnMethod(Method *M);
 
   // printResults - Loop over the results of the analysis, printing out unsafe
   // types.
index 956901dfaa2c3dc2668b5ec76019b40285c09d32..1005042ab9ab8065dc88476704a7e17d3011a91f 100644 (file)
@@ -11,7 +11,7 @@
 #include <set>
 class SymbolTable;
 
-class FindUsedTypes : public Pass {
+class FindUsedTypes : public MethodPass {
   std::set<const Type *> UsedTypes;
 
   bool IncludeSymbolTables;
@@ -45,14 +45,14 @@ private:
   void IncorporateSymbolTable(const SymbolTable *ST);
 
 public:
-  // doPassInitialization - This loops over global constants defined in the
+  // doInitialization - This loops over global constants defined in the
   // module, converting them to their new type.
   //
-  bool doPassInitialization(Module *M);
+  bool doInitialization(Module *M);
 
-  // doPerMethodWork - This incorporates all types used by the specified method
+  // runOnMethod - This incorporates all types used by the specified method
   //
-  bool doPerMethodWork(Method *M);
+  bool runOnMethod(Method *M);
 };
 
 #endif
index 72d8fabde042fc6c4c7ea8d0d5284b3f86ac6dd7..181ce98227e99d800668f63eba1f6d39b160b097 100644 (file)
@@ -1,7 +1,9 @@
 //===- llvm/Assembly/PrintModulePass.h - Printing Pass -----------*- C++ -*--=//
 //
-// This file defines a simple pass to print out methods of a module as they are
-// processed.
+// This file defines two passes to print out a module.  The PrintModulePass
+// pass simply prints out the entire module when it is executed.  The
+// PrintMethodPass class is designed to be pipelined with other MethodPass's,
+// and prints out the methods of the class as they are processed.
 //
 //===----------------------------------------------------------------------===//
 
 #include <iostream>
 
 class PrintModulePass : public Pass {
-  std::string Banner;     // String to print before each method
   std::ostream *Out;      // ostream to print on
   bool DeleteStream;      // Delete the ostream in our dtor?
-  bool PrintPerMethod;    // Print one method at a time rather than the whole?
 public:
-  inline PrintModulePass(const std::string &B, std::ostream *o = &std::cout,
-                         bool DS = false,
-                         bool printPerMethod = true)
-    : Banner(B), Out(o), DeleteStream(DS), PrintPerMethod(printPerMethod) {
+  inline PrintModulePass(std::ostream *o = &std::cout, bool DS = false)
+    : Out(o), DeleteStream(DS) {
   }
   
   inline ~PrintModulePass() {
     if (DeleteStream) delete Out;
   }
   
-  // doPerMethodWork - This pass just prints a banner followed by the method as
-  // it's processed.
-  //
-  bool doPerMethodWork(Method *M) {
-    if (PrintPerMethod)
-      (*Out) << Banner << M;
+  bool run(Module *M) {
+    (*Out) << M;
     return false;
   }
+};
 
-  // doPassFinalization - Virtual method overriden by subclasses to do any post
-  // processing needed after all passes have run.
+class PrintMethodPass : public MethodPass {
+  std::string Banner;     // String to print before each method
+  std::ostream *Out;      // ostream to print on
+  bool DeleteStream;      // Delete the ostream in our dtor?
+public:
+  inline PrintMethodPass(const std::string &B, std::ostream *o = &std::cout,
+                         bool DS = false)
+    : Banner(B), Out(o), DeleteStream(DS) {
+  }
+  
+  inline ~PrintMethodPass() {
+    if (DeleteStream) delete Out;
+  }
+  
+  // runOnMethod - This pass just prints a banner followed by the method as
+  // it's processed.
   //
-  bool doPassFinalization(Module *M) {
-    if (! PrintPerMethod)
-      (*Out) << Banner << M;
+  bool runOnMethod(Method *M) {
+    (*Out) << Banner << M;
     return false;
   }
 };
index 6a0edbcd99f64b776027d7a12a0fd107e3bddabf..bd9d42369ecb7baaa91f015e1d64b906edcba889 100644 (file)
@@ -23,7 +23,7 @@ public:
     if (DeleteStream) delete Out;
   }
   
-  bool doPassFinalization(Module *M) {
+  bool run(Module *M) {
     WriteBytecodeToFile(M, *Out);    
     return false;
   }
index 8f53051da34fe3d027f77f078dc249dbb199f3bf..05fb13341008522b49dff925dd007d4ebf11068c 100644 (file)
@@ -13,7 +13,7 @@
 #include "llvm/Pass.h"
 class TargetData;
 
-class LowerAllocations : public Pass {
+class LowerAllocations : public MethodPass {
   Method *MallocMeth;   // Methods in the module we are processing
   Method *FreeMeth;     // Initialized by doPassInitializationVirt
 
@@ -28,12 +28,12 @@ public:
   //
   // This function is always successful.
   //
-  bool doPassInitialization(Module *M);
+  bool doInitialization(Module *M);
 
   // doPerMethodWork - This method does the actual work of converting
   // instructions over, assuming that the pass has already been initialized.
   //
-  bool doPerMethodWork(Method *M);
+  bool runOnMethod(Method *M);
 };
 
 #endif
index 520cc7fe6cf02a52807f86f35e7efc27badd9b55..abc08fdbadfc719311633513e5a720035dc9483f 100644 (file)
@@ -13,13 +13,13 @@ class CallInst;
 
 namespace opt {
 
-struct MethodInlining : public Pass {
+struct MethodInlining : public MethodPass {
   // DoMethodInlining - Use a heuristic based approach to inline methods that
   // seem to look good.
   //
   static bool doMethodInlining(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) {
+  virtual bool runOnMethod(Method *M) {
     return doMethodInlining(M);
   }
 };
index 65bae751a81ab0c7a914081f8039cd6645da75bf..27bf7ab02192b1bb5077d8ef03ae5b8a81473ca3 100644 (file)
 
 #include "llvm/Pass.h"
 
-struct HoistPHIConstants : public Pass {
+struct HoistPHIConstants : public MethodPass {
   // doHoistPHIConstants - Hoist constants out of PHI instructions
   //
   static bool doHoistPHIConstants(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) { return doHoistPHIConstants(M); }
+  virtual bool runOnMethod(Method *M) { return doHoistPHIConstants(M); }
 };
 
 #endif
index 99ff169a1a0b21f851262d6dc1fe3e014a0fed05..6bdba2241d354bb06a77b386bb1c71038f75bc36 100644 (file)
@@ -8,7 +8,7 @@
 
 #include "llvm/Analysis/FindUsedTypes.h"
 
-class CleanupGCCOutput : public Pass {
+class CleanupGCCOutput : public MethodPass {
   Method *Malloc, *Free;  // Pointers to external declarations, or null if none
   FindUsedTypes FUT;      // Use FUT to eliminate type names that are never used
 public:
@@ -27,14 +27,14 @@ public:
   //
   // Also, initialize instance variables.
   //
-  bool doPassInitialization(Module *M);
+  bool doInitialization(Module *M);
 
   // doPerMethodWork - This method simplifies the specified method hopefully.
   //
-  bool doPerMethodWork(Method *M);
+  bool runOnMethod(Method *M);
 
   // doPassFinalization - Strip out type names that are unused by the program
-  bool doPassFinalization(Module *M);
+  bool doFinalization(Module *M);
 private:
   bool doOneCleanupPass(Method *M);
 };
index 37d830ccf85f56f7dd4b668ca1ac60685d40af72..54f699a81183de20a5d926e832f589610d88a583 100644 (file)
@@ -22,7 +22,8 @@
 class Constant;
 class GlobalVariable;
 
-class ConstantMerge : public Pass {
+// FIXME: ConstantMerge should not be a methodPass!!!
+class ConstantMerge : public MethodPass {
 protected:
   std::map<Constant*, GlobalVariable*> Constants;
   unsigned LastConstantSeen;
@@ -34,14 +35,16 @@ public:
   //
   static bool mergeDuplicateConstants(Module *M);
 
-  // doPassInitialization - For this pass, process all of the globals in the
+  // doInitialization - For this pass, process all of the globals in the
   // module, eliminating duplicate constants.
   //
-  bool doPassInitialization(Module *M);
+  bool doInitialization(Module *M);
 
-  // doPassFinalization - Clean up internal state for this module
+  bool runOnMethod(Method*) { return false; }
+
+  // doFinalization - Clean up internal state for this module
   //
-  bool doPassFinalization(Module *M) {
+  bool doFinalization(Module *M) {
     LastConstantSeen = 0;
     Constants.clear();
     return false;
@@ -52,7 +55,7 @@ struct DynamicConstantMerge : public ConstantMerge {
   // doPerMethodWork - Check to see if any globals have been added to the 
   // global list for the module.  If so, eliminate them.
   //
-  bool doPerMethodWork(Method *M);
+  bool runOnMethod(Method *M);
 };
 
 #endif
index 5491751b54eddb8382fa02fe883255d12708cf0a..c4c74470de47a9d06fa1c40dcdb515e97493dc1e 100644 (file)
@@ -7,15 +7,17 @@
 #ifndef LLVM_TRANSFORM_IPO_GLOBALDCE_H
 #define LLVM_TRANSFORM_IPO_GLOBALDCE_H
 
+#include "llvm/Pass.h"
+
 namespace cfg { class CallGraph; }
 class Module;
 
-struct GlobalDCE 
+struct GlobalDCE : public Pass {
 
   // run - Do the GlobalDCE pass on the specified module, optionally updating
   // the specified callgraph to reflect the changes.
   //
-  bool run(Module *M, cfg::CallGraph *CG = 0);
+  bool run(Module *M);
 };
 
 #endif
index 77b962b1079cac4860b61dc68240326759878460..181996d45b5027aea1b9963ace94e1d0f39218ae 100644 (file)
@@ -1,22 +1,27 @@
-//===- llvm/Transforms/SwapStructContents.h - Permute Structs ----*- C++ -*--=//
+//===- llvm/Transforms/SimpleStructMutation.h - Permute Structs --*- C++ -*--=//
 //
-// This pass does a simple transformation that swaps all of the elements of the
-// struct types in the program around.
+// This pass does is a wrapper that can do a few simple structure mutation
+// transformations.
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H
-#define LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H
+#ifndef LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
+#define LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
 
 #include "llvm/Transforms/MutateStructTypes.h"
 
-// FIXME: Move to correct location!
-class PrebuiltStructMutation : public MutateStructTypes {
+class SimpleStructMutation : public MutateStructTypes {
 public:
-  enum Transform { SwapElements, SortElements };
+  enum Transform { SwapElements, SortElements } CurrentXForm;
 
-  PrebuiltStructMutation(Module *M, enum Transform XForm)
-    : MutateStructTypes(getTransforms(M, XForm)) {}
+  SimpleStructMutation(enum Transform XForm) : CurrentXForm(XForm) {}
+
+  virtual bool run(Module *M) {
+    setTransforms(getTransforms(M, CurrentXForm));
+    bool Changed = MutateStructTypes::run(M);
+    clearTransforms();
+    return Changed;
+  }
 
 private:
   static TransformsType getTransforms(Module *M, enum Transform);
index 13847161f10f754ccb7548c2d8e690d141d61556..996db1747ef34586d99b829dd5ba1a8d0a0b4a66 100644 (file)
@@ -11,7 +11,7 @@
 #include "llvm/Pass.h"
 class Method;
 
-class InsertTraceCode : public Pass {
+class InsertTraceCode : public MethodPass {
   bool TraceBasicBlockExits, TraceMethodExits;
   Method *PrintfMeth;
 public:
@@ -21,7 +21,7 @@ public:
 
   // Add a prototype for printf if it is not already in the program.
   //
-  bool doPassInitialization(Module *M);
+  bool doInitialization(Module *M);
 
   //--------------------------------------------------------------------------
   // Function InsertCodeToTraceValues
@@ -32,9 +32,9 @@ public:
   static bool doit(Method *M, bool traceBasicBlockExits,
                    bool traceMethodExits, Method *Printf);
 
-  // doPerMethodWork - This method does the work.  Always successful.
+  // runOnMethod - This method does the work.  Always successful.
   //
-  bool doPerMethodWork(Method *M) {
+  bool runOnMethod(Method *M) {
     return doit(M, TraceBasicBlockExits, TraceMethodExits, PrintfMeth);
   }
 };
index 23bf71c3b197cdfc2850e23ada483e036a48d955..390168f645eb6760dd287814e3d203cd09e14e73 100644 (file)
@@ -51,25 +51,40 @@ public:
   //
   typedef std::map<const StructType*, std::vector<int> > TransformsType;
 
-  MutateStructTypes(const TransformsType &Transforms);
+  MutateStructTypes(const TransformsType &Transforms) {
+    setTransforms(Transforms);
+  }
 
+  // run - do the transformation
+  virtual bool run(Module *M);
 
-  // doPassInitialization - This loops over global constants defined in the
+protected:
+
+  // Alternatively, it is valid to subclass this class and provide transforms
+  // this way.  See SimpleStructMutation for an example.
+  //
+  MutateStructTypes() {}
+  void setTransforms(const TransformsType &Transforms);
+  void clearTransforms();
+
+private:
+
+  // processGlobals - This loops over global constants defined in the
   // module, converting them to their new type.  Also this creates placeholder
   // methods for methods than need to be copied because they have a new
   // signature type.
   //
-  bool doPassInitialization(Module *M);
+  void processGlobals(Module *M);
 
-  // doPerMethodWork - This transforms the instructions of the method to use the
+  // transformMethod - This transforms the instructions of the method to use the
   // new types.
   //
-  bool doPerMethodWork(Method *M);
+  void transformMethod(Method *M);
 
-  // doPassFinalization - This removes the old versions of methods that are no
+  // removeDeadGlobals - This removes the old versions of methods that are no
   // longer needed.
   //
-  virtual bool doPassFinalization(Module *M);
+  void removeDeadGlobals(Module *M);
 
 private:
   // ConvertType - Convert from the old type system to the new one...
index 593ccf2496b222f6931eedc3b7dae8ffc7e7e15e..b652f33712f6a5bd55393e8a06179890813fb204 100644 (file)
 // expressions as possible, by converting expressions to use getelementptr and
 // friends.
 //
-struct RaisePointerReferences : public Pass {
+struct RaisePointerReferences : public MethodPass {
   static bool doit(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) { return doit(M); }
+  virtual bool runOnMethod(Method *M) { return doit(M); }
 };
 
 
@@ -26,10 +26,10 @@ struct RaisePointerReferences : public Pass {
 // converts all induction variables to reference a cannonical induction
 // variable (which starts at 0 and counts by 1).
 //
-struct EliminateAuxillaryInductionVariables : public Pass {
+struct EliminateAuxillaryInductionVariables : public MethodPass {
   static bool doit(Method *M) { return false; } // TODO!
 
-  virtual bool doPerMethodWork(Method *M) { return doit(M); }
+  virtual bool runOnMethod(Method *M) { return doit(M); }
 };
 
 #endif
index e77a9c060062897d11595d93cd5f6915fad1ac5a..f4418665f9d965c57e160bfb8395ce9fcdcb4bd0 100644 (file)
@@ -12,7 +12,7 @@ class TerminatorInst;
 
 namespace opt {
 
-struct ConstantPropogation : public Pass {
+struct ConstantPropogation : public MethodPass {
   // doConstantPropogation - Do trivial constant propogation and expression
   // folding
   static bool doConstantPropogation(Method *M);
@@ -22,7 +22,7 @@ struct ConstantPropogation : public Pass {
   //
   static bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I);
 
-  inline bool doPerMethodWork(Method *M) {
+  inline bool runOnMethod(Method *M) {
     return doConstantPropogation(M);
   }
 };
@@ -39,10 +39,10 @@ bool ConstantFoldTerminator(TerminatorInst *T);
 //===----------------------------------------------------------------------===//
 // Sparse Conditional Constant Propogation Pass
 //
-struct SCCPPass : public Pass {
+struct SCCPPass : public MethodPass {
   static bool doSCCP(Method *M);
 
-  inline bool doPerMethodWork(Method *M) {
+  inline bool runOnMethod(Method *M) {
     return doSCCP(M);
   }
 };
index 86943ebd8555568fb7dc4eee6712e01bb313def6..0e9c620548d2f53cd28072467f3f21f1dca1f874 100644 (file)
@@ -13,7 +13,7 @@
 
 namespace opt {
 
-struct DeadCodeElimination : public Pass {
+struct DeadCodeElimination : public MethodPass {
   // External Interface:
   //
   static bool doDCE(Method *M);
@@ -33,23 +33,23 @@ struct DeadCodeElimination : public Pass {
   static bool RemoveUnusedGlobalValues(Module *M);
 
   // Pass Interface...
-  virtual bool doPassInitialization(Module *M) {
+  virtual bool doInitialization(Module *M) {
     return RemoveUnusedGlobalValues(M);
   }
-  virtual bool doPerMethodWork(Method *M) { return doDCE(M); }
-  virtual bool doPassFinalization(Module *M) {
+  virtual bool runOnMethod(Method *M) { return doDCE(M); }
+  virtual bool doFinalization(Module *M) {
     return RemoveUnusedGlobalValues(M);
   }
 };
 
 
 
-struct AgressiveDCE : public Pass {
+struct AgressiveDCE : public MethodPass {
   // DoADCE - Execute the Agressive Dead Code Elimination Algorithm
   //
   static bool doADCE(Method *M);                        // Defined in ADCE.cpp
 
-  virtual bool doPerMethodWork(Method *M) {
+  virtual bool runOnMethod(Method *M) {
     return doADCE(M);
   }
 };
index 00a43b5ab879917ae5f4f929170b40b07e49ea97..13f811994b66095d6f5d5bc3f3cb1aa88f34928c 100644 (file)
 
 #include "llvm/Pass.h"
 
-struct InductionVariableSimplify : public Pass {
+struct InductionVariableSimplify : public MethodPass {
   static bool doit(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) { return doit(M); }
+  virtual bool runOnMethod(Method *M) { return doit(M); }
 };
 
 #endif
index 82ec9fcc75ff4a24d0d76b814898a0bea93c4310..146239d82bf3b51022990093a46528bcef6f27c8 100644 (file)
 
 namespace opt {
 
-struct InductionVariableCannonicalize : public Pass {
+struct InductionVariableCannonicalize : public MethodPass {
   // doInductionVariableCannonicalize - Simplify induction variables in loops
   //
   static bool doIt(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) {
+  virtual bool runOnMethod(Method *M) {
     return doIt(M);
   }
 };
index 09762d15526f8439131e4e823c1260029c5993be..c79a1caf4b5b4ac73394047e7a852db880d4b61b 100644 (file)
 
 #include "llvm/Pass.h"
 
-struct InstructionCombining : public Pass {
+struct InstructionCombining : public MethodPass {
   static bool doit(Method *M);
   static bool CombineInstruction(Instruction *I);
 
-  virtual bool doPerMethodWork(Method *M) { return doit(M); }
+  virtual bool runOnMethod(Method *M) { return doit(M); }
 };
 
 #endif
index 1feb4381e96bf51e3e2f0722e2f8f35dbd13e286..ff31a4b5323465dacb0e5c421a65f809ca14b084 100644 (file)
 
 namespace opt {
 
-struct SymbolStripping : public Pass {
+struct SymbolStripping : public MethodPass {
   // doSymbolStripping - Remove all symbolic information from a method
   //
   static bool doSymbolStripping(Method *M);
 
-  virtual bool doPerMethodWork(Method *M) {
+  virtual bool runOnMethod(Method *M) {
     return doSymbolStripping(M);
   }
 };
 
-struct FullSymbolStripping : public Pass {
+struct FullSymbolStripping : public MethodPass {
   
   // doStripGlobalSymbols - Remove all symbolic information from all methods 
   // in a module, and all module level symbols. (method names, etc...)
   //
   static bool doStripGlobalSymbols(Module *M);
 
-  virtual bool doPassInitialization(Module *M) {
+  virtual bool doInitialization(Module *M) {
     return doStripGlobalSymbols(M);
   }
 
-  virtual bool doPerMethodWork(Method *M) {
+  virtual bool runOnMethod(Method *M) {
     return SymbolStripping::doSymbolStripping(M);
   }
 };
index 1058e6ed39bc1a2b4fbfbfa88f1dfda1354a946c..85b5da8ce2ef936911d1d614649302156d8b9a3e 100644 (file)
@@ -45,11 +45,11 @@ static inline bool isSafeInstruction(const Instruction *I) {
 }
 
 
-// doPerMethodWork - Inspect the operations that the specified method does on
+// runOnMethod - Inspect the operations that the specified method does on
 // values of various types.  If they are deemed to be 'unsafe' note that the
 // type is not safe to transform.
 //
-bool FindUnsafePointerTypes::doPerMethodWork(Method *Meth) {
+bool FindUnsafePointerTypes::runOnMethod(Method *Meth) {
   const Method *M = Meth;  // We don't need/want write access
   for (Method::const_inst_iterator I = M->inst_begin(), E = M->inst_end();
        I != E; ++I) {
index 1d98983115cf4813b38acc7915a3749702afea24..c439407cb13c8d3654bd00bbc1121df082d0e8ac 100644 (file)
@@ -35,10 +35,10 @@ void FindUsedTypes::IncorporateSymbolTable(const SymbolTable *ST) {
 }
 
 
-// doPassInitialization - This loops over global constants defined in the
+// doInitialization - This loops over global constants defined in the
 // module, converting them to their new type.
 //
-bool FindUsedTypes::doPassInitialization(Module *m) {
+bool FindUsedTypes::doInitialization(Module *m) {
   const Module *M = m;
   if (IncludeSymbolTables && M->hasSymbolTable())
     IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
@@ -51,7 +51,7 @@ bool FindUsedTypes::doPassInitialization(Module *m) {
 
 // doPerMethodWork - This incorporates all types used by the specified method
 //
-bool FindUsedTypes::doPerMethodWork(Method *m) {
+bool FindUsedTypes::runOnMethod(Method *m) {
   const Method *M = m;
   if (IncludeSymbolTables && M->hasSymbolTable())
   IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...
index ff2442d2b65ef21c3d3984036e12f3605c11918e..acb3b6b9379941780c93c1c9edc24fd0c4507b9a 100644 (file)
@@ -65,16 +65,16 @@ bool ConstantMerge::mergeDuplicateConstants(Module *M) {
 }
 
 
-// doPassInitialization - For this pass, process all of the globals in the
+// doInitialization - For this pass, process all of the globals in the
 // module, eliminating duplicate constants.
 //
-bool ConstantMerge::doPassInitialization(Module *M) {
+bool ConstantMerge::doInitialization(Module *M) {
   return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
 }
 
 // doPerMethodWork - Check to see if any globals have been added to the 
 // global list for the module.  If so, eliminate them.
 //
-bool DynamicConstantMerge::doPerMethodWork(Method *M) {
+bool DynamicConstantMerge::runOnMethod(Method *M) {
   return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen, Constants);
 }
index d5e9ea07bdf9390efa0badf1fbfc9dcf2aec34e9..696f4bd7d710056577b4fb5e0b76e124e8432e6c 100644 (file)
@@ -220,14 +220,14 @@ static inline bool ShouldNukeSymtabEntry(const std::pair<string, Value*> &E) {
   return false;
 }
 
-// doPassInitialization - For this pass, it removes global symbol table
+// doInitialization - For this pass, it removes global symbol table
 // entries for primitive types.  These are never used for linking in GCC and
 // they make the output uglier to look at, so we nuke them.
 //
-bool CleanupGCCOutput::doPassInitialization(Module *M) {
+bool CleanupGCCOutput::doInitialization(Module *M) {
   bool Changed = false;
 
-  FUT.doPassInitialization(M);
+  FUT.doInitialization(M);
 
   if (PtrSByte == 0)
     PtrSByte = PointerType::get(Type::SByteTy);
@@ -551,17 +551,17 @@ static bool fixLocalProblems(Method *M) {
 
 // doPerMethodWork - This method simplifies the specified method hopefully.
 //
-bool CleanupGCCOutput::doPerMethodWork(Method *M) {
+bool CleanupGCCOutput::runOnMethod(Method *M) {
   bool Changed = fixLocalProblems(M);
   while (doOneCleanupPass(M)) Changed = true;
 
-  FUT.doPerMethodWork(M);
+  FUT.runOnMethod(M);
   return Changed;
 }
 
-bool CleanupGCCOutput::doPassFinalization(Module *M) {
+bool CleanupGCCOutput::doFinalization(Module *M) {
   bool Changed = false;
-  FUT.doPassFinalization(M);
+  FUT.doFinalization(M);
 
   if (M->hasSymbolTable()) {
     SymbolTable *ST = M->getSymbolTable();
index dacd3295ef9912014c7517fc5bbfc0ab5b3148cc..664381cec684ee50162368ae724d48a754b3ddfe 100644 (file)
 #include "Support/DepthFirstIterator.h"
 #include <set>
 
-static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
-  // Create a call graph if one is not already available...
-  cfg::CallGraph &CallGraph = CG ? *CG : *new cfg::CallGraph(M);
-  
+static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph &CallGraph) {
   // Calculate which methods are reachable from the external methods in the call
   // graph.
   //
@@ -36,11 +33,7 @@ static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
   }
 
   // Nothing to do if no unreachable methods have been found...
-  if (MethodsToDelete.empty()) {
-    // Free the created call graph if it was not passed in
-    if (&CallGraph != CG) delete &CallGraph;
-    return false;
-  }
+  if (MethodsToDelete.empty()) return false;
 
   // Unreachables methods have been found and should have no references to them,
   // delete them now.
@@ -49,11 +42,12 @@ static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
         E = MethodsToDelete.end(); I != E; ++I)
     delete CallGraph.removeMethodFromModule(*I);
 
-  // Free the created call graph if it was not passed in
-  if (&CallGraph != CG) delete &CallGraph;
   return true;
 }
 
-bool GlobalDCE::run(Module *M, cfg::CallGraph *CG = 0) {
-  return RemoveUnreachableMethods(M, CG);
+bool GlobalDCE::run(Module *M) {
+  // TODO: FIXME: GET THE CALL GRAPH FROM THE PASS!
+  // Create a call graph if one is not already available...
+  cfg::CallGraph CallGraph(M);
+  return RemoveUnreachableMethods(M, CallGraph);
 }
index df2b67ef41a493343c0f31a1d501bf7bec7c0af4..331a8743e520db989c87f8ef8a8de9d4c82bb39d 100644 (file)
@@ -20,9 +20,9 @@
 #include "llvm/iMemory.h"
 #include "llvm/iTerminators.h"
 #include "llvm/iOther.h"
+#include "Support/STLExtras.h"
 #include <algorithm>
 using std::map;
-using std::make_pair;
 using std::vector;
 
 // To enable debugging, uncomment this...
@@ -56,7 +56,7 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
   const Type *DestTy = 0;
 
   PATypeHolder<Type> PlaceHolder = OpaqueType::get();
-  TypeMap.insert(make_pair(Ty, PlaceHolder.get()));
+  TypeMap.insert(std::make_pair(Ty, PlaceHolder.get()));
 
   switch (Ty->getPrimitiveID()) {
   case Type::MethodTyID: {
@@ -100,7 +100,7 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
 
   // Refine our little placeholder value into a real type...
   cast<DerivedType>(PlaceHolder.get())->refineAbstractTypeTo(DestTy);
-  TypeMap.insert(make_pair(Ty, PlaceHolder.get()));
+  TypeMap.insert(std::make_pair(Ty, PlaceHolder.get()));
 
   return PlaceHolder.get();
 }
@@ -179,21 +179,20 @@ Value *MutateStructTypes::ConvertValue(const Value *V) {
 }
 
 
-// Ctor - Take a map that specifies what transformation to do for each field
-// of the specified structure types.  There is one element of the vector for
-// each field of the structure.  The value specified indicates which slot of
+// setTransforms - Take a map that specifies what transformation to do for each
+// field of the specified structure types.  There is one element of the vector
+// for each field of the structure.  The value specified indicates which slot of
 // the destination structure the field should end up in.  A negative value 
 // indicates that the field should be deleted entirely.
 //
-MutateStructTypes::MutateStructTypes(const map<const StructType*,
-                                               vector<int> > &XForm) {
+void MutateStructTypes::setTransforms(const TransformsType &XForm) {
 
   // Loop over the types and insert dummy entries into the type map so that 
   // recursive types are resolved properly...
   for (map<const StructType*, vector<int> >::const_iterator I = XForm.begin(),
          E = XForm.end(); I != E; ++I) {
     const StructType *OldTy = I->first;
-    TypeMap.insert(make_pair(OldTy, OpaqueType::get()));
+    TypeMap.insert(std::make_pair(OldTy, OpaqueType::get()));
   }
 
   // Loop over the type specified and figure out what types they should become
@@ -229,17 +228,24 @@ MutateStructTypes::MutateStructTypes(const map<const StructType*,
     cast<DerivedType>(OldTypeStub)->refineAbstractTypeTo(NSTy);
 
     // Add the transformation to the Transforms map.
-    Transforms.insert(make_pair(OldTy, make_pair(NSTy, InVec)));
+    Transforms.insert(std::make_pair(OldTy, std::make_pair(NSTy, InVec)));
 
     DEBUG_MST(cerr << "Mutate " << OldTy << "\nTo " << NSTy << endl);
   }
 }
 
+void MutateStructTypes::clearTransforms() {
+  Transforms.clear();
+  TypeMap.clear();
+  GlobalMap.clear();
+  assert(LocalValueMap.empty() &&
+         "Local Value Map should always be empty between transformations!");
+}
 
-// doPassInitialization - This loops over global constants defined in the
+// doInitialization - This loops over global constants defined in the
 // module, converting them to their new type.
 //
-bool MutateStructTypes::doPassInitialization(Module *M) {
+void MutateStructTypes::processGlobals(Module *M) {
   // Loop through the methods in the module and create a new version of the
   // method to contained the transformed code.  Don't use an iterator, because
   // we will be adding values to the end of the vector, and it could be
@@ -285,14 +291,12 @@ bool MutateStructTypes::doPassInitialization(Module *M) {
       }
     }
   }
-
-  return true;
 }
 
 
-// doPassFinalization - For this pass, all this does is remove the old versions
+// removeDeadGlobals - For this pass, all this does is remove the old versions
 // of the methods and global variables that we no longer need.
-bool MutateStructTypes::doPassFinalization(Module *M) {
+void MutateStructTypes::removeDeadGlobals(Module *M) {
   // The first half of the methods in the module have to go.
   //unsigned NumMethods = M->size();
   //unsigned NumGVars   = M->gsize();
@@ -313,20 +317,18 @@ bool MutateStructTypes::doPassFinalization(Module *M) {
     else
       ++I;
   }
-  
-  return true;
 }
 
 
 
-// doPerMethodWork - This transforms the instructions of the method to use the
+// transformMethod - This transforms the instructions of the method to use the
 // new types.
 //
-bool MutateStructTypes::doPerMethodWork(Method *m) {
+void MutateStructTypes::transformMethod(Method *m) {
   const Method *M = m;
   map<const GlobalValue*, GlobalValue*>::iterator GMI = GlobalMap.find(M);
   if (GMI == GlobalMap.end())
-    return false;  // Do not affect one of our new methods that we are creating
+    return;  // Do not affect one of our new methods that we are creating
 
   Method *NewMeth = cast<Method>(GMI->second);
 
@@ -501,5 +503,14 @@ bool MutateStructTypes::doPerMethodWork(Method *m) {
   }
 
   LocalValueMap.clear();
-  return true;
+}
+
+
+bool MutateStructTypes::run(Module *M) {
+  processGlobals(M);
+
+  for_each(M->begin(), M->end(),
+           bind_obj(this, &MutateStructTypes::transformMethod));
+
+  removeDeadGlobals(M);
 }
index d0b8bb2807ce641e77580c694b6bdd3474e3d325..571638e867ef343e28d97d5356fdfcb1ca870529 100644 (file)
@@ -58,18 +58,18 @@ static unsigned getIndex(const vector<pair<unsigned, unsigned> > &Vec,
 
 static inline void GetTransformation(const StructType *ST,
                                      vector<int> &Transform,
-                                enum PrebuiltStructMutation::Transform XForm) {
+                                enum SimpleStructMutation::Transform XForm) {
   unsigned NumElements = ST->getElementTypes().size();
   Transform.reserve(NumElements);
 
   switch (XForm) {
-  case PrebuiltStructMutation::SwapElements:
+  case SimpleStructMutation::SwapElements:
     // The transformation to do is: just simply swap the elements
     for (unsigned i = 0; i < NumElements; ++i)
       Transform.push_back(NumElements-i-1);
     break;
 
-  case PrebuiltStructMutation::SortElements: {
+  case SimpleStructMutation::SortElements: {
     vector<pair<unsigned, unsigned> > ElList;
 
     // Build mapping from index to size
@@ -87,26 +87,26 @@ static inline void GetTransformation(const StructType *ST,
   }
 }
 
-// doPassInitialization - This does all of the work of the pass
-//
-PrebuiltStructMutation::TransformsType
-  PrebuiltStructMutation::getTransforms(Module *M, enum Transform XForm) {
+SimpleStructMutation::TransformsType
+  SimpleStructMutation::getTransforms(Module *M, enum Transform XForm) {
+
+  // FIXME: These should be calculated by the Pass framework!
+
   // We need to know which types to modify, and which types we CAN'T modify
-  FindUsedTypes          FUT/*(true)*/; // TODO: Do symbol tables as well
-  FindUnsafePointerTypes FUPT;
+  FindUsedTypes          *FUT = new FindUsedTypes(/*true*/); // TODO: Do symbol tables as well
+  FindUnsafePointerTypes *FUPT = new FindUnsafePointerTypes();
 
   // Simutaneously find all of the types used, and all of the types that aren't
   // safe.
   //
-  vector<Pass*> Analyses;
-  Analyses.push_back(&FUT);
-  Analyses.push_back(&FUPT);
-  Pass::runAllPasses(M, Analyses);  // Do analyses
-
+  PassManager Analyses;
+  Analyses.add(FUT);
+  Analyses.add(FUPT);
+  Analyses.run(M);  // Do analyses
 
   // Get the results out of the analyzers...
-  const set<PointerType*> &UnsafePTys = FUPT.getUnsafeTypes();
-  const set<const Type *> &UsedTypes  = FUT.getTypes();
+  const set<PointerType*> &UnsafePTys = FUPT->getUnsafeTypes();
+  const set<const Type *> &UsedTypes  = FUT->getTypes();
 
 
   // Combine the two sets, weeding out non structure types.  Closures in C++
index 00acac8d1f7d29cf6e3ca03919e6b4f10ce96365..c778ca8b0dfc57255c2539ce6eb5a1448f2611ca 100644 (file)
@@ -23,7 +23,7 @@ using std::string;
 
 // Add a prototype for printf if it is not already in the program.
 //
-bool InsertTraceCode::doPassInitialization(Module *M) {
+bool InsertTraceCode::doInitialization(Module *M) {
   SymbolTable *ST = M->getSymbolTable();
   const Type *SBP = PointerType::get(Type::SByteTy);
   const MethodType *MTy =
index ca1085e3edc73569b65c99020a2740898c4a3f74..4f3f182cf32d3fffd918a7bfe9f8a52ee90d5bc4 100644 (file)
 using std::vector;
 
 
-// doPassInitialization - For the lower allocations pass, this ensures that a
+// doInitialization - For the lower allocations pass, this ensures that a
 // module contains a declaration for a malloc and a free function.
 //
 // This function is always successful.
 //
-bool LowerAllocations::doPassInitialization(Module *M) {
+bool LowerAllocations::doInitialization(Module *M) {
   bool Changed = false;
   const MethodType *MallocType = 
     MethodType::get(PointerType::get(Type::SByteTy),
@@ -55,10 +55,10 @@ bool LowerAllocations::doPassInitialization(Module *M) {
   return Changed;  // Always successful
 }
 
-// doPerMethodWork - This method does the actual work of converting
+// runOnMethod - This method does the actual work of converting
 // instructions over, assuming that the pass has already been initialized.
 //
-bool LowerAllocations::doPerMethodWork(Method *M) {
+bool LowerAllocations::runOnMethod(Method *M) {
   bool Changed = false;
   assert(MallocMeth && FreeMeth && M && "Pass not initialized!");
 
index 073b248349912542fd002253b59d621be366c847..7e2b6f3e46c98b88bdd83067b6e00fe8fdf56916 100644 (file)
@@ -63,19 +63,19 @@ int main(int argc, char **argv) {
   // 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;
index 6b51f79b3801019ae1db7a18450e727f0ea384c6..3cc8a723f3d297151c615ce4d724674363afde27 100644 (file)
@@ -52,21 +52,20 @@ static inline string GetFileNameRoot(const string &InputFilename) {
 // 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 @@ public:
   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 @@ public:
 };
 
 
+
 //===---------------------------------------------------------------------===//
 // Function main()
 // 
@@ -119,18 +118,18 @@ int main(int argc, char **argv) {
   }
 
   // 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 @@ int main(int argc, char **argv) {
       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 @@ int main(int argc, char **argv) {
     }
     
     // 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;
 }
index 8a2208d92d3b5bab6969d2526e55bab6d74884a3..7f9acf03e6b62c0d6a3ef38fe02fd65ddab826d1 100644 (file)
@@ -34,14 +34,13 @@ enum Opts {
   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 @@ struct {
   { 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 @@ cl::EnumList<enum Opts> OptimizationList(cl::NoFlags,
 
   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 @@ static void RunOptimization(Module *M, enum Opts Opt) {
       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 @@ int main(int argc, char **argv) {
     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]);