diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp index db7634c33e6..43a286aa15d 100644 --- a/lib/Transforms/IPO/DeadTypeElimination.cpp +++ b/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 #include 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/lib/Transforms/LevelRaise.cpp b/lib/Transforms/LevelRaise.cpp index 2f2f77f975f..6883008a7ae 100644 --- a/lib/Transforms/LevelRaise.cpp +++ b/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 #include #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(T1)) return false; - if (!T2->isPrimitiveType() && !isa(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 ValueTypeCache; -typedef map ValueMapCache; - - - -// ExpressionConvertableToType - Return true if it is possible -static bool ExpressionConvertableToType(Value *V, const Type *Ty) { - Instruction *I = dyn_cast(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(V) && - !isa(V->getType()) && !isa(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(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(I); - const PointerType *PTy = dyn_cast(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 Indices = GEP->getIndices(); - const Type *BaseType = GEP->getPtrOperand()->getType(); - - while (Indices.size() && - cast(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(V); - if (I == 0) - if (ConstPoolVal *CPV = cast(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(I)->getOpcode(), - ConvertExpressionToType(I->getOperand(0), Ty), - ConvertExpressionToType(I->getOperand(1), Ty), - Name); - break; - - case Instruction::Shl: - case Instruction::Shr: - Res = new ShiftInst(cast(I)->getOpcode(), - ConvertExpressionToType(I->getOperand(0), Ty), - I->getOperand(1), Name); - break; - - case Instruction::Load: { - LoadInst *LI = cast(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(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 Indices = GEP->getIndices(); - const Type *BaseType = GEP->getPtrOperand()->getType(); - const Type *PVTy = cast(Ty)->getValueType(); - Res = 0; - while (Indices.size() && - cast(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(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(Ty)) { - LoadInst *LI = cast(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(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(Ty)) { - if (isa(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(I); - const PointerType *PTy = dyn_cast(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 Indices = GEP->getIndices(); - const Type *BaseType = GEP->getPtrOperand()->getType(); - - while (Indices.size() && - cast(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(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(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(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(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(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 Indices = GEP->getIndices(); - const Type *BaseType = GEP->getPtrOperand()->getType(); - const Type *PVTy = cast(Ty)->getValueType(); - Res = 0; - while (Indices.size() && - cast(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 index 00000000000..e7eef2d21fb --- /dev/null +++ b/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/lib/Transforms/TransformInternals.h b/lib/Transforms/TransformInternals.h new file mode 100644 index 00000000000..e6e65efd03d --- /dev/null +++ b/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 + +// 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 ValueTypeCache; +typedef map 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