Refactor code to share stuff
authorChris Lattner <sabre@nondot.org>
Sun, 4 Nov 2001 23:24:06 +0000 (23:24 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 4 Nov 2001 23:24:06 +0000 (23:24 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1127 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/DeadTypeElimination.cpp
lib/Transforms/LevelRaise.cpp
lib/Transforms/TransformInternals.cpp [new file with mode: 0644]
lib/Transforms/TransformInternals.h [new file with mode: 0644]

index db7634c33e60de5811f77ca1681b64e4429a1dee..43a286aa15d059699ee36f980faad04a445f9a16 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/CleanupGCCOutput.h"
+#include "TransformInternals.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
 #include "llvm/iTerminators.h"
-#include <map>
 #include <algorithm>
 
 static const Type *PtrArrSByte = 0; // '[sbyte]*' type
 static const Type *PtrSByte = 0;    // 'sbyte*' type
 
-
-// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
-// with a value, then remove and delete the original instruction.
-//
-static void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
-                                 BasicBlock::iterator &BI, Value *V) {
-  Instruction *I = *BI;
-  // Replaces all of the uses of the instruction with uses of the value
-  I->replaceAllUsesWith(V);
-
-  // Remove the unneccesary instruction now...
-  BIL.remove(BI);
-
-  // Make sure to propogate a name if there is one already...
-  if (I->hasName() && !V->hasName())
-    V->setName(I->getName(), BIL.getParent()->getSymbolTable());
-
-  // Remove the dead instruction now...
-  delete I;
-}
-
-
-// ReplaceInstWithInst - Replace the instruction specified by BI with the
-// instruction specified by I.  The original instruction is deleted and BI is
-// updated to point to the new instruction.
-//
-static void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
-                                BasicBlock::iterator &BI, Instruction *I) {
-  assert(I->getParent() == 0 &&
-         "ReplaceInstWithInst: Instruction already inserted into basic block!");
-
-  // Insert the new instruction into the basic block...
-  BI = BIL.insert(BI, I)+1;
-
-  // Replace all uses of the old instruction, and delete it.
-  ReplaceInstWithValue(BIL, BI, I);
-
-  // Reexamine the instruction just inserted next time around the cleanup pass
-  // loop.
-  --BI;
-}
-
-
-
 // ConvertCallTo - Convert a call to a varargs function with no arg types
 // specified to a concrete nonvarargs method.
 //
index 2f2f77f975f7301387722b7e1cfdb42136fe0a95..6883008a7aeb2322c99b9e46e71ba08b4716e68f 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Transforms/LevelChange.h"
+#include "TransformInternals.h"
 #include "llvm/Method.h"
 #include "llvm/Support/STLExtras.h"
 #include "llvm/iOther.h"
 #include "llvm/iMemory.h"
 #include "llvm/ConstPoolVals.h"
-#include "llvm/Target/TargetData.h"
 #include "llvm/Optimizations/ConstantHandling.h"
 #include "llvm/Optimizations/DCE.h"
-#include <map>
 #include <algorithm>
 
 #include "llvm/Assembly/Writer.h"
 
-//#define DEBUG_PEEPHOLE_INSTS 1
+#define DEBUG_PEEPHOLE_INSTS 1
 
 #ifdef DEBUG_PEEPHOLE_INSTS
 #define PRINT_PEEPHOLE(ID, NUM, I)            \
        PRINT_PEEPHOLE(ID, 2, I3); } while (0)
 
 
