Skip to content

Commit 1dc123e

Browse files
committed
Track dependencies of SIL instructions on opened archetypes which they use
Till now there was no way in SIL to explicitly express a dependency of an instruction on any opened archetypes used by it. This was a cause of many errors and correctness issues. In many cases the code was moved around without taking into account these dependencies, which resulted in breaking the invariant that any uses of an opened archetype should be dominated by the definition of this archetype. This patch does the following: - Map opened archetypes to the instructions defining them, i.e. to open_existential instructions. - Introduce a helper class SILOpenedArchetypesTracker for creating and maintaining such mappingss. - Each SIL instruction which uses an opened archetype as a type gets an additional "typedef" operand representing a dependency of the instruction on this archetype. These typedef operands are an in-memory representation. They are not serialized. Instead, they are re-constructed when reading binary or textual SIL files. - SILVerifier was extended to conduct more thorough checks related to the usage of opened archetypes.
1 parent 5384712 commit 1dc123e

26 files changed

+1242
-133
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 110 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "swift/SIL/SILDebugScope.h"
1717
#include "swift/SIL/SILFunction.h"
1818
#include "swift/SIL/SILModule.h"
19+
#include "swift/SIL/SILOpenedArchetypesTracker.h"
1920
#include "llvm/ADT/PointerUnion.h"
2021
#include "llvm/ADT/StringExtras.h"
2122

@@ -40,6 +41,40 @@ class SILBuilder {
4041
/// recorded in this list.
4142
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr;
4243

44+
/// Maps opened archetypes to their definitions. If provided,
45+
/// can be used by the builder. It is supposed to be used
46+
/// only by SILGen or SIL deserializers.
47+
SILOpenedArchetypesTracker *OpenedArchetypes = nullptr;
48+
49+
bool canProvideTypeDefs() const {
50+
return OpenedArchetypes != nullptr;
51+
}
52+
53+
// Build a set of typedef operands for an apply instruction. This is done by
54+
// scanning the list of substitutions and collecting all opened archetypes.
55+
void createApplyTypeDefs(SILInstruction *I, ArrayRef<Substitution> Subs) {
56+
// Copy the typedefs into the apply instruction.
57+
if (canProvideTypeDefs()) {
58+
unsigned Idx = 0;
59+
auto TypeDefs = I->getTypeDefOperandsBuf();
60+
for (auto Sub : Subs) {
61+
auto Ty = Sub.getReplacement().getCanonicalTypeOrNull();
62+
if (!Ty->hasOpenedExistential())
63+
continue;
64+
Ty.visit([&](Type t) {
65+
if (t->isOpenedExistential()) {
66+
auto Def =
67+
getOpenedArchetypeDef(getModule().Types.getLoweredType(t),
68+
getModule(), OpenedArchetypes);
69+
assert(getOpenedArchetypeOf(Def->getType().getSwiftRValueType()) &&
70+
"Typedef should be of an opened existential type");
71+
TypeDefs[Idx++].set(Def);
72+
}
73+
});
74+
}
75+
}
76+
}
77+
4378
public:
4479
SILBuilder(SILFunction &F) : F(F), BB(0) {}
4580

@@ -75,6 +110,14 @@ class SILBuilder {
75110
return F.getModule().getTypeLowering(T);
76111
}
77112

113+
void setOpenedArchetypes(SILOpenedArchetypesTracker &OpenedArchetypes) {
114+
this->OpenedArchetypes = &OpenedArchetypes;
115+
}
116+
117+
SILOpenedArchetypesTracker *getOpenedArchetypes() const {
118+
return OpenedArchetypes;
119+
}
120+
78121
void setCurrentDebugScope(const SILDebugScope *DS) { CurDebugScope = DS; }
79122
const SILDebugScope *getCurrentDebugScope() const { return CurDebugScope; }
80123

@@ -260,8 +303,10 @@ class SILBuilder {
260303
ApplyInst *createApply(SILLocation Loc, SILValue Fn, SILType SubstFnTy,
261304
SILType Result, ArrayRef<Substitution> Subs,
262305
ArrayRef<SILValue> Args, bool isNonThrowing) {
263-
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, SubstFnTy,
306+
auto *I = insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, SubstFnTy,
264307
Result, Subs, Args, isNonThrowing, F));
308+
createApplyTypeDefs(I, Subs);
309+
return I;
265310
}
266311

