summaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2002-01-21 07:31:50 +0000
committerChris Lattner <sabre@nondot.org>2002-01-21 07:31:50 +0000
commitf4de63f65fa995e68e3cd268117ab065068be413 (patch)
tree2fd8cd44af0f23dafd94102c1c0152b1cd82fe4d /lib/Transforms
parentaff5bcebb7fb9880e0a3518a8e7c999e738d531c (diff)
downloadllvm-f4de63f65fa995e68e3cd268117ab065068be413.tar.gz
llvm-f4de63f65fa995e68e3cd268117ab065068be413.tar.bz2
llvm-f4de63f65fa995e68e3cd268117ab065068be413.tar.xz
Implement a more powerful, simpler, pass system. This pass system can figure
out how to run a collection of passes optimially given their behaviors and charactaristics. Convert code to use it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1507 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp6
-rw-r--r--lib/Transforms/IPO/DeadTypeElimination.cpp14
-rw-r--r--lib/Transforms/IPO/GlobalDCE.cpp20
-rw-r--r--lib/Transforms/IPO/MutateStructTypes.cpp55
-rw-r--r--lib/Transforms/IPO/SimpleStructMutation.cpp32
-rw-r--r--lib/Transforms/Instrumentation/TraceValues.cpp2
-rw-r--r--lib/Transforms/Utils/LowerAllocations.cpp8
7 files changed, 71 insertions, 66 deletions
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
index ff2442d2b6..acb3b6b937 100644
--- a/lib/Transforms/IPO/ConstantMerge.cpp
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -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);
}
diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp
index d5e9ea07bd..696f4bd7d7 100644
--- a/lib/Transforms/IPO/DeadTypeElimination.cpp
+++ b/lib/Transforms/IPO/DeadTypeElimination.cpp
@@ -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();
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp
index dacd3295ef..664381cec6 100644
--- a/lib/Transforms/IPO/GlobalDCE.cpp
+++ b/lib/Transforms/IPO/GlobalDCE.cpp
@@ -11,10 +11,7 @@
#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);
}
diff --git a/lib/Transforms/IPO/MutateStructTypes.cpp b/lib/Transforms/IPO/MutateStructTypes.cpp
index df2b67ef41..331a8743e5 100644
--- a/lib/Transforms/IPO/MutateStructTypes.cpp
+++ b/lib/Transforms/IPO/MutateStructTypes.cpp
@@ -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);
}
diff --git a/lib/Transforms/IPO/SimpleStructMutation.cpp b/lib/Transforms/IPO/SimpleStructMutation.cpp
index d0b8bb2807..571638e867 100644
--- a/lib/Transforms/IPO/SimpleStructMutation.cpp
+++ b/lib/Transforms/IPO/SimpleStructMutation.cpp
@@ -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++
diff --git a/lib/Transforms/Instrumentation/TraceValues.cpp b/lib/Transforms/Instrumentation/TraceValues.cpp
index 00acac8d1f..c778ca8b0d 100644
--- a/lib/Transforms/Instrumentation/TraceValues.cpp
+++ b/lib/Transforms/Instrumentation/TraceValues.cpp
@@ -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 =
diff --git a/lib/Transforms/Utils/LowerAllocations.cpp b/lib/Transforms/Utils/LowerAllocations.cpp
index ca1085e3ed..4f3f182cf3 100644
--- a/lib/Transforms/Utils/LowerAllocations.cpp
+++ b/lib/Transforms/Utils/LowerAllocations.cpp
@@ -17,12 +17,12 @@
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!");