X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FExprTypeConvert.cpp;h=0f80c2f8bb223fd34a769ca8a2376c7d194abc0c;hb=2a010afefc507cfcd6734435e6a404639a7f81d9;hp=995df98b6b53c1d267b3165eed4946f4a90d0460;hpb=cd484a47ea5c2dfeccd392b0a9ad59a09889f098;p=oota-llvm.git diff --git a/lib/Transforms/ExprTypeConvert.cpp b/lib/Transforms/ExprTypeConvert.cpp index 995df98b6b5..0f80c2f8bb2 100644 --- a/lib/Transforms/ExprTypeConvert.cpp +++ b/lib/Transforms/ExprTypeConvert.cpp @@ -1,27 +1,33 @@ //===- ExprTypeConvert.cpp - Code to change an LLVM Expr Type -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file implements the part of level raising that checks to see if it is // possible to coerce an entire expression tree into a different type. If -// convertable, other routines from this file will do the conversion. +// convertible, other routines from this file will do the conversion. // //===----------------------------------------------------------------------===// #include "TransformInternals.h" -#include "llvm/iOther.h" -#include "llvm/iPHINode.h" -#include "llvm/iMemory.h" -#include "llvm/ConstantHandling.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" #include "llvm/Analysis/Expressions.h" #include "Support/STLExtras.h" -#include "Support/Statistic.h" +#include "Support/Debug.h" #include -using std::cerr; +using namespace llvm; -static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes); +static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, + ValueTypeCache &ConvertedTypes, + const TargetData &TD); static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, - ValueMapCache &VMC); + ValueMapCache &VMC, const TargetData &TD); // Peephole Malloc instructions: we take a look at the use chain of the // malloc instruction, and try to find out if the following conditions hold: @@ -34,8 +40,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, // If these conditions hold, we convert the malloc to allocate an [RTy] // element. TODO: This comment is out of date WRT arrays // -static bool MallocConvertableToType(MallocInst *MI, const Type *Ty, - ValueTypeCache &CTMap) { +static bool MallocConvertibleToType(MallocInst *MI, const Type *Ty, + ValueTypeCache &CTMap, + const TargetData &TD) { if (!isa(Ty)) return false; // Malloc always returns pointers // Deal with the type to allocate, not the pointer type... @@ -43,10 +50,11 @@ static bool MallocConvertableToType(MallocInst *MI, const Type *Ty, if (!Ty->isSized()) return false; // Can only alloc something with a size // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpression(MI->getArraySize()); + ExprType Expr = ClassifyExpr(MI->getArraySize()); // Get information about the base datatype being allocated, before & after int ReqTypeSize = TD.getTypeSize(Ty); + if (ReqTypeSize == 0) return false; unsigned OldTypeSize = TD.getTypeSize(MI->getType()->getElementType()); // Must have a scale or offset to analyze it... @@ -73,12 +81,13 @@ static bool MallocConvertableToType(MallocInst *MI, const Type *Ty, static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty, const std::string &Name, - ValueMapCache &VMC){ + ValueMapCache &VMC, + const TargetData &TD){ BasicBlock *BB = MI->getParent(); BasicBlock::iterator It = BB->end(); // Analyze the number of bytes allocated... - ExprType Expr = ClassifyExpression(MI->getArraySize()); + ExprType Expr = ClassifyExpr(MI->getArraySize()); const PointerType *AllocTy = cast(Ty); const Type *ElType = AllocTy->getElementType(); @@ -100,7 +109,7 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty, // If we have a scale, apply it first... if (Expr.Var) { - // Expr.Var is not neccesarily unsigned right now, insert a cast now. + // Expr.Var is not necessarily unsigned right now, insert a cast now. if (Expr.Var->getType() != Type::UIntTy) Expr.Var = new CastInst(Expr.Var, Type::UIntTy, Expr.Var->getName()+"-uint", It); @@ -129,9 +138,9 @@ static Instruction *ConvertMallocToType(MallocInst *MI, const Type *Ty, } -// ExpressionConvertableToType - Return true if it is possible -bool ExpressionConvertableToType(Value *V, const Type *Ty, - ValueTypeCache &CTMap) { +// ExpressionConvertibleToType - Return true if it is possible +bool llvm::ExpressionConvertibleToType(Value *V, const Type *Ty, + ValueTypeCache &CTMap, const TargetData &TD) { // Expression type must be holdable in a register. if (!Ty->isFirstClassType()) return false; @@ -139,28 +148,23 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, ValueTypeCache::iterator CTMI = CTMap.find(V); if (CTMI != CTMap.end()) return CTMI->second == Ty; + // If it's a constant... all constants can be converted to a different + // type. + // + if (Constant *CPV = dyn_cast(V)) + return true; + CTMap[V] = Ty; if (V->getType() == Ty) return true; // Expression already correct type! 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). We just ask the constant propogator to see if - // it can convert the value... - // - if (Constant *CPV = dyn_cast(V)) - if (ConstantFoldCastInstruction(CPV, Ty)) - return true; // Don't worry about deallocating, it's a constant. - - return false; // Otherwise, we can't convert! - } + if (I == 0) return false; // Otherwise, we can't convert! switch (I->getOpcode()) { case Instruction::Cast: // We can convert the expr if the cast destination type is losslessly - // convertable to the requested type. - if (!Ty->isLosslesslyConvertableTo(I->getType())) return false; + // convertible to the requested type. + if (!Ty->isLosslesslyConvertibleTo(I->getType())) return false; // We also do not allow conversion of a cast that casts from a ptr to array // of X to a *X. For example: cast [4 x %List *] * %val to %List * * @@ -176,8 +180,8 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, case Instruction::Add: case Instruction::Sub: if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false; - if (!ExpressionConvertableToType(I->getOperand(0), Ty, CTMap) || - !ExpressionConvertableToType(I->getOperand(1), Ty, CTMap)) + if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD) || + !ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD)) return false; break; case Instruction::Shr: @@ -186,32 +190,35 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, // FALL THROUGH case Instruction::Shl: if (!Ty->isInteger()) return false; - if (!ExpressionConvertableToType(I->getOperand(0), Ty, CTMap)) + if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD)) return false; break; case Instruction::Load: { LoadInst *LI = cast(I); - if (!ExpressionConvertableToType(LI->getPointerOperand(), - PointerType::get(Ty), CTMap)) + if (!ExpressionConvertibleToType(LI->getPointerOperand(), + PointerType::get(Ty), CTMap, TD)) return false; break; } - case Instruction::PHINode: { + case Instruction::PHI: { PHINode *PN = cast(I); + // Be conservative if we find a giant PHI node. + if (PN->getNumIncomingValues() > 32) return false; + for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) - if (!ExpressionConvertableToType(PN->getIncomingValue(i), Ty, CTMap)) + if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD)) return false; break; } case Instruction::Malloc: - if (!MallocConvertableToType(cast(I), Ty, CTMap)) + if (!MallocConvertibleToType(cast(I), Ty, CTMap, TD)) return false; break; case Instruction::GetElementPtr: { - // GetElementPtr's are directly convertable to a pointer type if they have + // GetElementPtr's are directly convertible 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: @@ -249,23 +256,22 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, // and we could convert this to an appropriate GEP for the new type. // if (GEP->getNumOperands() == 2 && - GEP->getOperand(1)->getType() == Type::LongTy && GEP->getType() == PointerType::get(Type::SByteTy)) { // Do not Check to see if our incoming pointer can be converted // to be a ptr to an array of the right type... because in more cases than // not, it is simply not analyzable because of pointer/array - // discrepencies. To fix this, we will insert a cast before the GEP. + // discrepancies. To fix this, we will insert a cast before the GEP. // // Check to see if 'N' is an expression that can be converted to // the appropriate size... if so, allow it. // std::vector Indices; - const Type *ElTy = ConvertableToGEP(PTy, I->getOperand(1), Indices); + const Type *ElTy = ConvertibleToGEP(PTy, I->getOperand(1), Indices, TD); if (ElTy == PVTy) { - if (!ExpressionConvertableToType(I->getOperand(0), - PointerType::get(ElTy), CTMap)) + if (!ExpressionConvertibleToType(I->getOperand(0), + PointerType::get(ElTy), CTMap, TD)) return false; // Can't continue, ExConToTy might have polluted set! break; } @@ -277,11 +283,11 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, // getelemenptr [[int] *] * %reg115, long %reg138 ; [int]** // if (GEP->getNumOperands() == 2 && - GEP->getOperand(1)->getType() == Type::LongTy && + PTy->getElementType()->isSized() && TD.getTypeSize(PTy->getElementType()) == TD.getTypeSize(GEP->getType()->getElementType())) { const PointerType *NewSrcTy = PointerType::get(PVTy); - if (!ExpressionConvertableToType(I->getOperand(0), NewSrcTy, CTMap)) + if (!ExpressionConvertibleToType(I->getOperand(0), NewSrcTy, CTMap, TD)) return false; break; } @@ -289,23 +295,41 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty, return false; // No match, maybe next time. } + case Instruction::Call: { + if (isa(I->getOperand(0))) + return false; // Don't even try to change direct calls. + + // If this is a function pointer, we can convert the return type if we can + // convert the source function pointer. + // + const PointerType *PT = cast(I->getOperand(0)->getType()); + const FunctionType *FT = cast(PT->getElementType()); + std::vector ArgTys(FT->param_begin(), FT->param_end()); + const FunctionType *NewTy = + FunctionType::get(Ty, ArgTys, FT->isVarArg()); + if (!ExpressionConvertibleToType(I->getOperand(0), + PointerType::get(NewTy), CTMap, TD)) + return false; + break; + } default: return false; } - // Expressions are only convertable if all of the users of the expression can + // Expressions are only convertible if all of the users of the expression can // have this value converted. This makes use of the map to avoid infinite // recursion. // for (Value::use_iterator It = I->use_begin(), E = I->use_end(); It != E; ++It) - if (!OperandConvertableToType(*It, I, Ty, CTMap)) + if (!OperandConvertibleToType(*It, I, Ty, CTMap, TD)) return false; return true; } -Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { +Value *llvm::ConvertExpressionToType(Value *V, const Type *Ty, + ValueMapCache &VMC, const TargetData &TD) { if (V->getType() == Ty) return V; // Already where we need to be? ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(V); @@ -320,21 +344,18 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { return VMCI->second; } - DEBUG(cerr << "CETT: " << (void*)V << " " << V); + DEBUG(std::cerr << "CETT: " << (void*)V << " " << *V); Instruction *I = dyn_cast(V); - if (I == 0) - if (Constant *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 = ConstantFoldCastInstruction(CPV, Ty); - assert(Result && "ConstantFoldCastInstruction Failed!!!"); - assert(Result->getType() == Ty && "Const prop of cast failed!"); - - // Add the instruction to the expression map - VMC.ExprMap[V] = Result; - return Result; - } + if (I == 0) { + Constant *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 = ConstantExpr::getCast(CPV, Ty); + // Add the instruction to the expression map + //VMC.ExprMap[V] = Result; + return Result; + } BasicBlock *BB = I->getParent(); @@ -358,8 +379,8 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { Dummy, Dummy, Name); VMC.ExprMap[I] = Res; // Add node to expression eagerly - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC)); - Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), Ty, VMC)); + Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC, TD)); + Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), Ty, VMC, TD)); break; case Instruction::Shl: @@ -367,7 +388,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { Res = new ShiftInst(cast(I)->getOpcode(), Dummy, I->getOperand(1), Name); VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC)); + Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), Ty, VMC, TD)); break; case Instruction::Load: { @@ -376,14 +397,14 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { Res = new LoadInst(Constant::getNullValue(PointerType::get(Ty)), Name); VMC.ExprMap[I] = Res; Res->setOperand(0, ConvertExpressionToType(LI->getPointerOperand(), - PointerType::get(Ty), VMC)); + PointerType::get(Ty), VMC, TD)); assert(Res->getOperand(0)->getType() == PointerType::get(Ty)); assert(Ty == Res->getType()); assert(Res->getType()->isFirstClassType() && "Load of structure or array!"); break; } - case Instruction::PHINode: { + case Instruction::PHI: { PHINode *OldPN = cast(I); PHINode *NewPN = new PHINode(Ty, Name); @@ -393,7 +414,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { Value *OldVal = OldPN->getIncomingValue(0); ValueHandle OldValHandle(VMC, OldVal); OldPN->removeIncomingValue(BB, false); - Value *V = ConvertExpressionToType(OldVal, Ty, VMC); + Value *V = ConvertExpressionToType(OldVal, Ty, VMC, TD); NewPN->addIncoming(V, BB); } Res = NewPN; @@ -401,12 +422,12 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { } case Instruction::Malloc: { - Res = ConvertMallocToType(cast(I), Ty, Name, VMC); + Res = ConvertMallocToType(cast(I), Ty, Name, VMC, TD); break; } case Instruction::GetElementPtr: { - // GetElementPtr's are directly convertable to a pointer type if they have + // GetElementPtr's are directly convertible 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: @@ -438,11 +459,10 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { } if (Res == 0 && GEP->getNumOperands() == 2 && - GEP->getOperand(1)->getType() == Type::LongTy && GEP->getType() == PointerType::get(Type::SByteTy)) { // Otherwise, we can convert a GEP from one form to the other iff the - // current gep is of the form 'getelementptr [sbyte]*, unsigned N + // current gep is of the form 'getelementptr sbyte*, unsigned N // and we could convert this to an appropriate GEP for the new type. // const PointerType *NewSrcTy = PointerType::get(PVTy); @@ -452,15 +472,15 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { // the appropriate size... if so, allow it. // std::vector Indices; - const Type *ElTy = ConvertableToGEP(NewSrcTy, I->getOperand(1), - Indices, &It); + const Type *ElTy = ConvertibleToGEP(NewSrcTy, I->getOperand(1), + Indices, TD, &It); if (ElTy) { assert(ElTy == PVTy && "Internal error, setup wrong!"); Res = new GetElementPtrInst(Constant::getNullValue(NewSrcTy), Indices, Name); VMC.ExprMap[I] = Res; Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), - NewSrcTy, VMC)); + NewSrcTy, VMC, TD)); } } @@ -476,16 +496,38 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { Indices, Name); VMC.ExprMap[I] = Res; Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), - NewSrcTy, VMC)); + NewSrcTy, VMC, TD)); } assert(Res && "Didn't find match!"); - break; // No match, maybe next time. + break; } + case Instruction::Call: { + assert(!isa(I->getOperand(0))); + + // If this is a function pointer, we can convert the return type if we can + // convert the source function pointer. + // + const PointerType *PT = cast(I->getOperand(0)->getType()); + const FunctionType *FT = cast(PT->getElementType()); + std::vector ArgTys(FT->param_begin(), FT->param_end()); + const FunctionType *NewTy = + FunctionType::get(Ty, ArgTys, FT->isVarArg()); + const PointerType *NewPTy = PointerType::get(NewTy); + if (Ty == Type::VoidTy) + Name = ""; // Make sure not to name calls that now return void! + + Res = new CallInst(Constant::getNullValue(NewPTy), + std::vector(I->op_begin()+1, I->op_end()), + Name); + VMC.ExprMap[I] = Res; + Res->setOperand(0, ConvertExpressionToType(I->getOperand(0),NewPTy,VMC,TD)); + break; + } default: - assert(0 && "Expression convertable, but don't know how to convert?"); + assert(0 && "Expression convertible, but don't know how to convert?"); return 0; } @@ -496,29 +538,29 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) { // Add the instruction to the expression map VMC.ExprMap[I] = Res; - // Expressions are only convertable if all of the users of the expression can - // have this value converted. This makes use of the map to avoid infinite - // recursion. - // + unsigned NumUses = I->use_size(); for (unsigned It = 0; It < NumUses; ) { unsigned OldSize = NumUses; - ConvertOperandToType(*(I->use_begin()+It), I, Res, VMC); + Value::use_iterator UI = I->use_begin(); + std::advance(UI, It); + ConvertOperandToType(*UI, I, Res, VMC, TD); NumUses = I->use_size(); if (NumUses == OldSize) ++It; } - DEBUG(cerr << "ExpIn: " << (void*)I << " " << I - << "ExpOut: " << (void*)Res << " " << Res); + DEBUG(std::cerr << "ExpIn: " << (void*)I << " " << *I + << "ExpOut: " << (void*)Res << " " << *Res); return Res; } -// ValueConvertableToType - Return true if it is possible -bool ValueConvertableToType(Value *V, const Type *Ty, - ValueTypeCache &ConvertedTypes) { +// ValueConvertibleToType - Return true if it is possible +bool llvm::ValueConvertibleToType(Value *V, const Type *Ty, + ValueTypeCache &ConvertedTypes, + const TargetData &TD) { ValueTypeCache::iterator I = ConvertedTypes.find(V); if (I != ConvertedTypes.end()) return I->second == Ty; ConvertedTypes[V] = Ty; @@ -528,7 +570,7 @@ bool ValueConvertableToType(Value *V, const Type *Ty, // 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)) + if (!OperandConvertibleToType(*I, V, Ty, ConvertedTypes, TD)) return false; } @@ -539,14 +581,15 @@ bool ValueConvertableToType(Value *V, const Type *Ty, -// OperandConvertableToType - Return true if it is possible to convert operand +// OperandConvertibleToType - 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) { +static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty, + ValueTypeCache &CTMap, + const TargetData &TD) { // if (V->getType() == Ty) return true; // Operand already the right type? // Expression type must be holdable in a register. @@ -560,10 +603,10 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, 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. + // convertible to the requested type. // Also, do not change a cast that is a noop cast. For all intents and // purposes it should be eliminated. - if (!Ty->isLosslesslyConvertableTo(I->getOperand(0)->getType()) || + if (!Ty->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) || I->getType() == I->getOperand(0)->getType()) return false; @@ -573,7 +616,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, // signedness doesn't change... or if the current cast is not a lossy // conversion. // - if (!I->getType()->isLosslesslyConvertableTo(I->getOperand(0)->getType()) && + if (!I->getType()->isLosslesslyConvertibleTo(I->getOperand(0)->getType()) && I->getOperand(0)->getType()->isSigned() != Ty->isSigned()) return false; @@ -592,15 +635,15 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (isa(Ty)) { Value *IndexVal = I->getOperand(V == I->getOperand(0) ? 1 : 0); std::vector Indices; - if (const Type *ETy = ConvertableToGEP(Ty, IndexVal, Indices)) { + if (const Type *ETy = ConvertibleToGEP(Ty, IndexVal, Indices, TD)) { const Type *RetTy = PointerType::get(ETy); // Only successful if we can convert this type to the required type - if (ValueConvertableToType(I, RetTy, CTMap)) { + if (ValueConvertibleToType(I, RetTy, CTMap, TD)) { CTMap[I] = RetTy; return true; } - // We have to return failure here because ValueConvertableToType could + // We have to return failure here because ValueConvertibleToType could // have polluted our map return false; } @@ -610,21 +653,21 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false; Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0); - return ValueConvertableToType(I, Ty, CTMap) && - ExpressionConvertableToType(OtherOp, Ty, CTMap); + return ValueConvertibleToType(I, Ty, CTMap, TD) && + ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD); } case Instruction::SetEQ: case Instruction::SetNE: { Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0); - return ExpressionConvertableToType(OtherOp, Ty, CTMap); + return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD); } case Instruction::Shr: if (Ty->isSigned() != V->getType()->isSigned()) return false; // FALL THROUGH case Instruction::Shl: - assert(I->getOperand(0) == V); + if (I->getOperand(1) == V) return false; // Cannot change shift amount type if (!Ty->isInteger()) return false; - return ValueConvertableToType(I, Ty, CTMap); + return ValueConvertibleToType(I, Ty, CTMap, TD); case Instruction::Free: assert(I->getOperand(0) == V); @@ -643,7 +686,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (const CompositeType *CT = dyn_cast(LoadedTy)) { unsigned Offset = 0; // No offset, get first leaf. std::vector Indices; // Discarded... - LoadedTy = getStructOffsetType(CT, Offset, Indices, false); + LoadedTy = getStructOffsetType(CT, Offset, Indices, TD, false); assert(Offset == 0 && "Offset changed from zero???"); } @@ -653,7 +696,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (TD.getTypeSize(LoadedTy) != TD.getTypeSize(LI->getType())) return false; - return ValueConvertableToType(LI, LoadedTy, CTMap); + return ValueConvertibleToType(LI, LoadedTy, CTMap, TD); } return false; @@ -665,7 +708,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (CTMI != CTMap.end()) { // Operand #1 is in the table already? // If so, check to see if it's Ty*, or, more importantly, if it is a // pointer to a structure where the first element is a Ty... this code - // is neccesary because we might be trying to change the source and + // is necessary because we might be trying to change the source and // destination type of the store (they might be related) and the dest // pointer type might be a pointer to structure. Below we allow pointer // to structures where the 0th element is compatible with the value, @@ -684,7 +727,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, if (const StructType *SElTy = dyn_cast(ElTy)) { unsigned Offset = 0; std::vector Indices; - ElTy = getStructOffsetType(ElTy, Offset, Indices, false); + ElTy = getStructOffsetType(ElTy, Offset, Indices, TD, false); assert(Offset == 0 && "Offset changed!"); if (ElTy == 0) // Element at offset zero in struct doesn't exist! return false; // Can only happen for {}* @@ -699,8 +742,8 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, // 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), - CTMap); + return ExpressionConvertibleToType(I->getOperand(1), PointerType::get(Ty), + CTMap, TD); } else if (const PointerType *PT = dyn_cast(Ty)) { const Type *ElTy = PT->getElementType(); assert(V == I->getOperand(1)); @@ -711,7 +754,7 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, // unsigned Offset = 0; std::vector Indices; - ElTy = getStructOffsetType(ElTy, Offset, Indices, false); + ElTy = getStructOffsetType(ElTy, Offset, Indices, TD, false); assert(Offset == 0 && "Offset changed!"); if (ElTy == 0) // Element at offset zero in struct doesn't exist! return false; // Can only happen for {}* @@ -722,8 +765,12 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, TD.getTypeSize(ElTy) != TD.getTypeSize(I->getOperand(0)->getType())) return false; - // Can convert store if the incoming value is convertable... - return ExpressionConvertableToType(I->getOperand(0), ElTy, CTMap); + // Can convert store if the incoming value is convertible and if the + // result will preserve semantics... + const Type *Op0Ty = I->getOperand(0)->getType(); + if (!(Op0Ty->isIntegral() ^ ElTy->isIntegral()) && + !(Op0Ty->isFloatingPoint() ^ ElTy->isFloatingPoint())) + return ExpressionConvertibleToType(I->getOperand(0), ElTy, CTMap, TD); } return false; } @@ -742,14 +789,18 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, Instruction *TempScale = 0; // If the old data element is not unit sized, we have to create a scale - // instruction so that ConvertableToGEP will know the REAL amount we are + // instruction so that ConvertibleToGEP will know the REAL amount we are // indexing by. Note that this is never inserted into the instruction // stream, so we have to delete it when we're done. // if (DataSize != 1) { - TempScale = BinaryOperator::create(Instruction::Mul, Index, - ConstantSInt::get(Type::LongTy, - DataSize)); + Value *CST; + if (Index->getType()->isSigned()) + CST = ConstantSInt::get(Index->getType(), DataSize); + else + CST = ConstantUInt::get(Index->getType(), DataSize); + + TempScale = BinaryOperator::create(Instruction::Mul, Index, CST); Index = TempScale; } @@ -757,20 +808,23 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, // be converted to the appropriate size... if so, allow it. // std::vector Indices; - const Type *ElTy = ConvertableToGEP(Ty, Index, Indices); + const Type *ElTy = ConvertibleToGEP(Ty, Index, Indices, TD); delete TempScale; // Free our temporary multiply if we made it if (ElTy == 0) return false; // Cannot make conversion... - return ValueConvertableToType(I, PointerType::get(ElTy), CTMap); + return ValueConvertibleToType(I, PointerType::get(ElTy), CTMap, TD); } return false; - case Instruction::PHINode: { + case Instruction::PHI: { PHINode *PN = cast(I); + // Be conservative if we find a giant PHI node. + if (PN->getNumIncomingValues() > 32) return false; + for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i) - if (!ExpressionConvertableToType(PN->getIncomingValue(i), Ty, CTMap)) + if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD)) return false; - return ValueConvertableToType(PN, Ty, CTMap); + return ValueConvertibleToType(PN, Ty, CTMap, TD); } case Instruction::Call: { @@ -807,47 +861,49 @@ static bool OperandConvertableToType(User *U, Value *V, const Type *Ty, // Okay, at this point, we know that the call and the function type match // number of arguments. Now we see if we can convert the arguments - // themselves. Note that we do not require operands to be convertable, + // themselves. Note that we do not require operands to be convertible, // we can insert casts if they are convertible but not compatible. The // reason for this is that we prefer to have resolved functions but casted // arguments if possible. // - const FunctionType::ParamTypes &PTs = FTy->getParamTypes(); - for (unsigned i = 0, NA = PTs.size(); i < NA; ++i) - if (!PTs[i]->isLosslesslyConvertableTo(I->getOperand(i+1)->getType())) + for (unsigned i = 0, NA = FTy->getNumParams(); i < NA; ++i) + if (!FTy->getParamType(i)->isLosslesslyConvertibleTo(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... + // necessary... // - return ValueConvertableToType(I, FTy->getReturnType(), CTMap); + return ValueConvertibleToType(I, FTy->getReturnType(), CTMap, TD); } const PointerType *MPtr = cast(I->getOperand(0)->getType()); const FunctionType *FTy = cast(MPtr->getElementType()); if (!FTy->isVarArg()) return false; - if ((OpNum-1) < FTy->getParamTypes().size()) + if ((OpNum-1) < FTy->getNumParams()) return false; // It's not in the varargs section... // If we get this far, we know the value is in the varargs section of the // function! We can convert if we don't reinterpret the value... // - return Ty->isLosslesslyConvertableTo(V->getType()); + return Ty->isLosslesslyConvertibleTo(V->getType()); } } return false; } -void ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC) { +void llvm::ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC, + const TargetData &TD) { ValueHandle VH(VMC, V); unsigned NumUses = V->use_size(); for (unsigned It = 0; It < NumUses; ) { unsigned OldSize = NumUses; - ConvertOperandToType(*(V->use_begin()+It), V, NewVal, VMC); + Value::use_iterator UI = V->use_begin(); + std::advance(UI, It); + ConvertOperandToType(*UI, V, NewVal, VMC, TD); NumUses = V->use_size(); if (NumUses == OldSize) ++It; } @@ -856,7 +912,7 @@ void ConvertValueToNewType(Value *V, Value *NewVal, ValueMapCache &VMC) { static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, - ValueMapCache &VMC) { + ValueMapCache &VMC, const TargetData &TD) { if (isa(U)) return; // Valuehandles don't let go of operands... if (VMC.OperandsMapped.count(U)) return; @@ -867,7 +923,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, return; - Instruction *I = cast(U); // Only Instructions convertable + Instruction *I = cast(U); // Only Instructions convertible BasicBlock *BB = I->getParent(); assert(BB != 0 && "Instruction not embedded in basic block!"); @@ -875,7 +931,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, I->setName(""); Instruction *Res; // Result of conversion - //cerr << endl << endl << "Type:\t" << Ty << "\nInst: " << I << "BB Before: " << BB << endl; + //std::cerr << endl << endl << "Type:\t" << Ty << "\nInst: " << I + // << "BB Before: " << BB << endl; // Prevent I from being removed... ValueHandle IHandle(VMC, I); @@ -906,13 +963,13 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, std::vector Indices; BasicBlock::iterator It = I; - if (const Type *ETy = ConvertableToGEP(NewTy, IndexVal, Indices, &It)) { + if (const Type *ETy = ConvertibleToGEP(NewTy, IndexVal, Indices, TD,&It)){ // If successful, convert the add to a GEP //const Type *RetTy = PointerType::get(ETy); // First operand is actually the given pointer... Res = new GetElementPtrInst(NewVal, Indices, Name); assert(cast(Res->getType())->getElementType() == ETy && - "ConvertableToGEP broken!"); + "ConvertibleToGEP broken!"); break; } } @@ -927,7 +984,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0; Value *OtherOp = I->getOperand(OtherIdx); - Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC); + Value *NewOther = ConvertExpressionToType(OtherOp, NewTy, VMC, TD); Res->setOperand(OtherIdx, NewOther); Res->setOperand(!OtherIdx, NewVal); @@ -955,10 +1012,10 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, if (const CompositeType *CT = dyn_cast(LoadedTy)) { std::vector Indices; - Indices.push_back(ConstantSInt::get(Type::LongTy, 0)); + Indices.push_back(Constant::getNullValue(Type::UIntTy)); unsigned Offset = 0; // No offset, get first leaf. - LoadedTy = getStructOffsetType(CT, Offset, Indices, false); + LoadedTy = getStructOffsetType(CT, Offset, Indices, TD, false); assert(LoadedTy->isFirstClassType()); if (Indices.size() != 1) { // Do not generate load X, 0 @@ -978,7 +1035,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, ValueMapCache::ExprMapTy::iterator VMCI = VMC.ExprMap.find(I->getOperand(1)); if (VMCI != VMC.ExprMap.end()) { - // Comments describing this stuff are in the OperandConvertableToType + // Comments describing this stuff are in the OperandConvertibleToType // switch statement for Store... // const Type *ElTy = @@ -991,10 +1048,10 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, const StructType *SElTy = cast(ElTy); std::vector Indices; - Indices.push_back(Constant::getNullValue(Type::LongTy)); + Indices.push_back(Constant::getNullValue(Type::UIntTy)); unsigned Offset = 0; - const Type *Ty = getStructOffsetType(ElTy, Offset, Indices, false); + const Type *Ty = getStructOffsetType(ElTy, Offset, Indices, TD,false); assert(Offset == 0 && "Offset changed!"); assert(NewTy == Ty && "Did not convert to correct type!"); @@ -1011,7 +1068,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, Res = new StoreInst(NewVal, Constant::getNullValue(NewPT)); VMC.ExprMap[I] = Res; Res->setOperand(1, ConvertExpressionToType(I->getOperand(1), - NewPT, VMC)); + NewPT, VMC, TD)); } } else { // Replace the source pointer const Type *ValTy = cast(NewTy)->getElementType(); @@ -1020,10 +1077,10 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, if (isa(ValTy)) { std::vector Indices; - Indices.push_back(Constant::getNullValue(Type::LongTy)); + Indices.push_back(Constant::getNullValue(Type::UIntTy)); unsigned Offset = 0; - ValTy = getStructOffsetType(ValTy, Offset, Indices, false); + ValTy = getStructOffsetType(ValTy, Offset, Indices, TD, false); assert(Offset == 0 && ValTy); @@ -1034,7 +1091,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, Res = new StoreInst(Constant::getNullValue(ValTy), SrcPtr); VMC.ExprMap[I] = Res; - Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), ValTy, VMC)); + Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), + ValTy, VMC, TD)); } break; } @@ -1051,19 +1109,23 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, if (DataSize != 1) { // Insert a multiply of the old element type is not a unit size... - Index = BinaryOperator::create(Instruction::Mul, Index, - ConstantSInt::get(Type::LongTy, DataSize), - "scale", It); + Value *CST; + if (Index->getType()->isSigned()) + CST = ConstantSInt::get(Index->getType(), DataSize); + else + CST = ConstantUInt::get(Index->getType(), DataSize); + + Index = BinaryOperator::create(Instruction::Mul, Index, CST, "scale", It); } // Perform the conversion now... // std::vector Indices; - const Type *ElTy = ConvertableToGEP(NewVal->getType(), Index, Indices, &It); + const Type *ElTy = ConvertibleToGEP(NewVal->getType(),Index,Indices,TD,&It); assert(ElTy != 0 && "GEP Conversion Failure!"); Res = new GetElementPtrInst(NewVal, Indices, Name); assert(Res->getType() == PointerType::get(ElTy) && - "ConvertableToGet failed!"); + "ConvertibleToGet failed!"); } #if 0 if (I->getType() == PointerType::get(Type::SByteTy)) { @@ -1076,8 +1138,8 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, // be converted to the appropriate size... if so, allow it. // std::vector Indices; - const Type *ElTy = ConvertableToGEP(NewVal->getType(), I->getOperand(1), - Indices, &It); + const Type *ElTy = ConvertibleToGEP(NewVal->getType(), I->getOperand(1), + Indices, TD, &It); assert(ElTy != 0 && "GEP Conversion Failure!"); Res = new GetElementPtrInst(NewVal, Indices, Name); @@ -1093,7 +1155,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, #endif break; - case Instruction::PHINode: { + case Instruction::PHI: { PHINode *OldPN = cast(I); PHINode *NewPN = new PHINode(NewTy, Name); VMC.ExprMap[I] = NewPN; @@ -1101,8 +1163,9 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, while (OldPN->getNumOperands()) { BasicBlock *BB = OldPN->getIncomingBlock(0); Value *OldVal = OldPN->getIncomingValue(0); + ValueHandle OldValHandle(VMC, OldVal); OldPN->removeIncomingValue(BB, false); - Value *V = ConvertExpressionToType(OldVal, NewTy, VMC); + Value *V = ConvertExpressionToType(OldVal, NewTy, VMC, TD); NewPN->addIncoming(V, BB); } Res = NewPN; @@ -1116,11 +1179,13 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, if (Meth == OldVal) { // Changing the function pointer? const PointerType *NewPTy = cast(NewVal->getType()); const FunctionType *NewTy = cast(NewPTy->getElementType()); - const FunctionType::ParamTypes &PTs = NewTy->getParamTypes(); + + if (NewTy->getReturnType() == Type::VoidTy) + Name = ""; // Make sure not to name a void call! // Get an iterator to the call instruction so that we can insert casts for - // operands if needbe. Note that we do not require operands to be - // convertable, we can insert casts if they are convertible but not + // operands if need be. Note that we do not require operands to be + // convertible, we can insert casts if they are convertible but not // compatible. The reason for this is that we prefer to have resolved // functions but casted arguments if possible. // @@ -1129,12 +1194,14 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, // 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) - if (Params[i]->getType() != PTs[i]) { + for (unsigned i = 0; i != NewTy->getNumParams(); ++i) + if (Params[i]->getType() != NewTy->getParamType(i)) { // Create a cast to convert it to the right type, we know that this // is a lossless cast... // - Params[i] = new CastInst(Params[i], PTs[i], "call.resolve.cast", It); + Params[i] = new CastInst(Params[i], NewTy->getParamType(i), + "callarg.cast." + + Params[i]->getName(), It); } Meth = NewVal; // Update call destination to new value @@ -1150,7 +1217,7 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, break; } default: - assert(0 && "Expression convertable, but don't know how to convert?"); + assert(0 && "Expression convertible, but don't know how to convert?"); return; } @@ -1161,40 +1228,45 @@ static void ConvertOperandToType(User *U, Value *OldVal, Value *NewVal, assert(It != BB->end() && "Instruction not in own basic block??"); BB->getInstList().insert(It, Res); // Keep It pointing to old instruction - DEBUG(cerr << "COT CREATED: " << (void*)Res << " " << Res - << "In: " << (void*)I << " " << I << "Out: " << (void*)Res - << " " << Res); + DEBUG(std::cerr << "COT CREATED: " << (void*)Res << " " << *Res + << "In: " << (void*)I << " " << *I << "Out: " << (void*)Res + << " " << *Res); // Add the instruction to the expression map VMC.ExprMap[I] = Res; if (I->getType() != Res->getType()) - ConvertValueToNewType(I, Res, VMC); + ConvertValueToNewType(I, Res, VMC, TD); else { - for (unsigned It = 0; It < I->use_size(); ) { - User *Use = *(I->use_begin()+It); - if (isa(Use)) // Don't remove ValueHandles! - ++It; - else - Use->replaceUsesOfWith(I, Res); + bool FromStart = true; + Value::use_iterator UI; + while (1) { + if (FromStart) UI = I->use_begin(); + if (UI == I->use_end()) break; + + if (isa(*UI)) { + ++UI; + FromStart = false; + } else { + User *U = *UI; + if (!FromStart) --UI; + U->replaceUsesOfWith(I, Res); + if (!FromStart) ++UI; + } } - - for (Value::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) - assert(isa((Value*)*UI) &&"Uses of Instruction remain!!!"); } } ValueHandle::ValueHandle(ValueMapCache &VMC, Value *V) : Instruction(Type::VoidTy, UserOp1, ""), Cache(VMC) { - //DEBUG(cerr << "VH AQUIRING: " << (void*)V << " " << V); + //DEBUG(std::cerr << "VH AQUIRING: " << (void*)V << " " << V); Operands.push_back(Use(V, this)); } ValueHandle::ValueHandle(const ValueHandle &VH) : Instruction(Type::VoidTy, UserOp1, ""), Cache(VH.Cache) { - //DEBUG(cerr << "VH AQUIRING: " << (void*)V << " " << V); + //DEBUG(std::cerr << "VH AQUIRING: " << (void*)V << " " << V); Operands.push_back(Use((Value*)VH.getOperand(0), this)); } @@ -1203,11 +1275,11 @@ static void RecursiveDelete(ValueMapCache &Cache, Instruction *I) { assert(I->getParent() && "Inst not in basic block!"); - //DEBUG(cerr << "VH DELETING: " << (void*)I << " " << I); + //DEBUG(std::cerr << "VH DELETING: " << (void*)I << " " << I); for (User::op_iterator OI = I->op_begin(), OE = I->op_end(); OI != OE; ++OI) - if (Instruction *U = dyn_cast(OI->get())) { + if (Instruction *U = dyn_cast(OI)) { *OI = 0; RecursiveDelete(Cache, U); } @@ -1220,7 +1292,7 @@ static void RecursiveDelete(ValueMapCache &Cache, Instruction *I) { } ValueHandle::~ValueHandle() { - if (Operands[0]->use_size() == 1) { + if (Operands[0]->hasOneUse()) { Value *V = Operands[0]; Operands[0] = 0; // Drop use! @@ -1230,7 +1302,8 @@ ValueHandle::~ValueHandle() { // RecursiveDelete(Cache, dyn_cast(V)); } else { - //DEBUG(cerr << "VH RELEASING: " << (void*)Operands[0].get() << " " - // << Operands[0]->use_size() << " " << Operands[0]); + //DEBUG(std::cerr << "VH RELEASING: " << (void*)Operands[0].get() << " " + // << Operands[0]->use_size() << " " << Operands[0]); } } +