267312
ApplyInst *createApply(SILLocation Loc, SILValue Fn, ArrayRef<SILValue> Args,
@@ -276,18 +321,22 @@ class SILBuilder {
276321
ArrayRef<Substitution> subs,
277322
ArrayRef<SILValue> args, SILBasicBlock *normalBB,
278323
SILBasicBlock *errorBB) {
279-
return insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
324+
auto *I = insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
280325
fn, substFnTy, subs, args,
281326
normalBB, errorBB, F));
327+
createApplyTypeDefs(I, subs);
328+
return I;
282329
}
283330

284331
PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
285332
SILType SubstFnTy,
286333
ArrayRef<Substitution> Subs,
287334
ArrayRef<SILValue> Args,
288335
SILType ClosureTy) {
289-
return insert(PartialApplyInst::create(
336+
auto I = insert(PartialApplyInst::create(
290337
getSILDebugLocation(Loc), Fn, SubstFnTy, Subs, Args, ClosureTy, F));
338+
createApplyTypeDefs(I, Subs);
339+
return I;
291340
}
292341

293342
BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
@@ -526,8 +575,11 @@ class SILBuilder {
526575

527576
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,
528577
SILType Ty) {
529-
return insert(new (F.getModule()) UncheckedRefCastInst(
578+
auto *I = insert(new (F.getModule()) UncheckedRefCastInst(
530579
getSILDebugLocation(Loc), Op, Ty));
580+
I->getTypeDefOperandsBuf()[0].set(
581+
getOpenedArchetypeDef(Ty, getModule(), OpenedArchetypes));
582+
return I;
531583
}
532584

533585
UncheckedRefCastAddrInst *
@@ -539,20 +591,29 @@ class SILBuilder {
539591

540592
UncheckedAddrCastInst *createUncheckedAddrCast(SILLocation Loc, SILValue Op,
541593
SILType Ty) {
542-
return insert(new (F.getModule()) UncheckedAddrCastInst(
594+
auto *I = insert(new (F.getModule()) UncheckedAddrCastInst(
543595
getSILDebugLocation(Loc), Op, Ty));
596+
I->getTypeDefOperandsBuf()[0].set(
597+
getOpenedArchetypeDef(Ty, getModule(), OpenedArchetypes));
598+
return I;
544599
}
545600

546601
UncheckedTrivialBitCastInst *
547602
createUncheckedTrivialBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
548-
return insert(new (F.getModule()) UncheckedTrivialBitCastInst(
603+
auto *I = insert(new (F.getModule()) UncheckedTrivialBitCastInst(
549604
getSILDebugLocation(Loc), Op, Ty));
605+
I->getTypeDefOperandsBuf()[0].set(
606+
getOpenedArchetypeDef(Ty, getModule(), OpenedArchetypes));
607+
return I;
550608
}
551609

552610
UncheckedBitwiseCastInst *
553611
createUncheckedBitwiseCast(SILLocation Loc, SILValue Op, SILType Ty) {
554-
return insert(new (F.getModule()) UncheckedBitwiseCastInst(
612+
auto *I = insert(new (F.getModule()) UncheckedBitwiseCastInst(
555613
getSILDebugLocation(Loc), Op, Ty));
614+
I->getTypeDefOperandsBuf()[0].set(
615+
getOpenedArchetypeDef(Ty, getModule(), OpenedArchetypes));
616+
return I;
556617
}
557618

558619
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
@@ -648,8 +709,11 @@ class SILBuilder {
648709

649710
UnconditionalCheckedCastInst *
650711
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
651-
return insert(new (F.getModule()) UnconditionalCheckedCastInst(
712+
auto *I = insert(new (F.getModule()) UnconditionalCheckedCastInst(
652713
getSILDebugLocation(Loc), op, destTy));
714+
I->getTypeDefOperandsBuf()[0].set(
715+
getOpenedArchetypeDef(destTy, getModule(), OpenedArchetypes));
716+
return I;
653717
}
654718

655719
UnconditionalCheckedCastAddrInst *createUnconditionalCheckedCastAddr(
@@ -912,55 +976,78 @@ class SILBuilder {
912976

913977
OpenExistentialAddrInst *
914978
createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy) {
915-
return insert(new (F.getModule()) OpenExistentialAddrInst(
979+
auto *I = insert(new (F.getModule()) OpenExistentialAddrInst(
916980
getSILDebugLocation(Loc), Operand, SelfTy));
981+
if (canProvideTypeDefs())
982+
OpenedArchetypes->registerOpenedArchetypes(I);
983+
return I;
917984
}
918985

919986
OpenExistentialMetatypeInst *createOpenExistentialMetatype(SILLocation Loc,
920987
SILValue operand,
921988
SILType selfTy) {
922-
return insert(new (F.getModule()) OpenExistentialMetatypeInst(
989+
auto *I = insert(new (F.getModule()) OpenExistentialMetatypeInst(
923990
getSILDebugLocation(Loc), operand, selfTy));
924-
}
991+
if (canProvideTypeDefs())
992+
OpenedArchetypes->registerOpenedArchetypes(I);
993+
return I;
994+
}
925995

926996
OpenExistentialRefInst *
927997
createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
928-
return insert(new (F.getModule()) OpenExistentialRefInst(
998+
auto *I = insert(new (F.getModule()) OpenExistentialRefInst(
929999
getSILDebugLocation(Loc), Operand, Ty));
1000+
if (canProvideTypeDefs())
1001+
OpenedArchetypes->registerOpenedArchetypes(I);
1002+
return I;
9301003
}
9311004

9321005
OpenExistentialBoxInst *
9331006
createOpenExistentialBox(SILLocation Loc, SILValue Operand, SILType Ty) {
934-
return insert(new (F.getModule()) OpenExistentialBoxInst(
1007+
auto *I = insert(new (F.getModule()) OpenExistentialBoxInst(
9351008
getSILDebugLocation(Loc), Operand, Ty));
936-
}
1009+
if (canProvideTypeDefs())
1010+
OpenedArchetypes->registerOpenedArchetypes(I);
1011+
return I;
1012+
}
9371013

9381014
InitExistentialAddrInst *
9391015
createInitExistentialAddr(SILLocation Loc, SILValue Existential,
9401016
CanType FormalConcreteType,
9411017
SILType LoweredConcreteType,
9421018
ArrayRef<ProtocolConformanceRef> Conformances) {
943-
return insert(InitExistentialAddrInst::create(
1019+
auto *I = insert(InitExistentialAddrInst::create(
9441020
getSILDebugLocation(Loc), Existential, FormalConcreteType,
9451021
LoweredConcreteType, Conformances, &F));
1022+
I->getTypeDefOperandsBuf()[0].set(getOpenedArchetypeDef(
1023+
getModule().Types.getLoweredType(FormalConcreteType), getModule(),
1024+
OpenedArchetypes));
1025+
return I;
9461026
}
9471027

9481028
InitExistentialMetatypeInst *
9491029
createInitExistentialMetatype(SILLocation Loc, SILValue metatype,
9501030
SILType existentialType,
9511031
ArrayRef<ProtocolConformanceRef> conformances) {
952-
return insert(InitExistentialMetatypeInst::create(
1032+
auto *I = insert(InitExistentialMetatypeInst::create(
9531033
getSILDebugLocation(Loc), existentialType, metatype, conformances,
9541034
&F));
1035+
I->getTypeDefOperandsBuf()[0].set(
1036+
getOpenedArchetypeDef(existentialType, getModule(), OpenedArchetypes));
1037+
return I;
9551038
}
9561039

9571040
InitExistentialRefInst *
9581041
createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
9591042
CanType FormalConcreteType, SILValue Concrete,
9601043
ArrayRef<ProtocolConformanceRef> Conformances) {
961-
return insert(InitExistentialRefInst::create(
1044+
auto *I = insert(InitExistentialRefInst::create(
9621045
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType,
9631046
Concrete, Conformances, &F));
1047+
I->getTypeDefOperandsBuf()[0].set(getOpenedArchetypeDef(
1048+
getModule().Types.getLoweredType(FormalConcreteType), getModule(),
1049+
OpenedArchetypes));
1050+
return I;
9641051
}
9651052

9661053
DeinitExistentialAddrInst *createDeinitExistentialAddr(SILLocation Loc,
@@ -1306,9 +1393,12 @@ class SILBuilder {
13061393
SILValue op, SILType destTy,
13071394
SILBasicBlock *successBB,
13081395
SILBasicBlock *failureBB) {
1309-
return insertTerminator(new (F.getModule()) CheckedCastBranchInst(
1310-
getSILDebugLocation(Loc), isExact, op, destTy, successBB,
1311-
failureBB));
1396+
auto *I = insertTerminator(new (F.getModule()) CheckedCastBranchInst(
1397+
getSILDebugLocation(Loc), isExact, op, destTy,
1398+
successBB, failureBB));
1399+
I->getTypeDefOperandsBuf()[0].set(
1400+
getOpenedArchetypeDef(destTy, getModule(), OpenedArchetypes));
1401+
return I;
13121402
}
13131403

13141404
CheckedCastAddrBranchInst *

0 commit comments

Comments
 (0)