Skip to content

Commit d125f3a

Browse files
authored
Merge pull request #35265 from meg-gupta/fixcseclone
Fix CSE::processOpenExistentialRef
2 parents c974725 + 30ae4ad commit d125f3a

File tree

2 files changed

+35
-17
lines changed

2 files changed

+35
-17
lines changed

lib/SILOptimizer/Transforms/CSE.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -581,10 +581,6 @@ class CSE {
581581

582582
SILOptFunctionBuilder &FuncBuilder;
583583

584-
SILOpenedArchetypesTracker &OpenedArchetypesTracker;
585-
586-
InstructionCloner &Cloner;
587-
588584
DeadEndBlocks &DeadEndBBs;
589585

590586
OwnershipFixupContext &FixupCtx;
@@ -594,16 +590,10 @@ class CSE {
594590
llvm::SmallVector<ApplyInst *, 8> lazyPropertyGetters;
595591

596592
CSE(bool RunsOnHighLevelSil, SideEffectAnalysis *SEA,
597-
SILOptFunctionBuilder &FuncBuilder,
598-
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
599-
InstructionCloner &Cloner, DeadEndBlocks &DeadEndBBs,
593+
SILOptFunctionBuilder &FuncBuilder, DeadEndBlocks &DeadEndBBs,
600594
OwnershipFixupContext &FixupCtx)
601-
: SEA(SEA), FuncBuilder(FuncBuilder),
602-
OpenedArchetypesTracker(OpenedArchetypesTracker), Cloner(Cloner),
603-
DeadEndBBs(DeadEndBBs), FixupCtx(FixupCtx),
604-
RunsOnHighLevelSil(RunsOnHighLevelSil) {
605-
Cloner.getBuilder().setOpenedArchetypesTracker(&OpenedArchetypesTracker);
606-
}
595+
: SEA(SEA), FuncBuilder(FuncBuilder), DeadEndBBs(DeadEndBBs),
596+
FixupCtx(FixupCtx), RunsOnHighLevelSil(RunsOnHighLevelSil) {}
607597

608598
bool processFunction(SILFunction &F, DominanceInfo *DT);
609599

@@ -843,11 +833,16 @@ bool CSE::processOpenExistentialRef(OpenExistentialRefInst *Inst,
843833
}
844834

845835
// Now process candidates.
836+
SILOpenedArchetypesTracker OpenedArchetypesTracker(Inst->getFunction());
846837
// Register the new archetype to be used.
847838
OpenedArchetypesTracker.registerOpenedArchetypes(VI);
839+
// Use a cloner. It makes copying the instruction and remapping of
840+
// opened archetypes trivial.
841+
InstructionCloner Cloner(Inst->getFunction());
848842
Cloner.registerOpenedExistentialRemapping(
849843
OldOpenedArchetype->castTo<ArchetypeType>(), NewOpenedArchetype);
850844
auto &Builder = Cloner.getBuilder();
845+
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
851846

852847
llvm::SmallPtrSet<SILInstruction *, 16> Processed;
853848
// Now clone each candidate and replace the opened archetype
@@ -1401,14 +1396,11 @@ class SILCSE : public SILFunctionTransform {
14011396
SILOptFunctionBuilder FuncBuilder(*this);
14021397

14031398
auto *Fn = getFunction();
1404-
SILOpenedArchetypesTracker OpenedArchetypesTracker(Fn);
1405-
InstructionCloner Cloner(Fn);
14061399
DeadEndBlocks DeadEndBBs(Fn);
14071400
JointPostDominanceSetComputer Computer(DeadEndBBs);
14081401
InstModCallbacks callbacks;
14091402
OwnershipFixupContext FixupCtx{callbacks, DeadEndBBs, Computer};
1410-
CSE C(RunsOnHighLevelSil, SEA, FuncBuilder, OpenedArchetypesTracker, Cloner,
1411-
DeadEndBBs, FixupCtx);
1403+
CSE C(RunsOnHighLevelSil, SEA, FuncBuilder, DeadEndBBs, FixupCtx);
14121404
bool Changed = false;
14131405

14141406
// Perform the traditional CSE.

test/SILOptimizer/cse.sil

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,32 @@ bb3:
12441244
return %20 : $()
12451245
}
12461246

1247+
// This test is not a repro but used to show why we need a local Cloner object in CSE::processOpenExistentialRef.
1248+
// Discussion:
1249+
// Since the CSE pass can delete instructions and allocate instructions whose state can be cached in the Cloner, we have to use local Cloner object so that we don't accidentally refer to stale state
1250+
// In this test users of %9 are all cloned and original instructions are deleted. Users of %13 are similarly cloned and original instructions are deleted so the types can be remapped.
1251+
// Instructions can further get deleted in the main CSE pass as well as during SimplifyInstruction.
1252+
// For some heap allocation patterns newly allocated instructions can get the same address of a previously allocated instruction, and can end up referring to a stale state in the Cloner.
1253+
//
1254+
// CHECK-LABEL: sil @cse_open_existential_ref_local_cloner :
1255+
// CHECK: open_existential_ref
1256+
// CHECK-NOT: open_existential_ref
1257+
// CHECK-LABEL: } // end sil function 'cse_open_existential_ref_local_cloner'
1258+
sil @cse_open_existential_ref_local_cloner : $@convention(thin) (@guaranteed Proto, Bool) -> () {
1259+
bb0(%0 : $Proto, %1 : $Bool):
1260+
%4 = open_existential_ref %0 : $Proto to $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto
1261+
%5 = witness_method $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThis, %4 : $@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1262+
%6 = apply %5<@opened("1B68354A-4796-11E6-B7DF-B8E856428C60") Proto>(%4) : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1263+
%9 = open_existential_ref %0 : $Proto to $@opened("1B685052-4796-11E6-B7DF-B8E856428C60") Proto
1264+
%10 = witness_method $@opened("1B685052-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThat, %9 : $@opened("1B685052-4796-11E6-B7DF-B8E856428C60") Proto : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1265+
%11 = apply %10<@opened("1B685052-4796-11E6-B7DF-B8E856428C60") Proto>(%9) : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1266+
%13 = open_existential_ref %0 : $Proto to $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto
1267+
%14 = witness_method $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto, #Proto.doThis, %13 : $@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1268+
%15 = apply %14<@opened("1B6851A6-4796-11E6-B7DF-B8E856428C60") Proto>(%13) : $@convention(witness_method: Proto) <τ_0_0 where τ_0_0 : Proto> (@guaranteed τ_0_0) -> ()
1269+
%res = tuple ()
1270+
return %res : $()
1271+
}
1272+
12471273
// Check that we don't CSE open_existential_ref if they are not compeltely equal.
12481274
// CHECK-LABEL: sil @dont_cse_open_existential_ref
12491275
// CHECK: open_existential_ref

0 commit comments

Comments
 (0)