Skip to content

Commit 00955c1

Browse files
authored
Merge pull request #23648 from Azoy/maybe-add-default-arg-generator
[SILGen] Emit default arg generator for stored property kind
2 parents 167341a + bbf680d commit 00955c1

File tree

10 files changed

+276
-73
lines changed

10 files changed

+276
-73
lines changed

lib/SILGen/SILGen.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,19 +1060,41 @@ void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) {
10601060
}
10611061
}
10621062

1063-
void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, Expr *arg,
1064-
DefaultArgumentKind kind,
1065-
DeclContext *initDC) {
1066-
switch (kind) {
1063+
void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant,
1064+
ParamDecl *param) {
1065+
auto initDC = param->getDefaultArgumentInitContext();
1066+
1067+
switch (param->getDefaultArgumentKind()) {
10671068
case DefaultArgumentKind::None:
10681069
llvm_unreachable("No default argument here?");
10691070

1070-
case DefaultArgumentKind::Normal:
1071-
break;
1071+
case DefaultArgumentKind::Normal: {
1072+
auto arg = param->getDefaultValue();
1073+
emitOrDelayFunction(*this, constant,
1074+
[this,constant,arg,initDC](SILFunction *f) {
1075+
preEmitFunction(constant, arg, f, arg);
1076+
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
1077+
SILGenFunction SGF(*this, *f, initDC);
1078+
SGF.emitGeneratorFunction(constant, arg);
1079+
postEmitFunction(constant, f);
1080+
});
1081+
return;
1082+
}
10721083

1073-
case DefaultArgumentKind::Inherited:
1084+
case DefaultArgumentKind::StoredProperty: {
1085+
auto arg = param->getStoredProperty();
1086+
emitOrDelayFunction(*this, constant,
1087+
[this,constant,arg,initDC](SILFunction *f) {
1088+
preEmitFunction(constant, arg, f, arg);
1089+
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
1090+
SILGenFunction SGF(*this, *f, initDC);
1091+
SGF.emitGeneratorFunction(constant, arg);
1092+
postEmitFunction(constant, f);
1093+
});
10741094
return;
1095+
}
10751096

1097+
case DefaultArgumentKind::Inherited:
10761098
case DefaultArgumentKind::Column:
10771099
case DefaultArgumentKind::File:
10781100
case DefaultArgumentKind::Line:
@@ -1081,18 +1103,8 @@ void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, Expr *arg,
10811103
case DefaultArgumentKind::NilLiteral:
10821104
case DefaultArgumentKind::EmptyArray:
10831105
case DefaultArgumentKind::EmptyDictionary:
1084-
case DefaultArgumentKind::StoredProperty:
10851106
return;
10861107
}
1087-
1088-
emitOrDelayFunction(*this, constant,
1089-
[this,constant,arg,initDC](SILFunction *f) {
1090-
preEmitFunction(constant, arg, f, arg);
1091-
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
1092-
SILGenFunction SGF(*this, *f, initDC);
1093-
SGF.emitGeneratorFunction(constant, arg);
1094-
postEmitFunction(constant, f);
1095-
});
10961108
}
10971109

10981110
void SILGenModule::
@@ -1161,10 +1173,9 @@ void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl,
11611173
ParameterList *paramList) {
11621174
unsigned index = 0;
11631175
for (auto param : *paramList) {
1164-
if (auto defaultArg = param->getDefaultValue())
1176+
if (param->isDefaultArgument())
11651177
emitDefaultArgGenerator(SILDeclRef::getDefaultArgGenerator(decl, index),
1166-
defaultArg, param->getDefaultArgumentKind(),
1167-
param->getDefaultArgumentInitContext());
1178+
param);
11681179
++index;
11691180
}
11701181
}

lib/SILGen/SILGen.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
240240
void emitEnumConstructor(EnumElementDecl *decl);
241241

242242
/// Emits the default argument generator with the given expression.
243-
void emitDefaultArgGenerator(SILDeclRef constant, Expr *arg,
244-
DefaultArgumentKind kind, DeclContext *DC);
243+
void emitDefaultArgGenerator(SILDeclRef constant, ParamDecl *param);
245244

246245
/// Emits the stored property initializer for the given pattern.
247246
void emitStoredPropertyInitialization(PatternBindingDecl *pd, unsigned i);

