@@ -59,7 +59,10 @@ static SILValue stripCopiesAndBorrows(SILValue v) {
59
59
// / It is important to note that, we can not assume that the partial apply, the
60
60
// / apply site, or the callee value are control dependent in any way. This
61
61
// / requires us to need to be very careful. See inline comments.
62
- static void fixupReferenceCounts (
62
+ // /
63
+ // / Returns true if the stack nesting is invalidated and must be corrected
64
+ // / afterwards.
65
+ static bool fixupReferenceCounts (
63
66
PartialApplyInst *pai, FullApplySite applySite, SILValue calleeValue,
64
67
ArrayRef<ParameterConvention> captureArgConventions,
65
68
MutableArrayRef<SILValue> capturedArgs, bool isCalleeGuaranteed) {
@@ -72,6 +75,7 @@ static void fixupReferenceCounts(
72
75
// FIXME: Can we cache this in between inlining invocations?
73
76
DeadEndBlocks deadEndBlocks (pai->getFunction ());
74
77
SmallVector<SILBasicBlock *, 4 > leakingBlocks;
78
+ bool invalidatedStackNesting = false ;
75
79
76
80
// Add a copy of each non-address type capture argument to lifetime extend the
77
81
// captured argument over at least the inlined function and till the end of a
@@ -83,14 +87,6 @@ static void fixupReferenceCounts(
83
87
for (unsigned i : indices (captureArgConventions)) {
84
88
auto convention = captureArgConventions[i];
85
89
SILValue &v = capturedArgs[i];
86
- if (v->getType ().isAddress ()) {
87
- // FIXME: What about indirectly owned parameters? The invocation of the
88
- // closure would perform an indirect copy which we should mimick here.
89
- assert (convention != ParameterConvention::Indirect_In &&
90
- " Missing indirect copy" );
91
- continue ;
92
- }
93
-
94
90
auto *f = applySite.getFunction ();
95
91
96
92
// See if we have a trivial value. In such a case, just continue. We do not
@@ -102,11 +98,40 @@ static void fixupReferenceCounts(
102
98
103
99
switch (convention) {
104
100
case ParameterConvention::Indirect_In:
101
+ llvm_unreachable (" Missing indirect copy" );
102
+
105
103
case ParameterConvention::Indirect_In_Constant:
106
104
case ParameterConvention::Indirect_Inout:
107
105
case ParameterConvention::Indirect_InoutAliasable:
108
- case ParameterConvention::Indirect_In_Guaranteed:
109
- llvm_unreachable (" Should be handled above" );
106
+ break ;
107
+
108
+ case ParameterConvention::Indirect_In_Guaranteed: {
109
+ // Do the same as for Direct_Guaranteed, just the address version.
110
+ // (See comment below).
111
+ SILBuilderWithScope builder (pai);
112
+ auto *stackLoc = builder.createAllocStack (loc, v->getType ().getObjectType ());
113
+ builder.createCopyAddr (loc, v, stackLoc, IsNotTake, IsInitialization);
114
+ visitedBlocks.clear ();
115
+
116
+ LinearLifetimeChecker checker (visitedBlocks, deadEndBlocks);
117
+ bool consumedInLoop = checker.completeConsumingUseSet (
118
+ pai, applySite.getCalleeOperand (),
119
+ [&](SILBasicBlock::iterator insertPt) {
120
+ SILBuilderWithScope builder (insertPt);
121
+ builder.createDestroyAddr (loc, stackLoc);
122
+ builder.createDeallocStack (loc, stackLoc);
123
+ });
124
+
125
+ if (!consumedInLoop) {
126
+ applySite.insertAfterInvocation ([&](SILBasicBlock::iterator iter) {
127
+ SILBuilderWithScope (iter).createDestroyAddr (loc, stackLoc);
128
+ SILBuilderWithScope (iter).createDeallocStack (loc, stackLoc);
129
+ });
130
+ }
131
+ v = stackLoc;
132
+ invalidatedStackNesting = true ;
133
+ break ;
134
+ }
110
135
111
136
case ParameterConvention::Direct_Guaranteed: {
112
137
// If we have a direct_guaranteed value, the value is being taken by the
@@ -242,6 +267,7 @@ static void fixupReferenceCounts(
242
267
SILBuilderWithScope (iter).emitDestroyValueOperation (loc, calleeValue);
243
268
});
244
269
}
270
+ return invalidatedStackNesting;
245
271
}
246
272
247
273
static SILValue cleanupLoadedCalleeValue (SILValue calleeValue, LoadInst *li) {
@@ -917,8 +943,9 @@ runOnFunctionRecursively(SILOptFunctionBuilder &FuncBuilder,
917
943
// We need to insert the copies before the partial_apply since if we can
918
944
// not remove the partial_apply the captured values will be dead by the
919
945
// time we hit the call site.
920
- fixupReferenceCounts (PAI, InnerAI, CalleeValue, CapturedArgConventions,
921
- CapturedArgs, IsCalleeGuaranteed);
946
+ invalidatedStackNesting |= fixupReferenceCounts (PAI, InnerAI,
947
+ CalleeValue, CapturedArgConventions,
948
+ CapturedArgs, IsCalleeGuaranteed);
922
949
}
923
950
924
951
// Register a callback to record potentially unused function values after
0 commit comments