Skip to content

Commit 8ef8bb4

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 7b226ad commit 8ef8bb4

29 files changed

+1568
-283
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 68 additions & 30 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

@@ -261,7 +285,8 @@ class SILBuilder {
261285
SILType Result, ArrayRef<Substitution> Subs,
262286
ArrayRef<SILValue> Args, bool isNonThrowing) {
263287
return insert(ApplyInst::create(getSILDebugLocation(Loc), Fn, SubstFnTy,
264-
Result, Subs, Args, isNonThrowing, F));
288+
Result, Subs, Args, isNonThrowing, F,
289+
OpenedArchetypes));
265290
}
266291

267292
ApplyInst *createApply(SILLocation Loc, SILValue Fn, ArrayRef<SILValue> Args,
@@ -278,16 +303,18 @@ class SILBuilder {
278303
SILBasicBlock *errorBB) {
279304
return insertTerminator(TryApplyInst::create(getSILDebugLocation(Loc),
280305
fn, substFnTy, subs, args,
281-
normalBB, errorBB, F));
306+
normalBB, errorBB, F,
307+
OpenedArchetypes));
282308
}
283309

284310
PartialApplyInst *createPartialApply(SILLocation Loc, SILValue Fn,
285311
SILType SubstFnTy,
286312
ArrayRef<Substitution> Subs,
287313
ArrayRef<SILValue> Args,
288314
SILType ClosureTy) {
289-
return insert(PartialApplyInst::create(
290-
getSILDebugLocation(Loc), Fn, SubstFnTy, Subs, Args, ClosureTy, F));
315+
return insert(PartialApplyInst::create(getSILDebugLocation(Loc), Fn,
316+
SubstFnTy, Subs, Args, ClosureTy, F,
317+
OpenedArchetypes));
291318
}
292319