lib/SILGen/SILGenApply.cpp

Lines changed: 5 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3186,40 +3186,11 @@ void DelayedArgument::emitDefaultArgument(SILGenFunction &SGF,
31863186
const DefaultArgumentStorage &info,
31873187
SmallVectorImpl<ManagedValue> &args,
31883188
size_t &argIndex) {
3189-
RValue value;
3190-
bool isStoredPropertyDefaultArg = false;
3191-
3192-
// Check if this is a synthesized memberwise constructor for stored property
3193-
// default values
3194-
if (auto ctor = dyn_cast<ConstructorDecl>(info.defaultArgsOwner.getDecl())) {
3195-
if (ctor->isMemberwiseInitializer() && ctor->isImplicit()) {
3196-
auto param = ctor->getParameters()->get(info.destIndex);
3197-
3198-
if (auto var = param->getStoredProperty()) {
3199-
// This is a stored property default arg. Do not emit a call to the
3200-
// default arg generator, but rather the variable initializer expression
3201-
isStoredPropertyDefaultArg = true;
3202-
3203-
auto pbd = var->getParentPatternBinding();
3204-
auto entry = pbd->getPatternEntryForVarDecl(var);
3205-
auto subs = info.defaultArgsOwner.getSubstitutions();
3206-
3207-
value = SGF.emitApplyOfStoredPropertyInitializer(info.loc,
3208-
entry, subs,
3209-
info.resultType,
3210-
info.origResultType,
3211-
SGFContext());
3212-
}
3213-
}
3214-
}
3215-
3216-
if (!isStoredPropertyDefaultArg) {
3217-
value = SGF.emitApplyOfDefaultArgGenerator(info.loc,
3218-
info.defaultArgsOwner,
3219-
info.destIndex,
3220-
info.resultType,
3221-
info.origResultType);
3222-
}
3189+
auto value = SGF.emitApplyOfDefaultArgGenerator(info.loc,
3190+
info.defaultArgsOwner,
3191+
info.destIndex,
3192+
info.resultType,
3193+
info.origResultType);
32233194

32243195
SmallVector<ManagedValue, 4> loweredArgs;
32253196
SmallVector<DelayedArgument, 4> delayedArgs;

lib/SILGen/SILGenFunction.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,56 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) {
638638
emitEpilog(Loc);
639639
}
640640

641+
void SILGenFunction::emitGeneratorFunction(SILDeclRef function, VarDecl *var) {
642+
MagicFunctionName = SILGenModule::getMagicFunctionName(function);
643+
644+
RegularLocation loc(var);
645+
loc.markAutoGenerated();
646+
647+
auto decl = function.getAbstractFunctionDecl();
648+
auto *dc = decl->getInnermostDeclContext();
649+
auto interfaceType = var->getValueInterfaceType();
650+
emitProlog(/*paramList*/ nullptr, /*selfParam*/ nullptr, interfaceType, dc,
651+
false);
652+
prepareEpilog(var->getType(), false, CleanupLocation::get(loc));
653+
654+
auto pbd = var->getParentPatternBinding();
655+
auto entry = pbd->getPatternEntryForVarDecl(var);
656+
auto subs = getForwardingSubstitutionMap();
657+
auto resultType = decl->mapTypeIntoContext(interfaceType)->getCanonicalType();
658+
auto origResultType = AbstractionPattern(resultType);
659+
660+
SmallVector<SILValue, 4> directResults;
661+
662+
if (F.getConventions().hasIndirectSILResults()) {
663+
Scope scope(Cleanups, CleanupLocation(var));
664+
665+
SmallVector<CleanupHandle, 4> cleanups;
666+
auto init = prepareIndirectResultInit(resultType, directResults, cleanups);
667+
668+
emitApplyOfStoredPropertyInitializer(loc, entry, subs, resultType,
669+
origResultType,
670+
SGFContext(init.get()));
671+
672+
for (auto cleanup : cleanups) {
673+
Cleanups.forwardCleanup(cleanup);
674+
}
675+
} else {
676+
Scope scope(Cleanups, CleanupLocation(var));
677+
678+
// If we have no indirect results, just return the result.
679+
auto result = emitApplyOfStoredPropertyInitializer(loc, entry, subs,
680+
resultType,
681+
origResultType,
682+
SGFContext())
683+
.ensurePlusOne(*this, loc);
684+
std::move(result).forwardAll(*this, directResults);
685+
}
686+
687+
Cleanups.emitBranchAndCleanups(ReturnDest, loc, directResults);
688+
emitEpilog(loc);
689+
}
690+
641691
static SILLocation getLocation(ASTNode Node) {
642692
if (auto *E = Node.dyn_cast<Expr *>())
643693
return E;

lib/SILGen/SILGenFunction.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
554554
// be in a different scope.
555555
}
556556

