@@ -64,6 +64,12 @@ llvm::Value *irgen::emitDistributedActorInitializeRemote(
64
64
65
65
namespace {
66
66
67
+ struct AllocationInfo {
68
+ SILType Type;
69
+ const TypeInfo &TI;
70
+ StackAddress Addr;
71
+ };
72
+
67
73
class DistributedAccessor {
68
74
IRGenModule &IGM;
69
75
IRGenFunction &IGF;
@@ -76,6 +82,9 @@ class DistributedAccessor {
76
82
// / The asynchronous context associated with this accessor.
77
83
AsyncContextLayout AsyncLayout;
78
84
85
+ // / The list of all arguments that were allocated on the stack.
86
+ SmallVector<AllocationInfo, 4 > AllocatedArguments;
87
+
79
88
public:
80
89
DistributedAccessor (IRGenFunction &IGF, SILFunction *method,
81
90
CanSILFunctionType accessorTy);
@@ -203,28 +212,56 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
203
212
// 3. Adjust typed pointer to the alignement of the type.
204
213
auto alignedOffset = typeInfo.roundUpToTypeAlignment (IGF, eltPtr, paramTy);
205
214
206
- // 4. Create an exploded version of the type to pass as an
207
- // argument to distributed method.
208
-
209
215
if (paramTy.isObject ()) {
210
216
auto &nativeSchema = typeInfo.nativeParameterValueSchema (IGM);
211
-
212
- if (nativeSchema.requiresIndirect ()) {
213
- llvm_unreachable (" indirect parameters are not supported" );
214
- }
215
-
216
217
// If schema is empty, skip to the next argument.
217
218
if (nativeSchema.empty ())
218
219
continue ;
220
+ }
221
+
222
+ // 4. Create an exploded version of the type to pass as an
223
+ // argument to distributed method.
224
+
225
+ switch (param.getConvention ()) {
226
+ case ParameterConvention::Indirect_In:
227
+ case ParameterConvention::Indirect_In_Constant: {
228
+ // The +1 argument is passed indirectly, so we need to copy it into
229
+ // a temporary.
219
230
220
- // 5. Load argument value from the element pointer.
221
- cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, alignedOffset, arguments);
222
- } else {
223
- // If the value is not loadable e.g. generic or resilient
224
- // pass its address as an argument.
225
- //
226
- // TODO: This needs to be copied and destroyed.
231
+ auto stackAddr = typeInfo.allocateStack (IGF, paramTy, " arg.temp" );
232
+ auto argPtr = stackAddr.getAddress ().getAddress ();
233
+
234
+ typeInfo.initializeWithCopy (IGF, stackAddr.getAddress (), alignedOffset,
235
+ paramTy, /* isOutlined=*/ false );
236
+ arguments.add (argPtr);
237
+
238
+ // Remember to deallocate later.
239
+ AllocatedArguments.push_back ({paramTy, typeInfo, stackAddr});
240
+ break ;
241
+ }
242
+
243
+ case ParameterConvention::Indirect_In_Guaranteed: {
244
+ // The argument is +0, so we can use the address of the param in
245
+ // the context directly.
227
246
arguments.add (alignedOffset.getAddress ());
247
+ break ;
248
+ }
249
+
250
+ case ParameterConvention::Indirect_Inout:
251
+ case ParameterConvention::Indirect_InoutAliasable:
252
+ llvm_unreachable (" indirect parameters are not supported" );
253
+
254
+ case ParameterConvention::Direct_Guaranteed:
255
+ case ParameterConvention::Direct_Unowned: {
256
+ cast<LoadableTypeInfo>(typeInfo).loadAsTake (IGF, alignedOffset,
257
+ arguments);
258
+ break ;
259
+ }
260
+
261
+ case ParameterConvention::Direct_Owned:
262
+ // Copy the value out at +1.
263
+ cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, alignedOffset,
264
+ arguments);
228
265
}
229
266
230
267
// 6. Move the offset to the beginning of the next element, unless
@@ -335,6 +372,12 @@ void DistributedAccessor::emit() {
335
372
336
373
emission->end ();
337
374
375
+ // Deallocate all of the copied arguments.
376
+ {
377
+ for (auto &entry : AllocatedArguments)
378
+ entry.TI .deallocateStack (IGF, entry.Addr , entry.Type );
379
+ }
380
+
338
381
Explosion voidResult;
339
382
emitAsyncReturn (IGF, AsyncLayout,
340
383
accessorConv.getSILResultType (expansionContext),
0 commit comments