Skip to content

[+0-all-args] Fix SILGenBuilder::createFunctionInputArgument(...) for… #15089

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
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
58 changes: 48 additions & 10 deletions lib/SILGen/SILGenBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,18 +519,56 @@ ManagedValue SILGenBuilder::createLoadCopy(SILLocation loc, ManagedValue v,
return SGF.emitManagedRValueWithCleanup(result, lowering);
}

ManagedValue SILGenBuilder::createFunctionArgument(SILType type,
ValueDecl *decl) {
SILFunction &F = getFunction();

SILFunctionArgument *arg = F.begin()->createFunctionArgument(type, decl);
if (arg->getType().isObject()) {
if (arg->getOwnershipKind().isTrivialOr(ValueOwnershipKind::Owned))
return SGF.emitManagedRValueWithCleanup(arg);
return ManagedValue::forBorrowedRValue(arg);
static ManagedValue createInputFunctionArgument(SILGenBuilder &B, SILType type,
SILLocation loc,
ValueDecl *decl = nullptr) {
auto &SGF = B.getSILGenFunction();
SILFunction &F = B.getFunction();
assert((F.isBare() || decl) &&
"Function arguments of non-bare functions must have a decl");
auto *arg = F.begin()->createFunctionArgument(type, decl);
switch (arg->getArgumentConvention()) {
case SILArgumentConvention::Indirect_In_Guaranteed:
case SILArgumentConvention::Direct_Guaranteed:
// Guaranteed parameters are passed at +0.
return ManagedValue::forUnmanaged(arg);
case SILArgumentConvention::Direct_Unowned:
// Unowned parameters are only guaranteed at the instant of the call, so we
// must retain them even if we're in a context that can accept a +0 value.
return ManagedValue::forUnmanaged(arg).copy(SGF, loc);

case SILArgumentConvention::Direct_Owned:
return SGF.emitManagedRValueWithCleanup(arg);

case SILArgumentConvention::Indirect_In:
if (SGF.silConv.useLoweredAddresses())
return SGF.emitManagedBufferWithCleanup(arg);
return SGF.emitManagedRValueWithCleanup(arg);

case SILArgumentConvention::Indirect_Inout:
case SILArgumentConvention::Indirect_InoutAliasable:
// An inout parameter is +0 and guaranteed, but represents an lvalue.
return ManagedValue::forLValue(arg);
case SILArgumentConvention::Indirect_In_Constant:
llvm_unreachable("Convention not produced by SILGen");
case SILArgumentConvention::Direct_Deallocating:
case SILArgumentConvention::Indirect_Out:
llvm_unreachable("unsupported convention for API");
}
llvm_unreachable("bad parameter convention");
}

ManagedValue SILGenBuilder::createInputFunctionArgument(SILType type,
ValueDecl *decl) {
return ::createInputFunctionArgument(*this, type, SILLocation(decl), decl);
}

return SGF.emitManagedBufferWithCleanup(arg);
ManagedValue
SILGenBuilder::createInputFunctionArgument(SILType type,
Optional<SILLocation> inputLoc) {
assert(inputLoc.hasValue() && "This optional is only for overload resolution "
"purposes! Do not pass in None here!");
return ::createInputFunctionArgument(*this, type, *inputLoc);
}

ManagedValue
Expand Down
15 changes: 14 additions & 1 deletion lib/SILGen/SILGenBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,20 @@ class SILGenBuilder : public SILBuilder {
ManagedValue createLoadCopy(SILLocation loc, ManagedValue addr,
const TypeLowering &lowering);

ManagedValue createFunctionArgument(SILType type, ValueDecl *decl);
/// Create a SILArgument for an input parameter. Asserts if used to create a
/// function argument for an out parameter.
ManagedValue createInputFunctionArgument(SILType type, ValueDecl *decl);

/// Create a SILArgument for an input parameter. Uses \p loc to create any
/// copies necessary. Asserts if used to create a function argument for an out
/// parameter.
///
/// *NOTE* This API purposely used an Optional<SILLocation> to distinguish
/// this API from the ValueDecl * API in C++. This is necessary since
/// ValueDecl * can implicitly convert to SILLocation. The optional forces the
/// user to be explicit that they want to use this API.
ManagedValue createInputFunctionArgument(SILType type,
Optional<SILLocation> loc);

using SILBuilder::createEnum;
ManagedValue createEnum(SILLocation loc, ManagedValue payload,
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenConstructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
ctor->hasThrows());

SILType selfTy = getLoweredLoadableType(selfDecl->getType());
ManagedValue selfArg = B.createFunctionArgument(selfTy, selfDecl);
ManagedValue selfArg = B.createInputFunctionArgument(selfTy, selfDecl);

if (!NeedsBoxForSelf) {
SILLocation PrologueLoc(selfDecl);
Expand Down
38 changes: 1 addition & 37 deletions lib/SILGen/SILGenPoly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,40 +785,6 @@ ManagedValue Transform::transformTuple(ManagedValue inputTuple,
return SGF.emitManagedRValueWithCleanup(outputTuple, outputTL);
}

static ManagedValue manageParam(SILGenFunction &SGF,
SILLocation loc,
SILValue paramValue,
SILParameterInfo info) {
switch (info.getConvention()) {
case ParameterConvention::Indirect_In_Guaranteed:
if (SGF.silConv.useLoweredAddresses())
return ManagedValue::forUnmanaged(paramValue);
LLVM_FALLTHROUGH;
case ParameterConvention::Direct_Guaranteed:
return SGF.emitManagedBeginBorrow(loc, paramValue);
// Unowned parameters are only guaranteed at the instant of the call, so we
// must retain them even if we're in a context that can accept a +0 value.
case ParameterConvention::Direct_Unowned:
paramValue = SGF.getTypeLowering(paramValue->getType())
.emitCopyValue(SGF.B, loc, paramValue);
LLVM_FALLTHROUGH;
case ParameterConvention::Direct_Owned:
return SGF.emitManagedRValueWithCleanup(paramValue);

case ParameterConvention::Indirect_In:
if (SGF.silConv.useLoweredAddresses())
return SGF.emitManagedBufferWithCleanup(paramValue);
return SGF.emitManagedRValueWithCleanup(paramValue);

case ParameterConvention::Indirect_Inout:
case ParameterConvention::Indirect_InoutAliasable:
return ManagedValue::forLValue(paramValue);
case ParameterConvention::Indirect_In_Constant:
break;
}
llvm_unreachable("bad parameter convention");
}

void SILGenFunction::collectThunkParams(
SILLocation loc, SmallVectorImpl<ManagedValue> &params,
SmallVectorImpl<SILArgument *> *indirectResults) {
Expand All @@ -834,9 +800,7 @@ void SILGenFunction::collectThunkParams(
auto paramTypes = F.getLoweredFunctionType()->getParameters();
for (auto param : paramTypes) {
auto paramTy = F.mapTypeIntoContext(F.getConventions().getSILType(param));
auto paramValue = F.begin()->createFunctionArgument(paramTy);
auto paramMV = manageParam(*this, loc, paramValue, param);
params.push_back(paramMV);
params.push_back(B.createInputFunctionArgument(paramTy, loc));
}
}

Expand Down
38 changes: 2 additions & 36 deletions lib/SILGen/SILGenProlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,39 +92,6 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
: SGF(sgf), parent(parent), loc(l), functionArgs(functionArgs),
parameters(parameters) {}

ManagedValue getManagedValue(SILValue arg, CanType t,
SILParameterInfo parameterInfo) const {
switch (parameterInfo.getConvention()) {
case ParameterConvention::Direct_Guaranteed:
case ParameterConvention::Indirect_In_Guaranteed:
// If we have a guaranteed parameter, it is passed in at +0, and its
// lifetime is guaranteed. We can potentially use the argument as-is
// if the parameter is bound as a 'let' without cleaning up.
return ManagedValue::forUnmanaged(arg);

case ParameterConvention::Direct_Unowned:
// An unowned parameter is passed at +0, like guaranteed, but it isn't
// kept alive by the caller, so we need to retain and manage it
// regardless.
return SGF.emitManagedRetain(loc, arg);

case ParameterConvention::Indirect_Inout:
case ParameterConvention::Indirect_InoutAliasable:
// An inout parameter is +0 and guaranteed, but represents an lvalue.
return ManagedValue::forLValue(arg);

case ParameterConvention::Direct_Owned:
case ParameterConvention::Indirect_In:
// An owned or 'in' parameter is passed in at +1. We can claim ownership
// of the parameter and clean it up when it goes out of scope.
return SGF.emitManagedRValueWithCleanup(arg);

case ParameterConvention::Indirect_In_Constant:
break;
}
llvm_unreachable("bad parameter convention");
}

ManagedValue visitType(CanType t) {
auto argType = SGF.getLoweredType(t);
// Pop the next parameter info.
Expand All @@ -136,9 +103,8 @@ class EmitBBArguments : public CanTypeVisitor<EmitBBArguments,
SGF.getSILType(parameterInfo))
&& "argument does not have same type as specified by parameter info");

SILValue arg =
parent->createFunctionArgument(argType, loc.getAsASTNode<ValueDecl>());
ManagedValue mv = getManagedValue(arg, t, parameterInfo);
ManagedValue mv = SGF.B.createInputFunctionArgument(
argType, loc.getAsASTNode<ValueDecl>());

// If the value is a (possibly optional) ObjC block passed into the entry
// point of the function, then copy it so we can treat the value reliably
Expand Down
2 changes: 1 addition & 1 deletion lib/SILGen/SILGenThunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ void SILGenFunction::emitCurryThunk(SILDeclRef thunk) {
->getInput();
selfTy = vd->getInnermostDeclContext()->mapTypeIntoContext(selfTy);
ManagedValue selfArg =
B.createFunctionArgument(getLoweredType(selfTy), nullptr);
B.createInputFunctionArgument(getLoweredType(selfTy), SILLocation(vd));

// Forward substitutions.
auto subs = F.getForwardingSubstitutions();
Expand Down