@@ -7444,10 +7444,14 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
74447444// / especially since the same BasicBlock may be passed as an argument multiple
74457445// / times. To do this, we can precompute a map, PhiPredIVs, of PHINode -> Pred
74467446// / BasicBlock -> IncomingValue and add it in the Wrapper so isEqual can do O(1)
7447- // / checking of the incoming values.
7447+ // / checking of the incoming values. We also want to use the incoming Phi
7448+ // / values of a getCaseSuccessor to calculate the hash value. In order to avoid
7449+ // / iterating all of the successor Phis on evry call to getHashValue, we
7450+ // / precompute a list of incoming values from getCaseSucessor, PhiVals.
74487451struct CaseHandleWrapper {
74497452 const SwitchInst::CaseHandle Case;
74507453 DenseMap<PHINode *, DenseMap<BasicBlock *, Value *>> *PhiPredIVs;
7454+ SmallVector<Value *> *PhiVals;
74517455};
74527456
74537457namespace llvm {
@@ -7468,8 +7472,15 @@ template <> struct DenseMapInfo<const CaseHandleWrapper *> {
74687472 assert (BI->getNumSuccessors () == 1 &&
74697473 " Expected unconditional branches to have one successor" );
74707474 assert (Succ->size () == 1 && " Expected just a single branch in the BB" );
7475+
7476+ // Since the BB is just a single BranchInst with a single successor, we hash
7477+ // the BB and the incoming Values of its successor incoming PHI values.
7478+ // Initially, we tried to just use the successor BB as the hash, but this
7479+ // has better performance.
74717480 BasicBlock *BB = BI->getSuccessor (0 );
7472- return hash_value (BB);
7481+ return hash_combine (
7482+ hash_value (BB),
7483+ hash_combine_range (CHW->PhiVals ->begin (), CHW->PhiVals ->end ()));
74737484 }
74747485 static bool isEqual (const CaseHandleWrapper *LHS,
74757486 const CaseHandleWrapper *RHS) {
@@ -7519,6 +7530,7 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI) {
75197530 SmallPtrSet<PHINode *, 8 > Phis;
75207531 SmallPtrSet<BasicBlock *, 8 > Seen;
75217532 DenseMap<PHINode *, DenseMap<BasicBlock *, Value *>> PhiPredIVs;
7533+ DenseMap<BasicBlock *, SmallVector<Value *>> PhiVals;
75227534 std::vector<CaseHandleWrapper> Cases;
75237535 Cases.reserve (SI->getNumCases ());
75247536 for (auto &Case : SI->cases ()) {
@@ -7551,17 +7563,24 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI) {
75517563 for (PHINode &Phi : Succ->phis ())
75527564 Phis.insert (&Phi);
75537565
7554- Cases.emplace_back (CaseHandleWrapper{Case, &PhiPredIVs});
7566+ PhiVals[BB] = SmallVector<Value *>();
7567+ Cases.emplace_back (CaseHandleWrapper{Case, &PhiPredIVs, &PhiVals[BB]});
75557568 }
75567569
7557- // Precompute the data structures to improve performance of isEqual for
7558- // CaseHandleWrapper.
7570+ // Precompute the data structures to improve performance of isEqual and
7571+ // getHashValue for CaseHandleWrapper.
75597572 PhiPredIVs.reserve (Phis.size ());
75607573 for (PHINode *Phi : Phis) {
75617574 PhiPredIVs[Phi] =
75627575 DenseMap<BasicBlock *, Value *>(Phi->getNumIncomingValues ());
7563- for (Use &IV : Phi->incoming_values ())
7564- PhiPredIVs[Phi].insert ({Phi->getIncomingBlock (IV), IV.get ()});
7576+ for (Use &IV : Phi->incoming_values ()) {
7577+ BasicBlock *BB = Phi->getIncomingBlock (IV);
7578+ PhiPredIVs[Phi].insert ({BB, IV.get ()});
7579+ // Only need to track PhiVals for BBs we've added as keys in the loop
7580+ // above.
7581+ if (PhiVals.contains (BB))
7582+ PhiVals[BB].emplace_back (IV.get ());
7583+ }
75657584 }
75667585
75677586 // Build a set such that if the CaseHandleWrapper exists in the set and
0 commit comments