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:
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.
#include <set>
class SymbolTable;
-class FindUsedTypes : public Pass {
+class FindUsedTypes : public MethodPass {
std::set<const Type *> UsedTypes;
bool IncludeSymbolTables;
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
//===- 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;
}
};
if (DeleteStream) delete Out;
}
- bool doPassFinalization(Module *M) {
+ bool run(Module *M) {
WriteBytecodeToFile(M, *Out);
return false;
}
#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
//
// 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
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);
}
};
#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
#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:
//
// 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);
};
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;
//
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;
// 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
#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
-//===- 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);
#include "llvm/Pass.h"
class Method;
-class InsertTraceCode : public Pass {
+class InsertTraceCode : public MethodPass {
bool TraceBasicBlockExits, TraceMethodExits;
Method *PrintfMeth;
public:
// Add a prototype for printf if it is not already in the program.
//
- bool doPassInitialization(Module *M);
+ bool doInitialization(Module *M);
//--------------------------------------------------------------------------
// Function InsertCodeToTraceValues
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);
}
};
//
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...
// 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); }
};
// 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
namespace opt {
-struct ConstantPropogation : public Pass {
+struct ConstantPropogation : public MethodPass {
// doConstantPropogation - Do trivial constant propogation and expression
// folding
static bool doConstantPropogation(Method *M);
//
static bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I);
- inline bool doPerMethodWork(Method *M) {
+ inline bool runOnMethod(Method *M) {
return doConstantPropogation(M);
}
};
//===----------------------------------------------------------------------===//
// 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);
}
};
namespace opt {
-struct DeadCodeElimination : public Pass {
+struct DeadCodeElimination : public MethodPass {
// External Interface:
//
static bool doDCE(Method *M);
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);
}
};
#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
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);
}
};
#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
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);
}
};
}
-// 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) {
}
-// 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...
// 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...
}
-// 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);
}
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);
// 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();
#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.
//
}
// 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.
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);
}
#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...
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: {
// 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();
}
}
-// 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
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
}
}
}
-
- 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();
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);
}
LocalValueMap.clear();
- return true;
+}
+
+
+bool MutateStructTypes::run(Module *M) {
+ processGlobals(M);
+
+ for_each(M->begin(), M->end(),
+ bind_obj(this, &MutateStructTypes::transformMethod));
+
+ removeDeadGlobals(M);
}
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
}
}
-// 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++
// 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 =
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),
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!");
// 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;
// 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;
}
};
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;
};
+
//===---------------------------------------------------------------------===//
// Function main()
//
}
// 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 != "-" &&
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...
}
// 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;
}
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() },
{ 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, "-");
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"),
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) {
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]);