-namespace {
- struct VISIBILITY_HIDDEN ConstRules {
- ConstRules() {}
- virtual ~ConstRules() {}
-
- // Binary Operators...
- virtual Constant *add(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *sub(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *mul(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *urem(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *srem(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *frem(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *udiv(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *sdiv(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *fdiv(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *op_and(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *op_or (const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *op_xor(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *shl(const Constant *V1, const Constant *V2) const = 0;
- virtual Constant *shr(const Constant *V1, const Constant *V2) const = 0;
- 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.
- //
- static ConstRules &get(const Constant *V1, const Constant *V2);
- private:
- ConstRules(const ConstRules &); // Do not implement
- ConstRules &operator=(const ConstRules &); // Do not implement
- };
-}
-
-
-//===----------------------------------------------------------------------===//
-// TemplateRules Class
-//===----------------------------------------------------------------------===//
-//
-// TemplateRules - Implement a subclass of ConstRules that provides all
-// operations as noops. All other rules classes inherit from this class so
-// that if functionality is needed in the future, it can simply be added here
-// and to ConstRules without changing anything else...
-//
-// This class also provides subclasses with typesafe implementations of methods
-// so that don't have to do type casting.
-//
-namespace {
-template<class ArgType, class SubClassName>
-class VISIBILITY_HIDDEN TemplateRules : public ConstRules {
-
-
- //===--------------------------------------------------------------------===//
- // Redirecting functions that cast to the appropriate types
- //===--------------------------------------------------------------------===//
-
- virtual Constant *add(const Constant *V1, const Constant *V2) const {
- return SubClassName::Add((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *sub(const Constant *V1, const Constant *V2) const {
- return SubClassName::Sub((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *mul(const Constant *V1, const Constant *V2) const {
- return SubClassName::Mul((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *udiv(const Constant *V1, const Constant *V2) const {
- return SubClassName::UDiv((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *sdiv(const Constant *V1, const Constant *V2) const {
- return SubClassName::SDiv((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *fdiv(const Constant *V1, const Constant *V2) const {
- return SubClassName::FDiv((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *urem(const Constant *V1, const Constant *V2) const {
- return SubClassName::URem((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *srem(const Constant *V1, const Constant *V2) const {
- return SubClassName::SRem((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *frem(const Constant *V1, const Constant *V2) const {
- return SubClassName::FRem((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *op_and(const Constant *V1, const Constant *V2) const {
- return SubClassName::And((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *op_or(const Constant *V1, const Constant *V2) const {
- return SubClassName::Or((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *op_xor(const Constant *V1, const Constant *V2) const {
- return SubClassName::Xor((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *shl(const Constant *V1, const Constant *V2) const {
- return SubClassName::Shl((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *shr(const Constant *V1, const Constant *V2) const {
- return SubClassName::Shr((const ArgType *)V1, (const ArgType *)V2);
- }
-
- virtual Constant *lessthan(const Constant *V1, const Constant *V2) const {
- return SubClassName::LessThan((const ArgType *)V1, (const ArgType *)V2);
- }
- virtual Constant *equalto(const Constant *V1, const Constant *V2) const {
- 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
- //===--------------------------------------------------------------------===//
-
- static Constant *Add (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Sub (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Mul (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *SDiv(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *UDiv(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *FDiv(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *URem(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *SRem(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *FRem(const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *And (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Or (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Xor (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Shl (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *Shr (const ArgType *V1, const ArgType *V2) { return 0; }
- static Constant *LessThan(const ArgType *V1, const ArgType *V2) {
- return 0;
- }
- static Constant *EqualTo(const ArgType *V1, const ArgType *V2) {
- 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() {}
-};
-} // end anonymous namespace
-
-
-//===----------------------------------------------------------------------===//
-// EmptyRules Class
-//===----------------------------------------------------------------------===//
-//
-// EmptyRules provides a concrete base class of ConstRules that does nothing
-//
-namespace {
-struct VISIBILITY_HIDDEN EmptyRules
- : public TemplateRules<Constant, EmptyRules> {
- static Constant *EqualTo(const Constant *V1, const Constant *V2) {
- if (V1 == V2) return ConstantBool::getTrue();
- return 0;
- }
-};
-} // end anonymous namespace
-
-
-
-//===----------------------------------------------------------------------===//
-// BoolRules Class
-//===----------------------------------------------------------------------===//
-//
-// BoolRules provides a concrete base class of ConstRules for the 'bool' type.
-//
-namespace {
-struct VISIBILITY_HIDDEN BoolRules
- : public TemplateRules<ConstantBool, BoolRules> {
-
- static Constant *LessThan(const ConstantBool *V1, const ConstantBool *V2) {
- return ConstantBool::get(V1->getValue() < V2->getValue());
- }
-
- static Constant *EqualTo(const Constant *V1, const Constant *V2) {
- return ConstantBool::get(V1 == V2);
- }
-
- static Constant *And(const ConstantBool *V1, const ConstantBool *V2) {
- return ConstantBool::get(V1->getValue() & V2->getValue());
- }
-
- static Constant *Or(const ConstantBool *V1, const ConstantBool *V2) {
- return ConstantBool::get(V1->getValue() | V2->getValue());
- }
-
- 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
-
-
-//===----------------------------------------------------------------------===//
-// NullPointerRules Class
-//===----------------------------------------------------------------------===//
-//
-// NullPointerRules provides a concrete base class of ConstRules for null
-// pointers.
-//
-namespace {
-struct VISIBILITY_HIDDEN NullPointerRules
- : public TemplateRules<ConstantPointerNull, 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
-
-//===----------------------------------------------------------------------===//
-// ConstantPackedRules Class
-//===----------------------------------------------------------------------===//
-
-/// DoVectorOp - Given two packed constants and a function pointer, apply the
-/// function pointer to each element pair, producing a new ConstantPacked
-/// constant.
-static Constant *EvalVectorOp(const ConstantPacked *V1,
- const ConstantPacked *V2,
- Constant *(*FP)(Constant*, Constant*)) {
- std::vector<Constant*> Res;
- for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i)
- Res.push_back(FP(const_cast<Constant*>(V1->getOperand(i)),
- const_cast<Constant*>(V2->getOperand(i))));
- return ConstantPacked::get(Res);
-}
-
-/// PackedTypeRules provides a concrete base class of ConstRules for
-/// ConstantPacked operands.
-///
-namespace {
-struct VISIBILITY_HIDDEN ConstantPackedRules
- : public TemplateRules<ConstantPacked, ConstantPackedRules> {
-
- static Constant *Add(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getAdd);
- }
- static Constant *Sub(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getSub);
- }
- static Constant *Mul(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getMul);
- }
- static Constant *UDiv(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getUDiv);
- }
- static Constant *SDiv(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getSDiv);
- }
- static Constant *FDiv(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getFDiv);
- }
- static Constant *URem(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getURem);
- }
- static Constant *SRem(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getSRem);
- }
- static Constant *FRem(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getFRem);
- }
- static Constant *And(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getAnd);
- }
- static Constant *Or (const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getOr);
- }
- static Constant *Xor(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getXor);
- }
- static Constant *Shl(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getShl);
- }
- static Constant *Shr(const ConstantPacked *V1, const ConstantPacked *V2) {
- return EvalVectorOp(V1, V2, ConstantExpr::getShr);
- }
- static Constant *LessThan(const ConstantPacked *V1, const ConstantPacked *V2){
- return 0;
- }
- static Constant *EqualTo(const ConstantPacked *V1, const ConstantPacked *V2) {
- for (unsigned i = 0, e = V1->getNumOperands(); i != e; ++i) {
- Constant *C =
- ConstantExpr::getSetEQ(const_cast<Constant*>(V1->getOperand(i)),
- const_cast<Constant*>(V2->getOperand(i)));
- if (ConstantBool *CB = dyn_cast<ConstantBool>(C))
- return CB;
- }
- // Otherwise, could not decide from any element pairs.
- return 0;
- }
-};
-} // end anonymous namespace
-
-
-//===----------------------------------------------------------------------===//
-// GeneralPackedRules Class
-//===----------------------------------------------------------------------===//
-
-/// GeneralPackedRules provides a concrete base class of ConstRules for
-/// PackedType operands, where both operands are not ConstantPacked. The usual
-/// cause for this is that one operand is a ConstantAggregateZero.
-///
-namespace {
-struct VISIBILITY_HIDDEN GeneralPackedRules
- : public TemplateRules<Constant, GeneralPackedRules> {
-};
-} // end anonymous namespace
-
-
-//===----------------------------------------------------------------------===//
-// DirectIntRules Class
-//===----------------------------------------------------------------------===//
-//
-// DirectIntRules provides implementations of functions that are valid on
-// integer types, but not all types in general.
-//
-namespace {
-template <class BuiltinType, Type **Ty>
-struct VISIBILITY_HIDDEN DirectIntRules
- : public TemplateRules<ConstantInt, DirectIntRules<BuiltinType, Ty> > {
-
- static Constant *Add(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R = (BuiltinType)V1->getZExtValue() +
- (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *Sub(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R = (BuiltinType)V1->getZExtValue() -
- (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *Mul(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R = (BuiltinType)V1->getZExtValue() *
- (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *LessThan(const ConstantInt *V1, const ConstantInt *V2) {
- bool R = (BuiltinType)V1->getZExtValue() < (BuiltinType)V2->getZExtValue();
- return ConstantBool::get(R);
- }
-
- static Constant *EqualTo(const ConstantInt *V1, const ConstantInt *V2) {
- bool R = (BuiltinType)V1->getZExtValue() == (BuiltinType)V2->getZExtValue();
- 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;
- BuiltinType R = (BuiltinType)(V1->getZExtValue() / V2->getZExtValue());
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *SDiv(const ConstantInt *V1, const ConstantInt *V2) {
- if (V2->isNullValue()) // X / 0
- return 0;
- if (V2->isAllOnesValue() && // MIN_INT / -1
- (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue())
- return 0;
- BuiltinType R = (BuiltinType)(V1->getSExtValue() / V2->getSExtValue());
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *URem(const ConstantInt *V1,
- const ConstantInt *V2) {
- if (V2->isNullValue()) return 0; // X / 0
- BuiltinType R = (BuiltinType)(V1->getZExtValue() % V2->getZExtValue());
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *SRem(const ConstantInt *V1,
- const ConstantInt *V2) {
- if (V2->isNullValue()) return 0; // X % 0
- if (V2->isAllOnesValue() && // MIN_INT % -1
- (BuiltinType)V1->getSExtValue() == -(BuiltinType)V1->getSExtValue())
- return 0;
- BuiltinType R = (BuiltinType)(V1->getSExtValue() % V2->getSExtValue());
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *And(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R =
- (BuiltinType)V1->getZExtValue() & (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
- static Constant *Or(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R =
- (BuiltinType)V1->getZExtValue() | (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
- static Constant *Xor(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R =
- (BuiltinType)V1->getZExtValue() ^ (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *Shl(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R =
- (BuiltinType)V1->getZExtValue() << (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-
- static Constant *Shr(const ConstantInt *V1, const ConstantInt *V2) {
- BuiltinType R =
- (BuiltinType)V1->getZExtValue() >> (BuiltinType)V2->getZExtValue();
- return ConstantInt::get(*Ty, R);
- }
-};
-} // end anonymous namespace
-
-
-//===----------------------------------------------------------------------===//
-// DirectFPRules Class
-//===----------------------------------------------------------------------===//
-//
-/// DirectFPRules provides implementations of functions that are valid on
-/// floating point types, but not all types in general.
-///
-namespace {
-template <class BuiltinType, Type **Ty>
-struct VISIBILITY_HIDDEN DirectFPRules
- : public TemplateRules<ConstantFP, DirectFPRules<BuiltinType, Ty> > {
-
- static Constant *Add(const ConstantFP *V1, const ConstantFP *V2) {
- BuiltinType R = (BuiltinType)V1->getValue() +
- (BuiltinType)V2->getValue();
- return ConstantFP::get(*Ty, R);
- }
-
- static Constant *Sub(const ConstantFP *V1, const ConstantFP *V2) {
- BuiltinType R = (BuiltinType)V1->getValue() - (BuiltinType)V2->getValue();
- return ConstantFP::get(*Ty, R);
- }
-
- static Constant *Mul(const ConstantFP *V1, const ConstantFP *V2) {
- BuiltinType R = (BuiltinType)V1->getValue() * (BuiltinType)V2->getValue();
- return ConstantFP::get(*Ty, R);
- }
-
- static Constant *LessThan(const ConstantFP *V1, const ConstantFP *V2) {
- bool R = (BuiltinType)V1->getValue() < (BuiltinType)V2->getValue();
- return ConstantBool::get(R);
- }
-
- static Constant *EqualTo(const ConstantFP *V1, const ConstantFP *V2) {
- bool R = (BuiltinType)V1->getValue() == (BuiltinType)V2->getValue();
- 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(),
- (BuiltinType)V2->getValue());
- return ConstantFP::get(*Ty, Result);
- }
- static Constant *FDiv(const ConstantFP *V1, const ConstantFP *V2) {
- BuiltinType inf = std::numeric_limits<BuiltinType>::infinity();
- if (V2->isExactlyValue(0.0)) return ConstantFP::get(*Ty, inf);
- if (V2->isExactlyValue(-0.0)) return ConstantFP::get(*Ty, -inf);
- BuiltinType R = (BuiltinType)V1->getValue() / (BuiltinType)V2->getValue();
- return ConstantFP::get(*Ty, R);
- }
-};
-} // end anonymous namespace
-
-static ManagedStatic<EmptyRules> EmptyR;
-static ManagedStatic<BoolRules> BoolR;
-static ManagedStatic<NullPointerRules> NullPointerR;
-static ManagedStatic<ConstantPackedRules> ConstantPackedR;
-static ManagedStatic<GeneralPackedRules> GeneralPackedR;
-static ManagedStatic<DirectIntRules<signed char , &Type::SByteTy> > SByteR;
-static ManagedStatic<DirectIntRules<unsigned char , &Type::UByteTy> > UByteR;
-static ManagedStatic<DirectIntRules<signed short , &Type::ShortTy> > ShortR;
-static ManagedStatic<DirectIntRules<unsigned short, &Type::UShortTy> > UShortR;
-static ManagedStatic<DirectIntRules<signed int , &Type::IntTy> > IntR;
-static ManagedStatic<DirectIntRules<unsigned int , &Type::UIntTy> > UIntR;
-static ManagedStatic<DirectIntRules<int64_t , &Type::LongTy> > LongR;
-static ManagedStatic<DirectIntRules<uint64_t , &Type::ULongTy> > ULongR;
-static ManagedStatic<DirectFPRules <float , &Type::FloatTy> > FloatR;
-static ManagedStatic<DirectFPRules <double , &Type::DoubleTy> > DoubleR;
-
-/// ConstRules::get - This method returns the constant rules implementation that
-/// implements the semantics of the two specified constants.
-ConstRules &ConstRules::get(const Constant *V1, const Constant *V2) {
- if (isa<ConstantExpr>(V1) || isa<ConstantExpr>(V2) ||
- isa<GlobalValue>(V1) || isa<GlobalValue>(V2) ||
- isa<UndefValue>(V1) || isa<UndefValue>(V2))
- return *EmptyR;
-
- switch (V1->getType()->getTypeID()) {
- default: assert(0 && "Unknown value type for constant folding!");
- case Type::BoolTyID: return *BoolR;
- case Type::PointerTyID: return *NullPointerR;
- case Type::SByteTyID: return *SByteR;
- case Type::UByteTyID: return *UByteR;
- case Type::ShortTyID: return *ShortR;
- case Type::UShortTyID: return *UShortR;
- case Type::IntTyID: return *IntR;
- case Type::UIntTyID: return *UIntR;
- case Type::LongTyID: return *LongR;
- case Type::ULongTyID: return *ULongR;
- case Type::FloatTyID: return *FloatR;
- case Type::DoubleTyID: return *DoubleR;
- case Type::PackedTyID:
- if (isa<ConstantPacked>(V1) && isa<ConstantPacked>(V2))
- return *ConstantPackedR;
- return *GeneralPackedR; // Constant folding rules for ConstantAggregateZero.
- }
-}
-
-