Programs that actually free memory were broken
[oota-llvm.git] / lib / Transforms / IPO / MutateStructTypes.cpp
index c9f7917bd98f4da38deda2894cd06912cba9e48c..fcad5fa050bfed7d85eae298d0d3f78083a39c25 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#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
 
@@ -37,7 +47,7 @@
 struct ValuePlaceHolder : public Instruction {
   ValuePlaceHolder(const Type *Ty) : Instruction(Ty, UserOp1, "") {}
 
-  virtual Instruction *clone() const { abort(); }
+  virtual Instruction *clone() const { abort(); return 0; }
   virtual const char *getOpcodeName() const { return "placeholder"; }
 };
 
@@ -47,25 +57,25 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
   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();
-  TypeMap.insert(make_pair(Ty, PlaceHolder.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: {
@@ -86,7 +96,7 @@ const Type *MutateStructTypes::ConvertType(const Type *Ty) {
 
   case Type::PointerTyID:
     DestTy = PointerType::get(
-                 ConvertType(cast<PointerType>(Ty)->getValueType()));
+                 ConvertType(cast<PointerType>(Ty)->getElementType()));
     break;
   default:
     assert(0 && "Unknown type!");
@@ -97,7 +107,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();
 }
@@ -150,7 +160,7 @@ Value *MutateStructTypes::ConvertValue(const Value *V) {
     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);
@@ -176,21 +186,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
@@ -217,7 +226,7 @@ MutateStructTypes::MutateStructTypes(const map<const StructType*,
     }
 
     // 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...
@@ -226,38 +235,46 @@ 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(cast<StructType>(NSTy.get()), 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) {
-  // 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
+void MutateStructTypes::processGlobals(Module *M) {
+  // 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;
@@ -282,69 +299,60 @@ bool MutateStructTypes::doPassInitialization(Module *M) {
       }
     }
   }
-
-  return true;
 }
 
 
-// doPassFinalization - 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) {
-  // The first half of the methods in the module have to go.
-  unsigned NumMethods = M->size();
-  unsigned NumGVars   = M->gsize();
-
+// removeDeadGlobals - For this pass, all this does is remove the old versions
+// of the functions and global variables that we no longer need.
+void MutateStructTypes::removeDeadGlobals(Module *M) {
   // 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;
   }
-  
-  return true;
 }
 
 
 
-// doPerMethodWork - This transforms the instructions of the method to use the
+// transformMethod - This transforms the instructions of the function to use the
 // new types.
 //
-bool MutateStructTypes::doPerMethodWork(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 false;  // 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();
@@ -432,16 +440,15 @@ bool MutateStructTypes::doPerMethodWork(Method *m) {
         const Value *Ptr = MAI->getPointerOperand();
         Value *NewPtr = ConvertValue(Ptr);
         if (!Indices.empty()) {
-          const Type *PTy = cast<PointerType>(Ptr->getType())->getValueType();
+          const Type *PTy = cast<PointerType>(Ptr->getType())->getElementType();
           AdjustIndices(cast<CompositeType>(PTy), Indices);
         }
 
-        if (const LoadInst *LI = dyn_cast<LoadInst>(I)) {
+        if (isa<LoadInst>(I)) {
           NewI = new LoadInst(NewPtr, Indices);
-        } else if (const StoreInst *SI = dyn_cast<StoreInst>(I)) {
+        } else if (isa<StoreInst>(I)) {
           NewI = new StoreInst(ConvertValue(I->getOperand(0)), NewPtr, Indices);
-        } else if (const GetElementPtrInst *GEP =
-                   dyn_cast<GetElementPtrInst>(I)) {
+        } else if (isa<GetElementPtrInst>(I)) {
           NewI = new GetElementPtrInst(NewPtr, Indices);
         } else {
           assert(0 && "Unknown memory access inst!!!");
@@ -499,5 +506,26 @@ bool MutateStructTypes::doPerMethodWork(Method *m) {
   }
 
   LocalValueMap.clear();
+}
+
+
+bool MutateStructTypes::run(Module *M) {
+  processGlobals(M);
+
+  for_each(M->begin(), M->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);
+}