//===- 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
// convertible, other routines from this file will do the conversion.
//
//===----------------------------------------------------------------------===//
#include "TransformInternals.h"
#include "llvm/Constants.h"
#include "llvm/Instructions.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
#include <algorithm>
using namespace llvm;
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, const TargetData &TD);
// 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;
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 (isa<Constant>(V) && !isa<GlobalValue>(V))
return true;
CTMap[V] = Ty;
if (V->getType() == Ty) return true; // Expression already correct type!
Instruction *I = dyn_cast<Instruction>(V);
if (I == 0) return false; // Otherwise, we can't convert!
switch (I->getOpcode()) {
case Instruction::BitCast:
if (!cast<BitCastInst>(I)->isLosslessCast())
return false;
// We 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 * *
//
if (const PointerType *SPT =
dyn_cast<PointerType>(I->getOperand(0)->getType()))
if (const PointerType *DPT = dyn_cast<PointerType>(I->getType()))
if (const ArrayType *AT = dyn_cast<ArrayType>(SPT->getElementType()))
if (AT->getElementType() == DPT->getElementType())
return false;
// Otherwise it is a lossless cast and we can allow it
break;
case Instruction::Add:
case Instruction::Sub:
if (!Ty->isInteger() && !Ty->isFloatingPoint()) return false;
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD) ||
!ExpressionConvertibleToType(I->getOperand(1), Ty, CTMap, TD))
return false;
break;
case Instruction::LShr:
case Instruction::AShr:
if (!Ty->isInteger()) return false;
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
return false;
break;
case Instruction::Shl:
if (!Ty->isInteger()) return false;
if (!ExpressionConvertibleToType(I->getOperand(0), Ty, CTMap, TD))
return false;
break;
case Instruction::Load: {
LoadInst *LI = cast<LoadInst>(I);
if (!ExpressionConvertibleToType(LI->getPointerOperand(),
PointerType::get(Ty), CTMap, TD))
return false;
break;
}
case Instruction::PHI: {
PHINode *PN = cast<PHINode>(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 (!ExpressionConvertibleToType(PN->ge