Support changing the pointer type of a store for the case where we are
[oota-llvm.git] / lib / Transforms / ExprTypeConvert.cpp
index 02e14b6caaa665731b7797ad1d49062157ba33e9..cbf22b035a81ab3c303a98974dabdf5bdc6bb5b8 100644 (file)
 #include "llvm/iPHINode.h"
 #include "llvm/iMemory.h"
 #include "llvm/ConstantVals.h"
-#include "llvm/Optimizations/ConstantHandling.h"
-#include "llvm/Optimizations/DCE.h"
+#include "llvm/Transforms/Scalar/ConstantHandling.h"
+#include "llvm/Transforms/Scalar/DCE.h"
 #include "llvm/Analysis/Expressions.h"
 #include "Support/STLExtras.h"
 #include <map>
 #include <algorithm>
+#include <iostream>
+using std::cerr;
 
 #include "llvm/Assembly/Writer.h"
 
@@ -96,7 +98,8 @@ static bool MallocConvertableToType(MallocInst *MI, const Type *Ty,
 }
 
 static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty,
-                                        const string &Name, ValueMapCache &VMC){
+                                        const std::string &Name,
+                                        ValueMapCache &VMC){
   BasicBlock *BB = MI->getParent();
   BasicBlock::iterator It = BB->end();
 
@@ -187,7 +190,7 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty,
     // it can convert the value...
     //
     if (Constant *CPV = dyn_cast<Constant>(V))
-      if (opt::ConstantFoldCastInstruction(CPV, Ty))
+      if (ConstantFoldCastInstruction(CPV, Ty))
         return true;  // Don't worry about deallocating, it's a constant.
 
     return false;              // Otherwise, we can't convert!
@@ -270,7 +273,7 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty,
     // index array.  If there are, check to see if removing them causes us to
     // get to the right type...
     //
-    vector<Value*> Indices = GEP->copyIndices();
+    std::vector<Value*> Indices = GEP->copyIndices();
     const Type *BaseType = GEP->getPointerOperand()->getType();
     const Type *ElTy = 0;
 
@@ -302,10 +305,9 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty,
       // Check to see if 'N' is an expression that can be converted to
       // the appropriate size... if so, allow it.
       //
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       const Type *ElTy = ConvertableToGEP(PTy, I->getOperand(1), Indices);
-      if (ElTy) {
-        assert(ElTy == PVTy && "Internal error, setup wrong!");
+      if (ElTy == PVTy) {
         if (!ExpressionConvertableToType(I->getOperand(0),
                                          PointerType::get(ElTy), CTMap))
           return false;  // Can't continue, ExConToTy might have polluted set!
@@ -354,6 +356,10 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
   ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V);
   if (VMCI != VMC.ExprMap.end()) {
     assert(VMCI->second->getType() == Ty);
+
+    if (Instruction *I = dyn_cast<Instruction>(V))
+      ValueHandle IHandle(VMC, I);  // Remove I if it is unused now!
+
     return VMCI->second;
   }
 
@@ -366,7 +372,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
     if (Constant *CPV = cast<Constant>(V)) {
       // Constants are converted by constant folding the cast that is required.
       // We assume here that all casts are implemented for constant prop.
-      Value *Result = opt::ConstantFoldCastInstruction(CPV, Ty);
+      Value *Result = ConstantFoldCastInstruction(CPV, Ty);
       assert(Result && "ConstantFoldCastInstruction Failed!!!");
       assert(Result->getType() == Ty && "Const prop of cast failed!");
 
@@ -378,7 +384,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
 
   BasicBlock *BB = I->getParent();
   BasicBlock::InstListType &BIL = BB->getInstList();
-  string Name = I->getName();  if (!Name.empty()) I->setName("");
+  std::string Name = I->getName();  if (!Name.empty()) I->setName("");
   Instruction *Res;     // Result of conversion
 
   ValueHandle IHandle(VMC, I);  // Prevent I from being removed!
@@ -460,7 +466,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
     // index array.  If there are, check to see if removing them causes us to
     // get to the right type...
     //
-    vector<Value*> Indices = GEP->copyIndices();
+    std::vector<Value*> Indices = GEP->copyIndices();
     const Type *BaseType = GEP->getPointerOperand()->getType();
     const Type *PVTy = cast<PointerType>(Ty)->getElementType();
     Res = 0;
@@ -491,7 +497,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
       // Check to see if 'N' is an expression that can be converted to
       // the appropriate size... if so, allow it.
       //
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       const Type *ElTy = ConvertableToGEP(NewSrcTy, I->getOperand(1),
                                           Indices, &It);
       if (ElTy) {        
@@ -579,9 +585,11 @@ bool ValueConvertableToType(Value *V, const Type *Ty,
   // It is safe to convert the specified value to the specified type IFF all of
   // the uses of the value can be converted to accept the new typed value.
   //
-  for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I)
-    if (!OperandConvertableToType(*I, V, Ty, ConvertedTypes))
-      return false;
+  if (V->getType() != Ty) {
+    for (Value::use_iterator I = V->use_begin(), E = V->use_end(); I != E; ++I)
+      if (!OperandConvertableToType(*I, V, Ty, ConvertedTypes))
+        return false;
+  }
 
   return true;
 }
@@ -634,7 +642,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
   case Instruction::Add:
     if (isa<PointerType>(Ty)) {
       Value *IndexVal = I->getOperand(V == I->getOperand(0) ? 1 : 0);
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       if (const Type *ETy = ConvertableToGEP(Ty, IndexVal, Indices)) {
         const Type *RetTy = PointerType::get(ETy);
 
@@ -685,7 +693,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
       // They could be loading the first element of a composite type...
       if (const CompositeType *CT = dyn_cast<CompositeType>(LoadedTy)) {
         unsigned Offset = 0;     // No offset, get first leaf.
-        vector<Value*> Indices;  // Discarded...
+        std::vector<Value*> Indices;  // Discarded...
         LoadedTy = getStructOffsetType(CT, Offset, Indices, false);
         assert(Offset == 0 && "Offset changed from zero???");
       }
@@ -713,6 +721,18 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
       const Type *ElTy = PT->getElementType();
       assert(V == I->getOperand(1));
 
+      if (isa<StructType>(ElTy)) {
+        // We can change the destination pointer if we can store our first
+        // argument into the first element of the structure...
+        //
+        unsigned Offset = 0;
+        std::vector<Value*> Indices;
+        ElTy = getStructOffsetType(ElTy, Offset, Indices, false);
+        assert(Offset == 0 && "Offset changed!");
+        if (ElTy == 0)    // Element at offset zero in struct doesn't exist!
+          return false;   // Can only happen for {}*
+      }
+
       // Must move the same amount of data...
       if (TD.getTypeSize(ElTy) != TD.getTypeSize(I->getOperand(0)->getType()))
         return false;
@@ -751,7 +771,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
       // Check to see if the second argument is an expression that can
       // be converted to the appropriate size... if so, allow it.
       //
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       const Type *ElTy = ConvertableToGEP(Ty, Index, Indices);
       delete TempScale;   // Free our temporary multiply if we made it
 
@@ -773,8 +793,44 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
     assert (OI != I->op_end() && "Not using value!");
     unsigned OpNum = OI - I->op_begin();
 
-    if (OpNum == 0)
-      return false; // Can't convert method pointer type yet.  FIXME
+    // Are we trying to change the method pointer value to a new type?
+    if (OpNum == 0) {
+      PointerType *PTy = dyn_cast<PointerType>(Ty);
+      if (PTy == 0) return false;  // Can't convert to a non-pointer type...
+      MethodType *MTy = dyn_cast_or_null<MethodType>(PTy->getElementType());
+      if (MTy == 0) return false;  // Can't convert to a non ptr to method...
+
+      // Perform sanity checks to make sure that new method type has the
+      // correct number of arguments...
+      //
+      unsigned NumArgs = I->getNumOperands()-1;  // Don't include method ptr
+
+      // Cannot convert to a type that requires more fixed arguments than
+      // the call provides...
+      //
+      if (NumArgs < MTy->getParamTypes().size()) return false;
+      
+      // Unless this is a vararg method type, we cannot provide more arguments
+      // than are desired...
+      //
+      if (!MTy->isVarArg() && NumArgs > MTy->getParamTypes().size())
+        return false;
+
+      // Okay, at this point, we know that the call and the method type match
+      // number of arguments.  Now we see if we can convert the arguments
+      // themselves.
+      //
+      const MethodType::ParamTypes &PTs = MTy->getParamTypes();
+      for (unsigned i = 0, NA = PTs.size(); i < NA; ++i)
+        if (!PTs[i]->isLosslesslyConvertableTo(I->getOperand(i+1)->getType()))
+          return false;   // Operands must have compatible types!
+
+      // Okay, at this point, we know that all of the arguments can be
+      // converted.  We succeed if we can change the return type if
+      // neccesary...
+      //
+      return ValueConvertableToType(I, MTy->getReturnType(), CTMap);
+    }
     
     const PointerType *MPtr = cast<PointerType>(I->getOperand(0)->getType());
     const MethodType *MTy = cast<MethodType>(MPtr->getElementType());
@@ -823,7 +879,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
 
   BasicBlock *BB = I->getParent();
   BasicBlock::InstListType &BIL = BB->getInstList();
-  string Name = I->getName();  if (!Name.empty()) I->setName("");
+  std::string Name = I->getName();  if (!Name.empty()) I->setName("");
   Instruction *Res;     // Result of conversion
 
   //cerr << endl << endl << "Type:\t" << Ty << "\nInst: " << I << "BB Before: " << BB << endl;
@@ -844,12 +900,12 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
   case Instruction::Add:
     if (isa<PointerType>(NewTy)) {
       Value *IndexVal = I->getOperand(OldVal == I->getOperand(0) ? 1 : 0);
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
 
       if (const Type *ETy = ConvertableToGEP(NewTy, IndexVal, Indices, &It)) {
         // If successful, convert the add to a GEP
-        const Type *RetTy = PointerType::get(ETy);
+        //const Type *RetTy = PointerType::get(ETy);
         // First operand is actually the given pointer...
         Res = new GetElementPtrInst(NewVal, Indices, Name);
         assert(cast<PointerType>(Res->getType())->getElementType() == ETy &&
@@ -892,7 +948,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
     const Type *LoadedTy =
       cast<PointerType>(NewVal->getType())->getElementType();
 
-    vector<Value*> Indices;
+    std::vector<Value*> Indices;
     Indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
 
     if (const CompositeType *CT = dyn_cast<CompositeType>(LoadedTy)) {
@@ -914,14 +970,15 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
       Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), NewPT, VMC));
     } else {                           // Replace the source pointer
       const Type *ValTy = cast<PointerType>(NewTy)->getElementType();
-      vector<Value*> Indices;
-#if 0
-      Indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
-      while (ArrayType *AT = dyn_cast<ArrayType>(ValTy)) {
+      std::vector<Value*> Indices;
+
+      if (isa<StructType>(ValTy)) {
+        unsigned Offset = 0;
         Indices.push_back(ConstantUInt::get(Type::UIntTy, 0));
-        ValTy = AT->getElementType();
+        ValTy = getStructOffsetType(ValTy, Offset, Indices, false);
+        assert(Offset == 0 && ValTy);
       }
-#endif
+
       Res = new StoreInst(Constant::getNullConstant(ValTy), NewVal, Indices);
       VMC.ExprMap[I] = Res;
       Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), ValTy, VMC));
@@ -948,7 +1005,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
 
     // Perform the conversion now...
     //
-    vector<Value*> Indices;
+    std::vector<Value*> Indices;
     const Type *ElTy = ConvertableToGEP(NewVal->getType(), Index, Indices, &It);
     assert(ElTy != 0 && "GEP Conversion Failure!");
     Res = new GetElementPtrInst(NewVal, Indices, Name);
@@ -965,7 +1022,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
       // Check to see if the second argument is an expression that can
       // be converted to the appropriate size... if so, allow it.
       //
-      vector<Value*> Indices;
+      std::vector<Value*> Indices;
       const Type *ElTy = ConvertableToGEP(NewVal->getType(), I->getOperand(1),
                                           Indices, &It);
       assert(ElTy != 0 && "GEP Conversion Failure!");
@@ -1001,12 +1058,28 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
 
   case Instruction::Call: {
     Value *Meth = I->getOperand(0);
-    vector<Value*> Params(I->op_begin()+1, I->op_end());
+    std::vector<Value*> Params(I->op_begin()+1, I->op_end());
+
+    if (Meth == OldVal) {   // Changing the method pointer?
+      PointerType *NewPTy = cast<PointerType>(NewVal->getType());
+      MethodType *NewTy = cast<MethodType>(NewPTy->getElementType());
+      const MethodType::ParamTypes &PTs = NewTy->getParamTypes();
+
+      // Convert over all of the call operands to their new types... but only
+      // convert over the part that is not in the vararg section of the call.
+      //
+      for (unsigned i = 0; i < PTs.size(); ++i)
+        Params[i] = ConvertExpressionToType(Params[i], PTs[i], VMC);
+      Meth = NewVal;  // Update call destination to new value
 
-    vector<Value*>::iterator OI = find(Params.begin(), Params.end(), OldVal);
-    assert (OI != Params.end() && "Not using value!");
+    } else {                   // Changing an argument, must be in vararg area
+      std::vector<Value*>::iterator OI =
+        find(Params.begin(), Params.end(), OldVal);
+      assert (OI != Params.end() && "Not using value!");
+
+      *OI = NewVal;
+    }
 
-    *OI = NewVal;
     Res = new CallInst(Meth, Params, Name);
     break;
   }
@@ -1080,13 +1153,11 @@ static void RecursiveDelete(ValueMapCache &Cache, Instruction *I) {
 #endif
 
   for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); 
-       OI != OE; ++OI) {
-    Instruction *U = dyn_cast<Instruction>(*OI);
-    if (U) {
+       OI != OE; ++OI)
+    if (Instruction *U = dyn_cast<Instruction>(*OI)) {
       *OI = 0;
-      RecursiveDelete(Cache, dyn_cast<Instruction>(U));
+      RecursiveDelete(Cache, U);
     }
-  }
 
   I->getParent()->getInstList().remove(I);