-// TargetData Hack: Eventually we will have annotations given to us by the
-// backend so that we know stuff about type size and alignments.  For now
-// though, just use this, because it happens to match the model that GCC uses.
-//
-const TargetData TD("LevelRaise: Should be GCC though!");
-
-
-// losslessCastableTypes - Return true if the types are bitwise equivalent.
-// This predicate returns true if it is possible to cast from one type to
-// another without gaining or losing precision, or altering the bits in any way.
-//
-static bool losslessCastableTypes(const Type *T1, const Type *T2) {
-  if (!T1->isPrimitiveType() && !isa<PointerType>(T1)) return false;
-  if (!T2->isPrimitiveType() && !isa<PointerType>(T2)) return false;
-
-  if (T1->getPrimitiveID() == T2->getPrimitiveID())
-    return true;  // Handles identity cast, and cast of differing pointer types
-
-  // Now we know that they are two differing primitive or pointer types
-  switch (T1->getPrimitiveID()) {
-  case Type::UByteTyID:   return T2 == Type::SByteTy;
-  case Type::SByteTyID:   return T2 == Type::UByteTy;
-  case Type::UShortTyID:  return T2 == Type::ShortTy;
-  case Type::ShortTyID:   return T2 == Type::UShortTy;
-  case Type::UIntTyID:    return T2 == Type::IntTy;
-  case Type::IntTyID:     return T2 == Type::UIntTy;
-  case Type::ULongTyID:
-  case Type::LongTyID:
-  case Type::PointerTyID:
-    return T2 == Type::ULongTy || T2 == Type::LongTy ||
-           T2->getPrimitiveID() == Type::PointerTyID;
-  default:
-    return false;  // Other types have no identity values
-  }
-}
-
-
 // isReinterpretingCast - Return true if the cast instruction specified will
 // cause the operand to be "reinterpreted".  A value is reinterpreted if the
 // cast instruction would cause the underlying bits to change.
