aboutsummaryrefslogtreecommitdiff
path: root/lib/VMCore/ConstantFold.cpp
diff options
context:
space:
mode:
authorReid Spencer <rspencer@reidspencer.com>2006-12-19 03:15:47 +0000
committerReid Spencer <rspencer@reidspencer.com>2006-12-19 03:15:47 +0000
commit390437fc6d6e7a244e7c81683576e7d27a425cea (patch)
tree153f959ac127f1e5bf0c448adb0e5b21e8d759b8 /lib/VMCore/ConstantFold.cpp
parent0b985dc84a457225033f5276e53f618d815d74ae (diff)
Rewrite ConstantFoldCastInstruction so that it doesn't use any of the
ConstRules. Remove the casting rules from ConstRules and subclasses. This cleans up ConstantFolding significantly. Passes all tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32671 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/ConstantFold.cpp')
-rw-r--r--lib/VMCore/ConstantFold.cpp269
1 files changed, 50 insertions, 219 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 170df73272..29910b7bc9 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -54,21 +54,6 @@ namespace {
virtual Constant *lessthan(const Constant *V1, const Constant *V2) const =0;
virtual Constant *equalto(const Constant *V1, const Constant *V2) const = 0;
- // Casting operators.
- virtual Constant *castToBool (const Constant *V) const = 0;
- virtual Constant *castToSByte (const Constant *V) const = 0;
- virtual Constant *castToUByte (const Constant *V) const = 0;
- virtual Constant *castToShort (const Constant *V) const = 0;
- virtual Constant *castToUShort(const Constant *V) const = 0;
- virtual Constant *castToInt (const Constant *V) const = 0;
- virtual Constant *castToUInt (const Constant *V) const = 0;
- virtual Constant *castToLong (const Constant *V) const = 0;
- virtual Constant *castToULong (const Constant *V) const = 0;
- virtual Constant *castToFloat (const Constant *V) const = 0;
- virtual Constant *castToDouble(const Constant *V) const = 0;
- virtual Constant *castToPointer(const Constant *V,
- const PointerType *Ty) const = 0;
-
// ConstRules::get - Return an instance of ConstRules for the specified
// constant operands.
//
@@ -154,44 +139,6 @@ class VISIBILITY_HIDDEN TemplateRules : public ConstRules {
return SubClassName::EqualTo((const ArgType *)V1, (const ArgType *)V2);
}
- // Casting operators. ick
- virtual Constant *castToBool(const Constant *V) const {
- return SubClassName::CastToBool((const ArgType*)V);
- }
- virtual Constant *castToSByte(const Constant *V) const {
- return SubClassName::CastToSByte((const ArgType*)V);
- }
- virtual Constant *castToUByte(const Constant *V) const {
- return SubClassName::CastToUByte((const ArgType*)V);
- }
- virtual Constant *castToShort(const Constant *V) const {
- return SubClassName::CastToShort((const ArgType*)V);
- }
- virtual Constant *castToUShort(const Constant *V) const {
- return SubClassName::CastToUShort((const ArgType*)V);
- }
- virtual Constant *castToInt(const Constant *V) const {
- return SubClassName::CastToInt((const ArgType*)V);
- }
- virtual Constant *castToUInt(const Constant *V) const {
- return SubClassName::CastToUInt((const ArgType*)V);
- }
- virtual Constant *castToLong(const Constant *V) const {
- return SubClassName::CastToLong((const ArgType*)V);
- }
- virtual Constant *castToULong(const Constant *V) const {
- return SubClassName::CastToULong((const ArgType*)V);
- }
- virtual Constant *castToFloat(const Constant *V) const {
- return SubClassName::CastToFloat((const ArgType*)V);
- }
- virtual Constant *castToDouble(const Constant *V) const {
- return SubClassName::CastToDouble((const ArgType*)V);
- }
- virtual Constant *castToPointer(const Constant *V,
- const PointerType *Ty) const {
- return SubClassName::CastToPointer((const ArgType*)V, Ty);
- }
//===--------------------------------------------------------------------===//
// Default "noop" implementations
@@ -219,21 +166,6 @@ class VISIBILITY_HIDDEN TemplateRules : public ConstRules {
return 0;
}
- // Casting operators. ick
- static Constant *CastToBool (const Constant *V) { return 0; }
- static Constant *CastToSByte (const Constant *V) { return 0; }
- static Constant *CastToUByte (const Constant *V) { return 0; }
- static Constant *CastToShort (const Constant *V) { return 0; }
- static Constant *CastToUShort(const Constant *V) { return 0; }
- static Constant *CastToInt (const Constant *V) { return 0; }
- static Constant *CastToUInt (const Constant *V) { return 0; }
- static Constant *CastToLong (const Constant *V) { return 0; }
- static Constant *CastToULong (const Constant *V) { return 0; }
- static Constant *CastToFloat (const Constant *V) { return 0; }
- static Constant *CastToDouble(const Constant *V) { return 0; }
- static Constant *CastToPointer(const Constant *,
- const PointerType *) {return 0;}
-
public:
virtual ~TemplateRules() {}
};
@@ -287,25 +219,6 @@ struct VISIBILITY_HIDDEN BoolRules
static Constant *Xor(const ConstantBool *V1, const ConstantBool *V2) {
return ConstantBool::get(V1->getValue() ^ V2->getValue());
}
-
- // Casting operators. ick
-#define DEF_CAST(TYPE, CLASS, CTYPE) \
- static Constant *CastTo##TYPE (const ConstantBool *V) { \
- return CLASS::get(Type::TYPE##Ty, (CTYPE)(bool)V->getValue()); \
- }
-
- DEF_CAST(Bool , ConstantBool, bool)
- DEF_CAST(SByte , ConstantInt, signed char)
- DEF_CAST(UByte , ConstantInt, unsigned char)
- DEF_CAST(Short , ConstantInt, signed short)
- DEF_CAST(UShort, ConstantInt, unsigned short)
- DEF_CAST(Int , ConstantInt, signed int)
- DEF_CAST(UInt , ConstantInt, unsigned int)
- DEF_CAST(Long , ConstantInt, int64_t)
- DEF_CAST(ULong , ConstantInt, uint64_t)
- DEF_CAST(Float , ConstantFP , float)
- DEF_CAST(Double, ConstantFP , double)
-#undef DEF_CAST
};
} // end anonymous namespace
@@ -323,44 +236,6 @@ struct VISIBILITY_HIDDEN NullPointerRules
static Constant *EqualTo(const Constant *V1, const Constant *V2) {
return ConstantBool::getTrue(); // Null pointers are always equal
}
- static Constant *CastToBool(const Constant *V) {
- return ConstantBool::getFalse();
- }
- static Constant *CastToSByte (const Constant *V) {
- return ConstantInt::get(Type::SByteTy, 0);
- }
- static Constant *CastToUByte (const Constant *V) {
- return ConstantInt::get(Type::UByteTy, 0);
- }
- static Constant *CastToShort (const Constant *V) {
- return ConstantInt::get(Type::ShortTy, 0);
- }
- static Constant *CastToUShort(const Constant *V) {
- return ConstantInt::get(Type::UShortTy, 0);
- }
- static Constant *CastToInt (const Constant *V) {
- return ConstantInt::get(Type::IntTy, 0);
- }
- static Constant *CastToUInt (const Constant *V) {
- return ConstantInt::get(Type::UIntTy, 0);
- }
- static Constant *CastToLong (const Constant *V) {
- return ConstantInt::get(Type::LongTy, 0);
- }
- static Constant *CastToULong (const Constant *V) {
- return ConstantInt::get(Type::ULongTy, 0);
- }
- static Constant *CastToFloat (const Constant *V) {
- return ConstantFP::get(Type::FloatTy, 0);
- }
- static Constant *CastToDouble(const Constant *V) {
- return ConstantFP::get(Type::DoubleTy, 0);
- }
-
- static Constant *CastToPointer(const ConstantPointerNull *V,
- const PointerType *PTy) {
- return ConstantPointerNull::get(PTy);
- }
};
} // end anonymous namespace
@@ -497,32 +372,6 @@ struct VISIBILITY_HIDDEN DirectIntRules
return ConstantBool::get(R);
}
- static Constant *CastToPointer(const ConstantInt *V,
- const PointerType *PTy) {
- if (V->isNullValue()) // Is it a FP or Integral null value?
- return ConstantPointerNull::get(PTy);
- return 0; // Can't const prop other types of pointers
- }
-
- // Casting operators. ick
-#define DEF_CAST(TYPE, CLASS, CTYPE) \
- static Constant *CastTo##TYPE (const ConstantInt *V) { \
- return CLASS::get(Type::TYPE##Ty, (CTYPE)((BuiltinType)V->getZExtValue()));\
- }
-
- DEF_CAST(Bool , ConstantBool, bool)
- DEF_CAST(SByte , ConstantInt, signed char)
- DEF_CAST(UByte , ConstantInt, unsigned char)
- DEF_CAST(Short , ConstantInt, signed short)
- DEF_CAST(UShort, ConstantInt, unsigned short)
- DEF_CAST(Int , ConstantInt, signed int)
- DEF_CAST(UInt , ConstantInt, unsigned int)
- DEF_CAST(Long , ConstantInt, int64_t)
- DEF_CAST(ULong , ConstantInt, uint64_t)
- DEF_CAST(Float , ConstantFP , float)
- DEF_CAST(Double, ConstantFP , double)
-#undef DEF_CAST
-
static Constant *UDiv(const ConstantInt *V1, const ConstantInt *V2) {
if (V2->isNullValue()) // X / 0
return 0;
@@ -630,32 +479,6 @@ struct VISIBILITY_HIDDEN DirectFPRules
return ConstantBool::get(R);
}
- static Constant *CastToPointer(const ConstantFP *V,
- const PointerType *PTy) {
- if (V->isNullValue()) // Is it a FP or Integral null value?
- return ConstantPointerNull::get(PTy);
- return 0; // Can't const prop other types of pointers
- }
-
- // Casting operators. ick
-#define DEF_CAST(TYPE, CLASS, CTYPE) \
- static Constant *CastTo##TYPE (const ConstantFP *V) { \
- return CLASS::get(Type::TYPE##Ty, (CTYPE)(BuiltinType)V->getValue()); \
- }
-
- DEF_CAST(Bool , ConstantBool, bool)
- DEF_CAST(SByte , ConstantInt, signed char)
- DEF_CAST(UByte , ConstantInt, unsigned char)
- DEF_CAST(Short , ConstantInt, signed short)
- DEF_CAST(UShort, ConstantInt, unsigned short)
- DEF_CAST(Int , ConstantInt, signed int)
- DEF_CAST(UInt , ConstantInt, unsigned int)
- DEF_CAST(Long , ConstantInt, int64_t)
- DEF_CAST(ULong , ConstantInt, uint64_t)
- DEF_CAST(Float , ConstantFP , float)
- DEF_CAST(Double, ConstantFP , double)
-#undef DEF_CAST
-
static Constant *FRem(const ConstantFP *V1, const ConstantFP *V2) {
if (V2->isNullValue()) return 0;
BuiltinType Result = std::fmod((BuiltinType)V1->getValue(),
@@ -852,43 +675,67 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
}
}
- // We actually have to do a cast now, but first, we might need to fix up
- // the value of the operand.
+ // We actually have to do a cast now. Perform the cast according to the
+ // opcode specified.
switch (opc) {
- case Instruction::PtrToInt:
case Instruction::FPTrunc:
case Instruction::FPExt:
- break;
+ return ConstantFP::get(DestTy, cast<ConstantFP>(V)->getValue());
case Instruction::FPToUI: {
- ConstRules &Rules = ConstRules::get(V, V);
- V = Rules.castToULong(V); // make sure we get an unsigned value first
- break;
+ double dVal = cast<ConstantFP>(V)->getValue();
+ uint64_t iVal = (uint64_t) dVal;
+ return ConstantIntegral::get(DestTy, iVal);
}
case Instruction::FPToSI: {
- ConstRules &Rules = ConstRules::get(V, V);
- V = Rules.castToLong(V); // make sure we get a signed value first
- break;
+ double dVal = cast<ConstantFP>(V)->getValue();
+ int64_t iVal = (int64_t) dVal;
+ return ConstantIntegral::get(DestTy, iVal);
}
case Instruction::IntToPtr: //always treated as unsigned
- case Instruction::UIToFP:
+ if (V->isNullValue()) // Is it a FP or Integral null value?
+ return ConstantPointerNull::get(cast<PointerType>(DestTy));
+ return 0; // Other pointer types cannot be casted
+ case Instruction::PtrToInt: // always treated as unsigned
+ if (V->isNullValue())
+ return ConstantIntegral::get(DestTy, 0);
+ return 0; // Other pointer types cannot be casted
+ case Instruction::UIToFP: {
+ // First, extract the unsigned integer value
+ uint64_t Val;
+ if (isa<ConstantInt>(V))
+ Val = cast<ConstantIntegral>(V)->getZExtValue();
+ else if (const ConstantBool *CB = dyn_cast<ConstantBool>(V))
+ Val = CB->getValue() ? 1 : 0;
+ // Now generate the equivalent floating point value
+ double dVal = (double) Val;
+ return ConstantFP::get(DestTy, dVal);
+ }
+ case Instruction::SIToFP: {
+ // First, extract the signed integer value
+ int64_t Val;
+ if (isa<ConstantInt>(V))
+ Val = cast<ConstantIntegral>(V)->getSExtValue();
+ else if (const ConstantBool *CB = dyn_cast<ConstantBool>(V))
+ Val = CB->getValue() ? -1 : 0;
+ // Now generate the equivalent floating point value
+ double dVal = (double) Val;
+ return ConstantFP::get(DestTy, dVal);
+ }
case Instruction::ZExt:
- // A ZExt always produces an unsigned value so we need to cast the value
- // now before we try to cast it to the destination type
+ // Handle trunc directly here if it is a ConstantIntegral.
if (isa<ConstantInt>(V))
- V = ConstantInt::get(SrcTy->getUnsignedVersion(),
- cast<ConstantIntegral>(V)->getZExtValue());
- break;
- case Instruction::SIToFP:
+ return ConstantInt::get(DestTy, cast<ConstantInt>(V)->getZExtValue());
+ else if (const ConstantBool *CB = dyn_cast<ConstantBool>(V))
+ return ConstantInt::get(DestTy, CB->getValue() ? 1 : 0);
+ return 0;
case Instruction::SExt:
// A SExt always produces a signed value so we need to cast the value
// now before we try to cast it to the destiniation type.
if (isa<ConstantInt>(V))
- V = ConstantInt::get(SrcTy->getSignedVersion(),
- cast<ConstantIntegral>(V)->getSExtValue());
+ return ConstantInt::get(DestTy, cast<ConstantInt>(V)->getSExtValue());
else if (const ConstantBool *CB = dyn_cast<ConstantBool>(V))
- V = ConstantInt::get(Type::SByteTy, CB->getValue() ? -1 : 0);
-
- break;
+ return ConstantInt::get(DestTy, CB->getValue() ? -1 : 0);
+ return 0;
case Instruction::Trunc:
// We just handle trunc directly here. The code below doesn't work for
// trunc to bool.
@@ -896,7 +743,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
return ConstantIntegral::get(DestTy, CI->getZExtValue());
return 0;
case Instruction::BitCast:
- if (SrcTy == DestTy) return (Constant*)V; // no-op cast
+ if (SrcTy == DestTy)
+ return (Constant*)V; // no-op cast
// Check to see if we are casting a pointer to an aggregate to a pointer to
// the first element. If so, return the appropriate GEP instruction.
@@ -995,25 +843,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,
break;
}
- // Okay, no more folding possible, time to cast
- ConstRules &Rules = ConstRules::get(V, V);
- switch (DestTy->getTypeID()) {
- case Type::BoolTyID: return Rules.castToBool(V);
- case Type::UByteTyID: return Rules.castToUByte(V);
- case Type::SByteTyID: return Rules.castToSByte(V);
- case Type::UShortTyID: return Rules.castToUShort(V);
- case Type::ShortTyID: return Rules.castToShort(V);
- case Type::UIntTyID: return Rules.castToUInt(V);
- case Type::IntTyID: return Rules.castToInt(V);
- case Type::ULongTyID: return Rules.castToULong(V);
- case Type::LongTyID: return Rules.castToLong(V);
- case Type::FloatTyID: return Rules.castToFloat(V);
- case Type::DoubleTyID: return Rules.castToDouble(V);
- case Type::PointerTyID:
- return Rules.castToPointer(V, cast<PointerType>(DestTy));
- // what about packed ?
- default: return 0;
- }
+ assert(0 && "Failed to cast constant expression");
+ return 0;
}
Constant *llvm::ConstantFoldSelectInstruction(const Constant *Cond,