Skip to content

[Distributed] Strip marker protocols from distributed thunks and accessible functions #41871

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

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/swift/AST/ASTMangler.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ class ASTMangler : public Mangler {
Type GlobalActorBound,
ModuleDecl *Module);

std::string mangleDistributedThunk(const FuncDecl *thunk);

/// Mangle a completion handler block implementation function, used for importing ObjC
/// APIs as async.
///
Expand Down
4 changes: 4 additions & 0 deletions include/swift/AST/GenericSignature.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,10 @@ class GenericSignature {
ArrayRef<Requirement> requirements,
bool isKnownCanonical = false);

/// Produce a new generic signature which drops all of the marker
/// protocol conformance requirements associated with this one.
GenericSignature withoutMarkerProtocols() const;

public:
static ASTContext &getASTContext(TypeArrayView<GenericTypeParamType> params,
ArrayRef<Requirement> requirements);
Expand Down
8 changes: 8 additions & 0 deletions lib/AST/ASTMangler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3457,3 +3457,11 @@ ASTMangler::mangleOpaqueTypeDescriptorRecord(const OpaqueTypeDecl *decl) {
appendOperator("Ho");
return finalize();
}

std::string ASTMangler::mangleDistributedThunk(const FuncDecl *thunk) {
// Marker protocols cannot be checked at runtime, so there is no point
// in recording them for distributed thunks.
llvm::SaveAndRestore<bool> savedAllowMarkerProtocols(AllowMarkerProtocols,
false);
return mangleEntity(thunk, SymbolKind::DistributedThunk);
}
21 changes: 21 additions & 0 deletions lib/AST/GenericSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1163,3 +1163,24 @@ swift::buildGenericSignature(ASTContext &ctx,
addedRequirements},
GenericSignatureWithError()).getPointer();
}

