Skip to content

Commit 8e800e4

Browse files
authored
Recommit swiftlang#29812 with fixes (swiftlang#30342)
1 parent c7155bc commit 8e800e4

25 files changed

+329
-123
lines changed

include/swift/SIL/BasicBlockUtils.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,15 @@ class DeadEndBlocks {
7979
}
8080
return ReachableBlocks.count(block) == 0;
8181
}
82+
83+
bool empty() {
84+
if (!isComputed) {
85+
// Lazily compute the dataflow.
86+
compute();
87+
isComputed = true;
88+
}
89+
return ReachableBlocks.empty();
90+
}
8291
};
8392

8493
} // namespace swift

include/swift/SIL/TypeLowering.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,8 @@ enum class CaptureKind {
561561
StorageAddress,
562562
/// A local value captured as a constant.
563563
Constant,
564+
/// A let constant captured as a pointer to storage
565+
Immutable
564566
};
565567

566568

include/swift/SILOptimizer/Utils/InstOptUtils.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,12 +364,19 @@ void releasePartialApplyCapturedArg(
364364
SILParameterInfo paramInfo,
365365
InstModCallbacks callbacks = InstModCallbacks());
366366

367+
void deallocPartialApplyCapturedArg(
368+
SILBuilder &builder, SILLocation loc, SILValue arg,
369+
SILParameterInfo paramInfo);
370+
367371
/// Insert destroys of captured arguments of partial_apply [stack].
368372
void insertDestroyOfCapturedArguments(
369373
PartialApplyInst *pai, SILBuilder &builder,
370374
llvm::function_ref<bool(SILValue)> shouldInsertDestroy =
371375
[](SILValue arg) -> bool { return true; });
372376

377+
void insertDeallocOfCapturedArguments(
378+
PartialApplyInst *pai, SILBuilder &builder);
379+
373380
/// This iterator 'looks through' one level of builtin expect users exposing all
374381
/// users of the looked through builtin expect instruction i.e it presents a
375382
/// view that shows all users as if there were no builtin expect instructions

