Skip to content

[Test] Ensure linked dylib is copied to devices. #34221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

80 changes: 49 additions & 31 deletions lib/IRGen/GenCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,28 @@ AsyncContextLayout irgen::getAsyncContextLayout(
paramInfos.push_back({ty, parameter.getConvention()});
}

Optional<AsyncContextLayout::TrailingWitnessInfo> trailingWitnessInfo;
if (originalType->getRepresentation() ==
SILFunctionTypeRepresentation::WitnessMethod) {
assert(getTrailingWitnessSignatureLength(IGF.IGM, originalType) == 2);

// First, the Self metadata.
{
auto ty = SILType();
auto &ti = IGF.IGM.getTypeMetadataPtrTypeInfo();
valTypes.push_back(ty);
typeInfos.push_back(&ti);
}
// Then, the Self witness table.
{
auto ty = SILType();
auto &ti = IGF.IGM.getWitnessTablePtrTypeInfo();
valTypes.push_back(ty);
typeInfos.push_back(&ti);
}
trailingWitnessInfo = AsyncContextLayout::TrailingWitnessInfo();
}

// ResultTypes directResults...;
auto directResults = fnConv.getDirectSILResults();
for (auto result : directResults) {
Expand All @@ -192,20 +214,20 @@ AsyncContextLayout irgen::getAsyncContextLayout(
directReturnInfos.push_back(result);
}

return AsyncContextLayout(IGF.IGM, LayoutStrategy::Optimal, valTypes,
typeInfos, IGF, originalType, substitutedType,
substitutionMap, std::move(bindings), errorType,
canHaveValidError, paramInfos, indirectReturnInfos,
directReturnInfos, localContextInfo);
return AsyncContextLayout(
IGF.IGM, LayoutStrategy::Optimal, valTypes, typeInfos, IGF, originalType,
substitutedType, substitutionMap, std::move(bindings),
trailingWitnessInfo, errorType, canHaveValidError, paramInfos,
indirectReturnInfos, directReturnInfos, localContextInfo);
}

