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 We
+ // just ask the constant propogator to see if it can convert the value...
+ //
+ if (Constant *CPV = dyn_cast<Constant>(V))
+ return ConstantFoldCastInstruction(CPV, Ty);
+
+
CTMap[V] = Ty;
if (V->getType() == Ty) return true; // Expression already correct type!
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). We just ask the constant propogator to see if
- // it can convert the value...
- //
- if (Constant *CPV = dyn_cast<Constant>(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:
//
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);
return false; // No match, maybe next time.
}
+ case Instruction::Call: {
+ if (isa<Function>(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<PointerType>(I->getOperand(0)->getType());
+ const FunctionType *FT = cast<FunctionType>(PT->getElementType());
+ std::vector<const Type *> ArgTys(FT->getParamTypes().begin(),
+ FT->getParamTypes().end());
+ const FunctionType *NewTy =
+ FunctionType::get(Ty, ArgTys, FT->isVarArg());
+ if (!ExpressionConvertableToType(I->getOperand(0),
+ PointerType::get(NewTy), CTMap))
+ return false;
+ break;
+ }
default:
return false;
}
DEBUG(cerr << "CETT: " << (void*)V << " " << V);
Instruction *I = dyn_cast<Instruction>(V);
- if (I == 0)
- if (Constant *CPV = cast<Constant>(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<Constant>(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;
+ }
BasicBlock *BB = I->getParent();
assert(Res && "Didn't find match!");
- break; // No match, maybe next time.
+ break;
}
+ case Instruction::Call: {
+ assert(!isa<Function>(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<PointerType>(I->getOperand(0)->getType());
+ const FunctionType *FT = cast<FunctionType>(PT->getElementType());
+ std::vector<const Type *> ArgTys(FT->getParamTypes().begin(),
+ FT->getParamTypes().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<Value*>(I->op_begin()+1, I->op_end()),
+ Name);
+ VMC.ExprMap[I] = Res;
+ Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), NewPTy, VMC));
+ break;
+ }
default:
assert(0 && "Expression convertable, but don't know how to convert?");
return 0;
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);
const FunctionType *NewTy = cast<FunctionType>(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