lib/IRGen/GenFunc.cpp

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1319,9 +1319,32 @@ Optional<StackAddress> irgen::emitFunctionPartialApplication(
13191319
SmallVector<SILType, 4> argValTypes;
13201320
SmallVector<ParameterConvention, 4> argConventions;
13211321

1322+
// A context's HeapLayout stores all of the partially applied args.
1323+
// A HeapLayout is "fixed" if all of its fields have a fixed layout.
1324+
// Otherwise the HeapLayout is "non-fixed".
1325+
// Only a non-fixed HeapLayout needs TypeMetadata of the non-fixed fields
1326+
// during IRGen of the HeapLayout's destructor function.
1327+
// We should not consider partially applied args as TypeMetadata sources,
1328+
// because they are available only in the caller and the partial application
1329+
// forwarder, but not in the destructor function.
1330+
// It is safe to consider partially applied args as TypeMetadata sources for
1331+
// "fixed" HeapLayout, because they are not accessed during the IRGen of the
1332+
// destructor function.
1333+
bool considerParameterSources = true;
1334+
for (auto param : params) {
1335+
SILType argType = IGF.IGM.silConv.getSILType(param, origType);
1336+
auto argLoweringTy = getArgumentLoweringType(argType.getASTType(), param);
1337+
auto &ti = IGF.getTypeInfoForLowered(argLoweringTy);
1338+
1339+
if (!isa<FixedTypeInfo>(ti)) {
1340+
considerParameterSources = false;
1341+
break;
1342+
}
1343+
}
1344+
13221345
// Reserve space for polymorphic bindings.
1323-
auto bindings =
1324-
NecessaryBindings::forPartialApplyForwarder(IGF.IGM, origType, subs);
1346+
auto bindings = NecessaryBindings::forPartialApplyForwarder(
1347+
IGF.IGM, origType, subs, considerParameterSources);
13251348

13261349
if (!bindings.empty()) {
13271350
hasSingleSwiftRefcountedContext = No;
@@ -1524,7 +1547,7 @@ Optional<StackAddress> irgen::emitFunctionPartialApplication(
15241547
HeapNonFixedOffsets offsets(IGF, layout);
15251548
if (outType->isNoEscape()) {
15261549
stackAddr = IGF.emitDynamicAlloca(
1527-
IGF.IGM.Int8Ty, layout.emitSize(IGF.IGM), Alignment(16));
1550+
IGF.IGM.Int8Ty, layout.isFixedLayout() ? layout.emitSize(IGF.IGM) : offsets.getSize() , Alignment(16));
15281551
stackAddr = stackAddr->withAddress(IGF.Builder.CreateBitCast(
15291552
stackAddr->getAddress(), IGF.IGM.OpaquePtrTy));
15301553
data = stackAddr->getAddress().getAddress();

lib/IRGen/GenProto.cpp

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ class PolymorphicConvention {
112112
}
113113

114114
public:
115-
PolymorphicConvention(IRGenModule &IGM, CanSILFunctionType fnType);
115+
PolymorphicConvention(IRGenModule &IGM, CanSILFunctionType fnType, bool considerParameterSources);
116116

117117
ArrayRef<MetadataSource> getSources() const { return Sources; }
118118

@@ -179,8 +179,9 @@ class PolymorphicConvention {
179179
} // end anonymous namespace
180180

181181
PolymorphicConvention::PolymorphicConvention(IRGenModule &IGM,
182-
CanSILFunctionType fnType)
183-
: IGM(IGM), M(*IGM.getSwiftModule()), FnType(fnType) {
182+
CanSILFunctionType fnType,
183+
bool considerParameterSources = true)
184+
: IGM(IGM), M(*IGM.getSwiftModule()), FnType(fnType){
184185
initGenerics();
185186

186187
auto rep = fnType->getRepresentation();
@@ -212,16 +213,18 @@ PolymorphicConvention::PolymorphicConvention(IRGenModule &IGM,
212213
unsigned selfIndex = ~0U;
213214
auto params = fnType->getParameters();
214215

215-
// Consider 'self' first.
216-
if (fnType->hasSelfParam()) {
217-
selfIndex = params.size() - 1;
218-
considerParameter(params[selfIndex], selfIndex, true);
219-
}
216+
if (considerParameterSources) {
217+
// Consider 'self' first.
218+
if (fnType->hasSelfParam()) {
219+
selfIndex = params.size() - 1;
220+
considerParameter(params[selfIndex], selfIndex, true);
221+
}
220222

221-
// Now consider the rest of the parameters.
222-
for (auto index : indices(params)) {
223-
if (index != selfIndex)
224-
considerParameter(params[index], index, false);
223+
// Now consider the rest of the parameters.
224+
for (auto index : indices(params)) {
225+
if (index != selfIndex)
226+
considerParameter(params[index], index, false);
227+
}
225228
}
226229
}
227230
}
@@ -2975,14 +2978,16 @@ NecessaryBindings::forFunctionInvocations(IRGenModule &IGM,
29752978
NecessaryBindings
29762979
NecessaryBindings::forPartialApplyForwarder(IRGenModule &IGM,
29772980
CanSILFunctionType origType,
2978-
SubstitutionMap subs) {
2981+
SubstitutionMap subs,
2982+
bool considerParameterSources) {
29792983
return computeBindings(IGM, origType, subs,
2980-
true /*forPartialApplyForwarder*/);
2984+
true /*forPartialApplyForwarder*/,
2985+
considerParameterSources);
29812986
}
29822987

29832988
NecessaryBindings NecessaryBindings::computeBindings(
29842989
IRGenModule &IGM, CanSILFunctionType origType, SubstitutionMap subs,
2985-
bool forPartialApplyForwarder) {
2990+
bool forPartialApplyForwarder, bool considerParameterSources) {
29862991

29872992
NecessaryBindings bindings;
29882993
bindings.forPartialApply = forPartialApplyForwarder;
@@ -2992,7 +2997,7 @@ NecessaryBindings NecessaryBindings::computeBindings(
29922997
return bindings;
29932998

29942999
// Figure out what we're actually required to pass:
2995-
PolymorphicConvention convention(IGM, origType);
3000+
PolymorphicConvention convention(IGM, origType, considerParameterSources);
29963001

29973002
// - unfulfilled requirements
29983003
convention.enumerateUnfulfilledRequirements(

lib/IRGen/NecessaryBindings.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ class NecessaryBindings {
5959
SubstitutionMap subs);
6060
static NecessaryBindings forPartialApplyForwarder(IRGenModule &IGM,
6161
CanSILFunctionType origType,
62-
SubstitutionMap subs);
62+
SubstitutionMap subs,
63+
bool considerParameterSources = true);
6364

6465
/// Add whatever information is necessary to reconstruct type metadata
6566
/// for the given type.
@@ -98,7 +99,8 @@ class NecessaryBindings {
9899
static NecessaryBindings computeBindings(IRGenModule &IGM,
99100
CanSILFunctionType origType,
100101
SubstitutionMap subs,
101-
bool forPartialApplyForwarder);
102+
bool forPartialApplyForwarder,
103+
bool considerParameterSources = true);
102104
};
103105

104106
} // end namespace irgen

lib/SIL/LinearLifetimeChecker.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,8 @@ LinearLifetimeError LinearLifetimeChecker::checkValue(
499499
SILValue value, ArrayRef<Operand *> consumingUses,
500500
ArrayRef<Operand *> nonConsumingUses, ErrorBehaviorKind errorBehavior,
501501
SmallVectorImpl<SILBasicBlock *> *leakingBlocks) {
502-
assert(!consumingUses.empty() && "Must have at least one consuming user?!");
502+
assert((!consumingUses.empty() || !deadEndBlocks.empty()) &&
503+
"Must have at least one consuming user?!");
503504

504505
State state(value, visitedBlocks, errorBehavior, leakingBlocks, consumingUses,
505506
nonConsumingUses);

lib/SIL/SILFunctionType.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,9 +1464,8 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
14641464
case CaptureKind::Constant: {
14651465
// Constants are captured by value.
14661466
ParameterConvention convention;
1467-
if (loweredTL.isAddressOnly()) {
1468-
convention = ParameterConvention::Indirect_In_Guaranteed;
1469-
} else if (loweredTL.isTrivial()) {
1467+
assert (!loweredTL.isAddressOnly());
1468+
if (loweredTL.isTrivial()) {
14701469
convention = ParameterConvention::Direct_Unowned;
14711470
} else {
14721471
convention = ParameterConvention::Direct_Guaranteed;
@@ -1499,6 +1498,16 @@ lowerCaptureContextParameters(TypeConverter &TC, SILDeclRef function,
14991498
inputs.push_back(param);
15001499
break;
15011500
}
1501+
case CaptureKind::Immutable: {
1502+
// 'let' constants that are address-only are captured as the address of
1503+
// the value and will be consumed by the closure.
1504+
SILType ty = loweredTy.getAddressType();
1505+
auto param =
1506+
SILParameterInfo(ty.getASTType(),
1507+
ParameterConvention::Indirect_In_Guaranteed);
1508+
inputs.push_back(param);
1509+
break;
1510+
}
15021511
}
15031512
}
15041513
}

lib/SIL/SILVerifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1117,7 +1117,7 @@ class SILVerifier : public SILVerifierBase<SILVerifier> {
11171117
if (VarInfo)
11181118
if (unsigned ArgNo = VarInfo->ArgNo) {
11191119
// It is a function argument.
1120-
if (ArgNo < DebugVars.size() && !DebugVars[ArgNo].empty()) {
1120+
if (ArgNo < DebugVars.size() && !DebugVars[ArgNo].empty() && !VarInfo->Name.empty()) {
11211121
require(
11221122
DebugVars[ArgNo] == VarInfo->Name,
11231123
"Scope contains conflicting debug variables for one function "

lib/SIL/TypeLowering.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,10 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
103103
// by value. If it is address-only, then we can't load it, so capture it
104104
// by its address (like a var) instead.
105105
if (!var->supportsMutation() &&
106-
(Context.LangOpts.EnableSILOpaqueValues ||
107-
!getTypeLowering(
108-
var->getType(),
109-
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
110-
expansion.getResilienceExpansion()))
111-
.isAddressOnly()))
106+
!getTypeLowering(var->getType(),
107+
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
108+
expansion.getResilienceExpansion()))
109+
.isAddressOnly())
112110
return CaptureKind::Constant;
113111

114112
// In-out parameters are captured by address.
@@ -126,6 +124,16 @@ CaptureKind TypeConverter::getDeclCaptureKind(CapturedValue capture,
126124
return CaptureKind::Box;
127125
}
128126

127+
// For 'let' constants
128+
if (!var->supportsMutation()) {
129+
assert(getTypeLowering(
130+
var->getType(),
131+
TypeExpansionContext::noOpaqueTypeArchetypesSubstitution(
132+
expansion.getResilienceExpansion()))
133+
.isAddressOnly());
134+
return CaptureKind::Immutable;
135+
}
136+
129137
// If we're capturing into a non-escaping closure, we can generally just
130138
// capture the address of the value as no-escape.
131139
return (capture.isNoEscape()

0 commit comments

Comments
 (0)