// Static constructor to create a '0' constant of arbitrary type...
Constant *Constant::getNullValue(const Type *Ty) {
+ static uint64_t zero[2] = {0, 0};
switch (Ty->getTypeID()) {
case Type::IntegerTyID:
return ConstantInt::get(Ty, 0);
case Type::FloatTyID:
+ return ConstantFP::get(Ty, APFloat(APInt(32, 0)));
case Type::DoubleTyID:
+ return ConstantFP::get(Ty, APFloat(APInt(64, 0)));
case Type::X86_FP80TyID:
- case Type::PPC_FP128TyID:
+ return ConstantFP::get(Ty, APFloat(APInt(80, 2, zero)));
case Type::FP128TyID:
- return ConstantFP::get(Ty, 0.0);
+ case Type::PPC_FP128TyID:
+ return ConstantFP::get(Ty, APFloat(APInt(128, 2, zero)));
case Type::PointerTyID:
return ConstantPointerNull::get(cast<PointerType>(Ty));
case Type::StructTyID:
static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), 0); }
static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), 0); }
static unsigned getHashValue(const KeyTy &Key) {
- return DenseMapKeyInfo<void*>::getHashValue(Key.type) ^
+ return DenseMapInfo<void*>::getHashValue(Key.type) ^
Key.val.getHashValue();
}
- static bool isPod() { return true; }
+ static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+ return LHS == RHS;
+ }
+ static bool isPod() { return false; }
};
}
// ConstantFP
//===----------------------------------------------------------------------===//
-
-ConstantFP::ConstantFP(const Type *Ty, double V)
- : Constant(Ty, ConstantFPVal, 0, 0) {
- Val = V;
+ConstantFP::ConstantFP(const Type *Ty, const APFloat& V)
+ : Constant(Ty, ConstantFPVal, 0, 0), Val(V) {
+ // temporary
+ if (Ty==Type::FloatTy)
+ assert(&V.getSemantics()==&APFloat::IEEEsingle);
+ else if (Ty==Type::DoubleTy)
+ assert(&V.getSemantics()==&APFloat::IEEEdouble);
+ else if (Ty==Type::X86_FP80Ty)
+ assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+ else if (Ty==Type::FP128Ty)
+ assert(&V.getSemantics()==&APFloat::IEEEquad);
+ else
+ assert(0);
}
bool ConstantFP::isNullValue() const {
- return DoubleToBits(Val) == 0;
+ return Val.isZero() && !Val.isNegative();
}
-bool ConstantFP::isExactlyValue(double V) const {
- return DoubleToBits(V) == DoubleToBits(Val);
+ConstantFP *ConstantFP::getNegativeZero(const Type *Ty) {
+ APFloat apf = cast <ConstantFP>(Constant::getNullValue(Ty))->getValueAPF();
+ apf.changeSign();
+ return ConstantFP::get(Ty, apf);
}
+bool ConstantFP::isExactlyValue(const APFloat& V) const {
+ return Val.bitwiseIsEqual(V);
+}
namespace {
- struct DenseMapInt64KeyInfo {
- typedef std::pair<uint64_t, const Type*> KeyTy;
- static inline KeyTy getEmptyKey() { return KeyTy(0, 0); }
- static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); }
- static unsigned getHashValue(const KeyTy &Key) {
- return DenseMapKeyInfo<void*>::getHashValue(Key.second) ^ Key.first;
+ struct DenseMapAPFloatKeyInfo {
+ struct KeyTy {
+ APFloat val;
+ KeyTy(const APFloat& V) : val(V){}
+ KeyTy(const KeyTy& that) : val(that.val) {}
+ bool operator==(const KeyTy& that) const {
+ return this->val.bitwiseIsEqual(that.val);
+ }
+ bool operator!=(const KeyTy& that) const {
+ return !this->operator==(that);
+ }
+ };
+ static inline KeyTy getEmptyKey() {
+ return KeyTy(APFloat(APFloat::Bogus,1));
+ }
+ static inline KeyTy getTombstoneKey() {
+ return KeyTy(APFloat(APFloat::Bogus,2));
}
- static bool isPod() { return true; }
- };
- struct DenseMapInt32KeyInfo {
- typedef std::pair<uint32_t, const Type*> KeyTy;
- static inline KeyTy getEmptyKey() { return KeyTy(0, 0); }
- static inline KeyTy getTombstoneKey() { return KeyTy(1, 0); }
static unsigned getHashValue(const KeyTy &Key) {
- return DenseMapKeyInfo<void*>::getHashValue(Key.second) ^ Key.first;
+ return Key.val.getHashValue();
+ }
+ static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) {
+ return LHS == RHS;
}
- static bool isPod() { return true; }
+ static bool isPod() { return false; }
};
}
//---- ConstantFP::get() implementation...
//
-typedef DenseMap<DenseMapInt32KeyInfo::KeyTy, ConstantFP*,
- DenseMapInt32KeyInfo> FloatMapTy;
-typedef DenseMap<DenseMapInt64KeyInfo::KeyTy, ConstantFP*,
- DenseMapInt64KeyInfo> DoubleMapTy;
-
-static ManagedStatic<FloatMapTy> FloatConstants;
-static ManagedStatic<DoubleMapTy> DoubleConstants;
-
-ConstantFP *ConstantFP::get(const Type *Ty, double V) {
- if (Ty == Type::FloatTy) {
- uint32_t IntVal = FloatToBits((float)V);
-
- ConstantFP *&Slot = (*FloatConstants)[std::make_pair(IntVal, Ty)];
- if (Slot) return Slot;
- return Slot = new ConstantFP(Ty, (float)V);
- } else if (Ty == Type::DoubleTy) {
- uint64_t IntVal = DoubleToBits(V);
- ConstantFP *&Slot = (*DoubleConstants)[std::make_pair(IntVal, Ty)];
- if (Slot) return Slot;
- return Slot = new ConstantFP(Ty, V);
- // FIXME: Make long double constants work.
- } else if (Ty == Type::X86_FP80Ty ||
- Ty == Type::PPC_FP128Ty || Ty == Type::FP128Ty) {
- assert(0 && "Long double constants not handled yet.");
- } else {
- assert(0 && "Unknown FP Type!");
- }
+typedef DenseMap<DenseMapAPFloatKeyInfo::KeyTy, ConstantFP*,
+ DenseMapAPFloatKeyInfo> FPMapTy;
+
+static ManagedStatic<FPMapTy> FPConstants;
+
+ConstantFP *ConstantFP::get(const Type *Ty, const APFloat& V) {
+ // temporary
+ if (Ty==Type::FloatTy)
+ assert(&V.getSemantics()==&APFloat::IEEEsingle);
+ else if (Ty==Type::DoubleTy)
+ assert(&V.getSemantics()==&APFloat::IEEEdouble);
+ else if (Ty==Type::X86_FP80Ty)
+ assert(&V.getSemantics()==&APFloat::x87DoubleExtended);
+ else if (Ty==Type::FP128Ty)
+ assert(&V.getSemantics()==&APFloat::IEEEquad);
+ else
+ assert(0);
+
+ DenseMapAPFloatKeyInfo::KeyTy Key(V);
+ ConstantFP *&Slot = (*FPConstants)[Key];
+ if (Slot) return Slot;
+ return Slot = new ConstantFP(Ty, V);
}
-
//===----------------------------------------------------------------------===//
// ConstantXXX Classes
//===----------------------------------------------------------------------===//
return (Val >= Min && Val <= Max);
}
-bool ConstantFP::isValueValidForType(const Type *Ty, double Val) {
+bool ConstantFP::isValueValidForType(const Type *Ty, const APFloat& Val) {
+ // convert modifies in place, so make a copy.
+ APFloat Val2 = APFloat(Val);
switch (Ty->getTypeID()) {
default:
return false; // These can't be represented as floating point!
- // TODO: Figure out how to test if we can use a shorter type instead!
+ // FIXME rounding mode needs to be more flexible
case Type::FloatTyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ Val2.convert(APFloat::IEEEsingle, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
case Type::DoubleTyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ Val2.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven) ==
+ APFloat::opOK;
case Type::X86_FP80TyID:
- case Type::PPC_FP128TyID:
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ &Val2.getSemantics() == &APFloat::x87DoubleExtended;
case Type::FP128TyID:
- return true;
+ return &Val2.getSemantics() == &APFloat::IEEEsingle ||
+ &Val2.getSemantics() == &APFloat::IEEEdouble ||
+ &Val2.getSemantics() == &APFloat::IEEEquad;
}
}
Constant *ConstantExpr::getGetElementPtrTy(const Type *ReqTy, Constant *C,
Value* const *Idxs,
unsigned NumIdx) {
- assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, NumIdx, true) &&
+ assert(GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true) &&
"GEP indices invalid!");
if (Constant *FC = ConstantFoldGetElementPtr(C, (Constant**)Idxs, NumIdx))
unsigned NumIdx) {
// Get the result type of the getelementptr!
const Type *Ty =
- GetElementPtrInst::getIndexedType(C->getType(), Idxs, NumIdx, true);
+ GetElementPtrInst::getIndexedType(C->getType(), Idxs, Idxs+NumIdx, true);
assert(Ty && "GEP indices invalid!");
return getGetElementPtrTy(PointerType::get(Ty), C, Idxs, NumIdx);
}
if (const VectorType *PTy = dyn_cast<VectorType>(Ty))
if (PTy->getElementType()->isFloatingPoint()) {
std::vector<Constant*> zeros(PTy->getNumElements(),
- ConstantFP::get(PTy->getElementType(),-0.0));
+ ConstantFP::getNegativeZero(PTy->getElementType()));
return ConstantVector::get(PTy, zeros);
}
- if (Ty->isFloatingPoint())
- return ConstantFP::get(Ty, -0.0);
+ if (Ty->isFloatingPoint())
+ return ConstantFP::getNegativeZero(Ty);
return Constant::getNullValue(Ty);
}