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.

llvm-svn: 1507
This commit is contained in:
Chris Lattner 2002-01-21 07:31:50 +00:00
parent e8d81d0819
commit 0686e435d1
32 changed files with 238 additions and 208 deletions

View File

@ -22,7 +22,7 @@
class PointerType; class PointerType;
struct FindUnsafePointerTypes : public Pass { struct FindUnsafePointerTypes : public MethodPass {
// UnsafeTypes - Set of types that are not safe to transform. // UnsafeTypes - Set of types that are not safe to transform.
std::set<PointerType*> UnsafeTypes; std::set<PointerType*> UnsafeTypes;
public: public:
@ -32,11 +32,11 @@ public:
return UnsafeTypes; 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 // values of various types. If they are deemed to be 'unsafe' note that the
// type is not safe to transform. // 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 // printResults - Loop over the results of the analysis, printing out unsafe
// types. // types.

View File

@ -11,7 +11,7 @@
#include <set> #include <set>
class SymbolTable; class SymbolTable;
class FindUsedTypes : public Pass { class FindUsedTypes : public MethodPass {
std::set<const Type *> UsedTypes; std::set<const Type *> UsedTypes;
bool IncludeSymbolTables; bool IncludeSymbolTables;
@ -45,14 +45,14 @@ private:
void IncorporateSymbolTable(const SymbolTable *ST); void IncorporateSymbolTable(const SymbolTable *ST);
public: 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. // 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 #endif

View File

@ -1,7 +1,9 @@
//===- llvm/Assembly/PrintModulePass.h - Printing Pass -----------*- C++ -*--=// //===- llvm/Assembly/PrintModulePass.h - Printing Pass -----------*- C++ -*--=//
// //
// This file defines a simple pass to print out methods of a module as they are // This file defines two passes to print out a module. The PrintModulePass
// processed. // 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.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -13,36 +15,42 @@
#include <iostream> #include <iostream>
class PrintModulePass : public Pass { class PrintModulePass : public Pass {
std::string Banner; // String to print before each method
std::ostream *Out; // ostream to print on std::ostream *Out; // ostream to print on
bool DeleteStream; // Delete the ostream in our dtor? bool DeleteStream; // Delete the ostream in our dtor?
bool PrintPerMethod; // Print one method at a time rather than the whole?
public: public:
inline PrintModulePass(const std::string &B, std::ostream *o = &std::cout, inline PrintModulePass(std::ostream *o = &std::cout, bool DS = false)
bool DS = false, : Out(o), DeleteStream(DS) {
bool printPerMethod = true)
: Banner(B), Out(o), DeleteStream(DS), PrintPerMethod(printPerMethod) {
} }
inline ~PrintModulePass() { inline ~PrintModulePass() {
if (DeleteStream) delete Out; if (DeleteStream) delete Out;
} }
// doPerMethodWork - This pass just prints a banner followed by the method as bool run(Module *M) {
// it's processed. (*Out) << M;
//
bool doPerMethodWork(Method *M) {
if (PrintPerMethod)
(*Out) << Banner << M;
return false; return false;
} }
};
// doPassFinalization - Virtual method overriden by subclasses to do any post class PrintMethodPass : public MethodPass {
// processing needed after all passes have run. 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) { bool runOnMethod(Method *M) {
if (! PrintPerMethod) (*Out) << Banner << M;
(*Out) << Banner << M;
return false; return false;
} }
}; };

View File

@ -23,7 +23,7 @@ public:
if (DeleteStream) delete Out; if (DeleteStream) delete Out;
} }
bool doPassFinalization(Module *M) { bool run(Module *M) {
WriteBytecodeToFile(M, *Out); WriteBytecodeToFile(M, *Out);
return false; return false;
} }

View File

@ -13,7 +13,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
class TargetData; class TargetData;
class LowerAllocations : public Pass { class LowerAllocations : public MethodPass {
Method *MallocMeth; // Methods in the module we are processing Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doPassInitializationVirt Method *FreeMeth; // Initialized by doPassInitializationVirt
@ -28,12 +28,12 @@ public:
// //
// This function is always successful. // This function is always successful.
// //
bool doPassInitialization(Module *M); bool doInitialization(Module *M);
// doPerMethodWork - This method does the actual work of converting // doPerMethodWork - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized. // instructions over, assuming that the pass has already been initialized.
// //
bool doPerMethodWork(Method *M); bool runOnMethod(Method *M);
}; };
#endif #endif

View File