293320
BuiltinInst *createBuiltin(SILLocation Loc, Identifier Name, SILType ResultTy,
@@ -526,8 +553,8 @@ class SILBuilder {
526553

527554
UncheckedRefCastInst *createUncheckedRefCast(SILLocation Loc, SILValue Op,
528555
SILType Ty) {
529-
return insert(new (F.getModule()) UncheckedRefCastInst(
530-
getSILDebugLocation(Loc), Op, Ty));
556+
return insert(UncheckedRefCastInst::create(getSILDebugLocation(Loc), Op, Ty,
557+
F, OpenedArchetypes));
531558
}
532559

533560
UncheckedRefCastAddrInst *
@@ -539,20 +566,20 @@ class SILBuilder {
539566

540567
UncheckedAddrCastInst *createUncheckedAddrCast(SILLocation Loc, SILValue Op,
541568
SILType Ty) {
542-
return insert(new (F.getModule()) UncheckedAddrCastInst(
543-
getSILDebugLocation(Loc), Op, Ty));
569+
return insert(UncheckedAddrCastInst::create(getSILDebugLocation(Loc), Op,
570+
Ty, F, OpenedArchetypes));
544571
}
545572

546573
UncheckedTrivialBitCastInst *
547574
createUncheckedTrivialBitCast(SILLocation Loc, SILValue Op, SILType Ty) {
548-
return insert(new (F.getModule()) UncheckedTrivialBitCastInst(
549-
getSILDebugLocation(Loc), Op, Ty));
575+
return insert(UncheckedTrivialBitCastInst::create(
576+
getSILDebugLocation(Loc), Op, Ty, F, OpenedArchetypes));
550577
}
551578

552579
UncheckedBitwiseCastInst *
553580
createUncheckedBitwiseCast(SILLocation Loc, SILValue Op, SILType Ty) {
554-
return insert(new (F.getModule()) UncheckedBitwiseCastInst(
555-
getSILDebugLocation(Loc), Op, Ty));
581+
return insert(UncheckedBitwiseCastInst::create(getSILDebugLocation(Loc), Op,
582+
Ty, F, OpenedArchetypes));
556583
}
557584

558585
RefToBridgeObjectInst *createRefToBridgeObject(SILLocation Loc, SILValue Ref,
@@ -648,8 +675,8 @@ class SILBuilder {
648675

649676
UnconditionalCheckedCastInst *
650677
createUnconditionalCheckedCast(SILLocation Loc, SILValue op, SILType destTy) {
651-
return insert(new (F.getModule()) UnconditionalCheckedCastInst(
652-
getSILDebugLocation(Loc), op, destTy));
678+
return insert(UnconditionalCheckedCastInst::create(
679+
getSILDebugLocation(Loc), op, destTy, F, OpenedArchetypes));
653680
}
654681

655682
UnconditionalCheckedCastAddrInst *createUnconditionalCheckedCastAddr(
@@ -896,11 +923,10 @@ class SILBuilder {
896923
WitnessMethodInst *createWitnessMethod(SILLocation Loc, CanType LookupTy,
897924
ProtocolConformanceRef Conformance,
898925
SILDeclRef Member, SILType MethodTy,
899-
SILValue OptionalOpenedExistential,
900926
bool Volatile = false) {
901927
return insert(WitnessMethodInst::create(
902928
getSILDebugLocation(Loc), LookupTy, Conformance, Member, MethodTy,
903-
&F, OptionalOpenedExistential, Volatile));
929+
&F, OpenedArchetypes, Volatile));
904930
}
905931

906932
DynamicMethodInst *createDynamicMethod(SILLocation Loc, SILValue Operand,
@@ -912,27 +938,39 @@ class SILBuilder {
912938

913939
OpenExistentialAddrInst *
914940
createOpenExistentialAddr(SILLocation Loc, SILValue Operand, SILType SelfTy) {
915-
return insert(new (F.getModule()) OpenExistentialAddrInst(
941+
auto *I = insert(new (F.getModule()) OpenExistentialAddrInst(
916942
getSILDebugLocation(Loc), Operand, SelfTy));
943+
if (OpenedArchetypesTracker)
944+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
945+
return I;
917946
}
918947

919948
OpenExistentialMetatypeInst *createOpenExistentialMetatype(SILLocation Loc,
920949
SILValue operand,
921950
SILType selfTy) {
922-
return insert(new (F.getModule()) OpenExistentialMetatypeInst(
951+
auto *I = insert(new (F.getModule()) OpenExistentialMetatypeInst(
923952
getSILDebugLocation(Loc), operand, selfTy));
953+
if (OpenedArchetypesTracker)
954+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
955+
return I;
924956
}
925957

926958
OpenExistentialRefInst *
927959
createOpenExistentialRef(SILLocation Loc, SILValue Operand, SILType Ty) {
928-
return insert(new (F.getModule()) OpenExistentialRefInst(
960+
auto *I = insert(new (F.getModule()) OpenExistentialRefInst(
929961
getSILDebugLocation(Loc), Operand, Ty));
962+
if (OpenedArchetypesTracker)
963+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
964+
return I;
930965
}
931966

932967
OpenExistentialBoxInst *
933968
createOpenExistentialBox(SILLocation Loc, SILValue Operand, SILType Ty) {
934-
return insert(new (F.getModule()) OpenExistentialBoxInst(
969+
auto *I = insert(new (F.getModule()) OpenExistentialBoxInst(
935970
getSILDebugLocation(Loc), Operand, Ty));
971+
if (OpenedArchetypesTracker)
972+
OpenedArchetypesTracker->registerOpenedArchetypes(I);
973+
return I;
936974
}
937975

938976
InitExistentialAddrInst *
@@ -942,25 +980,25 @@ class SILBuilder {
942980
ArrayRef<ProtocolConformanceRef> Conformances) {
943981
return insert(InitExistentialAddrInst::create(
944982
getSILDebugLocation(Loc), Existential, FormalConcreteType,
945-
LoweredConcreteType, Conformances, &F));
983+
LoweredConcreteType, Conformances, &F, OpenedArchetypes));
946984
}
947985

948986
InitExistentialMetatypeInst *
949987
createInitExistentialMetatype(SILLocation Loc, SILValue metatype,
950988
SILType existentialType,
951989
ArrayRef<ProtocolConformanceRef> conformances) {
952990
return insert(InitExistentialMetatypeInst::create(
953-
getSILDebugLocation(Loc), existentialType, metatype, conformances,
954-
&F));
991+
getSILDebugLocation(Loc), existentialType, metatype, conformances, &F,
992+
OpenedArchetypes));
955993
}
956994

957995
InitExistentialRefInst *
958996
createInitExistentialRef(SILLocation Loc, SILType ExistentialType,
959997
CanType FormalConcreteType, SILValue Concrete,
960998
ArrayRef<ProtocolConformanceRef> Conformances) {
961999
return insert(InitExistentialRefInst::create(
962-
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType,
963-
Concrete, Conformances, &F));
1000+
getSILDebugLocation(Loc), ExistentialType, FormalConcreteType, Concrete,
1001+
Conformances, &F, OpenedArchetypes));
9641002
}
9651003

9661004
DeinitExistentialAddrInst *createDeinitExistentialAddr(SILLocation Loc,
@@ -992,8 +1030,8 @@ class SILBuilder {
9921030
}
9931031

9941032
MetatypeInst *createMetatype(SILLocation Loc, SILType Metatype) {
995-
return insert(new (F.getModule())
996-
MetatypeInst(getSILDebugLocation(Loc), Metatype));
1033+
return insert(MetatypeInst::create(getSILDebugLocation(Loc), Metatype,
1034+
&F, OpenedArchetypes));
9971035
}
9981036

9991037
ObjCMetatypeToObjectInst *
@@ -1306,9 +1344,9 @@ class SILBuilder {
13061344
SILValue op, SILType destTy,
13071345
SILBasicBlock *successBB,
13081346
SILBasicBlock *failureBB) {
1309-
return insertTerminator(new (F.getModule()) CheckedCastBranchInst(
1310-
getSILDebugLocation(Loc), isExact, op, destTy, successBB,
1311-
failureBB));
1347+
return insertTerminator(CheckedCastBranchInst::create(
1348+
getSILDebugLocation(Loc), isExact, op, destTy, successBB, failureBB, F,
1349+
OpenedArchetypes));
13121350
}
13131351

13141352
CheckedCastAddrBranchInst *

include/swift/SIL/SILCloner.h

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_SIL_SILCLONER_H
1818
#define SWIFT_SIL_SILCLONER_H
1919

20+
#include "swift/SIL/SILOpenedArchetypesTracker.h"
2021
#include "swift/SIL/SILBuilder.h"
2122
#include "swift/SIL/SILDebugScope.h"
2223
#include "swift/SIL/SILVisitor.h"
@@ -39,9 +40,19 @@ class SILCloner : protected SILVisitor<ImplClass> {
3940
public:
4041
using SILVisitor<ImplClass>::asImpl;
4142

43+
explicit SILCloner(SILFunction &F,
44+
SILOpenedArchetypesTracker &OpenedArchetypesTracker)
45+
: Builder(F), InsertBeforeBB(nullptr),
46+
OpenedArchetypesTracker(OpenedArchetypesTracker) {
47+
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
48+
}
49+
4250
explicit SILCloner(SILFunction &F)
43-
: Builder(F), InsertBeforeBB(nullptr) { }
44-
51+
: Builder(F), InsertBeforeBB(nullptr),
52+
OpenedArchetypesTracker(F) {
53+
Builder.setOpenedArchetypesTracker(&OpenedArchetypesTracker);
54+
}
55+
4556
/// Clients of SILCloner who want to know about any newly created
4657
/// instructions can install a SmallVector into the builder to collect them.
4758
void setTrackingList(SmallVectorImpl<SILInstruction*> *II) {
@@ -199,6 +210,14 @@ class SILCloner : protected SILVisitor<ImplClass> {
199210
void cleanUp(SILFunction *F);
200211

201212
public:
213+
void doPreProcess(SILInstruction *Orig) {
214+
// Extend the set of available opened archetypes by the opened archetypes
215+
// used by the instruction being cloned.
216+
auto OpenedArchetypeOperands = Orig->getOpenedArchetypeOperands();
217+
Builder.getOpenedArchetypes().addOpenedArchetypeOperands(
218+
OpenedArchetypeOperands);
219+
}
220+
202221
void doPostProcess(SILInstruction *Orig, SILInstruction *Cloned) {
203222
asImpl().postProcess(Orig, Cloned);
204223
assert((Orig->getDebugScope() ? Cloned->getDebugScope()!=nullptr : true) &&
@@ -217,6 +236,8 @@ class SILCloner : protected SILVisitor<ImplClass> {
217236
llvm::MapVector<SILBasicBlock*, SILBasicBlock*> BBMap;
218237

219238
TypeSubstitutionMap OpenedExistentialSubs;
239+
SILOpenedArchetypesTracker OpenedArchetypesTracker;
240+
220241
/// Set of basic blocks where unreachable was inserted.
221242
SmallPtrSet<SILBasicBlock *, 32> BlocksWithUnreachables;
222243
};
@@ -253,8 +274,27 @@ template<typename ImplClass>
253274
class SILClonerWithScopes : public SILCloner<ImplClass> {
254275
friend class SILCloner<ImplClass>;
255276
public:
256-
SILClonerWithScopes(SILFunction &To, bool Disable = false)
257-
: SILCloner<ImplClass>(To) {
277+
SILClonerWithScopes(SILFunction &To,
278+
SILOpenedArchetypesTracker &OpenedArchetypesTracker,
279+
bool Disable = false)
280+
: SILCloner<ImplClass>(To, OpenedArchetypesTracker) {
281+
282+
// We only want to do this when we generate cloned functions, not
283+
// when we inline.
284+
285+
// FIXME: This is due to having TypeSubstCloner inherit from
286+
// SILClonerWithScopes, and having TypeSubstCloner be used
287+
// both by passes that clone whole functions and ones that
288+
// inline functions.
289+
if (Disable)
290+
return;
291+
292+
scopeCloner.reset(new ScopeCloner(To));
293+
}
294+
295+
SILClonerWithScopes(SILFunction &To,
296+
bool Disable = false)
297+
: SILCloner<ImplClass>(To) {
258298

259299
// We only want to do this when we generate cloned functions, not
260300
// when we inline.
@@ -269,6 +309,7 @@ class SILClonerWithScopes : public SILCloner<ImplClass> {
269309
scopeCloner.reset(new ScopeCloner(To));
270310
}
271311

312+
272313
private:
273314
std::unique_ptr<ScopeCloner> scopeCloner;
274315
protected:
@@ -333,8 +374,12 @@ void
333374
SILCloner<ImplClass>::visitSILBasicBlock(SILBasicBlock* BB) {
334375
SILFunction &F = getBuilder().getFunction();
335376
// Iterate over and visit all instructions other than the terminator to clone.
336-
for (auto I = BB->begin(), E = --BB->end(); I != E; ++I)
377+
for (auto I = BB->begin(), E = --BB->end(); I != E; ++I) {
378+
// Update the set of available opened archetypes with the opned archetypes
379+
// used by the current instruction.
380+
doPreProcess(&*I);
337381
asImpl().visit(&*I);
382+
}
338383
// Iterate over successors to do the depth-first search.
339384
for (auto &Succ : BB->getSuccessors()) {
340385
auto BBI = BBMap.find(Succ);
@@ -1251,16 +1296,17 @@ template<typename ImplClass>
12511296
void
12521297
SILCloner<ImplClass>::visitWitnessMethodInst(WitnessMethodInst *Inst) {
12531298
auto conformance =
1254-
getOpConformance(Inst->getLookupType(), Inst->getConformance());
1299+
getOpConformance(Inst->getLookupType(), Inst->getConformance());
1300+
auto lookupType = Inst->getLookupType();
1301+
auto newLookupType = getOpASTType(lookupType);
12551302
getBuilder().setCurrentDebugScope(getOpScope(Inst->getDebugScope()));
12561303
doPostProcess(
12571304
Inst,
12581305
getBuilder()
12591306
.createWitnessMethod(
12601307
getOpLocation(Inst->getLoc()),
1261-
getOpASTType(Inst->getLookupType()), conformance,
1308+
newLookupType, conformance,
12621309
Inst->getMember(), getOpType(Inst->getType()),
1263-
Inst->hasOperand() ? getOpValue(Inst->getOperand()) : SILValue(),
12641310
Inst->isVolatile()));
12651311
}
12661312

0 commit comments

Comments
 (0)