AsyncContextLayout::AsyncContextLayout(
IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
ArrayRef<const TypeInfo *> fieldTypeInfos, IRGenFunction &IGF,
CanSILFunctionType originalType, CanSILFunctionType substitutedType,
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
SILType errorType, bool canHaveValidError,
ArrayRef<ArgumentInfo> argumentInfos,
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
ArrayRef<SILResultInfo> indirectReturnInfos,
ArrayRef<SILResultInfo> directReturnInfos,
Optional<AsyncContextLayout::ArgumentInfo> localContextInfo)
Expand All @@ -218,6 +240,7 @@ AsyncContextLayout::AsyncContextLayout(
indirectReturnInfos(indirectReturnInfos.begin(),
indirectReturnInfos.end()),
localContextInfo(localContextInfo), bindings(std::move(bindings)),
trailingWitnessInfo(trailingWitnessInfo),
argumentInfos(argumentInfos.begin(), argumentInfos.end()) {
#ifndef NDEBUG
assert(fieldTypeInfos.size() == fieldTypes.size() &&
Expand Down Expand Up @@ -1929,6 +1952,17 @@ class AsyncCallEmission final : public CallEmission {
getCallee().getSubstitutions());
}

void saveValue(ElementLayout layout, Explosion &explosion, bool isOutlined) {
Address addr = layout.project(IGF, context, /*offsets*/ llvm::None);
auto &ti = cast<LoadableTypeInfo>(layout.getType());
ti.initialize(IGF, explosion, addr, isOutlined);
}
void loadValue(ElementLayout layout, Explosion &explosion) {
Address addr = layout.project(IGF, context, /*offsets*/ llvm::None);
auto &ti = layout.getType();
cast<LoadableTypeInfo>(ti).loadAsTake(IGF, addr, explosion);
}

public:
AsyncCallEmission(IRGenFunction &IGF, llvm::Value *selfValue, Callee &&callee)
: CallEmission(IGF, selfValue, std::move(callee)) {
Expand Down Expand Up @@ -1974,21 +2008,15 @@ class AsyncCallEmission final : public CallEmission {
llArgs.add(selfValue);
}
auto layout = getAsyncContextLayout();
for (unsigned index = 0, count = layout.getArgumentCount(); index < count;
++index) {
auto fieldLayout = layout.getArgumentLayout(index);
Address fieldAddr =
fieldLayout.project(IGF, context, /*offsets*/ llvm::None);
auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType());
ti.initialize(IGF, llArgs, fieldAddr, isOutlined);
}
for (unsigned index = 0, count = layout.getIndirectReturnCount();
index < count; ++index) {
auto fieldLayout = layout.getIndirectReturnLayout(index);
Address fieldAddr =
fieldLayout.project(IGF, context, /*offsets*/ llvm::None);
cast<LoadableTypeInfo>(fieldLayout.getType())
.initialize(IGF, llArgs, fieldAddr, isOutlined);
saveValue(fieldLayout, llArgs, isOutlined);
}
for (unsigned index = 0, count = layout.getArgumentCount(); index < count;
++index) {
auto fieldLayout = layout.getArgumentLayout(index);
saveValue(fieldLayout, llArgs, isOutlined);
}
if (layout.hasBindings()) {
auto bindingLayout = layout.getBindingsLayout();
Expand All @@ -1997,10 +2025,7 @@ class AsyncCallEmission final : public CallEmission {
}
if (selfValue) {
auto fieldLayout = layout.getLocalContextLayout();
Address fieldAddr =
fieldLayout.project(IGF, context, /*offsets*/ llvm::None);
auto &ti = cast<LoadableTypeInfo>(fieldLayout.getType());
ti.initialize(IGF, llArgs, fieldAddr, isOutlined);
saveValue(fieldLayout, llArgs, isOutlined);
}
}
void emitCallToUnmappedExplosion(llvm::CallInst *call, Explosion &out) override {
Expand All @@ -2016,20 +2041,13 @@ class AsyncCallEmission final : public CallEmission {
// argument buffer.
return;
}
assert(call->arg_size() == 1);
auto context = call->arg_begin()->get();
// Gather the values.
Explosion nativeExplosion;
auto layout = getAsyncContextLayout();
auto dataAddr = layout.emitCastTo(IGF, context);
for (unsigned index = 0, count = layout.getDirectReturnCount();
index < count; ++index) {
auto fieldLayout = layout.getDirectReturnLayout(index);
Address fieldAddr =
fieldLayout.project(IGF, dataAddr, /*offsets*/ llvm::None);
auto &fieldTI = fieldLayout.getType();
cast<LoadableTypeInfo>(fieldTI).loadAsTake(IGF, fieldAddr,
nativeExplosion);
loadValue(fieldLayout, nativeExplosion);
}

out = nativeSchema.mapFromNative(IGF.IGM, IGF, nativeExplosion, resultType);
Expand Down
100 changes: 60 additions & 40 deletions lib/IRGen/GenCall.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ namespace irgen {
SILType type;
ParameterConvention convention;
};
struct TrailingWitnessInfo {};

private:
enum class FixedIndex : unsigned {
Expand All @@ -107,28 +108,59 @@ namespace irgen {
SmallVector<SILResultInfo, 4> indirectReturnInfos;
Optional<ArgumentInfo> localContextInfo;
NecessaryBindings bindings;
Optional<TrailingWitnessInfo> trailingWitnessInfo;
SmallVector<ArgumentInfo, 4> argumentInfos;

unsigned getErrorIndex() { return (unsigned)FixedIndex::Error; }
unsigned getFirstIndirectReturnIndex() {
return getErrorIndex() + getErrorCount();
}
unsigned getLocalContextIndex() {
assert(hasLocalContext());
return getFirstIndirectReturnIndex() + getIndirectReturnCount();
}
unsigned getIndexAfterLocalContext() {
return getFirstIndirectReturnIndex() + getIndirectReturnCount() +
(hasLocalContext() ? 1 : 0);
}
unsigned getBindingsIndex() {
assert(hasBindings());
return getIndexAfterLocalContext();
}
unsigned getIndexAfterBindings() {
return getIndexAfterLocalContext() + (hasBindings() ? 1 : 0);
}
unsigned getFirstArgumentIndex() { return getIndexAfterBindings(); }
unsigned getIndexAfterArguments() {
return getFirstArgumentIndex() + getArgumentCount();
}
unsigned getSelfMetadataIndex() {
assert(hasTrailingWitnesses());
return getIndexAfterArguments();
}
unsigned getSelfWitnessTableIndex() {
assert(hasTrailingWitnesses());
return getIndexAfterArguments() + 1;
}
unsigned getIndexAfterTrailingWitnesses() {
return getIndexAfterArguments() + (hasTrailingWitnesses() ? 2 : 0);
}
unsigned getFirstDirectReturnIndex() {
return getIndexAfterTrailingWitnesses();
}

public:
bool canHaveError() { return canHaveValidError; }
unsigned getErrorIndex() { return (unsigned)FixedIndex::Error; }
ElementLayout getErrorLayout() { return getElement(getErrorIndex()); }
unsigned getErrorCount() { return (unsigned)FixedCount::Error; }
SILType getErrorType() { return errorType; }

unsigned getFirstIndirectReturnIndex() {
return getErrorIndex() + getErrorCount();
}
ElementLayout getIndirectReturnLayout(unsigned index) {
return getElement(getFirstIndirectReturnIndex() + index);
}
unsigned getIndirectReturnCount() { return indirectReturnInfos.size(); }

bool hasLocalContext() { return (bool)localContextInfo; }
unsigned getLocalContextIndex() {
assert(hasLocalContext());
return getFirstIndirectReturnIndex() + getIndirectReturnCount();
}
ElementLayout getLocalContextLayout() {
assert(hasLocalContext());
return getElement(getLocalContextIndex());
Expand All @@ -141,65 +173,53 @@ namespace irgen {
assert(hasLocalContext());
return localContextInfo->type;
}
unsigned getIndexAfterLocalContext() {
return getFirstIndirectReturnIndex() + getIndirectReturnCount() +
(hasLocalContext() ? 1 : 0);
}

bool hasBindings() const { return !bindings.empty(); }
unsigned getBindingsIndex() {
assert(hasBindings());
return getIndexAfterLocalContext();
}
ElementLayout getBindingsLayout() {
assert(hasBindings());
return getElement(getBindingsIndex());
}
ParameterConvention getBindingsConvention() {
return ParameterConvention::Direct_Unowned;
}
const NecessaryBindings &getBindings() const { return bindings; }

unsigned getFirstArgumentIndex() {
return getIndexAfterLocalContext() + (hasBindings() ? 1 : 0);
}
ElementLayout getArgumentLayout(unsigned index) {
return getElement(getFirstArgumentIndex() + index);
}
ParameterConvention getArgumentConvention(unsigned index) {
return argumentInfos[index].convention;
}
SILType getArgumentType(unsigned index) {
return argumentInfos[index].type;
}
// Returns the type of a parameter of the substituted function using the
// indexing of the function parameters, *not* the indexing of
// AsyncContextLayout.
SILType getParameterType(unsigned index) {
SILFunctionConventions origConv(substitutedType, IGF.getSILModule());
return origConv.getSILArgumentType(
index, IGF.IGM.getMaximalTypeExpansionContext());
}
unsigned getArgumentCount() { return argumentInfos.size(); }
unsigned getIndexAfterArguments() {
return getFirstArgumentIndex() + getArgumentCount();
bool hasTrailingWitnesses() { return (bool)trailingWitnessInfo; }
ElementLayout getSelfMetadataLayout() {
assert(hasTrailingWitnesses());
return getElement(getSelfMetadataIndex());
}
ElementLayout getSelfWitnessTableLayout() {
return getElement(getSelfWitnessTableIndex());
}

unsigned getFirstDirectReturnIndex() { return getIndexAfterArguments(); }
unsigned getDirectReturnCount() { return directReturnInfos.size(); }
ElementLayout getDirectReturnLayout(unsigned index) {
return getElement(getFirstDirectReturnIndex() + index);
}

AsyncContextLayout(IRGenModule &IGM, LayoutStrategy strategy,
ArrayRef<SILType> fieldTypes,
ArrayRef<const TypeInfo *> fieldTypeInfos,
IRGenFunction &IGF, CanSILFunctionType originalType,
CanSILFunctionType substitutedType,
SubstitutionMap substitutionMap,
NecessaryBindings &&bindings, SILType errorType,
bool canHaveValidError,
ArrayRef<ArgumentInfo> argumentInfos,
ArrayRef<SILResultInfo> directReturnInfos,
ArrayRef<SILResultInfo> indirectReturnInfos,
Optional<ArgumentInfo> localContextInfo);
AsyncContextLayout(
IRGenModule &IGM, LayoutStrategy strategy, ArrayRef<SILType> fieldTypes,
ArrayRef<const TypeInfo *> fieldTypeInfos, IRGenFunction &IGF,
CanSILFunctionType originalType, CanSILFunctionType substitutedType,
SubstitutionMap substitutionMap, NecessaryBindings &&bindings,
Optional<TrailingWitnessInfo> trailingWitnessInfo, SILType errorType,
bool canHaveValidError, ArrayRef<ArgumentInfo> argumentInfos,
ArrayRef<SILResultInfo> directReturnInfos,
ArrayRef<SILResultInfo> indirectReturnInfos,
Optional<ArgumentInfo> localContextInfo);
};

AsyncContextLayout getAsyncContextLayout(IRGenFunction &IGF,
Expand Down
6 changes: 5 additions & 1 deletion lib/IRGen/GenProto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3098,7 +3098,11 @@ NecessaryBindings NecessaryBindings::computeBindings(
continue;

case MetadataSource::Kind::SelfMetadata:
bindings.addTypeMetadata(getSubstSelfType(IGM, origType, subs));
// Async functions pass the SelfMetadata and SelfWitnessTable parameters
// along explicitly.
if (forPartialApplyForwarder) {
bindings.addTypeMetadata(getSubstSelfType(IGM, origType, subs));
}
continue;

case MetadataSource::Kind::SelfWitnessTable:
Expand Down
Loading