Skip to content

Commit 9d4fc91

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 mappings. - Introduce a helper class SILOpenedArchetypesState for providing a read-only API for looking up available opened archetypes. - Each SIL instruction which uses an opened archetype as a type gets an additional opened archetype operand representing a dependency of the instruction on this archetype. These opened archetypes 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 104a72f commit 9d4fc91

29 files changed

+1892
-362
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 81 additions & 41 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,16 @@ class SILBuilder {
4041
/// recorded in this list.
4142
SmallVectorImpl<SILInstruction *> *InsertedInstrs = nullptr;
4243

44+
/// An immutable view on the set of available opened archetypes.
45+
/// It is passed down to SILInstruction constructors and create
46+
/// methods.
47+
SILOpenedArchetypesState OpenedArchetypes;
48+
49+
/// Maps opened archetypes to their definitions. If provided,
50+
/// can be used by the builder. It is supposed to be used
51+
/// only by SILGen or SIL deserializers.
52+
SILOpenedArchetypesTracker *OpenedArchetypesTracker = nullptr;
53+
4354
public:
4455
SILBuilder(SILFunction &F) : F(F), BB(0) {}
4556

@@ -75,6 +86,19 @@ class SILBuilder {
7586
return F.getModule().getTypeLowering(T);
7687
}
7788

89+
void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
90+
this->OpenedArchetypesTracker = Tracker;
91+
this->OpenedArchetypes.setOpenedArchetypesTracker(OpenedArchetypesTracker);
92+
}
93+
94+
SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
95+
return OpenedArchetypesTracker;
96+
}
97+
98+
SILOpenedArchetypesState &getOpenedArchetypes() {
99+
return OpenedArchetypes;
100+
}
101+
78102
void setCurrentDebugScope(const SILDebugScope *DS) { CurDebugScope = DS; }
79103
const SILDebugScope *getCurrentDebugScope() const { return CurDebugScope; }
80104

@@ -214,54 +238,57 @@ class SILBuilder {
214238
SILDebugVariable Var = SILDebugVariable()) {
215239
Loc.markAsPrologue();
216240
return insert(AllocStackInst::create(getSILDebugLocation(Loc),
217-
elementType, F, Var));
241+
elementType, F, OpenedArchetypes,
242+
Var));
218243
}
219244

220245
AllocRefInst *createAllocRef(SILLocation Loc, SILType elementType, bool objc,
221246
bool canAllocOnStack) {
222247
// AllocRefInsts expand to function calls and can therefore not be
223248
// counted towards the function prologue.
224249
assert(!Loc.isInPrologue());
225-
return insert(new (F.getModule()) AllocRefInst(
226-
getSILDebugLocation(Loc), elementType, F, objc, canAllocOnStack));
250+
return insert(AllocRefInst::create(getSILDebugLocation(Loc), elementType, F,
251+
objc, canAllocOnStack,
252+
OpenedArchetypes));
227253
}
228254

229255
AllocRefDynamicInst *createAllocRefDynamic(SILLocation Loc, SILValue operand,
230256
SILType type, bool objc) {
231257
// AllocRefDynamicInsts expand to function calls and can therefore
232258
// not be counted towards the function prologue.
233259
assert(!Loc.isInPrologue());
234-
return insert(new (F.getModule()) AllocRefDynamicInst(
235-
getSILDebugLocation(Loc), operand, type, objc));
260+
return insert(AllocRefDynamicInst::create(getSILDebugLocation(Loc), operand,
261+
type, objc, F, OpenedArchetypes));
236262
}
237263

238264
AllocValueBufferInst *
239265
createAllocValueBuffer(SILLocation Loc, SILType valueType, SILValue operand) {
240-
return insert(new (F.getModule()) AllocValueBufferInst(
241-
getSILDebugLocation(Loc), valueType, operand));
266+
return insert(AllocValueBufferInst::create(
267+
getSILDebugLocation(Loc), valueType, operand, F, OpenedArchetypes));
242268
}
243269

244270
AllocBoxInst *createAllocBox(SILLocation Loc, SILType ElementType,
245271
SILDebugVariable Var = SILDebugVariable()) {
246272
Loc.markAsPrologue();
247-
return insert(
248-
AllocBoxInst::create(getSILDebugLocation(Loc), ElementType, F, Var));
273+
return insert(AllocBoxInst::create(getSILDebugLocation(Loc), ElementType, F,
274+
OpenedArchetypes, Var));
249275
}
250276

