@@ -832,7 +832,8 @@ bool CSE::processLazyPropertyGetters(SILFunction &F) {
832832// / according to the provided type substitution map.
833833static void updateBasicBlockArgTypes (SILBasicBlock *BB,
834834 ArchetypeType *OldOpenedArchetype,
835- ArchetypeType *NewOpenedArchetype) {
835+ ArchetypeType *NewOpenedArchetype,
836+ InstructionWorklist &usersToHandle) {
836837 // Check types of all BB arguments.
837838 for (auto *Arg : BB->getSILPhiArguments ()) {
838839 if (!Arg->getType ().hasOpenedExistential ())
@@ -868,6 +869,7 @@ static void updateBasicBlockArgTypes(SILBasicBlock *BB,
868869 // Restore all uses to refer to the BB argument with updated type.
869870 for (auto ArgUse : OriginalArgUses) {
870871 ArgUse->set (NewArg);
872+ usersToHandle.pushIfNotVisited (ArgUse->getUser ());
871873 }
872874 }
873875}
@@ -879,7 +881,7 @@ static void updateBasicBlockArgTypes(SILBasicBlock *BB,
879881// / \V is the dominating open_existential_ref instruction
880882bool CSE::processOpenExistentialRef (OpenExistentialRefInst *Inst,
881883 OpenExistentialRefInst *VI) {
882- llvm::SmallSetVector<SILInstruction *, 16 > Candidates ;
884+ InstructionWorklist usersToHandle (Inst-> getFunction ()) ;
883885 const auto OldOpenedArchetype = Inst->getDefinedOpenedArchetype ();
884886 const auto NewOpenedArchetype = VI->getDefinedOpenedArchetype ();
885887
@@ -895,8 +897,7 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
895897 }
896898 }
897899 }
898-
899- Candidates.insert (User);
900+ usersToHandle.pushIfNotVisited (User);
900901 }
901902
902903 // Now process candidates.
@@ -907,43 +908,36 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
907908 OldOpenedArchetype->castTo <ArchetypeType>(), NewOpenedArchetype);
908909 auto &Builder = Cloner.getBuilder ();
909910
910- InstructionSet Processed (Inst->getFunction ());
911911 // Now clone each candidate and replace the opened archetype
912912 // by a dominating one.
913- while (!Candidates.empty ()) {
914- auto Candidate = Candidates.pop_back_val ();
915- if (Processed.contains (Candidate))
916- continue ;
917-
918- if (isa<TermInst>(Candidate)) {
913+ while (SILInstruction *user = usersToHandle.pop ()) {
914+ if (isa<TermInst>(user)) {
919915 // The current use of the opened archetype is a terminator instruction.
920916 // Check if any of the successor BBs uses this opened archetype in the
921917 // types of its basic block arguments. If this is the case, replace
922918 // those uses by the new opened archetype.
923- // FIXME: What about uses of those arguments?
924- for (auto *Successor : Candidate->getParent ()->getSuccessorBlocks ()) {
919+ for (auto *Successor : user->getParent ()->getSuccessorBlocks ()) {
925920 if (Successor->args_empty ())
926921 continue ;
927922 // If a BB has any arguments, update their types if necessary.
928923 updateBasicBlockArgTypes (Successor, OldOpenedArchetype,
929- NewOpenedArchetype);
924+ NewOpenedArchetype, usersToHandle );
930925 }
931926 }
932927
933928 // Compute if a candidate depends on the old opened archetype.
934929 // It always does if it has any type-dependent operands.
935930 bool DependsOnOldOpenedArchetype =
936- !Candidate ->getTypeDependentOperands ().empty ();
931+ !user ->getTypeDependentOperands ().empty ();
937932
938933 // Look for dependencies propagated via the candidate's results.
939- for (auto CandidateResult : Candidate->getResults ()) {
940- if (CandidateResult->use_empty () ||
941- !CandidateResult->getType ().hasOpenedExistential ())
934+ for (auto result : user->getResults ()) {
935+ if (result->use_empty () || !result->getType ().hasOpenedExistential ())
942936 continue ;
943937
944938 // Check if the result type depends on this specific opened existential.
945939 auto ResultDependsOnOldOpenedArchetype =
946- CandidateResult ->getType ().getASTType ().findIf (
940+ result ->getType ().getASTType ().findIf (
947941 [&OldOpenedArchetype](Type t) -> bool {
948942 return (CanType (t) == OldOpenedArchetype);
949943 });
@@ -953,24 +947,22 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
953947 DependsOnOldOpenedArchetype = true ;
954948
955949 // The users of this candidate are new candidates.
956- for (auto Use : CandidateResult ->getUses ()) {
957- Candidates. insert (Use->getUser ());
950+ for (auto Use : result ->getUses ()) {
951+ usersToHandle. pushIfNotVisited (Use->getUser ());
958952 }
959953 }
960954 }
961- // Remember that this candidate was processed already.
962- Processed.insert (Candidate);
963955
964956 // No need to clone if there is no dependency on the old opened archetype.
965957 if (!DependsOnOldOpenedArchetype)
966958 continue ;
967959
968- Builder.setInsertionPoint (Candidate );
969- auto NewI = Cloner.clone (Candidate );
960+ Builder.setInsertionPoint (user );
961+ auto NewI = Cloner.clone (user );
970962 // Result types of candidate's uses instructions may be using this archetype.
971963 // Thus, we need to try to replace it there.
972- Candidate ->replaceAllUsesPairwiseWith (NewI);
973- eraseFromParentWithDebugInsts (Candidate );
964+ user ->replaceAllUsesPairwiseWith (NewI);
965+ eraseFromParentWithDebugInsts (user );
974966 }
975967 return true ;
976968}
0 commit comments