GenericSignature GenericSignature::withoutMarkerProtocols() const {
auto requirements = getRequirements();
SmallVector<Requirement, 4> reducedRequirements;

// Drop all conformance requirements to marker protocols (if any).
llvm::copy_if(requirements, std::back_inserter(reducedRequirements),
[](const Requirement &requirement) {
if (requirement.getKind() == RequirementKind::Conformance) {
auto *protocol = requirement.getProtocolDecl();
return !protocol->isMarkerProtocol();
}
return true;
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, nice


// If nothing changed, let's return this signature back.
if (requirements.size() == reducedRequirements.size())
return *this;

return GenericSignature::get(getGenericParams(), reducedRequirements);
}
5 changes: 4 additions & 1 deletion lib/IRGen/GenDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4172,7 +4172,10 @@ void IRGenModule::emitAccessibleFunctions() {

GenericSignature signature;
if (auto *env = func->getGenericEnvironment()) {
signature = env->getGenericSignature();
// Drop all of the marker protocols because they are effect-less
// at runtime.
signature = env->getGenericSignature().withoutMarkerProtocols();

genericEnvironment =
getAddrOfGenericEnvironment(signature.getCanonicalSignature());
}
Expand Down
4 changes: 4 additions & 0 deletions lib/SIL/IR/SILDeclRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,6 +914,10 @@ std::string SILDeclRef::mangle(ManglingKind MKind) const {
return CDeclA->Name.str();
}

if (SKind == ASTMangler::SymbolKind::DistributedThunk) {
return mangler.mangleDistributedThunk(cast<FuncDecl>(getDecl()));
}

// Otherwise, fall through into the 'other decl' case.
LLVM_FALLTHROUGH;

Expand Down
9 changes: 4 additions & 5 deletions lib/Sema/CodeSynthesisDistributedActor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,11 +375,10 @@ deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) {
{
// --- Mangle the thunk name
Mangle::ASTMangler mangler;
auto symbolKind = swift::Mangle::ASTMangler::SymbolKind::DistributedThunk;
auto mangled = C.AllocateCopy(mangler.mangleEntity(thunk, symbolKind));
StringRef mangledTargetStringRef = StringRef(mangled);
auto mangledTargetStringLiteral = new (C)
StringLiteralExpr(mangledTargetStringRef, SourceRange(), implicit);
auto mangled =
C.AllocateCopy(mangler.mangleDistributedThunk(cast<FuncDecl>(thunk)));
auto mangledTargetStringLiteral =
new (C) StringLiteralExpr(mangled, SourceRange(), implicit);

// --- let target = RemoteCallTarget(<mangled name>)
targetVar->setInterfaceType(remoteCallTargetTy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import FakeDistributedActorSystems

typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem

protocol SomeProtocol {}
extension String: SomeProtocol {}

distributed actor Greeter {
distributed func noParams() {}
distributed func noParamsThrows() throws {}
Expand All @@ -28,9 +31,9 @@ distributed actor Greeter {
distributed func oneLabel(value: String, _ value2: String, _ value3: String) {}
distributed func parameterSingle(first: String) {}
distributed func parameterPair(first: String, second: Int) {}
// FIXME(distributed): rdar://90293494 fails to get
// distributed func generic<A: Codable & Sendable>(first: A) {}
// distributed func genericNoLabel<A: Codable & Sendable>(_ first: A) {}
distributed func generic<A: Codable & Sendable>(first: A) {}
distributed func genericThree<A: Codable & Sendable & SomeProtocol>(first: A) {}
distributed func genericThreeTwo<A: Codable & Sendable, B: Codable & SomeProtocol>(first: A, second: B) {}
}
extension Greeter {
distributed func parameterTriple(first: String, second: Int, third: Double) {}
Expand Down Expand Up @@ -65,16 +68,25 @@ func test() async throws {
_ = try await greeter.parameterTriple(first: "X", second: 2, third: 3.0)
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:)

// FIXME: rdar://90293494 seems to fail getting the substitutions?
// _ = try await greeter.generic(first: "X")
// // TODO: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:)
_ = try await greeter.generic(first: "X")
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.generic(first:)

_ = try await greeter.genericThree(first: "X")
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.genericThree(first:)

_ = try await greeter.genericThreeTwo(first: "X", second: "SecondValue")
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.genericThreeTwo(first:second:)

print("done")
// CHECK: done
}

@main struct Main {
static func main() async {
try! await test()
do {
try await test()
} catch {
print("ERROR: \(error)")
}
}
}
10 changes: 10 additions & 0 deletions test/Distributed/distributed_actor_accessor_section_coff.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ public distributed actor MyActor {
distributed func complex(_: [Int], _: Obj, _: String?, _: LargeStruct) -> LargeStruct {
fatalError()
}

// Make sure that Sendable doesn't show up in the mangled name
distributed func generic<T: Codable & Sendable>(_: T) {
}
}

@available(SwiftStdlib 5.7, *)
Expand Down Expand Up @@ -123,6 +127,12 @@ public distributed actor MyOtherActor {
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}})
// CHECK-SAME: , section ".sw5acfn$B", {{.*}}

/// -> `MyActor.generic`
// CHECK: @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTEHF" = private constant
// CHECK-SAME: @"symbolic x___________pSeRzSERzlIetMHngzo_ 27distributed_actor_accessors7MyActorC s5ErrorP"
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTETFTu" to i{{32|64}})
// CHECK-SAME: , section ".sw5acfn$B", {{.*}}

/// -> `MyOtherActor.empty`
// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant
// CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP"
Expand Down
10 changes: 10 additions & 0 deletions test/Distributed/distributed_actor_accessor_section_elf.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public distributed actor MyActor {
distributed func complex(_: [Int], _: Obj, _: String?, _: LargeStruct) -> LargeStruct {
fatalError()
}

// Make sure that Sendable doesn't show up in the mangled name
distributed func generic<T: Codable & Sendable>(_: T) {
}
}

@available(SwiftStdlib 5.7, *)
Expand Down Expand Up @@ -121,6 +125,12 @@ public distributed actor MyOtherActor {
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}})
// CHECK-SAME: , section "swift5_accessible_functions", {{.*}}

/// -> `MyActor.generic`
// CHECK: @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTEHF" = private constant
// CHECK-SAME: @"symbolic x___________pSeRzSERzlIetMHngzo_ 27distributed_actor_accessors7MyActorC s5ErrorP"
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTETFTu" to i{{32|64}})
// CHECK-SAME: , section "swift5_accessible_functions", {{.*}}

/// -> `MyOtherActor.empty`
// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant
// CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP"
Expand Down
10 changes: 10 additions & 0 deletions test/Distributed/distributed_actor_accessor_section_macho.swift
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ public distributed actor MyActor {
distributed func complex(_: [Int], _: Obj, _: String?, _: LargeStruct) -> LargeStruct {
fatalError()
}

// Make sure that Sendable doesn't show up in the mangled name
distributed func generic<T: Codable & Sendable>(_: T) {
}
}

@available(SwiftStdlib 5.7, *)
Expand Down Expand Up @@ -121,6 +125,12 @@ public distributed actor MyOtherActor {
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETFTu" to i{{32|64}})
// CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}}

/// -> `MyActor.generic`
// CHECK: @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTEHF" = private constant
// CHECK-SAME: @"symbolic x___________pSeRzSERzlIetMHngzo_ 27distributed_actor_accessors7MyActorC s5ErrorP"
// CHECK-SAME: (%swift.async_func_pointer* @"$s27distributed_actor_accessors7MyActorC7genericyyxYaKSeRzSERzlFTETFTu" to i{{32|64}})
// CHECK-SAME: , section {{"swift5_accessible_functions"|".sw5acfn$B"|"__TEXT, __swift5_acfuncs, regular"}}

/// -> `MyOtherActor.empty`
// CHECK: @"$s27distributed_actor_accessors12MyOtherActorC5emptyyyYaKFTEHF" = private constant
// CHECK-SAME: @"symbolic ___________pIetMHgzo_ 27distributed_actor_accessors12MyOtherActorC s5ErrorP"
Expand Down