Skip to content

Commit 897de2c

Browse files
authored
Merge pull request #4606 from swiftix/master
2 parents bbe3c2b + bb106ee commit 897de2c

File tree

2 files changed

+50
-5
lines changed

2 files changed

+50
-5
lines changed

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,13 +681,48 @@ bool CSE::processOpenExistentialRef(SILInstruction *Inst, ValueBase *V,
681681
auto &Builder = Cloner.getBuilder();
682682
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
683683

684+
llvm::SmallPtrSet<SILInstruction *, 16> Processed;
684685
// Now clone each candidate and replace the opened archetype
685686
// by a dominating one.
686-
for (auto Candidate : Candidates) {
687+
while (!Candidates.empty()) {
688+
auto Candidate = Candidates.pop_back_val();
689+
if (Processed.count(Candidate))
690+
continue;
691+
// True if a candidate depends on the old opened archetype.
692+
bool DependsOnOldOpenedArchetype = !Candidate->getTypeDependentOperands().empty();
693+
if (!Candidate->use_empty() &&
694+
Candidate->getType().getSwiftRValueType()->hasOpenedExistential()) {
695+
// Check if the result type of the candidate depends on the opened
696+
// existential in question.
697+
auto ResultDependsOnOldOpenedArchetype =
698+
Candidate->getType().getSwiftRValueType().findIf(
699+
[&OldOpenedArchetype](Type t) -> bool {
700+
if (t.getCanonicalTypeOrNull() == OldOpenedArchetype)
701+
return true;
702+
return false;
703+
});
704+
if (ResultDependsOnOldOpenedArchetype) {
705+
DependsOnOldOpenedArchetype |= ResultDependsOnOldOpenedArchetype;
706+
// We need to update uses of this candidate, because their types
707+
// may be affected.
708+
for (auto Use : Candidate->getUses()) {
709+
Candidates.insert(Use->getUser());
710+
}
711+
}
712+
}
713+
// Remember that this candidate was processed already.
714+
Processed.insert(Candidate);
715+
716+
// No need to clone if there is no dependency on the old opened archetype.
717+
if (!DependsOnOldOpenedArchetype)
718+
continue;
719+
687720
Builder.getOpenedArchetypes().addOpenedArchetypeOperands(
688721
Candidate->getTypeDependentOperands());
689722
Builder.setInsertionPoint(Candidate);
690723
auto NewI = Cloner.clone(Candidate);
724+
// Result types of candidate's uses instructions may be using this archetype.
725+
// Thus, we need to try to replace it there.
691726
Candidate->replaceAllUsesWith(NewI);
692727
if (I == Candidate->getIterator())
693728
I = NewI->getIterator();

test/SILOptimizer/cse.sil

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,8 @@ protocol Proto : class {
13251325
}
13261326

13271327
// Check that all open_existential_ref instructions are CSEd
1328+
// Any reference to the $@opened("1B685052-4796-11E6-B7DF-B8E856428C60") Proto should be replaced by
1329+
// references to $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto.
13281330
// CHECK-LABEL: sil @cse_open_existential : $@convention(thin) (@guaranteed Proto, Bool) -> ()
13291331
// CHECK: bb0
13301332
// CHECK: %[[OPENED_EXISTENTIAL:[0-9]+]] = open_existential_ref %{{[0-9]+}} : $Proto to $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto
@@ -1334,10 +1336,12 @@ protocol Proto : class {
13341336
// CHECK: bb1:
13351337
// CHECK-NEXT: %[[WM2:[0-9]+]] = witness_method $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThat!1
13361338
// CHECK-NEXT: apply %[[WM2]]{{.*}}(%[[OPENED_EXISTENTIAL]])
1337-
// CHECK-NEXT: br bb
1339+
// CHECK-NOT: 1B6851A6-4796-11E6-B7DF-B8E856428C60
1340+
// CHECK: br bb
13381341
// CHECK: bb2:
13391342
// CHECK-NEXT: apply %[[WM1]]{{.*}}(%[[OPENED_EXISTENTIAL]])
1340-
// CHECK-NEXT: br bb
1343+
// CHECK-NOT: 1B6851A6-4796-11E6-B7DF-B8E856428C60
1344+
// CHECK: br bb
13411345
// CHECK: bb3:
13421346
// CHECK-NEXT: tuple
13431347
// CHECK-NEXT: return
@@ -1359,10 +1363,16 @@ bb2: // Preds: bb0
13591363
%13 = open_existential_ref %0 : $Proto to $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
13601364
%14 = witness_method $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThis!1, %13 : $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto : $@convention(witness_method) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
13611365
%15 = apply %14<@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto>(%13) : $@convention(witness_method) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1366+
%16 = alloc_stack $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
1367+
store %13 to %16 : $*@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
1368+
// This is to check that result types of instructions are updated by CSE as well.
1369+
%17 = load %16 : $*@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
1370+
strong_release %17 : $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
1371+
dealloc_stack %16 : $*@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
13621372
br bb3
13631373

13641374
bb3:
1365-
%17 = tuple ()
1366-
return %17 : $()
1375+
%20 = tuple ()
1376+
return %20 : $()
13671377
}
13681378

0 commit comments

Comments
 (0)