diff options
| author | Chris Lattner <sabre@nondot.org> | 2001-11-04 23:24:06 +0000 | 
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2001-11-04 23:24:06 +0000 | 
| commit | 3084cb65ff1067e3db0f8481c919fe8d06901404 (patch) | |
| tree | 9ca038061fc753bc0092bb522180f533b4f6d08a | |
| parent | cb3da314d9edfce6e9a0690710ea0040bd304144 (diff) | |
| download | bcm5719-llvm-3084cb65ff1067e3db0f8481c919fe8d06901404.tar.gz bcm5719-llvm-3084cb65ff1067e3db0f8481c919fe8d06901404.zip  | |
Refactor code to share stuff
llvm-svn: 1127
| -rw-r--r-- | llvm/lib/Transforms/IPO/DeadTypeElimination.cpp | 46 | ||||
| -rw-r--r-- | llvm/lib/Transforms/LevelRaise.cpp | 560 | ||||
| -rw-r--r-- | llvm/lib/Transforms/TransformInternals.cpp | 89 | ||||
| -rw-r--r-- | llvm/lib/Transforms/TransformInternals.h | 56 | 
4 files changed, 148 insertions, 603 deletions
diff --git a/llvm/lib/Transforms/IPO/DeadTypeElimination.cpp b/llvm/lib/Transforms/IPO/DeadTypeElimination.cpp index db7634c33e6..43a286aa15d 100644 --- a/llvm/lib/Transforms/IPO/DeadTypeElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadTypeElimination.cpp @@ -16,61 +16,17 @@  //===----------------------------------------------------------------------===//  #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.  // diff --git a/llvm/lib/Transforms/LevelRaise.cpp b/llvm/lib/Transforms/LevelRaise.cpp index 2f2f77f975f..6883008a7ae 100644 --- a/llvm/lib/Transforms/LevelRaise.cpp +++ b/llvm/lib/Transforms/LevelRaise.cpp @@ -30,20 +30,19 @@  //===----------------------------------------------------------------------===//  #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)            \ @@ -60,43 +59,6 @@         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/llvm/lib/Transforms/TransformInternals.cpp b/llvm/lib/Transforms/TransformInternals.cpp new file mode 100644 index 00000000000..e7eef2d21fb --- /dev/null +++ b/llvm/lib/Transforms/TransformInternals.cpp @@ -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/llvm/lib/Transforms/TransformInternals.h b/llvm/lib/Transforms/TransformInternals.h new file mode 100644 index 00000000000..e6e65efd03d --- /dev/null +++ b/llvm/lib/Transforms/TransformInternals.h @@ -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  | 