@@ -153,524 +115,6 @@ static const Type *getStructOffsetType(const Type *Ty, unsigned &Offset,
 
 
 
-// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
-// with a value, then remove and delete the original instruction.
-//
-static void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
-                                 BasicBlock::iterator &BI, Value *V) {
-  Instruction *I = *BI;
-  // Replaces all of the uses of the instruction with uses of the value
-  I->replaceAllUsesWith(V);
-
-  // Remove the unneccesary instruction now...
-  BIL.remove(BI);
-
-  // Make sure to propogate a name if there is one already...
-  if (I->hasName() && !V->hasName())
-    V->setName(I->getName(), BIL.getParent()->getSymbolTable());
-
-  // Remove the dead instruction now...
-  delete I;
-}
-
-
-// ReplaceInstWithInst - Replace the instruction specified by BI with the
-// instruction specified by I.  The original instruction is deleted and BI is
-// updated to point to the new instruction.
-//
-static void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
-                                BasicBlock::iterator &BI, Instruction *I) {
-  assert(I->getParent() == 0 &&
-         "ReplaceInstWithInst: Instruction already inserted into basic block!");
-
-  // Insert the new instruction into the basic block...
-  BI = BIL.insert(BI, I)+1;
-
-  // Replace all uses of the old instruction, and delete it.
-  ReplaceInstWithValue(BIL, BI, I);
-
-  // Reexamine the instruction just inserted next time around the cleanup pass
-  // loop.
-  --BI;
-}
-
-
-
-typedef map<const Value*, const Type*> ValueTypeCache;
-typedef map<const Value*, Value*>      ValueMapCache;
-
-
-
-// ExpressionConvertableToType - Return true if it is possible
-static bool ExpressionConvertableToType(Value *V, const Type *Ty) {
-  Instruction *I = dyn_cast<Instruction>(V);
-  if (I == 0) {
-    // It's not an instruction, check to see if it's a constant... all constants
-    // can be converted to an equivalent value (except pointers, they can't be
-    // const prop'd in general).
-    //
-    if (isa<ConstPoolVal>(V) &&
-        !isa<PointerType>(V->getType()) && !isa<PointerType>(Ty)) return true;
-
-    return false;              // Otherwise, we can't convert!
-  }
-  if (I->getType() == Ty) return false;  // Expression already correct type!
-
-  switch (I->getOpcode()) {
-  case Instruction::Cast:
-    // We can convert the expr if the cast destination type is losslessly
-    // convertable to the requested type.
-    return losslessCastableTypes(Ty, I->getType());
-
-  case Instruction::Add:
-  case Instruction::Sub:
-    return ExpressionConvertableToType(I->getOperand(0), Ty) &&
-           ExpressionConvertableToType(I->getOperand(1), Ty);
-  case Instruction::Shr:
-    if (Ty->isSigned() != V->getType()->isSigned()) return false;
-    // FALL THROUGH
-  case Instruction::Shl:
-    return ExpressionConvertableToType(I->getOperand(0), Ty);
-
-  case Instruction::Load: {
-    LoadInst *LI = cast<LoadInst>(I);
-    if (LI->hasIndices()) return false;
-    return ExpressionConvertableToType(LI->getPtrOperand(),
-                                       PointerType::get(Ty));
-  }
-  case Instruction::GetElementPtr: {
-    // GetElementPtr's are directly convertable to a pointer type if they have
-    // a number of zeros at the end.  Because removing these values does not
-    // change the logical offset of the GEP, it is okay and fair to remove them.
-    // This can change this:
-    //   %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0  ; <%List **>
-    //   %t2 = cast %List * * %t1 to %List *
-    // into
-    //   %t2 = getelementptr %Hosp * %hosp, ubyte 4           ; <%List *>
-    // 
-    GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
-    const PointerType *PTy = dyn_cast<PointerType>(Ty);
-    if (!PTy) return false;
-
-    // Check to see if there are zero elements that we can remove from the
-    // index array.  If there are, check to see if removing them causes us to
-    // get to the right type...
-    //
-    vector<ConstPoolVal*> Indices = GEP->getIndices();
-    const Type *BaseType = GEP->getPtrOperand()->getType();
-
-    while (Indices.size() &&
-           cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
-      Indices.pop_back();
-      const Type *ElTy = GetElementPtrInst::getIndexedType(BaseType, Indices,
-                                                           true);
-      if (ElTy == PTy->getValueType())
-        return true;  // Found a match!!
-    }
-    break;   // No match, maybe next time.
-  }
-  }
-  return false;
-}
-
-
-static Value *ConvertExpressionToType(Value *V, const Type *Ty) {
-  assert(ExpressionConvertableToType(V, Ty) && "Value is not convertable!");
-  Instruction *I = dyn_cast<Instruction>(V);
-  if (I == 0)
-    if (ConstPoolVal *CPV = cast<ConstPoolVal>(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);
-      if (!Result) cerr << "Couldn't fold " << CPV << " to " << Ty << endl;
-      assert(Result && "ConstantFoldCastInstruction Failed!!!");
-      return Result;
-    }
-
-
-  BasicBlock *BB = I->getParent();
-  BasicBlock::InstListType &BIL = BB->getInstList();
-  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;
-
-  switch (I->getOpcode()) {
-  case Instruction::Cast:
-    Res = new CastInst(I->getOperand(0), Ty, Name);
-    break;
-    
-  case Instruction::Add:
-  case Instruction::Sub:
-    Res = BinaryOperator::create(cast<BinaryOperator>(I)->getOpcode(),
-                                 ConvertExpressionToType(I->getOperand(0), Ty),
-                                 ConvertExpressionToType(I->getOperand(1), Ty),
-                                 Name);
-    break;
-
-  case Instruction::Shl:
-  case Instruction::Shr:
-    Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(),
-                        ConvertExpressionToType(I->getOperand(0), Ty),
-                        I->getOperand(1), Name);
-    break;
-
-  case Instruction::Load: {
-    LoadInst *LI = cast<LoadInst>(I);
-    assert(!LI->hasIndices());
-    Res = new LoadInst(ConvertExpressionToType(LI->getPtrOperand(),
-                                               PointerType::get(Ty)), Name);
-    break;
-  }
-
-  case Instruction::GetElementPtr: {
-    // GetElementPtr's are directly convertable to a pointer type if they have
-    // a number of zeros at the end.  Because removing these values does not
-    // change the logical offset of the GEP, it is okay and fair to remove them.
-    // This can change this:
-    //   %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0  ; <%List **>
-    //   %t2 = cast %List * * %t1 to %List *
-    // into
-    //   %t2 = getelementptr %Hosp * %hosp, ubyte 4           ; <%List *>
-    // 
-    GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
-
-    // Check to see if there are zero elements that we can remove from the
-    // index array.  If there are, check to see if removing them causes us to
-    // get to the right type...
-    //
-    vector<ConstPoolVal*> Indices = GEP->getIndices();
-    const Type *BaseType = GEP->getPtrOperand()->getType();
-    const Type *PVTy = cast<PointerType>(Ty)->getValueType();
-    Res = 0;
-    while (Indices.size() &&
-           cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
-      Indices.pop_back();
-      if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
-        if (Indices.size() == 0) {
-          Res = new CastInst(GEP->getPtrOperand(), BaseType); // NOOP
-        } else {
-          Res = new GetElementPtrInst(GEP->getPtrOperand(), Indices, Name);
-        }
-        break;
-      }
-    }
-    assert(Res && "Didn't find match!");
-    break;   // No match, maybe next time.
-  }
-
-  default:
-    assert(0 && "Expression convertable, but don't know how to convert?");
-    return 0;
-  }
-
-  BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
-  assert(It != BIL.end() && "Instruction not in own basic block??");
-  BIL.insert(It, Res);
-
-  //cerr << "RInst: " << Res << "BB After: " << BB << endl << endl;
-
-  return Res;
-}
-
-static inline const Type *getTy(const Value *V, ValueTypeCache &CT) {
-  ValueTypeCache::iterator I = CT.find(V);
-  if (I == CT.end()) return V->getType();
-  return I->second;
-}
-
-
-static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
-                                     ValueTypeCache &ConvertedTypes);
-
-// RetValConvertableToType - Return true if it is possible
-static bool RetValConvertableToType(Value *V, const Type *Ty,
-                                    ValueTypeCache &ConvertedTypes) {
-  ValueTypeCache::iterator I = ConvertedTypes.find(V);
-  if (I != ConvertedTypes.end()) return I->second == Ty;
-  ConvertedTypes[V] = 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;
-
-  return true;
-}
-
-
-// OperandConvertableToType - Return true if it is possible to convert operand
-// V of User (instruction) U to the specified type.  This is true iff it is
-// possible to change the specified instruction to accept this.  CTMap is a map
-// of converted types, so that circular definitions will see the future type of
-// the expression, not the static current type.
-//
-static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
-                                     ValueTypeCache &CTMap) {
-  assert(V->getType() != Ty &&
-         "OperandConvertableToType: Operand is already right type!");
-  Instruction *I = dyn_cast<Instruction>(U);
-  if (I == 0) return false;              // We can't convert!
-
-  switch (I->getOpcode()) {
-  case Instruction::Cast:
-    assert(I->getOperand(0) == V);
-    // We can convert the expr if the cast destination type is losslessly
-    // convertable to the requested type.
-    return losslessCastableTypes(Ty, I->getOperand(0)->getType());
-
-  case Instruction::Add:
-  case Instruction::Sub: {
-    Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
-    return RetValConvertableToType(I, Ty, CTMap) &&
-           ExpressionConvertableToType(OtherOp, Ty);
-  }
-  case Instruction::SetEQ:
-  case Instruction::SetNE: {
-    Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
-    return ExpressionConvertableToType(OtherOp, Ty);
-  }
-  case Instruction::Shr:
-    if (Ty->isSigned() != V->getType()->isSigned()) return false;
-    // FALL THROUGH
-  case Instruction::Shl:
-    assert(I->getOperand(0) == V);
-    return RetValConvertableToType(I, Ty, CTMap);
-
-  case Instruction::Load:
-    assert(I->getOperand(0) == V);
-    if (const PointerType *PT = dyn_cast<PointerType>(Ty)) {
-      LoadInst *LI = cast<LoadInst>(I);
-      if (LI->hasIndices() || 
-          TD.getTypeSize(PT->getValueType()) != TD.getTypeSize(LI->getType()))
-        return false;
-
-      return RetValConvertableToType(LI, PT->getValueType(), CTMap);
-    }
-    return false;
-
-  case Instruction::Store: {
-    StoreInst *SI = cast<StoreInst>(I);
-    if (SI->hasIndices()) return false;
-
-    if (V == I->getOperand(0)) {
-      // Can convert the store if we can convert the pointer operand to match
-      // the new  value type...
-      return ExpressionConvertableToType(I->getOperand(1),PointerType::get(Ty));
-    } else if (const PointerType *PT = dyn_cast<PointerType>(Ty)) {
-      if (isa<ArrayType>(PT->getValueType()))
-        return false;  // Avoid getDataSize on unsized array type!
-      assert(V == I->getOperand(1));
-
-      // Must move the same amount of data...
-      if (TD.getTypeSize(PT->getValueType()) != 
-          TD.getTypeSize(I->getOperand(0)->getType())) return false;
-
-      // Can convert store if the incoming value is convertable...
-      return ExpressionConvertableToType(I->getOperand(0), PT->getValueType());
-    }
-    return false;
-  }
-
-
-#if 0
-  case Instruction::GetElementPtr: {
-    // GetElementPtr's are directly convertable to a pointer type if they have
-    // a number of zeros at the end.  Because removing these values does not
-    // change the logical offset of the GEP, it is okay and fair to remove them.
-    // This can change this:
-    //   %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0  ; <%List **>
-    //   %t2 = cast %List * * %t1 to %List *
-    // into
-    //   %t2 = getelementptr %Hosp * %hosp, ubyte 4           ; <%List *>
-    // 
-    GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
-    const PointerType *PTy = dyn_cast<PointerType>(Ty);
-    if (!PTy) return false;
-
-    // Check to see if there are zero elements that we can remove from the
-    // index array.  If there are, check to see if removing them causes us to
-    // get to the right type...
-    //
-    vector<ConstPoolVal*> Indices = GEP->getIndices();
-    const Type *BaseType = GEP->getPtrOperand()->getType();
-
-    while (Indices.size() &&
-           cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
-      Indices.pop_back();
-      const Type *ElTy = GetElementPtrInst::getIndexedType(BaseType, Indices,
-                                                           true);
-      if (ElTy == PTy->getValueType())
-        return true;  // Found a match!!
-    }
-    break;   // No match, maybe next time.
-  }
-#endif
-  }
-  return false;
-}
-
-
-
-
-
-
-static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
-                                 ValueMapCache &VMC);
-
-// RetValConvertableToType - Return true if it is possible
-static void ConvertUsersType(Value *V, Value *NewVal, ValueMapCache &VMC) {
-
-  // 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.
-  //
-  while (!V->use_empty()) {
-    unsigned OldSize = V->use_size();
-    ConvertOperandToType(V->use_back(), V, NewVal, VMC);
-    assert(V->use_size() != OldSize && "Use didn't detatch from value!");
-  }
-}
-
-
-
-static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal,
-                                 ValueMapCache &VMC) {
-  Instruction *I = cast<Instruction>(U);  // Only Instructions convertable
-
-  BasicBlock *BB = I->getParent();
-  BasicBlock::InstListType &BIL = BB->getInstList();
-  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;
-
-  switch (I->getOpcode()) {
-  case Instruction::Cast:
-    assert(I->getOperand(0) == OldVal);
-    Res = new CastInst(NewVal, I->getType(), Name);
-    break;
-
-  case Instruction::Add:
-  case Instruction::Sub:
-  case Instruction::SetEQ:
-  case Instruction::SetNE: {
-    unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0;
-    Value *OtherOp    = I->getOperand(OtherIdx);
-    Value *NewOther   = ConvertExpressionToType(OtherOp, NewVal->getType());
-
-    Res = BinaryOperator::create(cast<BinaryOperator>(I)->getOpcode(),
-                                 OtherIdx == 0 ? NewOther : NewVal,
-                                 OtherIdx == 1 ? NewOther : NewVal,
-                                 Name);
-    break;
-  }
-  case Instruction::Shl:
-  case Instruction::Shr:
-    assert(I->getOperand(0) == OldVal);
-    Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(), NewVal,
-                        I->getOperand(1), Name);
-    break;
-
-  case Instruction::Load:
-    assert(I->getOperand(0) == OldVal);
-    Res = new LoadInst(NewVal, Name);
-    break;
-
-  case Instruction::Store: {
-    if (I->getOperand(0) == OldVal) {  // Replace the source value
-      Value *NewPtr =
-        ConvertExpressionToType(I->getOperand(1),
-                                PointerType::get(NewVal->getType()));
-      Res = new StoreInst(NewVal, NewPtr);
-    } else {                           // Replace the source pointer
-      const Type *ValType =cast<PointerType>(NewVal->getType())->getValueType();
-      Value *NewV = ConvertExpressionToType(I->getOperand(0), ValType);
-      Res = new StoreInst(NewV, NewVal);
-    }
-    break;
-  }
-
-#if 0
-  case Instruction::GetElementPtr: {
-    // GetElementPtr's are directly convertable to a pointer type if they have
-    // a number of zeros at the end.  Because removing these values does not
-    // change the logical offset of the GEP, it is okay and fair to remove them.
-    // This can change this:
-    //   %t1 = getelementptr %Hosp * %hosp, ubyte 4, ubyte 0  ; <%List **>
-    //   %t2 = cast %List * * %t1 to %List *
-    // into
-    //   %t2 = getelementptr %Hosp * %hosp, ubyte 4           ; <%List *>
-    // 
-    GetElementPtrInst *GEP = cast<GetElementPtrInst>(I);
-
-    // Check to see if there are zero elements that we can remove from the
-    // index array.  If there are, check to see if removing them causes us to
-    // get to the right type...
-    //
-    vector<ConstPoolVal*> Indices = GEP->getIndices();
-    const Type *BaseType = GEP->getPtrOperand()->getType();
-    const Type *PVTy = cast<PointerType>(Ty)->getValueType();
-    Res = 0;
-    while (Indices.size() &&
-           cast<ConstPoolUInt>(Indices.back())->getValue() == 0) {
-      Indices.pop_back();
-      if (GetElementPtrInst::getIndexedType(BaseType, Indices, true) == PVTy) {
-        if (Indices.size() == 0) {
-          Res = new CastInst(GEP->getPtrOperand(), BaseType); // NOOP
-        } else {
-          Res = new GetElementPtrInst(GEP->getPtrOperand(), Indices, Name);
-        }
-        break;
-      }
-    }
-    assert(Res && "Didn't find match!");
-    break;   // No match, maybe next time.
-  }
-#endif
-
-  default:
-    assert(0 && "Expression convertable, but don't know how to convert?");
-    return;
-  }
-
-  BasicBlock::iterator It = find(BIL.begin(), BIL.end(), I);
-  assert(It != BIL.end() && "Instruction not in own basic block??");
-  BIL.insert(It, Res);   // Keep It pointing to old instruction
-
-#if DEBUG_PEEPHOLE_INSTS
-  cerr << "In: " << I << "Out: " << Res;
-#endif
-
-  //cerr << "RInst: " << Res << "BB After: " << BB << endl << endl;
-
-  if (I->getType() != Res->getType())
-    ConvertUsersType(I, Res, VMC);
-  else
-    I->replaceAllUsesWith(Res);
-
-  // Now we just need to remove the old instruction so we don't get infinite
-  // loops.  Note that we cannot use DCE because DCE won't remove a store
-  // instruction, for example.
-  assert(I->use_size() == 0 && "Uses of Instruction remain!!!");
-
-  It = find(BIL.begin(), BIL.end(), I);
-  assert(It != BIL.end() && "Instruction no longer in basic block??");
-  delete BIL.remove(It);
-}
-
-
-
-
-
-
-
-
-
-
-
-
 
 
 // DoInsertArrayCast - If the argument value has a pointer type, and if the