@ -13,13 +13,13 @@ class CallInst;
namespace opt { namespace opt {
struct MethodInlining : public Pass { struct MethodInlining : public MethodPass {
// DoMethodInlining - Use a heuristic based approach to inline methods that // DoMethodInlining - Use a heuristic based approach to inline methods that
// seem to look good. // seem to look good.
// //
static bool doMethodInlining(Method *M); static bool doMethodInlining(Method *M);
virtual bool doPerMethodWork(Method *M) { virtual bool runOnMethod(Method *M) {
return doMethodInlining(M); return doMethodInlining(M);
} }
}; };

View File

@ -11,12 +11,12 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
struct HoistPHIConstants : public Pass { struct HoistPHIConstants : public MethodPass {
// doHoistPHIConstants - Hoist constants out of PHI instructions // doHoistPHIConstants - Hoist constants out of PHI instructions
// //
static bool doHoistPHIConstants(Method *M); static bool doHoistPHIConstants(Method *M);
virtual bool doPerMethodWork(Method *M) { return doHoistPHIConstants(M); } virtual bool runOnMethod(Method *M) { return doHoistPHIConstants(M); }
}; };
#endif #endif

View File

@ -8,7 +8,7 @@
#include "llvm/Analysis/FindUsedTypes.h" #include "llvm/Analysis/FindUsedTypes.h"
class CleanupGCCOutput : public Pass { class CleanupGCCOutput : public MethodPass {
Method *Malloc, *Free; // Pointers to external declarations, or null if none Method *Malloc, *Free; // Pointers to external declarations, or null if none
FindUsedTypes FUT; // Use FUT to eliminate type names that are never used FindUsedTypes FUT; // Use FUT to eliminate type names that are never used
public: public:
@ -27,14 +27,14 @@ public:
// //
// Also, initialize instance variables. // Also, initialize instance variables.
// //
bool doPassInitialization(Module *M); bool doInitialization(Module *M);
// doPerMethodWork - This method simplifies the specified method hopefully. // 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 // doPassFinalization - Strip out type names that are unused by the program
bool doPassFinalization(Module *M); bool doFinalization(Module *M);
private: private:
bool doOneCleanupPass(Method *M); bool doOneCleanupPass(Method *M);
}; };

View File

@ -22,7 +22,8 @@
class Constant; class Constant;
class GlobalVariable; class GlobalVariable;
class ConstantMerge : public Pass { // FIXME: ConstantMerge should not be a methodPass!!!
class ConstantMerge : public MethodPass {
protected: protected:
std::map<Constant*, GlobalVariable*> Constants; std::map<Constant*, GlobalVariable*> Constants;
unsigned LastConstantSeen; unsigned LastConstantSeen;
@ -34,14 +35,16 @@ public:
// //
static bool mergeDuplicateConstants(Module *M); 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. // 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; LastConstantSeen = 0;
Constants.clear(); Constants.clear();
return false; return false;
@ -52,7 +55,7 @@ struct DynamicConstantMerge : public ConstantMerge {
// doPerMethodWork - Check to see if any globals have been added to the // doPerMethodWork - Check to see if any globals have been added to the
// global list for the module. If so, eliminate them. // global list for the module. If so, eliminate them.
// //
bool doPerMethodWork(Method *M); bool runOnMethod(Method *M);
}; };
#endif #endif

View File

@ -7,15 +7,17 @@
#ifndef LLVM_TRANSFORM_IPO_GLOBALDCE_H #ifndef LLVM_TRANSFORM_IPO_GLOBALDCE_H
#define LLVM_TRANSFORM_IPO_GLOBALDCE_H #define LLVM_TRANSFORM_IPO_GLOBALDCE_H
#include "llvm/Pass.h"
namespace cfg { class CallGraph; } namespace cfg { class CallGraph; }
class Module; class Module;
struct GlobalDCE { struct GlobalDCE : public Pass {
// run - Do the GlobalDCE pass on the specified module, optionally updating // run - Do the GlobalDCE pass on the specified module, optionally updating
// the specified callgraph to reflect the changes. // the specified callgraph to reflect the changes.
// //
bool run(Module *M, cfg::CallGraph *CG = 0); bool run(Module *M);
}; };
#endif #endif

View 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 // This pass does is a wrapper that can do a few simple structure mutation
// struct types in the program around. // transformations.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H #ifndef LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
#define LLVM_TRANSFORMS_SWAPSTRUCTCONTENTS_H #define LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
#include "llvm/Transforms/MutateStructTypes.h" #include "llvm/Transforms/MutateStructTypes.h"
// FIXME: Move to correct location! class SimpleStructMutation : public MutateStructTypes {
class PrebuiltStructMutation : public MutateStructTypes {
public: public:
enum Transform { SwapElements, SortElements }; enum Transform { SwapElements, SortElements } CurrentXForm;
PrebuiltStructMutation(Module *M, enum Transform XForm) SimpleStructMutation(enum Transform XForm) : CurrentXForm(XForm) {}
: MutateStructTypes(getTransforms(M, XForm)) {}
virtual bool run(Module *M) {
setTransforms(getTransforms(M, CurrentXForm));
bool Changed = MutateStructTypes::run(M);
clearTransforms();
return Changed;
}
private: private:
static TransformsType getTransforms(Module *M, enum Transform); static TransformsType getTransforms(Module *M, enum Transform);

View File

@ -11,7 +11,7 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
class Method; class Method;
class InsertTraceCode : public Pass { class InsertTraceCode : public MethodPass {
bool TraceBasicBlockExits, TraceMethodExits; bool TraceBasicBlockExits, TraceMethodExits;
Method *PrintfMeth; Method *PrintfMeth;
public: public:
@ -21,7 +21,7 @@ public:
// Add a prototype for printf if it is not already in the program. // Add a prototype for printf if it is not already in the program.
// //
bool doPassInitialization(Module *M); bool doInitialization(Module *M);
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
// Function InsertCodeToTraceValues // Function InsertCodeToTraceValues
@ -32,9 +32,9 @@ public:
static bool doit(Method *M, bool traceBasicBlockExits, static bool doit(Method *M, bool traceBasicBlockExits,
bool traceMethodExits, Method *Printf); 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); return doit(M, TraceBasicBlockExits, TraceMethodExits, PrintfMeth);
} }
}; };

View File

@ -51,25 +51,40 @@ public:
// //
typedef std::map<const StructType*, std::vector<int> > TransformsType; 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 // module, converting them to their new type. Also this creates placeholder
// methods for methods than need to be copied because they have a new // methods for methods than need to be copied because they have a new
// signature type. // 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. // 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. // longer needed.
// //
virtual bool doPassFinalization(Module *M); void removeDeadGlobals(Module *M);
private: private:
// ConvertType - Convert from the old type system to the new one... // ConvertType - Convert from the old type system to the new one...

View File

@ -15,10 +15,10 @@
// expressions as possible, by converting expressions to use getelementptr and // expressions as possible, by converting expressions to use getelementptr and
// friends. // friends.
// //
struct RaisePointerReferences : public Pass { struct RaisePointerReferences : public MethodPass {
static bool doit(Method *M); 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 // converts all induction variables to reference a cannonical induction
// variable (which starts at 0 and counts by 1). // 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! 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 #endif

View File

@ -12,7 +12,7 @@ class TerminatorInst;
namespace opt { namespace opt {
struct ConstantPropogation : public Pass { struct ConstantPropogation : public MethodPass {
// doConstantPropogation - Do trivial constant propogation and expression // doConstantPropogation - Do trivial constant propogation and expression
// folding // folding
static bool doConstantPropogation(Method *M); static bool doConstantPropogation(Method *M);
@ -22,7 +22,7 @@ struct ConstantPropogation : public Pass {
// //
static bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I); static bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I);
inline bool doPerMethodWork(Method *M) { inline bool runOnMethod(Method *M) {
return doConstantPropogation(M); return doConstantPropogation(M);
} }
}; };
@ -39,10 +39,10 @@ bool ConstantFoldTerminator(TerminatorInst *T);
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Sparse Conditional Constant Propogation Pass // Sparse Conditional Constant Propogation Pass
// //
struct SCCPPass : public Pass { struct SCCPPass : public MethodPass {
static bool doSCCP(Method *M); static bool doSCCP(Method *M);
inline bool doPerMethodWork(Method *M) { inline bool runOnMethod(Method *M) {
return doSCCP(M); return doSCCP(M);
} }
}; };

View File

@ -13,7 +13,7 @@
namespace opt { namespace opt {
struct DeadCodeElimination : public Pass { struct DeadCodeElimination : public MethodPass {
// External Interface: // External Interface:
// //
static bool doDCE(Method *M); static bool doDCE(Method *M);
@ -33,23 +33,23 @@ struct DeadCodeElimination : public Pass {
static bool RemoveUnusedGlobalValues(Module *M); static bool RemoveUnusedGlobalValues(Module *M);
// Pass Interface... // Pass Interface...
virtual bool doPassInitialization(Module *M) { virtual bool doInitialization(Module *M) {
return RemoveUnusedGlobalValues(M); return RemoveUnusedGlobalValues(M);
} }
virtual bool doPerMethodWork(Method *M) { return doDCE(M); } virtual bool runOnMethod(Method *M) { return doDCE(M); }
virtual bool doPassFinalization(Module *M) { virtual bool doFinalization(Module *M) {
return RemoveUnusedGlobalValues(M); return RemoveUnusedGlobalValues(M);
} }
}; };
struct AgressiveDCE : public Pass { struct AgressiveDCE : public MethodPass {
// DoADCE - Execute the Agressive Dead Code Elimination Algorithm // DoADCE - Execute the Agressive Dead Code Elimination Algorithm
// //
static bool doADCE(Method *M); // Defined in ADCE.cpp static bool doADCE(Method *M); // Defined in ADCE.cpp
virtual bool doPerMethodWork(Method *M) { virtual bool runOnMethod(Method *M) {
return doADCE(M); return doADCE(M);
} }
}; };

View File

@ -10,10 +10,10 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
struct InductionVariableSimplify : public Pass { struct InductionVariableSimplify : public MethodPass {
static bool doit(Method *M); static bool doit(Method *M);
virtual bool doPerMethodWork(Method *M) { return doit(M); } virtual bool runOnMethod(Method *M) { return doit(M); }
}; };
#endif #endif

View File

@ -12,12 +12,12 @@
namespace opt { namespace opt {
struct InductionVariableCannonicalize : public Pass { struct InductionVariableCannonicalize : public MethodPass {
// doInductionVariableCannonicalize - Simplify induction variables in loops // doInductionVariableCannonicalize - Simplify induction variables in loops
// //
static bool doIt(Method *M); static bool doIt(Method *M);
virtual bool doPerMethodWork(Method *M) { virtual bool runOnMethod(Method *M) {
return doIt(M); return doIt(M);
} }
}; };

View File

@ -17,11 +17,11 @@
#include "llvm/Pass.h" #include "llvm/Pass.h"
struct InstructionCombining : public Pass { struct InstructionCombining : public MethodPass {
static bool doit(Method *M); static bool doit(Method *M);
static bool CombineInstruction(Instruction *I); static bool CombineInstruction(Instruction *I);
virtual bool doPerMethodWork(Method *M) { return doit(M); } virtual bool runOnMethod(Method *M) { return doit(M); }
}; };
#endif #endif

View File

@ -12,28 +12,28 @@
namespace opt { namespace opt {
struct SymbolStripping : public Pass { struct SymbolStripping : public MethodPass {
// doSymbolStripping - Remove all symbolic information from a method // doSymbolStripping - Remove all symbolic information from a method
// //
static bool doSymbolStripping(Method *M); static bool doSymbolStripping(Method *M);
virtual bool doPerMethodWork(Method *M) { virtual bool runOnMethod(Method *M) {
return doSymbolStripping(M); return doSymbolStripping(M);
} }
}; };
struct FullSymbolStripping : public Pass { struct FullSymbolStripping : public MethodPass {
// doStripGlobalSymbols - Remove all symbolic information from all methods // doStripGlobalSymbols - Remove all symbolic information from all methods
// in a module, and all module level symbols. (method names, etc...) // in a module, and all module level symbols. (method names, etc...)
// //
static bool doStripGlobalSymbols(Module *M); static bool doStripGlobalSymbols(Module *M);
virtual bool doPassInitialization(Module *M) { virtual bool doInitialization(Module *M) {
return doStripGlobalSymbols(M); return doStripGlobalSymbols(M);
} }
virtual bool doPerMethodWork(Method *M) { virtual bool runOnMethod(Method *M) {
return SymbolStripping::doSymbolStripping(M); return SymbolStripping::doSymbolStripping(M);
} }
}; };

View 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 // values of various types. If they are deemed to be 'unsafe' note that the
// type is not safe to transform. // 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 const Method *M = Meth; // We don't need/want write access
for (Method::const_inst_iterator I = M->inst_begin(), E = M->inst_end(); for (Method::const_inst_iterator I = M->inst_begin(), E = M->inst_end();
I != E; ++I) { I != E; ++I) {

View 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. // module, converting them to their new type.
// //
bool FindUsedTypes::doPassInitialization(Module *m) { bool FindUsedTypes::doInitialization(Module *m) {
const Module *M = m; const Module *M = m;
if (IncludeSymbolTables && M->hasSymbolTable()) if (IncludeSymbolTables && M->hasSymbolTable())
IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first... 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 // doPerMethodWork - This incorporates all types used by the specified method
// //
bool FindUsedTypes::doPerMethodWork(Method *m) { bool FindUsedTypes::runOnMethod(Method *m) {
const Method *M = m; const Method *M = m;
if (IncludeSymbolTables && M->hasSymbolTable()) if (IncludeSymbolTables && M->hasSymbolTable())
IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first... IncorporateSymbolTable(M->getSymbolTable()); // Add symtab first...

View 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. // module, eliminating duplicate constants.
// //
bool ConstantMerge::doPassInitialization(Module *M) { bool ConstantMerge::doInitialization(Module *M) {
return ::mergeDuplicateConstants(M, LastConstantSeen, Constants); return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
} }
// doPerMethodWork - Check to see if any globals have been added to the // doPerMethodWork - Check to see if any globals have been added to the
// global list for the module. If so, eliminate them. // 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); return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen, Constants);
} }

View File

@ -220,14 +220,14 @@ static inline bool ShouldNukeSymtabEntry(const std::pair<string, Value*> &E) {
return false; 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 // 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. // 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; bool Changed = false;
FUT.doPassInitialization(M); FUT.doInitialization(M);
if (PtrSByte == 0) if (PtrSByte == 0)
PtrSByte = PointerType::get(Type::SByteTy); PtrSByte = PointerType::get(Type::SByteTy);
@ -551,17 +551,17 @@ static bool fixLocalProblems(Method *M) {
// doPerMethodWork - This method simplifies the specified method hopefully. // doPerMethodWork - This method simplifies the specified method hopefully.
// //
bool CleanupGCCOutput::doPerMethodWork(Method *M) { bool CleanupGCCOutput::runOnMethod(Method *M) {
bool Changed = fixLocalProblems(M); bool Changed = fixLocalProblems(M);
while (doOneCleanupPass(M)) Changed = true; while (doOneCleanupPass(M)) Changed = true;
FUT.doPerMethodWork(M); FUT.runOnMethod(M);
return Changed; return Changed;
} }
bool CleanupGCCOutput::doPassFinalization(Module *M) { bool CleanupGCCOutput::doFinalization(Module *M) {
bool Changed = false; bool Changed = false;
FUT.doPassFinalization(M); FUT.doFinalization(M);
if (M->hasSymbolTable()) { if (M->hasSymbolTable()) {
SymbolTable *ST = M->getSymbolTable(); SymbolTable *ST = M->getSymbolTable();

View File

@ -11,10 +11,7 @@
#include "Support/DepthFirstIterator.h" #include "Support/DepthFirstIterator.h"
#include <set> #include <set>
static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) { static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph &CallGraph) {
// Create a call graph if one is not already available...
cfg::CallGraph &CallGraph = CG ? *CG : *new cfg::CallGraph(M);
// Calculate which methods are reachable from the external methods in the call // Calculate which methods are reachable from the external methods in the call
// graph. // graph.
// //
@ -36,11 +33,7 @@ static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
} }
// Nothing to do if no unreachable methods have been found... // Nothing to do if no unreachable methods have been found...
if (MethodsToDelete.empty()) { if (MethodsToDelete.empty()) return false;
// Free the created call graph if it was not passed in
if (&CallGraph != CG) delete &CallGraph;
return false;
}
// Unreachables methods have been found and should have no references to them, // Unreachables methods have been found and should have no references to them,
// delete them now. // delete them now.
@ -49,11 +42,12 @@ static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph *CG) {
E = MethodsToDelete.end(); I != E; ++I) E = MethodsToDelete.end(); I != E; ++I)
delete CallGraph.removeMethodFromModule(*I); delete CallGraph.removeMethodFromModule(*I);
// Free the created call graph if it was not passed in
if (&CallGraph != CG) delete &CallGraph;
return true; return true;
} }
bool GlobalDCE::run(Module *M, cfg::CallGraph *CG = 0) { bool GlobalDCE::run(Module *M) {
return RemoveUnreachableMethods(M, CG); // 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);
} }

View File

@ -20,9 +20,9 @@
#include "llvm/iMemory.h" #include "llvm/iMemory.h"
#include "llvm/iTerminators.h" #include "llvm/iTerminators.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "Support/STLExtras.h"
#include <algorithm> #include <algorithm>
using std::map; using std::map;
using std::make_pair;
using std::vector; using std::vector;
// To enable debugging, uncomment this... // To enable debugging, uncomment this...
@ -56,7 +56,7 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
const Type *DestTy = 0; const Type *DestTy = 0;
PATypeHolder<Type> PlaceHolder = OpaqueType::get(); PATypeHolder<Type> PlaceHolder = OpaqueType::get();
TypeMap.insert(make_pair(Ty, PlaceHolder.get())); TypeMap.insert(std::make_pair(Ty, PlaceHolder.get()));
switch (Ty->getPrimitiveID()) { switch (Ty->getPrimitiveID()) {
case Type::MethodTyID: { case Type::MethodTyID: {
@ -100,7 +100,7 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
// Refine our little placeholder value into a real type... // Refine our little placeholder value into a real type...
cast<DerivedType>(PlaceHolder.get())->refineAbstractTypeTo(DestTy); cast<DerivedType>(PlaceHolder.get())->refineAbstractTypeTo(DestTy);
TypeMap.insert(make_pair(Ty, PlaceHolder.get())); TypeMap.insert(std::make_pair(Ty, PlaceHolder.get()));
return 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 // setTransforms - Take a map that specifies what transformation to do for each
// of the specified structure types. There is one element of the vector for // field of the specified structure types. There is one element of the vector
// each field of the structure. The value specified indicates which slot of // 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 // the destination structure the field should end up in. A negative value
// indicates that the field should be deleted entirely. // indicates that the field should be deleted entirely.
// //
MutateStructTypes::MutateStructTypes(const map<const StructType*, void MutateStructTypes::setTransforms(const TransformsType &XForm) {
vector<int> > &XForm) {
// Loop over the types and insert dummy entries into the type map so that // Loop over the types and insert dummy entries into the type map so that
// recursive types are resolved properly... // recursive types are resolved properly...
for (map<const StructType*, vector<int> >::const_iterator I = XForm.begin(), for (map<const StructType*, vector<int> >::const_iterator I = XForm.begin(),
E = XForm.end(); I != E; ++I) { E = XForm.end(); I != E; ++I) {
const StructType *OldTy = I->first; 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 // 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); cast<DerivedType>(OldTypeStub)->refineAbstractTypeTo(NSTy);
// Add the transformation to the Transforms map. // 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); 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. // 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 // 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 // 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 // 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. // 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. // The first half of the methods in the module have to go.
//unsigned NumMethods = M->size(); //unsigned NumMethods = M->size();
//unsigned NumGVars = M->gsize(); //unsigned NumGVars = M->gsize();
@ -313,20 +317,18 @@ bool MutateStructTypes::doPassFinalization(Module *M) {
else else
++I; ++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. // new types.
// //
bool MutateStructTypes::doPerMethodWork(Method *m) { void MutateStructTypes::transformMethod(Method *m) {
const Method *M = m; const Method *M = m;
map<const GlobalValue*, GlobalValue*>::iterator GMI = GlobalMap.find(M); map<const GlobalValue*, GlobalValue*>::iterator GMI = GlobalMap.find(M);
if (GMI == GlobalMap.end()) 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); Method *NewMeth = cast<Method>(GMI->second);
@ -501,5 +503,14 @@ bool MutateStructTypes::doPerMethodWork(Method *m) {
} }
LocalValueMap.clear(); LocalValueMap.clear();
return true; }
bool MutateStructTypes::run(Module *M) {
processGlobals(M);
for_each(M->begin(), M->end(),
bind_obj(this, &MutateStructTypes::transformMethod));
removeDeadGlobals(M);
} }

View File

@ -58,18 +58,18 @@ static unsigned getIndex(const vector<pair<unsigned, unsigned> > &Vec,
static inline void GetTransformation(const StructType *ST, static inline void GetTransformation(const StructType *ST,
vector<int> &Transform, vector<int> &Transform,
enum PrebuiltStructMutation::Transform XForm) { enum SimpleStructMutation::Transform XForm) {
unsigned NumElements = ST->getElementTypes().size(); unsigned NumElements = ST->getElementTypes().size();
Transform.reserve(NumElements); Transform.reserve(NumElements);
switch (XForm) { switch (XForm) {
case PrebuiltStructMutation::SwapElements: case SimpleStructMutation::SwapElements:
// The transformation to do is: just simply swap the elements // The transformation to do is: just simply swap the elements
for (unsigned i = 0; i < NumElements; ++i) for (unsigned i = 0; i < NumElements; ++i)
Transform.push_back(NumElements-i-1); Transform.push_back(NumElements-i-1);
break; break;
case PrebuiltStructMutation::SortElements: { case SimpleStructMutation::SortElements: {
vector<pair<unsigned, unsigned> > ElList; vector<pair<unsigned, unsigned> > ElList;
// Build mapping from index to size // 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 SimpleStructMutation::TransformsType
// SimpleStructMutation::getTransforms(Module *M, enum Transform XForm) {
PrebuiltStructMutation::TransformsType
PrebuiltStructMutation::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 // We need to know which types to modify, and which types we CAN'T modify
FindUsedTypes FUT/*(true)*/; // TODO: Do symbol tables as well FindUsedTypes *FUT = new FindUsedTypes(/*true*/); // TODO: Do symbol tables as well
FindUnsafePointerTypes FUPT; FindUnsafePointerTypes *FUPT = new FindUnsafePointerTypes();
// Simutaneously find all of the types used, and all of the types that aren't // Simutaneously find all of the types used, and all of the types that aren't
// safe. // safe.
// //
vector<Pass*> Analyses; PassManager Analyses;
Analyses.push_back(&FUT); Analyses.add(FUT);
Analyses.push_back(&FUPT); Analyses.add(FUPT);
Pass::runAllPasses(M, Analyses); // Do analyses Analyses.run(M); // Do analyses
// Get the results out of the analyzers... // Get the results out of the analyzers...
const set<PointerType*> &UnsafePTys = FUPT.getUnsafeTypes(); const set<PointerType*> &UnsafePTys = FUPT->getUnsafeTypes();
const set<const Type *> &UsedTypes = FUT.getTypes(); const set<const Type *> &UsedTypes = FUT->getTypes();
// Combine the two sets, weeding out non structure types. Closures in C++ // Combine the two sets, weeding out non structure types. Closures in C++

View File

@ -23,7 +23,7 @@ using std::string;
// Add a prototype for printf if it is not already in the program. // 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(); SymbolTable *ST = M->getSymbolTable();
const Type *SBP = PointerType::get(Type::SByteTy); const Type *SBP = PointerType::get(Type::SByteTy);
const MethodType *MTy = const MethodType *MTy =

View File

@ -17,12 +17,12 @@
using std::vector; 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. // module contains a declaration for a malloc and a free function.
// //
// This function is always successful. // This function is always successful.
// //
bool LowerAllocations::doPassInitialization(Module *M) { bool LowerAllocations::doInitialization(Module *M) {
bool Changed = false; bool Changed = false;
const MethodType *MallocType = const MethodType *MallocType =
MethodType::get(PointerType::get(Type::SByteTy), MethodType::get(PointerType::get(Type::SByteTy),
@ -55,10 +55,10 @@ bool LowerAllocations::doPassInitialization(Module *M) {
return Changed; // Always successful 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. // instructions over, assuming that the pass has already been initialized.
// //
bool LowerAllocations::doPerMethodWork(Method *M) { bool LowerAllocations::runOnMethod(Method *M) {
bool Changed = false; bool Changed = false;
assert(MallocMeth && FreeMeth && M && "Pass not initialized!"); assert(MallocMeth && FreeMeth && M && "Pass not initialized!");

View 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 // In addition to just parsing the input from GCC, we also want to spiff it up
// a little bit. Do this now. // a little bit. Do this now.
// //
std::vector<Pass*> Passes; PassManager Passes;
Passes.push_back(new opt::DeadCodeElimination()); // Remove Dead code/vars Passes.add(new opt::DeadCodeElimination()); // Remove Dead code/vars
Passes.push_back(new CleanupGCCOutput()); // Fix gccisms Passes.add(new CleanupGCCOutput()); // Fix gccisms
Passes.push_back(new InductionVariableSimplify()); // Simplify indvars Passes.add(new InductionVariableSimplify()); // Simplify indvars
Passes.push_back(new RaisePointerReferences()); // Eliminate casts Passes.add(new RaisePointerReferences()); // Eliminate casts
Passes.push_back(new ConstantMerge()); // Merge dup global consts Passes.add(new ConstantMerge()); // Merge dup global consts
Passes.push_back(new InstructionCombining()); // Combine silly seq's Passes.add(new InstructionCombining()); // Combine silly seq's
Passes.push_back(new opt::DeadCodeElimination()); // Remove Dead code/vars Passes.add(new opt::DeadCodeElimination()); // Remove Dead code/vars
// Run our queue of passes all at once now, efficiently. This form of // Run our queue of passes all at once now, efficiently. This form of
// runAllPasses frees the Pass objects after runAllPasses completes. // runAllPasses frees the Pass objects after runAllPasses completes.
// //
Pass::runAllPassesAndFree(M.get(), Passes); Passes.run(M.get());
WriteBytecodeToFile(M.get(), *Out); WriteBytecodeToFile(M.get(), *Out);
return 0; return 0;

View File

@ -52,21 +52,20 @@ static inline string GetFileNameRoot(const string &InputFilename) {
// Native code generation for a specified target. // Native code generation for a specified target.
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//
class GenerateCodeForTarget : public Pass { class GenerateCodeForTarget : public MethodPass {
TargetMachine &Target; TargetMachine &Target;
public: public:
inline GenerateCodeForTarget(TargetMachine &T) : Target(T) {} 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. // the specified method.
// //
bool doPerMethodWork(Method *M) { bool runOnMethod(Method *M) {
if (!M->isExternal() && Target.compileMethod(M)) { if (!M->isExternal() && Target.compileMethod(M)) {
cerr << "Error compiling " << InputFilename << "!\n"; 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) inline EmitAssembly(const TargetMachine &T, std::ostream *O, bool D)
: Target(T), Out(O), DeleteStream(D) {} : Target(T), Out(O), DeleteStream(D) {}
virtual bool run(Module *M) {
virtual bool doPassFinalization(Module *M) {
Target.emitAssembly(M, *Out); Target.emitAssembly(M, *Out);
if (DeleteStream) delete Out; if (DeleteStream) delete Out;
@ -95,6 +93,7 @@ public:
}; };
//===---------------------------------------------------------------------===// //===---------------------------------------------------------------------===//
// Function main() // 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... // 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 // 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... if (TraceBBValues || TraceMethodValues) { // If tracing enabled...
// Insert trace code in all methods in the module // Insert trace code in all methods in the module
Passes.push_back(new InsertTraceCode(TraceBBValues, Passes.add(new InsertTraceCode(TraceBBValues,
TraceBBValues ||TraceMethodValues)); TraceBBValues ||TraceMethodValues));
// Eliminate duplication in constant pool // 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 // Then write out the module with tracing code before code generation
assert(InputFilename != "-" && assert(InputFilename != "-" &&
@ -152,20 +151,20 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
Passes.push_back(new WriteBytecodePass(os, true)); Passes.add(new WriteBytecodePass(os, true));
} }
// Replace malloc and free instructions with library calls. // Replace malloc and free instructions with library calls.
// Do this after tracing until lli implements these lib calls. // Do this after tracing until lli implements these lib calls.
// For now, it will emulate malloc and free internally. // 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 LLVM dumping after transformations is requested, add it to the pipeline
if (DumpAsm) if (DumpAsm)
Passes.push_back(new PrintModulePass("Code after xformations: \n",&cerr)); Passes.add(new PrintMethodPass("Code after xformations: \n",&cerr));
// Generate Target code... // Generate Target code...
Passes.push_back(new GenerateCodeForTarget(Target)); Passes.add(new GenerateCodeForTarget(Target));
if (!DoNotEmitAssembly) { // If asm output is enabled... if (!DoNotEmitAssembly) { // If asm output is enabled...
// Figure out where we are going to send the output... // 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 // 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 // Run our queue of passes all at once now, efficiently.
// runAllPasses frees the Pass objects after runAllPasses completes. Passes.run(M.get());
Pass::runAllPassesAndFree(M.get(), Passes);
return 0; return 0;
} }

View File

@ -34,14 +34,13 @@ enum Opts {
indvars, instcombine, sccp, adce, raise, indvars, instcombine, sccp, adce, raise,
// Interprocedural optimizations... // Interprocedural optimizations...
globaldce, swapstructs, globaldce, swapstructs, sortstructs,
}; };
struct { struct {
enum Opts OptID; enum Opts OptID;
Pass *ThePass; Pass *ThePass;
} OptTable[] = { } OptTable[] = {
{ swapstructs, 0 },
{ dce , new opt::DeadCodeElimination() }, { dce , new opt::DeadCodeElimination() },
{ constprop , new opt::ConstantPropogation() }, { constprop , new opt::ConstantPropogation() },
{ inlining , new opt::MethodInlining() }, { inlining , new opt::MethodInlining() },
@ -55,8 +54,11 @@ struct {
{ raise , new RaisePointerReferences() }, { raise , new RaisePointerReferences() },
{ trace , new InsertTraceCode(true, true) }, { trace , new InsertTraceCode(true, true) },
{ tracem , new InsertTraceCode(false, true) }, { tracem , new InsertTraceCode(false, true) },
{ print , new PrintModulePass("Current Method: \n",&cerr) }, { print , new PrintMethodPass("Current Method: \n",&cerr) },
{ cleangcc , new CleanupGCCOutput() }, { 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, "-"); 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(globaldce , "Remove unreachable globals"),
clEnumVal(swapstructs, "Swap structure types around"), clEnumVal(swapstructs, "Swap structure types around"),
clEnumVal(sortstructs, "Sort structure elements"),
clEnumVal(cleangcc , "Cleanup GCC Output"), clEnumVal(cleangcc , "Cleanup GCC Output"),
clEnumVal(raise , "Raise to Higher Level"), clEnumVal(raise , "Raise to Higher Level"),
@ -95,18 +98,7 @@ static void RunOptimization(Module *M, enum Opts Opt) {
return; return;
} }
// Special cases that haven't been fit into a consistent framework yet... cerr << "Optimization tables inconsistent!!\n";
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";
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@ -118,6 +110,8 @@ int main(int argc, char **argv) {
return 1; return 1;
} }
PassManager Passes;
// Run all of the optimizations specified on the command line // Run all of the optimizations specified on the command line
for (unsigned i = 0; i < OptimizationList.size(); ++i) for (unsigned i = 0; i < OptimizationList.size(); ++i)
RunOptimization(M.get(), OptimizationList[i]); RunOptimization(M.get(), OptimizationList[i]);