@@ -134,42 +134,51 @@ class PartialApplyCombiner {
134
134
135
135
// / Returns true on success.
136
136
bool PartialApplyCombiner::allocateTemporaries () {
137
- // Copy the original arguments of the partial_apply into
138
- // newly created temporaries and use these temporaries instead of
139
- // the original arguments afterwards.
140
- // This is done to "extend" the life-time of original partial_apply
141
- // arguments, as they may be destroyed/deallocated before the last
142
- // use by one of the apply instructions.
143
- // TODO:
144
- // Copy arguments of the partial_apply into new temporaries
145
- // only if the lifetime of arguments ends before their uses
146
- // by apply instructions.
137
+ // Copy the original arguments of the partial_apply into newly created
138
+ // temporaries and use these temporaries instead of the original arguments
139
+ // afterwards.
140
+ //
141
+ // This is done to "extend" the life-time of original partial_apply arguments,
142
+ // as they may be destroyed/deallocated before the last use by one of the
143
+ // apply instructions.
144
+ //
145
+ // TODO: Copy arguments of the partial_apply into new temporaries only if the
146
+ // lifetime of arguments ends before their uses by apply instructions.
147
147
bool needsReleases = false ;
148
148
CanSILFunctionType PAITy =
149
149
PAI->getCallee ()->getType ().getAs <SILFunctionType>();
150
150
151
151
// Emit a destroy value for each captured closure argument.
152
152
ArrayRef<SILParameterInfo> Params = PAITy->getParameters ();
153
153
auto Args = PAI->getArguments ();
154
- unsigned Delta = Params.size () - Args.size ();
154
+ Params = Params.drop_front (Params. size () - Args.size () );
155
155
156
156
llvm::SmallVector<std::pair<SILValue, unsigned >, 8 > ArgsToHandle;
157
- for (unsigned AI = 0 , AE = Args. size (); AI != AE; ++AI ) {
158
- SILValue Arg = Args[AI ];
159
- SILParameterInfo Param = Params[AI + Delta ];
157
+ for (unsigned i : indices (Args) ) {
158
+ SILValue Arg = Args[i ];
159
+ SILParameterInfo Param = Params[i ];
160
160
if (Param.isIndirectMutating ())
161
161
continue ;
162
+
162
163
// Create a temporary and copy the argument into it, if:
163
164
// - the argument stems from an alloc_stack
164
165
// - the argument is consumed by the callee and is indirect
165
166
// (e.g. it is an @in argument)
166
167
if (isa<AllocStackInst>(Arg)
167
168
|| (Param.isConsumed ()
168
169
&& PAI->getSubstCalleeConv ().isSILIndirect (Param))) {
170
+ // If the argument has a dependent type, then we can not create a
171
+ // temporary for it at the beginning of the function, so we must bail.
172
+ //
173
+ // TODO: This is because we are inserting alloc_stack at the beginning/end
174
+ // of functions where the dependent type may not exist yet.
175
+ if (Arg->getType ().hasOpenedExistential ())
176
+ return false ;
177
+
169
178
// If the temporary is non-trivial, we need to release it later.
170
179
if (!Arg->getType ().isTrivial (PAI->getModule ()))
171
180
needsReleases = true ;
172
- ArgsToHandle.push_back (std::make_pair (Arg, AI ));
181
+ ArgsToHandle.push_back (std::make_pair (Arg, i ));
173
182
}
174
183
}
175
184
0 commit comments