diff --git a/lib/Transforms/TransformInternals.cpp b/lib/Transforms/TransformInternals.cpp
new file mode 100644 (file)
index 0000000..e7eef2d
--- /dev/null
@@ -0,0 +1,89 @@
+//===-- TransformInternals.cpp - Implement shared functions for transforms --=//
+//
+//  This file defines shared functions used by the different components of the
+//  Transforms library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TransformInternals.h"
+#include "llvm/Method.h"
+#include "llvm/Type.h"
+
+// TargetData Hack: Eventually we will have annotations given to us by the
+// backend so that we know stuff about type size and alignments.  For now
+// though, just use this, because it happens to match the model that GCC uses.
+//
+const TargetData TD("LevelRaise: Should be GCC though!");
+
+// losslessCastableTypes - Return true if the types are bitwise equivalent.
+// This predicate returns true if it is possible to cast from one type to
+// another without gaining or losing precision, or altering the bits in any way.
+//
+bool losslessCastableTypes(const Type *T1, const Type *T2) {
+  if (!T1->isPrimitiveType() && !T1->isPointerType()) return false;
+  if (!T2->isPrimitiveType() && !T2->isPointerType()) return false;
+
+  if (T1->getPrimitiveID() == T2->getPrimitiveID())
+    return true;  // Handles identity cast, and cast of differing pointer types
+
+  // Now we know that they are two differing primitive or pointer types
+  switch (T1->getPrimitiveID()) {
+  case Type::UByteTyID:   return T2 == Type::SByteTy;
+  case Type::SByteTyID:   return T2 == Type::UByteTy;
+  case Type::UShortTyID:  return T2 == Type::ShortTy;
+  case Type::ShortTyID:   return T2 == Type::UShortTy;
+  case Type::UIntTyID:    return T2 == Type::IntTy;
+  case Type::IntTyID:     return T2 == Type::UIntTy;
+  case Type::ULongTyID:
+  case Type::LongTyID:
+  case Type::PointerTyID:
+    return T2 == Type::ULongTy || T2 == Type::LongTy ||
+           T2->getPrimitiveID() == Type::PointerTyID;
+  default:
+    return false;  // Other types have no identity values
+  }
+}
+
+
+// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
+// with a value, then remove and delete the original instruction.
+//
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+                          BasicBlock::iterator &BI, Value *V) {
+  Instruction *I = *BI;
+  // Replaces all of the uses of the instruction with uses of the value
+  I->replaceAllUsesWith(V);
+
+  // Remove the unneccesary instruction now...
+  BIL.remove(BI);
+
+  // Make sure to propogate a name if there is one already...
+  if (I->hasName() && !V->hasName())
+    V->setName(I->getName(), BIL.getParent()->getSymbolTable());
+
+  // Remove the dead instruction now...
+  delete I;
+}
+
+
+// ReplaceInstWithInst - Replace the instruction specified by BI with the
+// instruction specified by I.  The original instruction is deleted and BI is
+// updated to point to the new instruction.
+//
+void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
+                         BasicBlock::iterator &BI, Instruction *I) {
+  assert(I->getParent() == 0 &&
+         "ReplaceInstWithInst: Instruction already inserted into basic block!");
+
+  // Insert the new instruction into the basic block...
+  BI = BIL.insert(BI, I)+1;
+
+  // Replace all uses of the old instruction, and delete it.
+  ReplaceInstWithValue(BIL, BI, I);
+
+  // Reexamine the instruction just inserted next time around the cleanup pass
+  // loop.
+  --BI;
+}
+
+
diff --git a/lib/Transforms/TransformInternals.h b/lib/Transforms/TransformInternals.h
new file mode 100644 (file)
index 0000000..e6e65ef
--- /dev/null
@@ -0,0 +1,56 @@
+//===-- TransformInternals.h - Shared functions for Transforms ---*- C++ -*--=//
+//
+//  This header file declares shared functions used by the different components
+//  of the Transforms library.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef TRANSFORM_INTERNALS_H
+#define TRANSFORM_INTERNALS_H
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Target/TargetData.h"
+#include <map>
+
+// TargetData Hack: Eventually we will have annotations given to us by the
+// backend so that we know stuff about type size and alignments.  For now
+// though, just use this, because it happens to match the model that GCC uses.
+//
+// FIXME: This should use annotations
+//
+extern const TargetData TD;
+
+// losslessCastableTypes - Return true if the types are bitwise equivalent.
+// This predicate returns true if it is possible to cast from one type to
+// another without gaining or losing precision, or altering the bits in any way.
+//
+bool losslessCastableTypes(const Type *T1, const Type *T2);
+
+
+// ReplaceInstWithValue - Replace all uses of an instruction (specified by BI)
+// with a value, then remove and delete the original instruction.
+//
+void ReplaceInstWithValue(BasicBlock::InstListType &BIL,
+                          BasicBlock::iterator &BI, Value *V);
+
+// ReplaceInstWithInst - Replace the instruction specified by BI with the
+// instruction specified by I.  The original instruction is deleted and BI is
+// updated to point to the new instruction.
+//
+void ReplaceInstWithInst(BasicBlock::InstListType &BIL,
+                         BasicBlock::iterator &BI, Instruction *I);
+
+
+// ------------- Expression Conversion ---------------------
+
+typedef map<const Value*, const Type*> ValueTypeCache;
+typedef map<const Value*, Value*>      ValueMapCache;
+
+// RetValConvertableToType - Return true if it is possible
+bool RetValConvertableToType(Value *V, const Type *Ty,
+                             ValueTypeCache &ConvertedTypes);
+
+void ConvertUsersType(Value *V, Value *NewVal, ValueMapCache &VMC);
+
+
+#endif