251277
AllocExistentialBoxInst *
252278
createAllocExistentialBox(SILLocation Loc, SILType ExistentialType,
253279
CanType ConcreteType,
254280
ArrayRef<ProtocolConformanceRef> Conformances) {
255281
return insert(AllocExistentialBoxInst::create(
256-
getSILDebugLocation(Loc), ExistentialType, ConcreteType,
257-
Conformances, &F));
282+
getSILDebugLocation(Loc), ExistentialType, ConcreteType, Conformances,
283+
&F, OpenedArchetypes));
258284
}
259285

260286
ApplyInst *createApply(SILLocation Loc, SILValue Fn, SILType SubstFnTy,
261287
SILType Result, ArrayRef<Substitution> Subs,
262288
ArrayRef<SILValue> Args, bool isNonThrowing) {
263289
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, SubstFnTy,
264-
Result, Subs, Args, isNonThrowing, F));
290+
Result, Subs, Args, isNonThrowing, F,
291+
OpenedArchetypes));
265292
}
266293

267294
ApplyInst *createApply(SILLocation Loc, SILValue Fn, ArrayRef<SILValue> Args,
@@ -278,16 +305,18 @@ class SILBuilder {
278305
SILBasicBlock *errorBB) {
279306
return insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
280307
fn, substFnTy, subs, args,
281-
normalBB, errorBB, F));
308+
normalBB, errorBB, F,
309+
OpenedArchetypes));
282310
}
283311

284312
PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
285313
SILType SubstFnTy,
286314
ArrayRef<Substitution> Subs,
287315
ArrayRef<SILValue> Args,
288316
SILType ClosureTy) {
289-
return insert(PartialApplyInst::create(
290-
getSILDebugLocation(Loc), Fn, SubstFnTy, Subs, Args, ClosureTy, F));
317+
return insert(PartialApplyInst::create(getSILDebugLocation(Loc), Fn,
318+
SubstFnTy, Subs, Args, ClosureTy, F,
319+
OpenedArchetypes));
291320
}
292321

293322
BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
@@ -526,8 +555,8 @@ class SILBuilder {
526555

527556
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,
528557
SILType Ty) {
529-
return insert(new (F.getModule()) UncheckedRefCastInst(
530-
getSILDebugLocation(Loc), Op, Ty));
558+
return insert(UncheckedRefCastInst::create(getSILDebugLocation(Loc), Op, Ty,
559+
F, OpenedArchetypes));
531560
}
532561

533562
UncheckedRefCastAddrInst *
@@ -539,20 +568,20 @@ class SILBuilder {
539568

540569
UncheckedAddrCastInst *createUncheckedAddrCast(SILLocation Loc, SILValue Op,
541570
SILType Ty) {
542-
return insert(new (F.getModule()) UncheckedAddrCastInst(
543-
getSILDebugLocation(Loc), Op, Ty));
571+
return insert(UncheckedAddrCastInst::create(getSILDebugLocation(Loc), Op,
572+
Ty, F, OpenedArchetypes));
544573
}
545574

546575
UncheckedTrivialBitCastInst *
547576
createUncheckedTrivialBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
548-
return insert(new (F.getModule()) UncheckedTrivialBitCastInst(
549-
getSILDebugLocation(Loc), Op, Ty));
577+
return insert(UncheckedTrivialBitCastInst::create(
578+
getSILDebugLocation(Loc), Op, Ty, F, OpenedArchetypes));
550579
}
551580

552581
UncheckedBitwiseCastInst *
553582
createUncheckedBitwiseCast(SILLocation Loc, SILValue Op, SILType Ty) {
554-
return insert(new (F.getModule()) UncheckedBitwiseCastInst(
555-
getSILDebugLocation(Loc), Op, Ty));
583+
return insert(UncheckedBitwiseCastInst::create(getSILDebugLocation(Loc), Op,
584+
Ty, F, OpenedArchetypes));
556585
}
557586

558587
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
@@ -648,8 +677,8 @@ class SILBuilder {
648677

649678
UnconditionalCheckedCastInst *
650679
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
651-
return insert(new (F.getModule()) UnconditionalCheckedCastInst(
652-
getSILDebugLocation(Loc), op, destTy));
680+
return insert(UnconditionalCheckedCastInst::create(
681+
getSILDebugLocation(Loc), op, destTy, F, OpenedArchetypes));
653682
}
654683

655684
UnconditionalCheckedCastAddrInst *createUnconditionalCheckedCastAddr(
@@ -896,11 +925,10 @@ class SILBuilder {
896925
WitnessMethodInst *createWitnessMethod(SILLocation Loc, CanType LookupTy,
897926
ProtocolConformanceRef Conformance,
898927
SILDeclRef Member, SILType MethodTy,
899-
SILValue OptionalOpenedExistential,
900928
bool Volatile = false) {
901929
return insert(WitnessMethodInst::create(
902930
getSILDebugLocation(Loc), LookupTy, Conformance, Member, MethodTy,
903-
&F, OptionalOpenedExistential, Volatile));
931+
&F, OpenedArchetypes, Volatile));
904932
}
905933

