Skip to content

Final preparations for using best resilience expansion in SIL #23263

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
3 changes: 2 additions & 1 deletion include/swift/SIL/TypeLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,8 @@ class TypeConverter {
TypeConverter &operator=(TypeConverter const &) = delete;

/// Return the CaptureKind to use when capturing a decl.
CaptureKind getDeclCaptureKind(CapturedValue capture);
CaptureKind getDeclCaptureKind(CapturedValue capture,
ResilienceExpansion expansion);

/// Return a most-general-possible abstraction pattern.
AbstractionPattern getMostGeneralAbstraction() {
Expand Down
5 changes: 5 additions & 0 deletions include/swift/SILOptimizer/Utils/Generics.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ class ReabstractionInfo {
return Serialized;
}

ResilienceExpansion getResilienceExpansion() const {
// FIXME: Expansion
return ResilienceExpansion::Minimal;
}

/// Returns true if the \p ParamIdx'th (non-result) formal parameter is
/// converted from indirect to direct.
bool isParamConverted(unsigned ParamIdx) const {
Expand Down
12 changes: 7 additions & 5 deletions lib/SIL/SILFunctionType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -714,6 +714,7 @@ static std::pair<AbstractionPattern, CanType> updateResultTypeForForeignError(
static void
lowerCaptureContextParameters(SILModule &M, AnyFunctionRef function,
CanGenericSignature genericSig,
ResilienceExpansion expansion,
SmallVectorImpl<SILParameterInfo> &inputs) {

// NB: The generic signature may be elided from the lowered function type
Expand Down Expand Up @@ -746,13 +747,11 @@ lowerCaptureContextParameters(SILModule &M, AnyFunctionRef function,
auto type = VD->getInterfaceType();
auto canType = type->getCanonicalType(origGenericSig);

// FIXME: Could be changed to Maximal at some point without impacting ABI,
// as long as we make sure all call sites are non inlinable.
auto &loweredTL =
Types.getTypeLowering(AbstractionPattern(genericSig, canType), canType,
ResilienceExpansion::Minimal);
expansion);
auto loweredTy = loweredTL.getLoweredType();
switch (Types.getDeclCaptureKind(capture)) {
switch (Types.getDeclCaptureKind(capture, expansion)) {
case CaptureKind::None:
break;
case CaptureKind::Constant: {
Expand Down Expand Up @@ -985,7 +984,10 @@ static CanSILFunctionType getSILFunctionType(
// from the function to which the argument is attached.
if (constant && !constant->isDefaultArgGenerator()) {
if (auto function = constant->getAnyFunctionRef()) {
lowerCaptureContextParameters(M, *function, genericSig, inputs);
// FIXME: Expansion
auto expansion = ResilienceExpansion::Minimal;
lowerCaptureContextParameters(M, *function, genericSig, expansion,
inputs);
}
}

Expand Down
14 changes: 10 additions & 4 deletions lib/SIL/SILType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -446,15 +446,21 @@ SILModuleConventions::SILModuleConventions(const SILModule &M)

bool SILModuleConventions::isReturnedIndirectlyInSIL(SILType type,
SILModule &M) {
if (SILModuleConventions(M).loweredAddresses)
return type.isAddressOnly(M);
if (SILModuleConventions(M).loweredAddresses) {
return M.Types.getTypeLowering(type,
ResilienceExpansion::Minimal)
.isAddressOnly();
}

return false;
}

bool SILModuleConventions::isPassedIndirectlyInSIL(SILType type, SILModule &M) {
if (SILModuleConventions(M).loweredAddresses)
return type.isAddressOnly(M);
if (SILModuleConventions(M).loweredAddresses) {
return M.Types.getTypeLowering(type,
ResilienceExpansion::Minimal)
.isAddressOnly();
}

return false;
}
Expand Down
7 changes: 3 additions & 4 deletions lib/SIL/TypeLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ static bool hasSingletonMetatype(CanType instanceType) {
return HasSingletonMetatype().visit(instanceType);
}

CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture) {
CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
ResilienceExpansion expansion) {
auto decl = capture.getDecl();
if (auto *var = dyn_cast<VarDecl>(decl)) {
assert(var->hasStorage() &&
Expand All @@ -97,9 +98,7 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture) {
// by its address (like a var) instead.
if (var->isImmutable() &&
(!SILModuleConventions(M).useLoweredAddresses() ||
// FIXME: Expansion
!getTypeLowering(var->getType(),
ResilienceExpansion::Minimal).isAddressOnly()))
!getTypeLowering(var->getType(), expansion).isAddressOnly()))
return CaptureKind::Constant;

// In-out parameters are captured by address.
Expand Down
4 changes: 0 additions & 4 deletions lib/SILGen/SILGenApply.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4507,8 +4507,6 @@ CallEmission::applyEnumElementConstructor(SGFContext C) {
// correctly.
firstLevelResult.formalType = callee.getSubstFormalType();
auto origFormalType = callee.getOrigFormalType();
auto substFnType =
SGF.getSILFunctionType(origFormalType, firstLevelResult.formalType);

// We have a fully-applied enum element constructor: open-code the
// construction.
Expand Down Expand Up @@ -4539,8 +4537,6 @@ CallEmission::applyEnumElementConstructor(SGFContext C) {
assert(uncurriedSites.size() == 1);
}

assert(substFnType->getNumResults() == 1);
(void)substFnType;
ManagedValue resultMV = SGF.emitInjectEnum(
uncurriedLoc, std::move(payload),
SGF.getLoweredType(formalResultType),
Expand Down
37 changes: 13 additions & 24 deletions lib/SILGen/SILGenBridging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,26 +333,15 @@ static ManagedValue emitManagedParameter(SILGenFunction &SGF, SILLocation loc,
llvm_unreachable("bad convention");
}

static void expandTupleTypes(CanType type, SmallVectorImpl<CanType> &results) {
if (auto tuple = dyn_cast<TupleType>(type)) {
for (auto eltType : tuple.getElementTypes())
expandTupleTypes(eltType, results);
} else {
results.push_back(type);
}
}

/// Recursively expand all the tuples in the given parameter list.
/// Callers assume that the resulting array will line up with the
/// SILFunctionType's parameter list, which is true as along as there
/// aren't any indirectly-passed tuples; we should be safe from that
/// here in the bridging code.
/// Get the type of each parameter, filtering out empty tuples.
static SmallVector<CanType, 8>
expandTupleTypes(AnyFunctionType::CanParamArrayRef params) {
getParameterTypes(AnyFunctionType::CanParamArrayRef params) {
SmallVector<CanType, 8> results;
for (auto param : params) {
assert(!param.isInOut() && !param.isVariadic());
expandTupleTypes(param.getPlainType(), results);
if (param.getPlainType()->isVoid())
continue;
results.push_back(param.getPlainType());
}
return results;
}
Expand Down Expand Up @@ -403,8 +392,8 @@ static void buildFuncToBlockInvokeBody(SILGenFunction &SGF,
assert(blockTy->getParameters().size() == funcTy->getParameters().size()
&& "block and function types don't match");

auto nativeParamTypes = expandTupleTypes(formalFuncType.getParams());
auto bridgedParamTypes = expandTupleTypes(formalBlockType.getParams());
auto nativeParamTypes = getParameterTypes(formalFuncType.getParams());
auto bridgedParamTypes = getParameterTypes(formalBlockType.getParams());

SmallVector<ManagedValue, 4> args;
for (unsigned i : indices(funcTy->getParameters())) {
Expand Down Expand Up @@ -839,8 +828,8 @@ static void buildBlockToFuncThunkBody(SILGenFunction &SGF,
}
}

auto formalBlockParams = expandTupleTypes(formalBlockTy.getParams());
auto formalFuncParams = expandTupleTypes(formalFuncTy.getParams());
auto formalBlockParams = getParameterTypes(formalBlockTy.getParams());
auto formalFuncParams = getParameterTypes(formalFuncTy.getParams());
assert(formalBlockParams.size() == blockTy->getNumParameters());
assert(formalFuncParams.size() == funcTy->getNumParameters());

Expand Down Expand Up @@ -1297,10 +1286,10 @@ static SILFunctionType *emitObjCThunkArguments(SILGenFunction &SGF,
assert(objcFnTy->getNumIndirectFormalResults() == 0
&& "Objective-C methods cannot have indirect results");

auto bridgedFormalTypes = expandTupleTypes(objcFormalFnTy.getParams());
auto bridgedFormalTypes = getParameterTypes(objcFormalFnTy.getParams());
bridgedFormalResultTy = objcFormalFnTy.getResult();

auto nativeFormalTypes = expandTupleTypes(swiftFormalFnTy.getParams());
auto nativeFormalTypes = getParameterTypes(swiftFormalFnTy.getParams());
nativeFormalResultTy = swiftFormalFnTy.getResult();

// Emit the other arguments, taking ownership of arguments if necessary.
Expand Down Expand Up @@ -1697,9 +1686,9 @@ void SILGenFunction::emitForeignToNativeThunk(SILDeclRef thunk) {

{
auto foreignFormalParams =
expandTupleTypes(foreignCI.LoweredType.getParams());
getParameterTypes(foreignCI.LoweredType.getParams());
auto nativeFormalParams =
expandTupleTypes(nativeCI.LoweredType.getParams());
getParameterTypes(nativeCI.LoweredType.getParams());

for (unsigned nativeParamIndex : indices(params)) {
// Bring the parameter to +1.
Expand Down
6 changes: 1 addition & 5 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -856,11 +856,7 @@ emitRValueForDecl(SILLocation loc, ConcreteDeclRef declRef, Type ncRefType,

// If this is a decl that we have an lvalue for, produce and return it.
ValueDecl *decl = declRef.getDecl();

if (!ncRefType) {
ncRefType = decl->getInnermostDeclContext()->mapTypeIntoContext(
decl->getInterfaceType());
}

CanType refType = ncRefType->getCanonicalType();

// If this is a reference to a module, produce an undef value. The
Expand Down
4 changes: 3 additions & 1 deletion lib/SILGen/SILGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@ void SILGenFunction::emitCaptures(SILLocation loc,

auto *vd = capture.getDecl();

switch (SGM.Types.getDeclCaptureKind(capture)) {
// FIXME: Expansion
auto expansion = ResilienceExpansion::Minimal;
switch (SGM.Types.getDeclCaptureKind(capture, expansion)) {
case CaptureKind::None:
break;

Expand Down
7 changes: 4 additions & 3 deletions lib/SILGen/SILGenProlog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,14 +354,15 @@ static void emitCaptureArguments(SILGenFunction &SGF,
closure.getGenericEnvironment(), interfaceType);
};

switch (SGF.SGM.Types.getDeclCaptureKind(capture)) {
// FIXME: Expansion
auto expansion = ResilienceExpansion::Minimal;
switch (SGF.SGM.Types.getDeclCaptureKind(capture, expansion)) {
case CaptureKind::None:
break;

case CaptureKind::Constant: {
auto type = getVarTypeInCaptureContext();
auto &lowering = SGF.SGM.Types.getTypeLowering(type,
ResilienceExpansion::Minimal);
auto &lowering = SGF.getTypeLowering(type);
// Constant decls are captured by value.
SILType ty = lowering.getLoweredType();
SILValue val = SGF.F.begin()->createFunctionArgument(ty, VD);
Expand Down
1 change: 1 addition & 0 deletions lib/SILOptimizer/IPO/CapturePromotion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ computeNewArgInterfaceTypes(SILFunction *F,
assert(paramBoxTy->getLayout()->getFields().size() == 1
&& "promoting compound box not implemented yet");
auto paramBoxedTy = paramBoxTy->getFieldType(F->getModule(), 0);
// FIXME: Expansion
auto &paramTL = Types.getTypeLowering(paramBoxedTy,
ResilienceExpansion::Minimal);
ParameterConvention convention;
Expand Down
32 changes: 27 additions & 5 deletions lib/SILOptimizer/IPO/GlobalOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,12 @@ static SILFunction *genGetterFromInit(SILOptFunctionBuilder &FunctionBuilder,
auto V = Store->getSrc();

SmallVector<SILInstruction *, 8> Insts;
if (!analyzeStaticInitializer(V, Insts))
if (!analyzeStaticInitializer(V, Insts)) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: can't analyze static initializer for "
<< SILG->getName() << '\n');
return nullptr;
}

Insts.push_back(cast<SingleValueInstruction>(Store->getDest()));
Insts.push_back(Store);

Expand Down Expand Up @@ -637,6 +641,9 @@ replaceLoadsByKnownValue(BuiltinInst *CallToOnce, SILFunction *AddrF,
SILFunction *InitF, SILGlobalVariable *SILG,
SingleValueInstruction *InitVal,
GlobalInitCalls &Calls) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: replacing loads with known value for "
<< SILG->getName() << '\n');

assert(isAssignedOnlyOnceInInitializer(SILG) &&
"The value of the initializer should be known at compile-time");
assert(SILG->getDecl() &&
Expand Down Expand Up @@ -736,6 +743,9 @@ void SILGlobalOpt::optimizeInitializer(SILFunction *AddrF,

// Remove "once" call from the addressor.
if (!isAssignedOnlyOnceInInitializer(SILG) || !SILG->getDecl()) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: building static initializer for "
<< SILG->getName() << '\n');

removeToken(CallToOnce->getOperand(0));
CallToOnce->eraseFromParent();
StaticInitCloner::appendToInitializer(SILG, InitVal);
Expand Down Expand Up @@ -819,6 +829,8 @@ void SILGlobalOpt::collectGlobalAccess(GlobalAddrInst *GAI) {
auto *F = GAI->getFunction();

if (!SILG->getLoweredType().isTrivial(*F)) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: type is not trivial: "
<< SILG->getName() << '\n');
GlobalVarSkipProcessing.insert(SILG);
return;
}
Expand All @@ -843,6 +855,9 @@ void SILGlobalOpt::collectGlobalAccess(GlobalAddrInst *GAI) {
continue;
}

LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: has non-store, non-load use: "
<< SILG->getName() << '\n';
Op->getUser()->dump());
// This global is not initialized by a simple
// constant value at this moment.
GlobalVarSkipProcessing.insert(SILG);
Expand All @@ -858,16 +873,23 @@ void SILGlobalOpt::optimizeGlobalAccess(SILGlobalVariable *SILG,
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: use static initializer for "
<< SILG->getName() << '\n');

if (GlobalVarSkipProcessing.count(SILG))
if (GlobalVarSkipProcessing.count(SILG)) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: already decided to skip: "
<< SILG->getName() << '\n');
return;
}

if (//!isAssignedOnlyOnceInInitializer(SILG) ||
!SILG->getDecl()) {
if (!SILG->getDecl()) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: no AST declaration: "
<< SILG->getName() << '\n');
return;
}

if (!GlobalLoadMap.count(SILG))
if (!GlobalLoadMap.count(SILG)) {
LLVM_DEBUG(llvm::dbgs() << "GlobalOpt: not in load map: "
<< SILG->getName() << '\n');
return;
}

// Generate a getter only if there are any loads from this variable.
SILFunction *GetterF = genGetterFromInit(FunctionBuilder, SI, SILG);
Expand Down
2 changes: 2 additions & 0 deletions lib/SILOptimizer/Transforms/ObjectOutliner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ bool ObjectOutliner::optimizeObjectAllocation(
<< ARI->getFunction()->getName() << '\n');

SILModule *Module = &ARI->getFunction()->getModule();
// FIXME: Expansion
assert(!Cl->isResilient(Module->getSwiftModule(),
ResilienceExpansion::Minimal) &&
"constructor call of resilient class should prevent static allocation");
Expand Down Expand Up @@ -448,6 +449,7 @@ void ObjectOutliner::replaceFindStringCall(ApplyInst *FindStringCall) {
return;


// FIXME: Expansion
assert(!cacheDecl->isResilient(Module->getSwiftModule(),
ResilienceExpansion::Minimal));

Expand Down
3 changes: 1 addition & 2 deletions lib/SILOptimizer/Utils/Devirtualize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,7 @@ bool swift::canDevirtualizeClassMethod(FullApplySite AI,
}

// We need to disable the “effectively final” opt if a function is inlinable
if (isEffectivelyFinalMethod && AI.getFunction()->getResilienceExpansion() ==
ResilienceExpansion::Minimal) {
if (isEffectivelyFinalMethod && AI.getFunction()->isSerialized()) {
LLVM_DEBUG(llvm::dbgs() << " FAIL: Could not optimize function "
"because it is an effectively-final inlinable: "
<< AI.getFunction()->getName() << "\n");
Expand Down
Loading