//
// 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 <algorithm>
using std::cerr;
-static bool OperandConvertableToType(User *U, Value *V, const Type *Ty,
+static bool OperandConvertibleToType(User *U, Value *V, const Type *Ty,
ValueTypeCache &ConvertedTypes,
const TargetData &TD);
// 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,
+static bool MallocConvertibleToType(MallocInst *MI, const Type *Ty,
ValueTypeCache &CTMap,
const TargetData &TD) {
if (!isa<PointerType>(Ty)) return false; // Malloc always returns pointers
}
-// ExpressionConvertableToType - Return true if it is possible
-bool ExpressionConvertableToType(Value *V, const Type *Ty,
+// ExpressionConvertibleToType - Return true if it is possible
+bool ExpressionConvertibleToType(Value *V, const Type *Ty,
ValueTypeCache &CTMap, const TargetData &TD) {
// Expression type must be holdable in a register.
if (!Ty->isFirstClassType())
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 * *
case Instruction::Add:
case Instruction::Sub:
if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false;
- if (!ExpressionConvertableToType(I->getOperand(0), Ty, CTMap, TD) ||
- !ExpressionConvertableToType(I->getOperand(1), Ty, CTMap, TD))
+ if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD) ||
+ !ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD))
return false;
break;
case Instruction::Shr:
// FALL THROUGH
case Instruction::Shl:
if (!Ty->isInteger()) return false;
- if (!ExpressionConvertableToType(I->getOperand(0), Ty, CTMap, TD))
+ if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
return false;
break;
case Instruction::Load: {
LoadInst *LI = cast<LoadInst>(I);
- if (!ExpressionConvertableToType(LI->getPointerOperand(),
+ if (!ExpressionConvertibleToType(LI->getPointerOperand(),
PointerType::get(Ty), CTMap, TD))
return false;
break;
case Instruction::PHINode: {
PHINode *PN = cast<PHINode>(I);
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i)
- if (!ExpressionConvertableToType(PN->getIncomingValue(i), Ty, CTMap, TD))
+ if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD))
return false;
break;
}
case Instruction::Malloc:
- if (!MallocConvertableToType(cast<MallocInst>(I), Ty, CTMap, TD))
+ if (!MallocConvertibleToType(cast<MallocInst>(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:
// the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
- const Type *ElTy = ConvertableToGEP(PTy, I->getOperand(1), Indices, TD);
+ const Type *ElTy = ConvertibleToGEP(PTy, I->getOperand(1), Indices, TD);
if (ElTy == PVTy) {
- if (!ExpressionConvertableToType(I->getOperand(0),
+ if (!ExpressionConvertibleToType(I->getOperand(0),
PointerType::get(ElTy), CTMap, TD))
return false; // Can't continue, ExConToTy might have polluted set!
break;
TD.getTypeSize(PTy->getElementType()) ==
TD.getTypeSize(GEP->getType()->getElementType())) {
const PointerType *NewSrcTy = PointerType::get(PVTy);
- if (!ExpressionConvertableToType(I->getOperand(0), NewSrcTy, CTMap, TD))
+ if (!ExpressionConvertibleToType(I->getOperand(0), NewSrcTy, CTMap, TD))
return false;
break;
}
FT->getParamTypes().end());
const FunctionType *NewTy =
FunctionType::get(Ty, ArgTys, FT->isVarArg());
- if (!ExpressionConvertableToType(I->getOperand(0),
+ if (!ExpressionConvertibleToType(I->getOperand(0),
PointerType::get(NewTy), CTMap, TD))
return false;
break;
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, TD))
+ if (!OperandConvertibleToType(*It, I, Ty, CTMap, TD))
return false;
return true;
}
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:
// the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
- const Type *ElTy = ConvertableToGEP(NewSrcTy, I->getOperand(1),
+ const Type *ElTy = ConvertibleToGEP(NewSrcTy, I->getOperand(1),
Indices, TD, &It);
if (ElTy) {
assert(ElTy == PVTy && "Internal error, setup wrong!");
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;
}
// Add the instruction to the expression map
VMC.ExprMap[I] = Res;
- // 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.
//
-// ValueConvertableToType - Return true if it is possible
-bool ValueConvertableToType(Value *V, const Type *Ty,
+// ValueConvertibleToType - Return true if it is possible
+bool ValueConvertibleToType(Value *V, const Type *Ty,
ValueTypeCache &ConvertedTypes,
const TargetData &TD) {
ValueTypeCache::iterator I = ConvertedTypes.find(V);
//
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, TD))
+ if (!OperandConvertibleToType(*I, V, Ty, ConvertedTypes, TD))
return false;
}
-// 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,
+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?
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;
// 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;
if (isa<PointerType>(Ty)) {
Value *IndexVal = I->getOperand(V == I->getOperand(0) ? 1 : 0);
std::vector<Value*> Indices;
- if (const Type *ETy = ConvertableToGEP(Ty, IndexVal, Indices, TD)) {
+ 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, TD)) {
+ 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;
}
if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false;
Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
- return ValueConvertableToType(I, Ty, CTMap, TD) &&
- ExpressionConvertableToType(OtherOp, Ty, CTMap, TD);
+ 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, TD);
+ return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
}
case Instruction::Shr:
if (Ty->isSigned() != V->getType()->isSigned()) return false;
case Instruction::Shl:
if (I->getOperand(1) == V) return false; // Cannot change shift amount type
if (!Ty->isInteger()) return false;
- return ValueConvertableToType(I, Ty, CTMap, TD);
+ return ValueConvertibleToType(I, Ty, CTMap, TD);
case Instruction::Free:
assert(I->getOperand(0) == V);
if (TD.getTypeSize(LoadedTy) != TD.getTypeSize(LI->getType()))
return false;
- return ValueConvertableToType(LI, LoadedTy, CTMap, TD);
+ return ValueConvertibleToType(LI, LoadedTy, CTMap, TD);
}
return false;
// 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),
+ return ExpressionConvertibleToType(I->getOperand(1), PointerType::get(Ty),
CTMap, TD);
} else if (const PointerType *PT = dyn_cast<PointerType>(Ty)) {
const Type *ElTy = PT->getElementType();
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, TD);
+ // Can convert store if the incoming value is convertible...
+ return ExpressionConvertibleToType(I->getOperand(0), ElTy, CTMap, TD);
}
return false;
}
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.
//
// be converted to the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
- const Type *ElTy = ConvertableToGEP(Ty, Index, Indices, TD);
+ 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, TD);
+ return ValueConvertibleToType(I, PointerType::get(ElTy), CTMap, TD);
}
return false;
case Instruction::PHINode: {
PHINode *PN = cast<PHINode>(I);
for (unsigned i = 0; i < PN->getNumIncomingValues(); ++i)
- if (!ExpressionConvertableToType(PN->getIncomingValue(i), Ty, CTMap, TD))
+ if (!ExpressionConvertibleToType(PN->getIncomingValue(i), Ty, CTMap, TD))
return false;
- return ValueConvertableToType(PN, Ty, CTMap, TD);
+ return ValueConvertibleToType(PN, Ty, CTMap, TD);
}
case Instruction::Call: {
// 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()))
+ if (!PTs[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...
//
- return ValueConvertableToType(I, FTy->getReturnType(), CTMap, TD);
+ return ValueConvertibleToType(I, FTy->getReturnType(), CTMap, TD);
}
const PointerType *MPtr = cast<PointerType>(I->getOperand(0)->getType());
// 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;
return;
- Instruction *I = cast<Instruction>(U); // Only Instructions convertable
+ Instruction *I = cast<Instruction>(U); // Only Instructions convertible
BasicBlock *BB = I->getParent();
assert(BB != 0 && "Instruction not embedded in basic block!");
std::vector<Value*> Indices;
BasicBlock::iterator It = I;
- if (const Type *ETy = ConvertableToGEP(NewTy, IndexVal, Indices, TD,&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<PointerType>(Res->getType())->getElementType() == ETy &&
- "ConvertableToGEP broken!");
+ "ConvertibleToGEP broken!");
break;
}
}
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 =
// Perform the conversion now...
//
std::vector<Value*> Indices;
- const Type *ElTy = ConvertableToGEP(NewVal->getType(),Index,Indices,TD,&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)) {
// be converted to the appropriate size... if so, allow it.
//
std::vector<Value*> Indices;
- const Type *ElTy = ConvertableToGEP(NewVal->getType(), I->getOperand(1),
+ const Type *ElTy = ConvertibleToGEP(NewVal->getType(), I->getOperand(1),
Indices, TD, &It);
assert(ElTy != 0 && "GEP Conversion Failure!");
// 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
+ // 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.
//
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;
}
// cast instruction would cause the underlying bits to change.
//
static inline bool isReinterpretingCast(const CastInst *CI) {
- return!CI->getOperand(0)->getType()->isLosslesslyConvertableTo(CI->getType());
+ return!CI->getOperand(0)->getType()->isLosslesslyConvertibleTo(CI->getType());
}
std::vector<Value*> Indices;
Value *Src = CI.getOperand(0);
- const Type *Result = ConvertableToGEP(DestPTy, Src, Indices, TD, &BI);
- if (Result == 0) return false; // Not convertable...
+ const Type *Result = ConvertibleToGEP(DestPTy, Src, Indices, TD, &BI);
+ if (Result == 0) return false; // Not convertible...
// Cannot handle subtracts if there is more than one index required...
if (HasSubUse && Indices.size() != 1) return false;
return false;
std::vector<Value*> Indices;
- if (!ConvertableToGEP(SrcPtr->getType(), OffsetVal, Indices, TD, &BI))
- return false; // Not convertable... perhaps next time
+ if (!ConvertibleToGEP(SrcPtr->getType(), OffsetVal, Indices, TD, &BI))
+ return false; // Not convertible... perhaps next time
if (getPointedToComposite(AddOp1->getType())) { // case 1
PRINT_PEEPHOLE2("add-to-gep1:in", AddOp2, *BI);
// destination type of the cast...
//
ConvertedTypes[CI] = CI->getType(); // Make sure the cast doesn't change
- if (ExpressionConvertableToType(Src, DestTy, ConvertedTypes, TD)) {
+ if (ExpressionConvertibleToType(Src, DestTy, ConvertedTypes, TD)) {
PRINT_PEEPHOLE3("CAST-SRC-EXPR-CONV:in ", Src, CI, BB->getParent());
DEBUG(cerr << "\nCONVERTING SRC EXPR TYPE:\n");
ConvertedTypes.clear();
// Make sure the source doesn't change type
ConvertedTypes[Src] = Src->getType();
- if (ValueConvertableToType(CI, Src->getType(), ConvertedTypes, TD)) {
+ if (ValueConvertibleToType(CI, Src->getType(), ConvertedTypes, TD)) {
PRINT_PEEPHOLE3("CAST-DEST-EXPR-CONV:in ", Src, CI, BB->getParent());
DEBUG(cerr << "\nCONVERTING EXPR TYPE:\n");
}
// If it doesn't have an add use, check to see if the dest type is
- // losslessly convertable to one of the types in the start of the struct
+ // losslessly convertible to one of the types in the start of the struct
// type.
//
if (!HasAddUse) {
Indices.push_back(Constant::getNullValue(CurCTy->getIndexType()));
// Did we find what we're looking for?
- if (ElTy->isLosslesslyConvertableTo(DestPointedTy)) break;
+ if (ElTy->isLosslesslyConvertibleTo(DestPointedTy)) break;
// Nope, go a level deeper.
++Depth;
Value *Pointer = SI->getPointerOperand();
// Peephole optimize the following instructions:
- // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly convertable to T2
+ // %t = cast <T1>* %P to <T2> * ;; If T1 is losslessly convertible to T2
// store <T2> %V, <T2>* %t
//
// Into:
if (CastInst *CI = dyn_cast<CastInst>(Pointer))
if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
- // convertable types?
- if (Val->getType()->isLosslesslyConvertableTo(CSPT->getElementType())) {
+ // convertible types?
+ if (Val->getType()->isLosslesslyConvertibleTo(CSPT->getElementType())) {
PRINT_PEEPHOLE3("st-src-cast:in ", Pointer, Val, SI);
// Insert the new T cast instruction... stealing old T's name
cast<PointerType>(Pointer->getType())->getElementType();
// Peephole optimize the following instructions:
- // %Val = cast <T1>* to <T2>* ;; If T1 is losslessly convertable to T2
+ // %Val = cast <T1>* to <T2>* ;; If T1 is losslessly convertible to T2
// %t = load <T2>* %P
//
// Into:
if (CastInst *CI = dyn_cast<CastInst>(Pointer))
if (Value *CastSrc = CI->getOperand(0)) // CSPT = CastSrcPointerType
if (const PointerType *CSPT = dyn_cast<PointerType>(CastSrc->getType()))
- // convertable types?
- if (PtrElType->isLosslesslyConvertableTo(CSPT->getElementType())) {
+ // convertible types?
+ if (PtrElType->isLosslesslyConvertibleTo(CSPT->getElementType())) {
PRINT_PEEPHOLE2("load-src-cast:in ", Pointer, LI);
// Create the new load instruction... loading the pre-casted value