@@ -832,7 +832,8 @@ bool CSE::processLazyPropertyGetters(SILFunction &F) {
832
832
// / according to the provided type substitution map.
833
833
static void updateBasicBlockArgTypes (SILBasicBlock *BB,
834
834
ArchetypeType *OldOpenedArchetype,
835
- ArchetypeType *NewOpenedArchetype) {
835
+ ArchetypeType *NewOpenedArchetype,
836
+ InstructionWorklist &usersToHandle) {
836
837
// Check types of all BB arguments.
837
838
for (auto *Arg : BB->getSILPhiArguments ()) {
838
839
if (!Arg->getType ().hasOpenedExistential ())
@@ -868,6 +869,7 @@ static void updateBasicBlockArgTypes(SILBasicBlock *BB,
868
869
// Restore all uses to refer to the BB argument with updated type.
869
870
for (auto ArgUse : OriginalArgUses) {
870
871
ArgUse->set (NewArg);
872
+ usersToHandle.pushIfNotVisited (ArgUse->getUser ());
871
873
}
872
874
}
873
875
}
@@ -879,7 +881,7 @@ static void updateBasicBlockArgTypes(SILBasicBlock *BB,
879
881
// / \V is the dominating open_existential_ref instruction
880
882
bool CSE::processOpenExistentialRef (OpenExistentialRefInst *Inst,
881
883
OpenExistentialRefInst *VI) {
882
- llvm::SmallSetVector<SILInstruction *, 16 > Candidates ;
884
+ InstructionWorklist usersToHandle (Inst-> getFunction ()) ;
883
885
const auto OldOpenedArchetype = Inst->getDefinedOpenedArchetype ();
884
886
const auto NewOpenedArchetype = VI->getDefinedOpenedArchetype ();
885
887
@@ -895,8 +897,7 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
895
897
}
896
898
}
897
899
}
898
-
899
- Candidates.insert (User);
900
+ usersToHandle.pushIfNotVisited (User);
900
901
}
901
902
902
903
// Now process candidates.
@@ -907,43 +908,36 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
907
908
OldOpenedArchetype->castTo <ArchetypeType>(), NewOpenedArchetype);
908
909
auto &Builder = Cloner.getBuilder ();
909
910
910
- InstructionSet Processed (Inst->getFunction ());
911
911
// Now clone each candidate and replace the opened archetype
912
912
// 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)) {
919
915
// The current use of the opened archetype is a terminator instruction.
920
916
// Check if any of the successor BBs uses this opened archetype in the
921
917
// types of its basic block arguments. If this is the case, replace
922
918
// 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 ()) {
925
920
if (Successor->args_empty ())
926
921
continue ;
927
922
// If a BB has any arguments, update their types if necessary.
928
923
updateBasicBlockArgTypes (Successor, OldOpenedArchetype,
929
- NewOpenedArchetype);
924
+ NewOpenedArchetype, usersToHandle );
930
925
}
931
926
}
932
927
933
928
// Compute if a candidate depends on the old opened archetype.
934
929
// It always does if it has any type-dependent operands.
935
930
bool DependsOnOldOpenedArchetype =
936
- !Candidate ->getTypeDependentOperands ().empty ();
931
+ !user ->getTypeDependentOperands ().empty ();
937
932
938
933
// 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 ())
942
936
continue ;
943
937
944
938
// Check if the result type depends on this specific opened existential.
945
939
auto ResultDependsOnOldOpenedArchetype =
946
- CandidateResult ->getType ().getASTType ().findIf (
940
+ result ->getType ().getASTType ().findIf (
947
941
[&OldOpenedArchetype](Type t) -> bool {
948
942
return (CanType (t) == OldOpenedArchetype);
949
943
});
@@ -953,24 +947,22 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
953
947
DependsOnOldOpenedArchetype = true ;
954
948
955
949
// 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 ());
958
952
}
959
953
}
960
954
}
961
- // Remember that this candidate was processed already.
962
- Processed.insert (Candidate);
963
955
964
956
// No need to clone if there is no dependency on the old opened archetype.
965
957
if (!DependsOnOldOpenedArchetype)
966
958
continue ;
967
959
968
- Builder.setInsertionPoint (Candidate );
969
- auto NewI = Cloner.clone (Candidate );
960
+ Builder.setInsertionPoint (user );
961
+ auto NewI = Cloner.clone (user );
970
962
// Result types of candidate's uses instructions may be using this archetype.
971
963
// Thus, we need to try to replace it there.
972
- Candidate ->replaceAllUsesPairwiseWith (NewI);
973
- eraseFromParentWithDebugInsts (Candidate );
964
+ user ->replaceAllUsesPairwiseWith (NewI);
965
+ eraseFromParentWithDebugInsts (user );
974
966
}
975
967
return true ;
976
968
}
0 commit comments