Skip to content

Commit 49bb555

Browse files
committed
SIL: Use the best resilience expansion when lowering types
This is a large patch; I couldn't split it up further while still keeping things working. There are four things being changed at once here: - Places that call SILType::isAddressOnly()/isLoadable() now call the SILFunction overload and not the SILModule one. - SILFunction's overloads of getTypeLowering() and getLoweredType() now pass the function's resilience expansion down, instead of hardcoding ResilienceExpansion::Minimal. - Various other places with '// FIXME: Expansion' now use a better resilience expansion. - A few tests were updated to reflect SILGen's improved code generation, and some new tests are added to cover more code paths that previously were uncovered and only manifested themselves as standard library build failures while I was working on this change.
1 parent 16b6501 commit 49bb555

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+548
-212
lines changed

include/swift/SIL/SILBuilder.h

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,13 @@ class SILBuilder {
198198
SILModule &getModule() const { return C.Module; }
199199
ASTContext &getASTContext() const { return getModule().getASTContext(); }
200200
const Lowering::TypeLowering &getTypeLowering(SILType T) const {
201-
// FIXME: Expansion
202-
return getModule().Types.getTypeLowering(T,
203-
ResilienceExpansion::Minimal);
201+
auto expansion = ResilienceExpansion::Maximal;
202+
// If there's no current SILFunction, we're inserting into a global
203+
// variable initializer.
204+
if (F)
205+
expansion = F->getResilienceExpansion();
206+
207+
return getModule().Types.getTypeLowering(T, expansion);
204208
}
205209

206210
void setOpenedArchetypesTracker(SILOpenedArchetypesTracker *Tracker) {
@@ -2157,15 +2161,7 @@ class SILBuilder {
21572161
if (!SILModuleConventions(M).useLoweredAddresses())
21582162
return true;
21592163

2160-
// FIXME: Just call getTypeLowering() here, and move this code there
2161-
2162-
auto expansion = ResilienceExpansion::Maximal;
2163-
// If there's no current SILFunction, we're inserting into a global
2164-
// variable initializer.
2165-
if (F)
2166-
expansion = F->getResilienceExpansion();
2167-
2168-
return M.Types.getTypeLowering(Ty, expansion).isLoadable();
2164+
return getTypeLowering(Ty).isLoadable();
21692165
}
21702166

21712167
void appendOperandTypeName(SILType OpdTy, llvm::SmallString<16> &Name) {

include/swift/SILOptimizer/Analysis/AliasAnalysis.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class AliasAnalysis : public SILAnalysis {
137137
SILType TBAAType2 = SILType());
138138

139139
/// Returns True if memory of type \p T1 and \p T2 may alias.
140-
bool typesMayAlias(SILType T1, SILType T2);
140+
bool typesMayAlias(SILType T1, SILType T2, const SILFunction &F);
141141

142142
virtual void handleDeleteNotification(SILNode *node) override {
143143
assert(node->isRepresentativeSILNodeInObject());

include/swift/SILOptimizer/Analysis/ArraySemantic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ class ArraySemanticsCall {
151151

152152
/// Replace a call to append(contentsOf: ) with a series of
153153
/// append(element: ) calls.
154-
bool replaceByAppendingValues(SILModule &M, SILFunction *AppendFn,
154+
bool replaceByAppendingValues(SILFunction *AppendFn,
155155
SILFunction *ReserveFn,
156156
const llvm::SmallVectorImpl<SILValue> &Vals,
157157
SubstitutionMap Subs);

include/swift/SILOptimizer/Utils/Generics.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,9 @@ class ReabstractionInfo {
156156
}
157157

158158
ResilienceExpansion getResilienceExpansion() const {
159-
// FIXME: Expansion
160-
return ResilienceExpansion::Minimal;
159+
return (Serialized
160+
? ResilienceExpansion::Minimal
161+
: ResilienceExpansion::Maximal);
161162
}
162163

163164
/// Returns true if the \p ParamIdx'th (non-result) formal parameter is

lib/SIL/SILFunction.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -228,45 +228,34 @@ bool SILFunction::isNoReturnFunction() const {
228228

229229
const TypeLowering &
230230
SILFunction::getTypeLowering(AbstractionPattern orig, Type subst) {
231-
// FIXME: Expansion
232231
return getModule().Types.getTypeLowering(orig, subst,
233-
ResilienceExpansion::Minimal);
232+
getResilienceExpansion());
234233
}
235234

236235
const TypeLowering &SILFunction::getTypeLowering(Type t) const {
237-
// FIXME: Expansion
238-
return getModule().Types.getTypeLowering(t, ResilienceExpansion::Minimal);
236+
return getModule().Types.getTypeLowering(t, getResilienceExpansion());
239237
}
240238

241239
SILType
242240
SILFunction::getLoweredType(AbstractionPattern orig, Type subst) const {
243-
// FIXME: Expansion
244241
return getModule().Types.getLoweredType(orig, subst,
245-
ResilienceExpansion::Minimal);
242+
getResilienceExpansion());
246243
}
247244

248245
SILType SILFunction::getLoweredType(Type t) const {
249-
// FIXME: Expansion
250-
return getModule().Types.getLoweredType(t,
251-
ResilienceExpansion::Minimal);
246+
return getModule().Types.getLoweredType(t, getResilienceExpansion());
252247
}
253248

254249
SILType SILFunction::getLoweredLoadableType(Type t) const {
255-
// FIXME: Expansion
256-
return getModule().Types.getLoweredLoadableType(t,
257-
ResilienceExpansion::Minimal);
250+
return getModule().Types.getLoweredLoadableType(t, getResilienceExpansion());
258251
}
259252

260253
const TypeLowering &SILFunction::getTypeLowering(SILType type) const {
261-
// FIXME: Expansion
262-
return getModule().Types.getTypeLowering(type,
263-
ResilienceExpansion::Minimal);
254+
return getModule().Types.getTypeLowering(type, getResilienceExpansion());
264255
}
265256

266257
bool SILFunction::isTypeABIAccessible(SILType type) const {
267-
// FIXME: Expansion
268-
return getModule().isTypeABIAccessible(type,
269-
ResilienceExpansion::Minimal);
258+
return getModule().isTypeABIAccessible(type, getResilienceExpansion());
270259
}
271260

272261
SILBasicBlock *SILFunction::createBasicBlock() {

lib/SIL/SILFunctionType.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,8 +984,9 @@ static CanSILFunctionType getSILFunctionType(
984984
// from the function to which the argument is attached.
985985
if (constant && !constant->isDefaultArgGenerator()) {
986986
if (auto function = constant->getAnyFunctionRef()) {
987-
// FIXME: Expansion
988-
auto expansion = ResilienceExpansion::Minimal;
987+
auto expansion = ResilienceExpansion::Maximal;
988+
if (constant->isSerialized())
989+
expansion = ResilienceExpansion::Minimal;
989990
lowerCaptureContextParameters(M, *function, genericSig, expansion,
990991
inputs);
991992
}

lib/SIL/SILType.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,7 @@ SILType SILType::getSILTokenType(const ASTContext &C) {
8181
}
8282

8383
bool SILType::isTrivial(const SILFunction &F) const {
84-
// FIXME: Should just call F.getTypeLowering()
85-
return F.getModule().Types.getTypeLowering(*this,
86-
ResilienceExpansion::Minimal).isTrivial();
84+
return F.getTypeLowering(*this).isTrivial();
8785
}
8886

8987
bool SILType::isReferenceCounted(SILModule &M) const {

lib/SILGen/RValue.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class ExplodeTupleValue
8585

8686
void visitType(CanType formalType, ManagedValue v) {
8787
// If we have a loadable type that has not been loaded, actually load it.
88-
if (!v.getType().isObject() && v.getType().isLoadable(SGF.getModule())) {
88+
if (!v.getType().isObject() && v.getType().isLoadable(SGF.F)) {
8989
if (v.isPlusOne(SGF)) {
9090
v = SGF.B.createLoadTake(loc, v);
9191
} else {
@@ -390,7 +390,7 @@ static void verifyHelper(ArrayRef<ManagedValue> values,
390390
auto result = Optional<ValueOwnershipKind>(ValueOwnershipKind::Any);
391391
Optional<bool> sameHaveCleanups;
392392
for (ManagedValue v : values) {
393-
assert((!SGF || !v.getType().isLoadable(SGF.get()->getModule()) ||
393+
assert((!SGF || !v.getType().isLoadable(SGF.get()->F) ||
394394
v.getType().isObject()) &&
395395
"All loadable values in an RValue must be an object");
396396

@@ -803,7 +803,7 @@ SILType RValue::getLoweredType(SILGenFunction &SGF) const & {
803803

804804
SILType RValue::getLoweredImplodedTupleType(SILGenFunction &SGF) const & {
805805
SILType loweredType = getLoweredType(SGF);
806-
if (loweredType.isAddressOnly(SGF.getModule()) &&
806+
if (loweredType.isAddressOnly(SGF.F) &&
807807
SGF.silConv.useLoweredAddresses())
808808
return loweredType.getAddressType();
809809
return loweredType.getObjectType();

lib/SILGen/SILGenApply.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4680,7 +4680,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
46804680
SGFContext C) {
46814681
// Easy case -- no payload
46824682
if (!payload) {
4683-
if (enumTy.isLoadable(SGM.M) || !silConv.useLoweredAddresses()) {
4683+
if (enumTy.isLoadable(F) || !silConv.useLoweredAddresses()) {
46844684
return emitManagedRValueWithCleanup(
46854685
B.createEnum(loc, SILValue(), element, enumTy.getObjectType()));
46864686
}
@@ -4725,7 +4725,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
47254725
}
47264726

47274727
// Loadable with payload
4728-
if (enumTy.isLoadable(SGM.M) || !silConv.useLoweredAddresses()) {
4728+
if (enumTy.isLoadable(F) || !silConv.useLoweredAddresses()) {
47294729
if (!payloadMV) {
47304730
// If the payload was indirect, we already evaluated it and
47314731
// have a single value. Otherwise, evaluate the payload.
@@ -5291,7 +5291,7 @@ ArgumentSource AccessorBaseArgPreparer::prepareAccessorAddressBaseArg() {
52915291
// If the base is currently an address, we may have to copy it.
52925292
if (shouldLoadBaseAddress()) {
52935293
if (selfParam.isConsumed() ||
5294-
base.getType().isAddressOnly(SGF.getModule())) {
5294+
base.getType().isAddressOnly(SGF.F)) {
52955295
// The load can only be a take if the base is a +1 rvalue.
52965296
auto shouldTake = IsTake_t(base.hasCleanup());
52975297

lib/SILGen/SILGenBuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,8 @@ ManagedValue SILGenBuilder::createOptionalSome(SILLocation loc,
698698

699699
ManagedValue SILGenBuilder::createManagedOptionalNone(SILLocation loc,
700700
SILType type) {
701-
if (!type.isAddressOnly(getModule()) || !SGF.silConv.useLoweredAddresses()) {
701+
if (!type.isAddressOnly(getFunction()) ||
702+
!SGF.silConv.useLoweredAddresses()) {
702703
SILValue noneValue = createOptionalNone(loc, type);
703704
return ManagedValue::forUnmanaged(noneValue);
704705
}

lib/SILGen/SILGenConstructor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ static RValue emitImplicitValueConstructorArg(SILGenFunction &SGF,
8787

8888
// This can happen if the value is resilient in the calling convention
8989
// but not resilient locally.
90-
if (argType.isLoadable(SGF.SGM.M) && argType.isAddress()) {
90+
if (argType.isLoadable(SGF.F) && argType.isAddress()) {
9191
if (mvArg.isPlusOne(SGF))
9292
mvArg = SGF.B.createLoadTake(loc, mvArg);
9393
else
@@ -109,7 +109,7 @@ static void emitImplicitValueConstructor(SILGenFunction &SGF,
109109

110110
// Emit the indirect return argument, if any.
111111
SILValue resultSlot;
112-
if (selfTy.isAddressOnly(SGF.SGM.M) && SGF.silConv.useLoweredAddresses()) {
112+
if (SILModuleConventions::isReturnedIndirectlyInSIL(selfTy, SGF.SGM.M)) {
113113
auto &AC = SGF.getASTContext();
114114
auto VD = new (AC) ParamDecl(VarDecl::Specifier::InOut,
115115
SourceLoc(), SourceLoc(),

lib/SILGen/SILGenDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ void TupleInitialization::copyOrInitValueInto(SILGenFunction &SGF,
111111
SILType fieldType) -> ManagedValue {
112112
ManagedValue elt =
113113
SGF.B.createTupleElementAddr(loc, value, i, fieldType);
114-
if (!fieldType.isAddressOnly(SGF.F.getModule())) {
114+
if (!fieldType.isAddressOnly(SGF.F)) {
115115
return SGF.B.createLoadTake(loc, elt);
116116
}
117117

lib/SILGen/SILGenExpr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4376,7 +4376,7 @@ ManagedValue SILGenFunction::emitBindOptional(SILLocation loc,
43764376

43774377
// If optValue was loadable, we emitted a switch_enum. In such a case, return
43784378
// the argument from hasValueBB.
4379-
if (optValue.getType().isLoadable(F.getModule())) {
4379+
if (optValue.getType().isLoadable(F)) {
43804380
return emitManagedRValueWithCleanup(hasValueBB->getArgument(0));
43814381
}
43824382

lib/SILGen/SILGenFunction.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -200,8 +200,7 @@ void SILGenFunction::emitCaptures(SILLocation loc,
200200

201201
auto *vd = capture.getDecl();
202202

203-
// FIXME: Expansion
204-
auto expansion = ResilienceExpansion::Minimal;
203+
auto expansion = F.getResilienceExpansion();
205204
switch (SGM.Types.getDeclCaptureKind(capture, expansion)) {
206205
case CaptureKind::None:
207206
break;

lib/SILGen/SILGenPattern.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ forwardIntoSubtree(SILGenFunction &SGF, SILLocation loc,
757757
}
758758

759759
// Only address only values use TakeOnSuccess.
760-
assert(outerMV.getType().isAddressOnly(SGF.getModule()) &&
760+
assert(outerMV.getType().isAddressOnly(SGF.F) &&
761761
"TakeOnSuccess can only be used with address only values");
762762

763763
assert((consumptionKind == CastConsumptionKind::TakeAlways ||
@@ -1434,7 +1434,7 @@ emitTupleDispatch(ArrayRef<RowToSpecialize> rows, ConsumableManagedValue src,
14341434
SILLocation loc = firstPat;
14351435

14361436
// If our source is an address that is loadable, perform a load_borrow.
1437-
if (src.getType().isAddress() && src.getType().isLoadable(SGF.getModule())) {
1437+
if (src.getType().isAddress() && src.getType().isLoadable(SGF.F)) {
14381438
// We should only see take_on_success if we have a base type that is address
14391439
// only.
14401440
assert(src.getFinalConsumption() != CastConsumptionKind::TakeOnSuccess &&
@@ -1476,7 +1476,7 @@ emitTupleDispatch(ArrayRef<RowToSpecialize> rows, ConsumableManagedValue src,
14761476
// At this point we know that we must have an address only type, since we
14771477
// would have loaded it earlier.
14781478
SILValue v = src.getFinalManagedValue().forward(SGF);
1479-
assert(v->getType().isAddressOnly(SGF.getModule()) &&
1479+
assert(v->getType().isAddressOnly(SGF.F) &&
14801480
"Loadable values were handled earlier");
14811481

14821482
// The destructured tuple that we pass off to our sub pattern. This may
@@ -1609,7 +1609,7 @@ emitCastOperand(SILGenFunction &SGF, SILLocation loc,
16091609
// We know that we must have a loadable type at this point since address only
16101610
// types do not need reabstraction and are addresses. So we should have exited
16111611
// above already.
1612-
assert(src.getType().isLoadable(SGF.getModule()) &&
1612+
assert(src.getType().isLoadable(SGF.F) &&
16131613
"Should have a loadable value at this point");
16141614

16151615
// Since our finalValue is loadable, we could not have had a take_on_success
@@ -1988,7 +1988,7 @@ void PatternMatchEmission::emitEnumElementDispatch(
19881988
loc.setDebugLoc(rows[0].Pattern);
19891989

19901990
// If our source is an address that is loadable, perform a load_borrow.
1991-
if (src.getType().isAddress() && src.getType().isLoadable(SGF.getModule())) {
1991+
if (src.getType().isAddress() && src.getType().isLoadable(SGF.F)) {
19921992
assert(src.getFinalConsumption() != CastConsumptionKind::TakeOnSuccess &&
19931993
"Can only have take_on_success with address only values");
19941994
src = {SGF.B.createLoadBorrow(loc, src.getFinalManagedValue()),
@@ -2008,7 +2008,7 @@ void PatternMatchEmission::emitEnumElementDispatch(
20082008
}
20092009

20102010
// After this point we now that we must have an address only type.
2011-
assert(src.getType().isAddressOnly(SGF.getModule()) &&
2011+
assert(src.getType().isAddressOnly(SGF.F) &&
20122012
"Should have an address only type here");
20132013

20142014
CanType sourceType = rows[0].Pattern->getType()->getCanonicalType();
@@ -2339,8 +2339,8 @@ void PatternMatchEmission::initSharedCaseBlockDest(CaseStmt *caseBlock,
23392339

23402340
// We don't pass address-only values in basic block arguments.
23412341
SILType ty = SGF.getLoweredType(vd->getType());
2342-
if (ty.isAddressOnly(SGF.F.getModule()))
2343-
continue;
2342+
if (ty.isAddressOnly(SGF.F))
2343+
return;
23442344
block->createPhiArgument(ty, ValueOwnershipKind::Owned, vd);
23452345
}
23462346
}
@@ -2369,7 +2369,7 @@ void PatternMatchEmission::emitAddressOnlyAllocations() {
23692369
continue;
23702370

23712371
SILType ty = SGF.getLoweredType(vd->getType());
2372-
if (!ty.isAddressOnly(SGF.F.getModule()))
2372+
if (!ty.isAddressOnly(SGF.F))
23732373
continue;
23742374
assert(!Temporaries[vd]);
23752375
Temporaries[vd] = SGF.emitTemporaryAllocation(vd, ty);
@@ -2448,7 +2448,7 @@ void PatternMatchEmission::emitSharedCaseBlocks() {
24482448
// Initialize mv at +1. We always pass values in at +1 for today into
24492449
// shared blocks.
24502450
ManagedValue mv;
2451-
if (ty.isAddressOnly(SGF.F.getModule())) {
2451+
if (ty.isAddressOnly(SGF.F)) {
24522452
// There's no basic block argument, since we don't allow basic blocks
24532453
// to have address arguments.
24542454
//
@@ -2661,7 +2661,7 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
26612661
// If we have an address-only type, initialize the temporary
26622662
// allocation. We're not going to pass the address as a block
26632663
// argument.
2664-
if (type.isAddressOnly(M)) {
2664+
if (type.isAddressOnly(SGF.F)) {
26652665
emission.emitAddressOnlyInitialization(expected, value);
26662666
break;
26672667
}
@@ -2755,15 +2755,15 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
27552755
if (subjectMV.isPlusOne(*this)) {
27562756
// And we have an address that is loadable, perform a load [take].
27572757
if (subjectMV.getType().isAddress() &&
2758-
subjectMV.getType().isLoadable(getModule())) {
2758+
subjectMV.getType().isLoadable(F)) {
27592759
subjectMV = B.createLoadTake(S, subjectMV);
27602760
}
27612761
return {subjectMV, CastConsumptionKind::TakeAlways};
27622762
}
27632763

27642764
// If we have a loadable address and +0, perform a load borrow.
27652765
if (subjectMV.getType().isAddress() &&
2766-
subjectMV.getType().isLoadable(getModule())) {
2766+
subjectMV.getType().isLoadable(F)) {
27672767
subjectMV = B.createLoadBorrow(S, subjectMV);
27682768
}
27692769

@@ -2859,7 +2859,7 @@ void SILGenFunction::emitSwitchFallthrough(FallthroughStmt *S) {
28592859
auto varLoc = VarLocs[var];
28602860
SILValue value = varLoc.value;
28612861

2862-
if (value->getType().isAddressOnly(M)) {
2862+
if (value->getType().isAddressOnly(F)) {
28632863
context->Emission.emitAddressOnlyInitialization(expected, value);
28642864
break;
28652865
}

lib/SILGen/SILGenProlog.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
127127

128128
// This can happen if the value is resilient in the calling convention
129129
// but not resilient locally.
130-
if (argType.isLoadable(SGF.SGM.M) && argType.isAddress()) {
130+
if (argType.isLoadable(SGF.F) && argType.isAddress()) {
131131
if (mv.isPlusOne(SGF))
132132
mv = SGF.B.createLoadTake(loc, mv);
133133
else
@@ -354,8 +354,7 @@ static void emitCaptureArguments(SILGenFunction &SGF,
354354
closure.getGenericEnvironment(), interfaceType);
355355
};
356356

357-
// FIXME: Expansion
358-
auto expansion = ResilienceExpansion::Minimal;
357+
auto expansion = SGF.F.getResilienceExpansion();
359358
switch (SGF.SGM.Types.getDeclCaptureKind(capture, expansion)) {
360359
case CaptureKind::None:
361360
break;

lib/SILGen/Scope.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ static void lifetimeExtendAddressOnlyRValueSubValues(
5353
}
5454

5555
// Otherwise, create the box and move the address only value into the box.
56-
assert(v->getType().isAddressOnly(SGF.getModule()) &&
56+
assert(v->getType().isAddressOnly(SGF.F) &&
5757
"RValue invariants imply that all RValue subtypes that are "
5858
"addresses must be address only.");
5959
auto boxTy = SILBoxType::get(v->getType().getASTType());

0 commit comments

Comments
 (0)