Skip to content

Commit 16d5716

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 fb8bd3a commit 16d5716

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
-214
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) {
@@ -2158,15 +2162,7 @@ class SILBuilder {
21582162
if (!SILModuleConventions(M).useLoweredAddresses())
21592163
return true;
21602164

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

21722168
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
@@ -1005,8 +1005,9 @@ static CanSILFunctionType getSILFunctionType(
10051005
// from the function to which the argument is attached.
10061006
if (constant && !constant->isDefaultArgGenerator()) {
10071007
if (auto function = constant->getAnyFunctionRef()) {
1008-
// FIXME: Expansion
1009-
auto expansion = ResilienceExpansion::Minimal;
1008+
auto expansion = ResilienceExpansion::Maximal;
1009+
if (constant->isSerialized())
1010+
expansion = ResilienceExpansion::Minimal;
10101011
lowerCaptureContextParameters(M, *function, genericSig, expansion,
10111012
inputs);
10121013
}

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
@@ -4669,7 +4669,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
46694669
SGFContext C) {
46704670
// Easy case -- no payload
46714671
if (!payload) {
4672-
if (enumTy.isLoadable(SGM.M) || !silConv.useLoweredAddresses()) {
4672+
if (enumTy.isLoadable(F) || !silConv.useLoweredAddresses()) {
46734673
return emitManagedRValueWithCleanup(
46744674
B.createEnum(loc, SILValue(), element, enumTy.getObjectType()));
46754675
}
@@ -4714,7 +4714,7 @@ ManagedValue SILGenFunction::emitInjectEnum(SILLocation loc,
47144714
}
47154715

47164716
// Loadable with payload
4717-
if (enumTy.isLoadable(SGM.M) || !silConv.useLoweredAddresses()) {
4717+
if (enumTy.isLoadable(F) || !silConv.useLoweredAddresses()) {
47184718
if (!payloadMV) {
47194719
// If the payload was indirect, we already evaluated it and
47204720
// have a single value. Otherwise, evaluate the payload.
@@ -5304,7 +5304,7 @@ ArgumentSource AccessorBaseArgPreparer::prepareAccessorAddressBaseArg() {
53045304
// If the base is currently an address, we may have to copy it.
53055305
if (shouldLoadBaseAddress()) {
53065306
if (selfParam.isConsumed() ||
5307-
base.getType().isAddressOnly(SGF.getModule())) {
5307+
base.getType().isAddressOnly(SGF.F)) {
53085308
// The load can only be a take if the base is a +1 rvalue.
53095309
auto shouldTake = IsTake_t(base.hasCleanup());
53105310

lib/SILGen/SILGenBuilder.cpp

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

553553
ManagedValue SILGenBuilder::createManagedOptionalNone(SILLocation loc,
554554
SILType type) {
555-
if (!type.isAddressOnly(getModule()) || !SGF.silConv.useLoweredAddresses()) {
555+
if (!type.isAddressOnly(getFunction()) ||
556+
!SGF.silConv.useLoweredAddresses()) {
556557
SILValue noneValue = createOptionalNone(loc, type);
557558
return ManagedValue::forUnmanaged(noneValue);
558559
}

lib/SILGen/SILGenConstructor.cpp

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

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

141141
// Emit the indirect return argument, if any.
142142
SILValue resultSlot;
143-
if (selfTy.isAddressOnly(SGF.SGM.M) && SGF.silConv.useLoweredAddresses()) {
143+
if (SILModuleConventions::isReturnedIndirectlyInSIL(selfTy, SGF.SGM.M)) {
144144
auto &AC = SGF.getASTContext();
145145
auto VD = new (AC) ParamDecl(VarDecl::Specifier::InOut,
146146
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
@@ -4424,7 +4424,7 @@ ManagedValue SILGenFunction::emitBindOptional(SILLocation loc,
44244424

44254425
// If optValue was loadable, we emitted a switch_enum. In such a case, return
44264426
// the argument from hasValueBB.
4427-
if (optValue.getType().isLoadable(F.getModule())) {
4427+
if (optValue.getType().isLoadable(F)) {
44284428
return emitManagedRValueWithCleanup(hasValueBB->getArgument(0));
44294429
}
44304430

lib/SILGen/SILGenFunction.cpp

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

209209
auto *vd = capture.getDecl();
210210

211-
// FIXME: Expansion
212-
auto expansion = ResilienceExpansion::Minimal;
211+
auto expansion = F.getResilienceExpansion();
213212
switch (SGM.Types.getDeclCaptureKind(capture, expansion)) {
214213
case CaptureKind::None:
215214
break;

lib/SILGen/SILGenPattern.cpp

Lines changed: 14 additions & 16 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
//
@@ -2654,7 +2654,6 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
26542654
// are threaded through here messily, but the explicit retains here counteract
26552655
// them, and then the retain/release pair gets optimized out.)
26562656
SmallVector<SILValue, 4> args;
2657-
SILModule &M = SGF.F.getModule();
26582657
SmallVector<VarDecl *, 4> patternVars;
26592658
row.getCasePattern()->collectVariables(patternVars);
26602659
for (auto *expected : caseBlock->getCaseBodyVariables()) {
@@ -2670,7 +2669,7 @@ static void switchCaseStmtSuccessCallback(SILGenFunction &SGF,
26702669
// If we have an address-only type, initialize the temporary
26712670
// allocation. We're not going to pass the address as a block
26722671
// argument.
2673-
if (type.isAddressOnly(M)) {
2672+
if (type.isAddressOnly(SGF.F)) {
26742673
emission.emitAddressOnlyInitialization(expected, value);
26752674
break;
26762675
}
@@ -2764,15 +2763,15 @@ void SILGenFunction::emitSwitchStmt(SwitchStmt *S) {
27642763
if (subjectMV.isPlusOne(*this)) {
27652764
// And we have an address that is loadable, perform a load [take].
27662765
if (subjectMV.getType().isAddress() &&
2767-
subjectMV.getType().isLoadable(getModule())) {
2766+
subjectMV.getType().isLoadable(F)) {
27682767
subjectMV = B.createLoadTake(S, subjectMV);
27692768
}
27702769
return {subjectMV, CastConsumptionKind::TakeAlways};
27712770
}
27722771

27732772
// If we have a loadable address and +0, perform a load borrow.
27742773
if (subjectMV.getType().isAddress() &&
2775-
subjectMV.getType().isLoadable(getModule())) {
2774+
subjectMV.getType().isLoadable(F)) {
27762775
subjectMV = B.createLoadBorrow(S, subjectMV);
27772776
}
27782777

@@ -2880,7 +2879,6 @@ void SILGenFunction::emitSwitchFallthrough(FallthroughStmt *S) {
28802879
}
28812880

28822881
// Generate branch args to pass along current vars to fallthrough case.
2883-
SILModule &M = F.getModule();
28842882
SmallVector<SILValue, 4> args;
28852883
CaseStmt *fallthroughSourceStmt = S->getFallthroughSource();
28862884

@@ -2898,7 +2896,7 @@ void SILGenFunction::emitSwitchFallthrough(FallthroughStmt *S) {
28982896
auto varLoc = VarLocs[var];
28992897
SILValue value = varLoc.value;
29002898

2901-
if (value->getType().isAddressOnly(M)) {
2899+
if (value->getType().isAddressOnly(F)) {
29022900
context->Emission.emitAddressOnlyInitialization(expected, value);
29032901
break;
29042902
}

0 commit comments

Comments
 (0)