From d46a8180c0381f3fc0b0d34e718d1528a5b8ece9 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 6 Dec 2014 00:02:31 +0000 Subject: [PATCH] Revert "LLVMContext: Store APInt/APFloat directly into the ConstantInt/FP DenseMaps." Somehow made DenseMap probe on forever on 32 bit machines. This reverts commit r223478. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223546 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/APInt.h | 3 +- lib/IR/Constants.cpp | 19 +++++++------ lib/IR/LLVMContextImpl.h | 61 ++++++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 26 deletions(-) diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 025397d9ce4..f4e7e3c6356 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -91,8 +91,6 @@ class APInt { APINT_WORD_SIZE = static_cast(sizeof(uint64_t)) }; - friend struct DenseMapAPIntKeyInfo; - /// \brief Fast internal constructor /// /// This constructor is used only internally for speed of construction of @@ -279,6 +277,7 @@ public: /// Simply makes *this a copy of that. /// @brief Copy Constructor. APInt(const APInt &that) : BitWidth(that.BitWidth), VAL(0) { + assert(BitWidth && "bitwidth too small"); if (isSingleWord()) VAL = that.VAL; else diff --git a/lib/IR/Constants.cpp b/lib/IR/Constants.cpp index c4b18adc616..e0cb835c2c6 100644 --- a/lib/IR/Constants.cpp +++ b/lib/IR/Constants.cpp @@ -555,17 +555,18 @@ Constant *ConstantInt::getFalse(Type *Ty) { } -// Get a ConstantInt from an APInt. +// Get a ConstantInt from an APInt. Note that the value stored in the DenseMap +// as the key, is a DenseMapAPIntKeyInfo::KeyTy which has provided the +// operator== and operator!= to ensure that the DenseMap doesn't attempt to +// compare APInt's of different widths, which would violate an APInt class +// invariant which generates an assertion. ConstantInt *ConstantInt::get(LLVMContext &Context, const APInt &V) { + // Get the corresponding integer type for the bit width of the value. + IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); // get an existing value or the insertion position LLVMContextImpl *pImpl = Context.pImpl; - ConstantInt *&Slot = pImpl->IntConstants[V]; - if (!Slot) { - // Get the corresponding integer type for the bit width of the value. - IntegerType *ITy = IntegerType::get(Context, V.getBitWidth()); - Slot = new ConstantInt(ITy, V); - } - assert(Slot->getType() == IntegerType::get(Context, V.getBitWidth())); + ConstantInt *&Slot = pImpl->IntConstants[DenseMapAPIntKeyInfo::KeyTy(V, ITy)]; + if (!Slot) Slot = new ConstantInt(ITy, V); return Slot; } @@ -688,7 +689,7 @@ Constant *ConstantFP::getZeroValueForNegation(Type *Ty) { ConstantFP* ConstantFP::get(LLVMContext &Context, const APFloat& V) { LLVMContextImpl* pImpl = Context.pImpl; - ConstantFP *&Slot = pImpl->FPConstants[V]; + ConstantFP *&Slot = pImpl->FPConstants[DenseMapAPFloatKeyInfo::KeyTy(V)]; if (!Slot) { Type *Ty; diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h index 41822f0d106..5fd8683ccaf 100644 --- a/lib/IR/LLVMContextImpl.h +++ b/lib/IR/LLVMContextImpl.h @@ -46,26 +46,55 @@ class Type; class Value; struct DenseMapAPIntKeyInfo { - static inline APInt getEmptyKey() { return APInt(nullptr, 0); } - static inline APInt getTombstoneKey() { - return APInt(reinterpret_cast(sizeof(uint64_t)), 0); - } - static unsigned getHashValue(const APInt &Key) { + struct KeyTy { + APInt val; + Type* type; + KeyTy(const APInt& V, Type* Ty) : val(V), type(Ty) {} + bool operator==(const KeyTy& that) const { + return type == that.type && this->val == that.val; + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + friend hash_code hash_value(const KeyTy &Key) { + return hash_combine(Key.type, Key.val); + } + }; + static inline KeyTy getEmptyKey() { return KeyTy(APInt(1,0), nullptr); } + static inline KeyTy getTombstoneKey() { return KeyTy(APInt(1,1), nullptr); } + static unsigned getHashValue(const KeyTy &Key) { return static_cast(hash_value(Key)); } - static bool isEqual(const APInt &LHS, const APInt &RHS) { - return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS; + static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { + return LHS == RHS; } }; struct DenseMapAPFloatKeyInfo { - static inline APFloat getEmptyKey() { return APFloat(APFloat::Bogus, 1); } - static inline APFloat getTombstoneKey() { return APFloat(APFloat::Bogus, 2); } - static unsigned getHashValue(const APFloat &Key) { + struct KeyTy { + APFloat val; + KeyTy(const APFloat& V) : val(V){} + bool operator==(const KeyTy& that) const { + return this->val.bitwiseIsEqual(that.val); + } + bool operator!=(const KeyTy& that) const { + return !this->operator==(that); + } + friend hash_code hash_value(const KeyTy &Key) { + return hash_combine(Key.val); + } + }; + static inline KeyTy getEmptyKey() { + return KeyTy(APFloat(APFloat::Bogus,1)); + } + static inline KeyTy getTombstoneKey() { + return KeyTy(APFloat(APFloat::Bogus,2)); + } + static unsigned getHashValue(const KeyTy &Key) { return static_cast(hash_value(Key)); } - static bool isEqual(const APFloat &LHS, const APFloat &RHS) { - return LHS.bitwiseIsEqual(RHS); + static bool isEqual(const KeyTy &LHS, const KeyTy &RHS) { + return LHS == RHS; } }; @@ -248,10 +277,12 @@ public: LLVMContext::YieldCallbackTy YieldCallback; void *YieldOpaqueHandle; - typedef DenseMap IntMapTy; + typedef DenseMap IntMapTy; IntMapTy IntConstants; - - typedef DenseMap FPMapTy; + + typedef DenseMap FPMapTy; FPMapTy FPConstants; FoldingSet AttrsSet; -- 2.34.1