Skip to content

[SILGen] Emit default arg generator for stored property kind #23648

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 31 additions & 20 deletions lib/SILGen/SILGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1060,19 +1060,41 @@ void SILGenModule::emitDestructor(ClassDecl *cd, DestructorDecl *dd) {
}
}

void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, Expr *arg,
DefaultArgumentKind kind,
DeclContext *initDC) {
switch (kind) {
void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant,
ParamDecl *param) {
auto initDC = param->getDefaultArgumentInitContext();

switch (param->getDefaultArgumentKind()) {
case DefaultArgumentKind::None:
llvm_unreachable("No default argument here?");

case DefaultArgumentKind::Normal:
break;
case DefaultArgumentKind::Normal: {
auto arg = param->getDefaultValue();
emitOrDelayFunction(*this, constant,
[this,constant,arg,initDC](SILFunction *f) {
preEmitFunction(constant, arg, f, arg);
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
SILGenFunction SGF(*this, *f, initDC);
SGF.emitGeneratorFunction(constant, arg);
postEmitFunction(constant, f);
});
return;
}

case DefaultArgumentKind::Inherited:
case DefaultArgumentKind::StoredProperty: {
auto arg = param->getStoredProperty();
emitOrDelayFunction(*this, constant,
[this,constant,arg,initDC](SILFunction *f) {
preEmitFunction(constant, arg, f, arg);
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
SILGenFunction SGF(*this, *f, initDC);
SGF.emitGeneratorFunction(constant, arg);
postEmitFunction(constant, f);
});
return;
}

case DefaultArgumentKind::Inherited:
case DefaultArgumentKind::Column:
case DefaultArgumentKind::File:
case DefaultArgumentKind::Line:
Expand All @@ -1081,18 +1103,8 @@ void SILGenModule::emitDefaultArgGenerator(SILDeclRef constant, Expr *arg,
case DefaultArgumentKind::NilLiteral:
case DefaultArgumentKind::EmptyArray:
case DefaultArgumentKind::EmptyDictionary:
case DefaultArgumentKind::StoredProperty:
return;
}

emitOrDelayFunction(*this, constant,
[this,constant,arg,initDC](SILFunction *f) {
preEmitFunction(constant, arg, f, arg);
PrettyStackTraceSILFunction X("silgen emitDefaultArgGenerator ", f);
SILGenFunction SGF(*this, *f, initDC);
SGF.emitGeneratorFunction(constant, arg);
postEmitFunction(constant, f);
});
}

void SILGenModule::
Expand Down Expand Up @@ -1161,10 +1173,9 @@ void SILGenModule::emitDefaultArgGenerators(SILDeclRef::Loc decl,
ParameterList *paramList) {
unsigned index = 0;
for (auto param : *paramList) {
if (auto defaultArg = param->getDefaultValue())
if (param->isDefaultArgument())
emitDefaultArgGenerator(SILDeclRef::getDefaultArgGenerator(decl, index),
defaultArg, param->getDefaultArgumentKind(),
param->getDefaultArgumentInitContext());
param);
++index;
}
}
Expand Down
3 changes: 1 addition & 2 deletions lib/SILGen/SILGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
void emitEnumConstructor(EnumElementDecl *decl);

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

/// Emits the stored property initializer for the given pattern.
void emitStoredPropertyInitialization(PatternBindingDecl *pd, unsigned i);
Expand Down
39 changes: 5 additions & 34 deletions lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3186,40 +3186,11 @@ void DelayedArgument::emitDefaultArgument(SILGenFunction &SGF,
const DefaultArgumentStorage &info,
SmallVectorImpl<ManagedValue> &args,
size_t &argIndex) {
RValue value;
bool isStoredPropertyDefaultArg = false;

// Check if this is a synthesized memberwise constructor for stored property
// default values
if (auto ctor = dyn_cast<ConstructorDecl>(info.defaultArgsOwner.getDecl())) {
if (ctor->isMemberwiseInitializer() && ctor->isImplicit()) {
auto param = ctor->getParameters()->get(info.destIndex);

if (auto var = param->getStoredProperty()) {
// This is a stored property default arg. Do not emit a call to the
// default arg generator, but rather the variable initializer expression
isStoredPropertyDefaultArg = true;

auto pbd = var->getParentPatternBinding();
auto entry = pbd->getPatternEntryForVarDecl(var);
auto subs = info.defaultArgsOwner.getSubstitutions();

value = SGF.emitApplyOfStoredPropertyInitializer(info.loc,
entry, subs,
info.resultType,
info.origResultType,
SGFContext());
}
}
}

if (!isStoredPropertyDefaultArg) {
value = SGF.emitApplyOfDefaultArgGenerator(info.loc,
info.defaultArgsOwner,
info.destIndex,
info.resultType,
info.origResultType);
}
auto value = SGF.emitApplyOfDefaultArgGenerator(info.loc,
info.defaultArgsOwner,
info.destIndex,
info.resultType,
info.origResultType);

SmallVector<ManagedValue, 4> loweredArgs;
SmallVector<DelayedArgument, 4> delayedArgs;
Expand Down
50 changes: 50 additions & 0 deletions lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,56 @@ void SILGenFunction::emitGeneratorFunction(SILDeclRef function, Expr *value) {
emitEpilog(Loc);
}

void SILGenFunction::emitGeneratorFunction(SILDeclRef function, VarDecl *var) {
MagicFunctionName = SILGenModule::getMagicFunctionName(function);

RegularLocation loc(var);
loc.markAutoGenerated();

auto decl = function.getAbstractFunctionDecl();
auto *dc = decl->getInnermostDeclContext();
auto interfaceType = var->getValueInterfaceType();
emitProlog(/*paramList*/ nullptr, /*selfParam*/ nullptr, interfaceType, dc,
false);
prepareEpilog(var->getType(), false, CleanupLocation::get(loc));

auto pbd = var->getParentPatternBinding();
auto entry = pbd->getPatternEntryForVarDecl(var);
auto subs = getForwardingSubstitutionMap();
auto resultType = decl->mapTypeIntoContext(interfaceType)->getCanonicalType();
auto origResultType = AbstractionPattern(resultType);

SmallVector<SILValue, 4> directResults;

if (F.getConventions().hasIndirectSILResults()) {
Scope scope(Cleanups, CleanupLocation(var));

SmallVector<CleanupHandle, 4> cleanups;
auto init = prepareIndirectResultInit(resultType, directResults, cleanups);

emitApplyOfStoredPropertyInitializer(loc, entry, subs, resultType,
origResultType,
SGFContext(init.get()));

for (auto cleanup : cleanups) {
Cleanups.forwardCleanup(cleanup);
}
} else {
Scope scope(Cleanups, CleanupLocation(var));

// If we have no indirect results, just return the result.
auto result = emitApplyOfStoredPropertyInitializer(loc, entry, subs,
resultType,
origResultType,
SGFContext())
.ensurePlusOne(*this, loc);
std::move(result).forwardAll(*this, directResults);
}

Cleanups.emitBranchAndCleanups(ReturnDest, loc, directResults);
emitEpilog(loc);
}

static SILLocation getLocation(ASTNode Node) {
if (auto *E = Node.dyn_cast<Expr *>())
return E;
Expand Down
9 changes: 9 additions & 0 deletions lib/SILGen/SILGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,11 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
// be in a different scope.
}

std::unique_ptr<Initialization>
prepareIndirectResultInit(CanType formalResultType,
SmallVectorImpl<SILValue> &directResultsBuffer,
SmallVectorImpl<CleanupHandle> &cleanups);

//===--------------------------------------------------------------------===//
// Entry points for codegen
//===--------------------------------------------------------------------===//
Expand Down Expand Up @@ -624,6 +629,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenFunction
/// Generate a nullary function that returns the given value.
void emitGeneratorFunction(SILDeclRef function, Expr *value);

/// Generate a nullary function that returns the value of the given variable's
/// expression initializer.
void emitGeneratorFunction(SILDeclRef function, VarDecl *var);

/// Generate an ObjC-compatible destructor (-dealloc).
void emitObjCDestructor(SILDeclRef dtor);

Expand Down
20 changes: 10 additions & 10 deletions lib/SILGen/SILGenStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,22 +425,22 @@ prepareIndirectResultInit(SILGenFunction &SGF, CanType resultType,
/// components of the result
/// \param cleanups - will be filled (after initialization completes)
/// with all the active cleanups managing the result values
static std::unique_ptr<Initialization>
prepareIndirectResultInit(SILGenFunction &SGF, CanType formalResultType,
SmallVectorImpl<SILValue> &directResultsBuffer,
SmallVectorImpl<CleanupHandle> &cleanups) {
auto fnConv = SGF.F.getConventions();
std::unique_ptr<Initialization>
SILGenFunction::prepareIndirectResultInit(CanType formalResultType,
SmallVectorImpl<SILValue> &directResultsBuffer,
SmallVectorImpl<CleanupHandle> &cleanups) {
auto fnConv = F.getConventions();

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

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

auto init = prepareIndirectResultInit(SGF, formalResultType, allResults,
directResults, indirectResultAddrs,
cleanups);
auto init = ::prepareIndirectResultInit(*this, formalResultType, allResults,
directResults, indirectResultAddrs,
cleanups);

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

// Emit the result expression into the initialization.
Expand Down
2 changes: 1 addition & 1 deletion lib/TBDGen/TBDGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ void TBDGenVisitor::visitAbstractFunctionDecl(AbstractFunctionDecl *AFD) {
// call site.
auto index = 0;
for (auto *param : *AFD->getParameters()) {
if (param->getDefaultValue())
if (param->isDefaultArgument())
addSymbol(SILDeclRef::getDefaultArgGenerator(AFD, index));
index++;
}
Expand Down
Loading