Take a baby step towards getting rid of inferred casts. Provide methods on

CastInst and ConstantExpr that allow the signedness to be explicitly passed
in and reliance on signedness removed from getCastOpcode. These are
temporary measures useful during the conversion of inferred casts.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32164 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Reid Spencer 2006-12-04 02:43:42 +00:00
parent 75575fcfe4
commit 56667123b7
4 changed files with 58 additions and 14 deletions

View File

@ -541,8 +541,15 @@ public:
const Type *Ty ///< The type to which the constant is converted
);
// This method uses the CastInst::getCastOpcode method to infer the
// cast opcode to use.
// @brief Get a ConstantExpr Conversion operator that casts C to Ty
static Constant *getCast(Constant *C, const Type *Ty);
static Constant *getInferredCast(Constant *C, bool SrcIsSigned,
const Type *Ty, bool DestIsSigned);
static Constant *getCast(Constant *C, const Type *Ty) {
return getInferredCast(C, C->getType()->isSigned(), Ty, Ty->isSigned());
}
/// @brief Return true if this is a convert constant expression
bool isCast() const;

View File

@ -303,7 +303,9 @@ public:
/// rules.
static Instruction::CastOps getCastOpcode(
const Value *Val, ///< The value to cast
const Type *Ty ///< The Type to which the value should be casted
bool SrcIsSigned, ///< Whether to treat the source as signed
const Type *Ty, ///< The Type to which the value should be casted
bool DstIsSigned ///< Whether to treate the dest. as signed
);
/// Joins the create method (with insert-before-instruction semantics) above
@ -316,12 +318,21 @@ public:
/// @brief Inline helper method to join create with getCastOpcode.
inline static CastInst *createInferredCast(
Value *S, ///< The value to be casted (operand 0)
bool SrcIsSigned, ///< Whether to treat the source as signed
const Type *Ty, ///< Type to which operand should be casted
bool DstIsSigned, ///< Whether to treate the dest. as signed
const std::string &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the CastInst
) {
return create(getCastOpcode(S, Ty), S, Ty, Name, InsertBefore);
return create(getCastOpcode(S, SrcIsSigned, Ty, DstIsSigned),
S, Ty, Name, InsertBefore);
}
static CastInst *createInferredCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< Type to which operand should be casted
const std::string &Name = "", ///< Name for the instruction
Instruction *InsertBefore = 0 ///< Place to insert the CastInst
);
/// Joins the get method (with insert-at-end-of-block semantics) method
/// above with the getCastOpcode method. getOpcode(S,Ty) is called first to
@ -334,13 +345,23 @@ public:
/// @brief Inline helper method to join create with getCastOpcode.
inline static CastInst *createInferredCast(
Value *S, ///< The value to be casted (operand 0)
bool SrcIsSigned, ///< Whether to treat the source as signed
const Type *Ty, ///< Type to which operand should be casted
bool DstIsSigned, ///< Whether to treate the dest. as signed
const std::string &Name, ///< Name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
) {
return create(getCastOpcode(S, Ty), S, Ty, Name, InsertAtEnd);
return create(getCastOpcode(S, SrcIsSigned, Ty, DstIsSigned),
S, Ty, Name, InsertAtEnd);
}
static CastInst *createInferredCast(
Value *S, ///< The value to be casted (operand 0)
const Type *Ty, ///< Type to which operand should be casted
const std::string &Name, ///< Name for the instruction
BasicBlock *InsertAtEnd ///< The block to insert the instruction into
);
/// There are several places where we need to know if a cast instruction
/// only deals with integer source and destination types. To simplify that
/// logic, this method is provided.

View File

@ -1486,9 +1486,11 @@ static inline Constant *getFoldedCast(
return ExprConstants->getOrCreate(Ty, Key);
}
Constant *ConstantExpr::getCast( Constant *C, const Type *Ty ) {
Constant *ConstantExpr::getInferredCast(Constant *C, bool SrcIsSigned,
const Type *Ty, bool DestIsSigned) {
// Note: we can't inline this because it requires the Instructions.h header
return getCast(CastInst::getCastOpcode(C, Ty), C, Ty);
return getCast(
CastInst::getCastOpcode(C, SrcIsSigned, Ty, DestIsSigned), C, Ty);
}
Constant *ConstantExpr::getCast(unsigned oc, Constant *C, const Type *Ty) {
@ -1612,10 +1614,9 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) {
Constant *ConstantExpr::getSizeOf(const Type *Ty) {
// sizeof is implemented as: (ulong) gep (Ty*)null, 1
return getCast(
getGetElementPtr(getNullValue(PointerType::get(Ty)),
std::vector<Constant*>(1, ConstantInt::get(Type::UIntTy, 1))),
Type::ULongTy);
return getCast(Instruction::PtrToInt, getGetElementPtr(getNullValue(
PointerType::get(Ty)), std::vector<Constant*>(1,
ConstantInt::get(Type::UIntTy, 1))), Type::ULongTy);
}
Constant *ConstantExpr::getPtrPtrFromArrayPtr(Constant *C) {

View File

@ -1507,7 +1507,8 @@ CastInst *CastInst::create(Instruction::CastOps op, Value *S, const Type *Ty,
// should not assert in checkCast. In other words, this produces a "correct"
// casting opcode for the arguments passed to it.
Instruction::CastOps
CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
CastInst::getCastOpcode(
const Value *Src, bool SrcIsSigned, const Type *DestTy, bool DestIsSigned) {
// Get the bit sizes, we'll need these
const Type *SrcTy = Src->getType();
unsigned SrcBits = SrcTy->getPrimitiveSizeInBits(); // 0 for ptr/packed
@ -1519,7 +1520,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
if (DestBits < SrcBits)
return Trunc; // int -> smaller int
else if (DestBits > SrcBits) { // its an extension
if (SrcTy->isSigned())
if (SrcIsSigned)
return SExt; // signed -> SEXT
else
return ZExt; // unsigned -> ZEXT
@ -1527,7 +1528,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
return BitCast; // Same size, No-op cast
}
} else if (SrcTy->isFloatingPoint()) { // Casting from floating pt
if (DestTy->isSigned())
if (DestIsSigned)
return FPToSI; // FP -> sint
else
return FPToUI; // FP -> uint
@ -1542,7 +1543,7 @@ CastInst::getCastOpcode(const Value *Src, const Type *DestTy) {
}
} else if (DestTy->isFloatingPoint()) { // Casting to floating pt
if (SrcTy->isIntegral()) { // Casting from integral
if (SrcTy->isSigned())
if (SrcIsSigned)
return SIToFP; // sint -> FP
else
return UIToFP; // uint -> FP
@ -1649,6 +1650,20 @@ checkCast(Instruction::CastOps op, Value *S, const Type *DstTy) {
}
}
CastInst *CastInst::createInferredCast(
Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore)
{
return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
Name, InsertBefore);
}
CastInst *CastInst::createInferredCast(
Value *S, const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
{
return createInferredCast(S, S->getType()->isSigned(), Ty, Ty->isSigned(),
Name, InsertAtEnd);
}
TruncInst::TruncInst(
Value *S, const Type *Ty, const std::string &Name, Instruction *InsertBefore
) : CastInst(Ty, Trunc, S, Name, InsertBefore) {