//
//===----------------------------------------------------------------------===//
-#include "llvm/Transforms/MutateStructTypes.h"
+#include "llvm/Transforms/IPO/MutateStructTypes.h"
#include "llvm/DerivedTypes.h"
-#include "llvm/Method.h"
+#include "llvm/Module.h"
+#include "llvm/Function.h"
+#include "llvm/BasicBlock.h"
#include "llvm/GlobalVariable.h"
#include "llvm/SymbolTable.h"
#include "llvm/iPHINode.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iOther.h"
+#include "llvm/Argument.h"
#include "Support/STLExtras.h"
#include <algorithm>
using std::map;
using std::vector;
+//FIXME: These headers are only included because the analyses are killed!!!
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Analysis/FindUnsafePointerTypes.h"
+//FIXME end
+
// To enable debugging, uncomment this...
//#define DEBUG_MST(x) x
-#ifdef DEBUG_MST
-#include "llvm/Assembly/Writer.h"
-#else
+#ifndef DEBUG_MST
#define DEBUG_MST(x) // Disable debug code
#endif
if (Ty->isPrimitiveType() ||
isa<OpaqueType>(Ty)) return Ty; // Don't convert primitives
- map<const Type *, PATypeHolder<Type> >::iterator I = TypeMap.find(Ty);
+ map<const Type *, PATypeHolder>::iterator I = TypeMap.find(Ty);
if (I != TypeMap.end()) return I->second;
const Type *DestTy = 0;
- PATypeHolder<Type> PlaceHolder = OpaqueType::get();
+ PATypeHolder PlaceHolder = OpaqueType::get();
TypeMap.insert(std::make_pair(Ty, PlaceHolder.get()));
switch (Ty->getPrimitiveID()) {
- case Type::MethodTyID: {
- const MethodType *MT = cast<MethodType>(Ty);
+ case Type::FunctionTyID: {
+ const FunctionType *MT = cast<FunctionType>(Ty);
const Type *RetTy = ConvertType(MT->getReturnType());
vector<const Type*> ArgTypes;
- for (MethodType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
+ for (FunctionType::ParamTypes::const_iterator I = MT->getParamTypes().begin(),
E = MT->getParamTypes().end(); I != E; ++I)
ArgTypes.push_back(ConvertType(*I));
- DestTy = MethodType::get(RetTy, ArgTypes, MT->isVarArg());
+ DestTy = FunctionType::get(RetTy, ArgTypes, MT->isVarArg());
break;
}
case Type::StructTyID: {
assert(0 && "Unable to convert constpool val of this type!");
}
- // Check to see if this is an out of method reference first...
+ // Check to see if this is an out of function reference first...
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
// Check to see if the value is in the map...
map<const GlobalValue*, GlobalValue*>::iterator I = GlobalMap.find(GV);
}
// Create a new type that corresponds to the destination type
- PATypeHolder<StructType> NSTy = StructType::get(NewType);
+ PATypeHolder NSTy = StructType::get(NewType);
// Refine the old opaque type to the new type to properly handle recursive
// types...
cast<DerivedType>(OldTypeStub)->refineAbstractTypeTo(NSTy);
// Add the transformation to the Transforms map.
- Transforms.insert(std::make_pair(OldTy, std::make_pair(NSTy, InVec)));
+ Transforms.insert(std::make_pair(OldTy,
+ std::make_pair(cast<StructType>(NSTy.get()), InVec)));
DEBUG_MST(cerr << "Mutate " << OldTy << "\nTo " << NSTy << endl);
}
// module, converting them to their new type.
//
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
+ // Loop through the functions in the module and create a new version of the
+ // function 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
// reallocated. Also, we don't want to process the values that we add.
//
- unsigned NumMethods = M->size();
- for (unsigned i = 0; i < NumMethods; ++i) {
- Method *Meth = M->begin()[i];
+ unsigned NumFunctions = M->size();
+ for (unsigned i = 0; i < NumFunctions; ++i) {
+ Function *Meth = M->begin()[i];
if (!Meth->isExternal()) {
- const MethodType *NewMTy =
- cast<MethodType>(ConvertType(Meth->getMethodType()));
+ const FunctionType *NewMTy =
+ cast<FunctionType>(ConvertType(Meth->getFunctionType()));
- // Create a new method to put stuff into...
- Method *NewMeth = new Method(NewMTy, Meth->hasInternalLinkage(),
+ // Create a new function to put stuff into...
+ Function *NewMeth = new Function(NewMTy, Meth->hasInternalLinkage(),
Meth->getName());
if (Meth->hasName())
Meth->setName("OLD."+Meth->getName());
- // Insert the new method into the method list... to be filled in later...
- M->getMethodList().push_back(NewMeth);
+ // Insert the new function into the method list... to be filled in later..
+ M->getFunctionList().push_back(NewMeth);
// Keep track of the association...
GlobalMap[Meth] = NewMeth;
// 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 functions and global variables that we no longer need.
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();
-
// Prepare for deletion of globals by dropping their interdependencies...
for(Module::iterator I = M->begin(); I != M->end(); ++I) {
if (GlobalMap.find(*I) != GlobalMap.end())
- (*I)->Method::dropAllReferences();
+ (*I)->Function::dropAllReferences();
}
- // Run through and delete the methods and global variables...
+ // Run through and delete the functions and global variables...
#if 0 // TODO: HANDLE GLOBAL VARIABLES
M->getGlobalList().delete_span(M->gbegin(), M->gbegin()+NumGVars/2);
#endif
for(Module::iterator I = M->begin(); I != M->end();) {
if (GlobalMap.find(*I) != GlobalMap.end())
- delete M->getMethodList().remove(I);
+ delete M->getFunctionList().remove(I);
else
++I;
}
-// transformMethod - This transforms the instructions of the method to use the
+// transformMethod - This transforms the instructions of the function to use the
// new types.
//
-void MutateStructTypes::transformMethod(Method *m) {
- const Method *M = m;
+void MutateStructTypes::transformMethod(Function *m) {
+ const Function *M = m;
map<const GlobalValue*, GlobalValue*>::iterator GMI = GlobalMap.find(M);
if (GMI == GlobalMap.end())
- return; // Do not affect one of our new methods that we are creating
+ return; // Do not affect one of our new functions that we are creating
- Method *NewMeth = cast<Method>(GMI->second);
+ Function *NewMeth = cast<Function>(GMI->second);
// Okay, first order of business, create the arguments...
- for (unsigned i = 0; i < M->getArgumentList().size(); ++i) {
- const MethodArgument *OMA = M->getArgumentList()[i];
- MethodArgument *NMA = new MethodArgument(ConvertType(OMA->getType()),
- OMA->getName());
- NewMeth->getArgumentList().push_back(NMA);
- LocalValueMap[OMA] = NMA; // Keep track of value mapping
+ for (unsigned i = 0, e = M->getArgumentList().size(); i != e; ++i) {
+ const Argument *OFA = M->getArgumentList()[i];
+ Argument *NFA = new Argument(ConvertType(OFA->getType()), OFA->getName());
+ NewMeth->getArgumentList().push_back(NFA);
+ LocalValueMap[OFA] = NFA; // Keep track of value mapping
}
// Loop over all of the basic blocks copying instructions over...
- for (Method::const_iterator BBI = M->begin(), BBE = M->end(); BBI != BBE;
+ for (Function::const_iterator BBI = M->begin(), BBE = M->end(); BBI != BBE;
++BBI) {
// Create a new basic block and establish a mapping between the old and new
const BasicBlock *BB = *BBI;
BasicBlock *NewBB = cast<BasicBlock>(ConvertValue(BB));
- NewMeth->getBasicBlocks().push_back(NewBB); // Add block to method
+ NewMeth->getBasicBlocks().push_back(NewBB); // Add block to function
// Copy over all of the instructions in the basic block...
for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end();
bind_obj(this, &MutateStructTypes::transformMethod));
removeDeadGlobals(M);
+ return true;
+}
+
+// getAnalysisUsageInfo - This function needs the results of the
+// FindUsedTypes and FindUnsafePointerTypes analysis passes...
+//
+void MutateStructTypes::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
+ Pass::AnalysisSet &Destroyed,
+ Pass::AnalysisSet &Provided) {
+ Destroyed.push_back(FindUsedTypes::ID);
+ Destroyed.push_back(FindUnsafePointerTypes::ID);
+ Destroyed.push_back(CallGraph::ID);
}