@@ -118,7 +118,7 @@ class DistributedAccessor {
118
118
loadArgument (unsigned argumentIdx,
119
119
llvm::Value *argumentSlot,
120
120
llvm::Value *argumentType,
121
- ParameterConvention convention ,
121
+ const SILParameterInfo ¶m ,
122
122
Explosion &arguments);
123
123
124
124
FunctionPointer getPointerToTarget () const ;
@@ -242,7 +242,6 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
242
242
// Load current offset
243
243
llvm::Value *currentOffset = IGF.Builder .CreateLoad (offset, " elt_offset" );
244
244
245
- // Load argument value into the provided explosion
246
245
if (paramTy.hasTypeParameter ()) {
247
246
auto offset =
248
247
Size (i * IGM.DataLayout .getTypeAllocSize (IGM.TypeMetadataPtrTy ));
@@ -257,8 +256,8 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
257
256
auto *argumentTy = IGF.Builder .CreateLoad (typeLoc, " arg_type" );
258
257
259
258
// Load argument value based using loaded type metadata.
260
- std::tie (currentOffset, valueSize) = loadArgument (
261
- i, currentOffset, argumentTy, param. getConvention () , arguments);
259
+ std::tie (currentOffset, valueSize) =
260
+ loadArgument ( i, currentOffset, argumentTy, param, arguments);
262
261
} else {
263
262
std::tie (currentOffset, valueSize) = loadArgument (
264
263
i, currentOffset, paramTy, param.getConvention (), arguments);
@@ -281,7 +280,7 @@ std::pair<llvm::Value *, llvm::Value *>
281
280
DistributedAccessor::loadArgument (unsigned argumentIdx,
282
281
llvm::Value *argumentSlot,
283
282
llvm::Value *argumentType,
284
- ParameterConvention convention ,
283
+ const SILParameterInfo ¶m ,
285
284
Explosion &arguments) {
286
285
// TODO: `emitLoad*` would actually load value witness table every
287
286
// time it's called, which is sub-optimal but all of the APIs that
@@ -305,18 +304,22 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
305
304
IGF.Builder .CreateIntToPtr (alignedSlot, IGM.OpaquePtrTy );
306
305
}
307
306
308
- switch (convention) {
307
+ Address argumentAddr (alignedSlot, IGM.getPointerAlignment ());
308
+
309
+ switch (param.getConvention ()) {
309
310
case ParameterConvention::Indirect_In:
310
311
case ParameterConvention::Indirect_In_Constant: {
311
- // The +1 argument is passed indirectly, so we need to copy it into
312
- // a temporary.
312
+ // The only way to load opaque type is to allocate a temporary
313
+ // variable on the stack for it and initialize from the given address
314
+ // either at +0 or +1 depending on convention.
313
315
314
316
auto stackAddr =
315
317
IGF.emitDynamicAlloca (IGM.Int8Ty , valueSize, Alignment (16 ));
316
318
auto argPtr = stackAddr.getAddress ().getAddress ();
317
319
318
320
emitInitializeWithCopyCall (IGF, argumentType, stackAddr.getAddress (),
319
- Address (alignedSlot, IGM.getPointerAlignment ()));
321
+ argumentAddr);
322
+
320
323
arguments.add (argPtr);
321
324
322
325
// Remember to deallocate later.
@@ -336,9 +339,22 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
336
339
llvm_unreachable (" indirect 'inout' parameters are not supported" );
337
340
338
341
case ParameterConvention::Direct_Guaranteed:
339
- case ParameterConvention::Direct_Unowned:
340
- case ParameterConvention::Direct_Owned:
341
- llvm_unreachable (" cannot pass opaque type directly" );
342
+ case ParameterConvention::Direct_Unowned: {
343
+ auto paramTy = param.getSILStorageInterfaceType ();
344
+ auto &typeInfo = IGM.getTypeInfo (paramTy);
345
+ Address eltPtr = IGF.Builder .CreateBitCast (
346
+ argumentAddr, IGM.getStoragePointerType (paramTy));
347
+
348
+ cast<LoadableTypeInfo>(typeInfo).loadAsTake (IGF, eltPtr, arguments);
349
+ break ;
350
+ }
351
+
352
+ case ParameterConvention::Direct_Owned: {
353
+ auto &typeInfo = IGM.getTypeInfo (param.getSILStorageInterfaceType ());
354
+ // Copy the value out at +1.
355
+ cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, argumentAddr, arguments);
356
+ break ;
357
+ }
342
358
}
343
359
344
360
return {alignedSlot, valueSize};
@@ -410,6 +426,7 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
410
426
case ParameterConvention::Direct_Owned:
411
427
// Copy the value out at +1.
412
428
cast<LoadableTypeInfo>(typeInfo).loadAsCopy (IGF, alignedOffset, arguments);
429
+ break ;
413
430
}
414
431
415
432
return {alignedOffset.getAddress (), typeInfo.getSize (IGF, paramTy)};
0 commit comments