Index: include/llvm/Transforms/Scalar/GVNExpression.h =================================================================== --- include/llvm/Transforms/Scalar/GVNExpression.h +++ include/llvm/Transforms/Scalar/GVNExpression.h @@ -32,6 +32,7 @@ #include #include +struct HashedExpression; namespace llvm { namespace GVNExpression { @@ -662,6 +663,57 @@ } // end namespace GVNExpression +struct ExactEqualsExpression { + const GVNExpression::Expression &E; + explicit ExactEqualsExpression(const GVNExpression::Expression &E) : E(E) {} + hash_code getComputedHash() const { return E.getComputedHash(); } + bool operator==(const GVNExpression::Expression &Other) const { + return E.exactlyEquals(Other); + } +}; + +template <> struct DenseMapInfo { + static const GVNExpression::Expression *getEmptyKey() { + auto Val = static_cast(-1); + Val <<= PointerLikeTypeTraits< + const GVNExpression::Expression *>::NumLowBitsAvailable; + return reinterpret_cast(Val); + } + static const GVNExpression::Expression *getTombstoneKey() { + auto Val = static_cast(~1U); + Val <<= PointerLikeTypeTraits< + const GVNExpression::Expression *>::NumLowBitsAvailable; + return reinterpret_cast(Val); + } + static unsigned getHashValue(const GVNExpression::Expression *E) { + return E->getComputedHash(); + } + static unsigned getHashValue(const ExactEqualsExpression &E) { + return E.getComputedHash(); + } + static bool isEqual(const ExactEqualsExpression &LHS, + const GVNExpression::Expression *RHS) { + if (RHS == getTombstoneKey() || RHS == getEmptyKey()) + return false; + return LHS == *RHS; + } + + static bool isEqual(const GVNExpression::Expression *LHS, + const GVNExpression::Expression *RHS) { + if (LHS == RHS) + return true; + if (LHS == getTombstoneKey() || RHS == getTombstoneKey() || + LHS == getEmptyKey() || RHS == getEmptyKey()) + return false; + // Compare hashes before equality. This is *not* what the hashtable does, + // since it is computing it modulo the number of buckets, whereas we are + // using the full hash keyspace. Since the hashes are precomputed, this + // check is *much* faster than equality. + if (LHS->getComputedHash() != RHS->getComputedHash()) + return false; + return *LHS == *RHS; + } +}; } // end namespace llvm #endif // LLVM_TRANSFORMS_SCALAR_GVNEXPRESSION_H Index: lib/Transforms/Scalar/NewGVN.cpp =================================================================== --- lib/Transforms/Scalar/NewGVN.cpp +++ lib/Transforms/Scalar/NewGVN.cpp @@ -377,56 +377,6 @@ int StoreCount = 0; }; -namespace llvm { -struct ExactEqualsExpression { - const Expression &E; - explicit ExactEqualsExpression(const Expression &E) : E(E) {} - hash_code getComputedHash() const { return E.getComputedHash(); } - bool operator==(const Expression &Other) const { - return E.exactlyEquals(Other); - } -}; - -template <> struct DenseMapInfo { - static const Expression *getEmptyKey() { - auto Val = static_cast(-1); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); - } - static const Expression *getTombstoneKey() { - auto Val = static_cast(~1U); - Val <<= PointerLikeTypeTraits::NumLowBitsAvailable; - return reinterpret_cast(Val); - } - static unsigned getHashValue(const Expression *E) { - return E->getComputedHash(); - } - static unsigned getHashValue(const ExactEqualsExpression &E) { - return E.getComputedHash(); - } - static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS) { - if (RHS == getTombstoneKey() || RHS == getEmptyKey()) - return false; - return LHS == *RHS; - } - - static bool isEqual(const Expression *LHS, const Expression *RHS) { - if (LHS == RHS) - return true; - if (LHS == getTombstoneKey() || RHS == getTombstoneKey() || - LHS == getEmptyKey() || RHS == getEmptyKey()) - return false; - // Compare hashes before equality. This is *not* what the hashtable does, - // since it is computing it modulo the number of buckets, whereas we are - // using the full hash keyspace. Since the hashes are precomputed, this - // check is *much* faster than equality. - if (LHS->getComputedHash() != RHS->getComputedHash()) - return false; - return *LHS == *RHS; - } -}; -} // end namespace llvm - namespace { class NewGVN { Function &F;