Skip to content

Commit dc978f2

Browse files
committed
[Distributed] IRGen: Support argument with generic parameters passed directly
This is the case of e.g. `Array<T>` where argument is `Array<Int>` we need to compute offset/size based on argument metadata but load the argument using parameter type information.
1 parent d55f8f7 commit dc978f2

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

lib/IRGen/GenDistributed.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ class DistributedAccessor {
118118
loadArgument(unsigned argumentIdx,
119119
llvm::Value *argumentSlot,
120120
llvm::Value *argumentType,
121-
ParameterConvention convention,
121+
const SILParameterInfo &param,
122122
Explosion &arguments);
123123

124124
FunctionPointer getPointerToTarget() const;
@@ -242,7 +242,6 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
242242
// Load current offset
243243
llvm::Value *currentOffset = IGF.Builder.CreateLoad(offset, "elt_offset");
244244

245-
// Load argument value into the provided explosion
246245
if (paramTy.hasTypeParameter()) {
247246
auto offset =
248247
Size(i * IGM.DataLayout.getTypeAllocSize(IGM.TypeMetadataPtrTy));
@@ -257,8 +256,8 @@ void DistributedAccessor::computeArguments(llvm::Value *argumentBuffer,
257256
auto *argumentTy = IGF.Builder.CreateLoad(typeLoc, "arg_type");
258257

259258
// 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);
262261
} else {
263262
std::tie(currentOffset, valueSize) = loadArgument(
264263
i, currentOffset, paramTy, param.getConvention(), arguments);
@@ -281,7 +280,7 @@ std::pair<llvm::Value *, llvm::Value *>
281280
DistributedAccessor::loadArgument(unsigned argumentIdx,
282281
llvm::Value *argumentSlot,
283282
llvm::Value *argumentType,
284-
ParameterConvention convention,
283+
const SILParameterInfo &param,
285284
Explosion &arguments) {
286285
// TODO: `emitLoad*` would actually load value witness table every
287286
// time it's called, which is sub-optimal but all of the APIs that
@@ -305,18 +304,22 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
305304
IGF.Builder.CreateIntToPtr(alignedSlot, IGM.OpaquePtrTy);
306305
}
307306

308-
switch (convention) {
307+
Address argumentAddr(alignedSlot, IGM.getPointerAlignment());
308+
309+
switch (param.getConvention()) {
309310
case ParameterConvention::Indirect_In:
310311
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.
313315

314316
auto stackAddr =
315317
IGF.emitDynamicAlloca(IGM.Int8Ty, valueSize, Alignment(16));
316318
auto argPtr = stackAddr.getAddress().getAddress();
317319

318320
emitInitializeWithCopyCall(IGF, argumentType, stackAddr.getAddress(),
319-
Address(alignedSlot, IGM.getPointerAlignment()));
321+
argumentAddr);
322+
320323
arguments.add(argPtr);
321324

322325
// Remember to deallocate later.
@@ -336,9 +339,22 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
336339
llvm_unreachable("indirect 'inout' parameters are not supported");
337340

338341
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+
}
342358
}
343359

344360
return {alignedSlot, valueSize};
@@ -410,6 +426,7 @@ DistributedAccessor::loadArgument(unsigned argumentIdx,
410426
case ParameterConvention::Direct_Owned:
411427
// Copy the value out at +1.
412428
cast<LoadableTypeInfo>(typeInfo).loadAsCopy(IGF, alignedOffset, arguments);
429+
break;
413430
}
414431

415432
return {alignedOffset.getAddress(), typeInfo.getSize(IGF, paramTy)};

0 commit comments

Comments
 (0)