557+
std::unique_ptr<Initialization>
558+
prepareIndirectResultInit(CanType formalResultType,
559+
SmallVectorImpl<SILValue> &directResultsBuffer,
560+
SmallVectorImpl<CleanupHandle> &cleanups);
561+
557562
//===--------------------------------------------------------------------===//
558563
// Entry points for codegen
559564
//===--------------------------------------------------------------------===//
@@ -624,6 +629,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
624629
/// Generate a nullary function that returns the given value.
625630
void emitGeneratorFunction(SILDeclRef function, Expr *value);
626631

632+
/// Generate a nullary function that returns the value of the given variable's
633+
/// expression initializer.
634+
void emitGeneratorFunction(SILDeclRef function, VarDecl *var);
635+
627636
/// Generate an ObjC-compatible destructor (-dealloc).
628637
void emitObjCDestructor(SILDeclRef dtor);
629638

lib/SILGen/SILGenStmt.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -425,22 +425,22 @@ prepareIndirectResultInit(SILGenFunction &SGF, CanType resultType,
425425
/// components of the result
426426
/// \param cleanups - will be filled (after initialization completes)
427427
/// with all the active cleanups managing the result values
428-
static std::unique_ptr<Initialization>
429-
prepareIndirectResultInit(SILGenFunction &SGF, CanType formalResultType,
430-
SmallVectorImpl<SILValue> &directResultsBuffer,
431-
SmallVectorImpl<CleanupHandle> &cleanups) {
432-
auto fnConv = SGF.F.getConventions();
428+
std::unique_ptr<Initialization>
429+
SILGenFunction::prepareIndirectResultInit(CanType formalResultType,
430+
SmallVectorImpl<SILValue> &directResultsBuffer,
431+
SmallVectorImpl<CleanupHandle> &cleanups) {
432+
auto fnConv = F.getConventions();
433433

434434
// Make space in the direct-results array for all the entries we need.
435435
directResultsBuffer.append(fnConv.getNumDirectSILResults(), SILValue());
436436

437437
ArrayRef<SILResultInfo> allResults = fnConv.funcTy->getResults();
438438
MutableArrayRef<SILValue> directResults = directResultsBuffer;
439-
ArrayRef<SILArgument*> indirectResultAddrs = SGF.F.getIndirectResults();
439+
ArrayRef<SILArgument*> indirectResultAddrs = F.getIndirectResults();
440440

441-
auto init = prepareIndirectResultInit(SGF, formalResultType, allResults,
442-
directResults, indirectResultAddrs,
443-
cleanups);
441+
auto init = ::prepareIndirectResultInit(*this, formalResultType, allResults,
442+
directResults, indirectResultAddrs,
443+
cleanups);
444444

445445
assert(allResults.empty());
446446
assert(directResults.empty());
@@ -460,7 +460,7 @@ void SILGenFunction::emitReturnExpr(SILLocation branchLoc,
460460
// Build an initialization which recursively destructures the tuple.
461461
SmallVector<CleanupHandle, 4> resultCleanups;
462462
InitializationPtr resultInit =
463-
prepareIndirectResultInit(*this, ret->getType()->getCanonicalType(),
463+
prepareIndirectResultInit(ret->getType()->getCanonicalType(),
464464
directResults, resultCleanups);
465465

466466
// Emit the result expression into the initialization.

lib/TBDGen/TBDGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
224224
// call site.
225225
auto index = 0;
226226
for (auto *param : *AFD->getParameters()) {
227-
if (param->getDefaultValue())
227+
if (param->isDefaultArgument())
228228
addSymbol(SILDeclRef::getDefaultArgGenerator(AFD, index));
229229
index++;
230230
}

0 commit comments

Comments
 (0)