906934
DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
@@ -912,27 +940,39 @@ class SILBuilder {
912940

913941
OpenExistentialAddrInst *
914942
createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy) {
915-
return insert(new (F.getModule()) OpenExistentialAddrInst(
943+
auto *I = insert(new (F.getModule()) OpenExistentialAddrInst(
916944
getSILDebugLocation(Loc), Operand, SelfTy));
945+
if (OpenedArchetypesTracker)
946+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
947+
return I;
917948
}
918949

919950
OpenExistentialMetatypeInst *createOpenExistentialMetatype(SILLocation Loc,
920951
SILValue operand,
921952
SILType selfTy) {
922-
return insert(new (F.getModule()) OpenExistentialMetatypeInst(
953+
auto *I = insert(new (F.getModule()) OpenExistentialMetatypeInst(
923954
getSILDebugLocation(Loc), operand, selfTy));
955+
if (OpenedArchetypesTracker)
956+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
957+
return I;
924958
}
925959

926960
OpenExistentialRefInst *
927961
createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
928-
return insert(new (F.getModule()) OpenExistentialRefInst(
962+
auto *I = insert(new (F.getModule()) OpenExistentialRefInst(
929963
getSILDebugLocation(Loc), Operand, Ty));
964+
if (OpenedArchetypesTracker)
965+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
966+
return I;
930967
}
931968

932969
OpenExistentialBoxInst *
933970
createOpenExistentialBox(SILLocation Loc, SILValue Operand, SILType Ty) {
934-
return insert(new (F.getModule()) OpenExistentialBoxInst(
971+
auto *I = insert(new (F.getModule()) OpenExistentialBoxInst(
935972
getSILDebugLocation(Loc), Operand, Ty));
973+
if (OpenedArchetypesTracker)
974+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
975+
return I;
936976
}
937977

938978
InitExistentialAddrInst *
@@ -942,25 +982,25 @@ class SILBuilder {
942982
ArrayRef<ProtocolConformanceRef> Conformances) {
943983
return insert(InitExistentialAddrInst::create(
944984
getSILDebugLocation(Loc), Existential, FormalConcreteType,
945-
LoweredConcreteType, Conformances, &F));
985+
LoweredConcreteType, Conformances, &F, OpenedArchetypes));
946986
}
947987

948988
InitExistentialMetatypeInst *
949989
createInitExistentialMetatype(SILLocation Loc, SILValue metatype,
950990
SILType existentialType,
951991
ArrayRef<ProtocolConformanceRef> conformances) {
952992
return insert(InitExistentialMetatypeInst::create(
953-
getSILDebugLocation(Loc), existentialType, metatype, conformances,
954-
&F));
993+
getSILDebugLocation(Loc), existentialType, metatype, conformances, &F,
994+
OpenedArchetypes));
955995
}
956996

957997
InitExistentialRefInst *
958998
createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
959999
CanType FormalConcreteType, SILValue Concrete,
9601000
ArrayRef<ProtocolConformanceRef> Conformances) {
9611001
return insert(InitExistentialRefInst::create(
962-
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType,
963-
Concrete, Conformances, &F));
1002+
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType, Concrete,
1003+
Conformances, &F, OpenedArchetypes));
9641004
}
9651005

9661006
DeinitExistentialAddrInst *createDeinitExistentialAddr(SILLocation Loc,
@@ -992,8 +1032,8 @@ class SILBuilder {
9921032
}
9931033

9941034
MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype) {
995-
return insert(new (F.getModule())
996-
MetatypeInst(getSILDebugLocation(Loc), Metatype));
1035+
return insert(MetatypeInst::create(getSILDebugLocation(Loc), Metatype,
1036+
&F, OpenedArchetypes));
9971037
}
9981038

9991039
ObjCMetatypeToObjectInst *
@@ -1306,9 +1346,9 @@ class SILBuilder {
13061346
SILValue op, SILType destTy,
13071347
SILBasicBlock *successBB,
13081348
SILBasicBlock *failureBB) {
1309-
return insertTerminator(new (F.getModule()) CheckedCastBranchInst(
1310-
getSILDebugLocation(Loc), isExact, op, destTy, successBB,
1311-
failureBB));
1349+
return insertTerminator(CheckedCastBranchInst::create(
1350+
getSILDebugLocation(Loc), isExact, op, destTy, successBB, failureBB, F,
1351+
OpenedArchetypes));
13121352
}
13131353

13141354
CheckedCastAddrBranchInst *

0 commit comments

Comments
 (0)