[llvm] 961483a - [NFCI][Local] Rewrite EliminateDuplicatePHINodes to optionally check hashing invariants
Roman Lebedev via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 29 12:04:17 PDT 2020
Author: Roman Lebedev
Date: 2020-08-29T22:03:10+03:00
New Revision: 961483a5ea7c0e628c025187287d1658457ffcb3
URL: https://github.com/llvm/llvm-project/commit/961483a5ea7c0e628c025187287d1658457ffcb3
DIFF: https://github.com/llvm/llvm-project/commit/961483a5ea7c0e628c025187287d1658457ffcb3.diff
LOG: [NFCI][Local] Rewrite EliminateDuplicatePHINodes to optionally check hashing invariants
EarlyCSE has a mode to verify the invariant that hash equality equals
key equality, but EliminateDuplicatePHINodes() doesn't.
I've verified that this would have caught the stage2-stage3 mismatches
5ec2b757cc7d37ff0d03b36ee863b0962fe78108 revert has fixed,
that were introduced last time in 3e69871ab5a66fb55913a2a2f5e7f5b42899a4c9.
Added:
Modified:
llvm/lib/Transforms/Utils/Local.cpp
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 4234935e2b7c..6aa3f051fcff 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -92,6 +92,17 @@ using namespace llvm::PatternMatch;
STATISTIC(NumRemoved, "Number of unreachable basic blocks removed");
+static cl::opt<bool> PHICSEDebugHash(
+ "phicse-debug-hash",
+#ifdef EXPENSIVE_CHECKS
+ cl::init(true),
+#else
+ cl::init(false),
+#endif
+ cl::Hidden,
+ cl::desc("Perform extra assertion checking to verify that PHINodes's hash "
+ "function is well-behaved w.r.t. its isEqual predicate"));
+
// Max recursion depth for collectBitParts used when detecting bswap and
// bitreverse idioms
static const unsigned BitPartRecursionMaxDepth = 64;
@@ -1133,7 +1144,11 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
return DenseMapInfo<PHINode *>::getTombstoneKey();
}
- static unsigned getHashValue(PHINode *PN) {
+ static bool isSentinel(PHINode *PN) {
+ return PN == getEmptyKey() || PN == getTombstoneKey();
+ }
+
+ static unsigned getHashValueImpl(PHINode *PN) {
// Compute a hash value on the operands. Instcombine will likely have
// sorted them, which helps expose duplicates, but we have to check all
// the operands to be safe in case instcombine hasn't run.
@@ -1142,12 +1157,32 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
hash_combine_range(PN->block_begin(), PN->block_end())));
}
- static bool isEqual(PHINode *LHS, PHINode *RHS) {
- if (LHS == getEmptyKey() || LHS == getTombstoneKey() ||
- RHS == getEmptyKey() || RHS == getTombstoneKey())
+ static unsigned getHashValue(PHINode *PN) {
+#ifndef NDEBUG
+ // If -phicse-debug-hash was specified, return a constant -- this
+ // will force all hashing to collide, so we'll exhaustively search
+ // the table for a match, and the assertion in isEqual will fire if
+ // there's a bug causing equal keys to hash
diff erently.
+ if (PHICSEDebugHash)
+ return 0;
+#endif
+ return getHashValueImpl(PN);
+ }
+
+ static bool isEqualImpl(PHINode *LHS, PHINode *RHS) {
+ if (isSentinel(LHS) || isSentinel(RHS))
return LHS == RHS;
return LHS->isIdenticalTo(RHS);
}
+
+ static bool isEqual(PHINode *LHS, PHINode *RHS) {
+ // These comparisons are nontrivial, so assert that equality implies
+ // hash equality (DenseMap demands this as an invariant).
+ bool Result = isEqualImpl(LHS, RHS);
+ assert(!Result || (isSentinel(LHS) && LHS == RHS) ||
+ getHashValueImpl(LHS) == getHashValueImpl(RHS));
+ return Result;
+ }
};
// Set of unique PHINodes.
More information about the llvm-commits
mailing list