@@ -7442,16 +7442,12 @@ static bool simplifySwitchOfCmpIntrinsic(SwitchInst *SI, IRBuilderBase &Builder,
74427442// / PHINode::getIncomingValueForBlock is O(|Preds|), so we'd like to avoid
74437443// / calling this function on each BasicBlock every time isEqual is called,
74447444// / especially since the same BasicBlock may be passed as an argument multiple
7445- // / times. To do this, we can precompute a map, PhiPredIVs, of PHINode -> Pred
7446- // / BasicBlock -> IncomingValue and add it in the Wrapper so isEqual can do O(1)
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.
7445+ // / times. To do this, we can precompute a map of PHINode -> Pred BasicBlock ->
7446+ // / IncomingValue and add it in the Wrapper so isEqual can do O(1) checking
7447+ // / of the incoming values.
74517448struct CaseHandleWrapper {
74527449 const SwitchInst::CaseHandle Case;
74537450 DenseMap<PHINode *, DenseMap<BasicBlock *, Value *>> *PhiPredIVs;
7454- DenseMap<BasicBlock *, SmallVector<Value *>> *PhiVals;
74557451};
74567452
74577453namespace llvm {
@@ -7473,14 +7469,22 @@ template <> struct DenseMapInfo<const CaseHandleWrapper *> {
74737469 " Expected unconditional branches to have one successor" );
74747470 assert (Succ->size () == 1 && " Expected just a single branch in the BB" );
74757471
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.
7472+ // Since we assume the BB is just a single BranchInst with a single
7473+ // succsessor, we hash as the BB and the incoming Values of its successor
7474+ // PHIs. Initially, we tried to just use the successor BB as the hash, but
7475+ // this had poor performance. We find that the extra computation of getting
7476+ // the incoming PHI values here leads to better performance on overall Set
7477+ // performance. We also tried to build a map from BB -> Succs.IncomingValues
7478+ // ahead of time and passing it in CaseHandleWrapper, but this slowed down
7479+ // the average compile time without having any impact on the worst case
7480+ // compile time.
74807481 BasicBlock *BB = BI->getSuccessor (0 );
7481- auto &Vals = (*CHW->PhiVals )[BB];
7482- return hash_combine (hash_value (BB),
7483- hash_combine_range (Vals.begin (), Vals.end ()));
7482+ SmallVector<Value *> PhiValsForBB;
7483+ for (PHINode &Phi : BB->phis ())
7484+ PhiValsForBB.emplace_back ((*CHW->PhiPredIVs )[&Phi][BB]);
7485+
7486+ return hash_combine (
7487+ BB, hash_combine_range (PhiValsForBB.begin (), PhiValsForBB.end ()));
74847488 }
74857489 static bool isEqual (const CaseHandleWrapper *LHS,
74867490 const CaseHandleWrapper *RHS) {
@@ -7530,7 +7534,6 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI) {
75307534 SmallPtrSet<PHINode *, 8 > Phis;
75317535 SmallPtrSet<BasicBlock *, 8 > Seen;
75327536 DenseMap<PHINode *, DenseMap<BasicBlock *, Value *>> PhiPredIVs;
7533- DenseMap<BasicBlock *, SmallVector<Value *>> PhiVals;
75347537 std::vector<CaseHandleWrapper> Cases;
75357538 Cases.reserve (SI->getNumCases ());
75367539 for (auto &Case : SI->cases ()) {
@@ -7558,32 +7561,22 @@ bool SimplifyCFGOpt::simplifyDuplicateSwitchArms(SwitchInst *SI) {
75587561 continue ;
75597562
75607563 if (Seen.insert (BB).second ) {
7561- // Keep track of which PHIs we need as keys in PhiPredIVs.
7562- for (BasicBlock *Succ : BI->successors ()) {
7563- for (PHINode &Phi : Succ->phis ()) {
7564+ // Keep track of which PHIs we need as keys in PhiPredIVs below .
7565+ for (BasicBlock *Succ : BI->successors ())
7566+ for (PHINode &Phi : Succ->phis ())
75647567 Phis.insert (&Phi);
7565- PhiVals[BB] = SmallVector<Value *>();
7566- }
7567- }
75687568 }
7569- Cases.emplace_back (CaseHandleWrapper{Case, &PhiPredIVs, &PhiVals });
7569+ Cases.emplace_back (CaseHandleWrapper{Case, &PhiPredIVs});
75707570 }
75717571
7572- // Precompute the data structures to improve performance of isEqual and
7573- // getHashValue for CaseHandleWrapper.
7572+ // Precompute a data structure to improve performance of isEqual for
7573+ // CaseHandleWrapper.
75747574 PhiPredIVs.reserve (Phis.size ());
75757575 for (PHINode *Phi : Phis) {
75767576 PhiPredIVs[Phi] =
75777577 DenseMap<BasicBlock *, Value *>(Phi->getNumIncomingValues ());
7578- for (Use &IV : Phi->incoming_values ()) {
7579- BasicBlock *BB = Phi->getIncomingBlock (IV);
7580- PhiPredIVs[Phi].insert ({BB, IV.get ()});
7581- // Only need to track PhiVals for BBs we've added as keys in the loop
7582- // above.
7583- auto Res = PhiVals.find (BB);
7584- if (Res != PhiVals.end ())
7585- Res->second .emplace_back (IV.get ());
7586- }
7578+ for (auto &IV : Phi->incoming_values ())
7579+ PhiPredIVs[Phi].insert ({Phi->getIncomingBlock (IV), IV.get ()});
75877580 }
75887581
75897582 // Build a set such that if the CaseHandleWrapper exists in the set and
0 commit comments