Skip to content

[Distributed] retain ad-hoc witnesses so that they are not optimized away in SIL #42252

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 8 commits into from
Apr 19, 2022

Conversation

ktoso
Copy link
Contributor

@ktoso ktoso commented Apr 7, 2022

Since some of them (e.g. the decodeNextArgument specifically) are only used directly form IRGen, optimization thinks they are not used and may remove them. Making it impossible to use final classes (or structs sometimes?) to develop decoder types for distributed actors.

@ktoso
Copy link
Contributor Author

ktoso commented Apr 7, 2022

resolves rdar://88211172 ([Distributed] SILGen must emit uses of decodeNextArgument so IRGen can get it cross module on FINAL classes)

@ktoso ktoso force-pushed the wip-retain-dist-decode branch from 5583241 to 51ccba4 Compare April 8, 2022 10:07
@ktoso ktoso force-pushed the wip-retain-dist-decode branch from 51ccba4 to e53355e Compare April 11, 2022 21:29
@ktoso ktoso added the distributed Feature → concurrency: distributed actor label Apr 11, 2022
@ktoso ktoso force-pushed the wip-retain-dist-decode branch 7 times, most recently from 0ab1ad8 to a640186 Compare April 13, 2022 08:27
@@ -2956,20 +2957,20 @@ bool SILDeserializer::hasSILFunction(StringRef Name,
IdentifierID replacedFunctionID;
GenericSignatureID genericSigID;
unsigned rawLinkage, isTransparent, isSerialized, isThunk,
isWithoutactuallyEscapingThunk, isGlobal, inlineStrategy,
isWithoutActuallyEscapingThunk, isGlobal, inlineStrategy,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

was just a typo, might as well fix

@ktoso ktoso requested review from xedin and aschwaighofer April 13, 2022 08:28
@ktoso ktoso force-pushed the wip-retain-dist-decode branch 2 times, most recently from e54a4d2 to b626c57 Compare April 13, 2022 08:32
@ktoso
Copy link
Contributor Author

ktoso commented Apr 13, 2022

@swift-ci please smoke test
@swift-ci please build toolchain macOS

I actually have trouble updating the SIL tests... will try some more later tonight.
Other than that this seems to work!?

toolchain to verify in real project where this has shown up

@ktoso
Copy link
Contributor Author

ktoso commented Apr 13, 2022

@swift-ci please smoke test

@ktoso
Copy link
Contributor Author

ktoso commented Apr 13, 2022

@swift-ci please build toolchain macOS

systemTy->getAnyNominal());
assert(decoderTy);

auto decodeFunc = C.getDecodeNextArgumentOnDistributedInvocationDecoder(
Copy link
Contributor

Choose a reason for hiding this comment

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

Nickpick. This is a lot of code inline. Does it make sense to sink the code into a method on actor (ClassDecl?)?

So that we have something like:

if (!constant.isDistributedThunk())
  return;
auto *actor = decl->getDeclContext()->getSelfNominalTypeDecl();
if (!actor)
  return;
auto decodeFunc = actor->ifActorGetDecodeNextArgumentOnDistributedInvocationDecode();
if (!decodeFunc)
  return;
auto decodeRef = SILDeclRef(decodeFunc);
...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cool, yeah happy to do that -- I always (over)-worry about putting things on ClassDecl but that'll make it much nicer.
I'll refactor a bit, thanks for calling it out 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Long method name but nicer:

    if (auto decodeFunc =
            getAssociatedDistributedInvocationDecoderDecodeNextArgumentFunction(
                decl)) {

      auto decodeRef = SILDeclRef(decodeFunc);
      auto *adHocWitness = getOrCreateDeclaration(decodeFunc, decodeRef);
      F->setReferencedAdHocRequirementWitnessFunction(adHocWitness);
    }

Copy link
Contributor

@aschwaighofer aschwaighofer left a comment

Choose a reason for hiding this comment

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

lgtm

public class FakeInvocationDecoder : DistributedTargetInvocationDecoder {

@available(SwiftStdlib 5.7, *)
public final class FakeInvocationDecoder: DistributedTargetInvocationDecoder {
Copy link
Contributor

Choose a reason for hiding this comment

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

How hard would it be to add enum and struct variants for the decoder so all possibilities are tested? I think we could gyb this and some other tests too?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll make a radar for it but right now I think that's a bit of a pain... I have no idea about gyb tbh

Copy link
Contributor

Choose a reason for hiding this comment

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

As soon as we are keeping track of that I am fine, I just don’t want it to be broken without us noticing…

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right yeah 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

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

rdar://91735574

Copy link
Contributor

@xedin xedin left a comment

Choose a reason for hiding this comment

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

LGTM! I agree with @aschwaighofer that we should extract code for decode into a request but that could be done separately. More important I think to add tests for decoder being class/final class/struct/enum.

@ktoso
Copy link
Contributor Author

ktoso commented Apr 13, 2022

Cool, will add the tests. Manually is fine tbh...

@ktoso ktoso force-pushed the wip-retain-dist-decode branch from b626c57 to d3ce178 Compare April 14, 2022 14:19
} else if (constant.isDistributedThunk()) {
if (auto decodeFuncDecl =
getAssociatedDistributedInvocationDecoderDecodeNextArgumentFunction(
decl)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: you can do that in the follow-up - if there is no decodeNextArgument we should fail here since the record of the thunk function is going to be ill-formed without it and that would lead to a crash in IRGen.

@xedin
Copy link
Contributor

xedin commented Apr 14, 2022

@swift-ci please test

@@ -9,7 +9,7 @@ distributed actor DA {
}

extension DA {
// CHECK-LABEL: sil hidden [thunk] [distributed] [ossa] @$s17distributed_thunk2DAC1fyyYaKFTE : $@convention(method) @async (@guaranteed DA) -> @error Error
// CHECK-LABEL: sil hidden [thunk] [distributed] [ref_adhoc_requirement_witness "$s11Distributed29LocalTestingInvocationDecoderC18decodeNextArgumentxyKSeRzSERzlF"] [ossa] @$s17distributed_thunk2DAC1fyyYaKFTE : $@convention(method) @async (@guaranteed DA) -> @error Error {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think I can make a gyb to test that struct/class/final class/enum all have ref_adhoc_requirement_witness referenced after you land these changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Awesome, thanks -- I'll fix the SIL test now and land it then

@ktoso ktoso force-pushed the wip-retain-dist-decode branch from d3ce178 to 00f7b6e Compare April 16, 2022 02:40
@ktoso
Copy link
Contributor Author

ktoso commented Apr 16, 2022

@swift-ci please test

@ktoso ktoso force-pushed the wip-retain-dist-decode branch from 00f7b6e to b239007 Compare April 17, 2022 05:34
@ktoso
Copy link
Contributor Author

ktoso commented Apr 17, 2022

@swift-ci please test

@ktoso
Copy link
Contributor Author

ktoso commented Apr 17, 2022

This only fails in one of the Linux builds now...


(existential_type
  (type_alias_type decl=FakeDistributedActorSystems.(file).FakeActorSystem.SerializationRequirement@/home/build-user/swift/test/Distributed/Runtime/../Inputs/FakeDistributedActorSystems.swift:44:20 underlying='Codable'
    (parent=struct_type decl=FakeDistributedActorSystems.(file).FakeActorSystem@/home/build-user/swift/test/Distributed/Runtime/../Inputs/FakeDistributedActorSystems.swift:40:15)))
(existential_type
  (type_alias_type decl=FakeDistributedActorSystems.(file).FakeRoundtripActorSystem.SerializationRequirement@/home/build-user/swift/test/Distributed/Runtime/../Inputs/FakeDistributedActorSystems.swift:120:20 underlying='Codable'
    (parent=class_type decl=FakeDistributedActorSystems.(file).FakeRoundtripActorSystem@/home/build-user/swift/test/Distributed/Runtime/../Inputs/FakeDistributedActorSystems.swift:116:20)))
Please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project and the crash backtrace.
Stack dump:
0.	Program arguments: /home/build-user/build/buildbot_linux/swift-linux-x86_64/bin/swift-frontend -frontend -c -primary-file /home/build-user/swift/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift /home/build-user/swift/test/Distributed/Runtime/../Inputs/FakeDistributedActorSystems.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -I /home/build-user/build/buildbot_linux/swift-linux-x86_64/test-linux-x86_64/Distributed/Runtime/Output/distributed_actor_func_calls_remoteCall_echo.swift.tmp -module-cache-path /home/build-user/build/buildbot_linux/swift-linux-x86_64/swift-test-results/x86_64-unknown-linux-gnu/clang-module-cache -swift-version 4 -O -define-availability "SwiftStdlib 9999:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999" -define-availability "SwiftStdlib 5.0:macOS 10.14.4, iOS 12.2, watchOS 5.2, tvOS 12.2" -define-availability "SwiftStdlib 5.1:macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0" -define-availability "SwiftStdlib 5.2:macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4" -define-availability "SwiftStdlib 5.3:macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0" -define-availability "SwiftStdlib 5.4:macOS 11.3, iOS 14.5, watchOS 7.4, tvOS 14.5" -define-availability "SwiftStdlib 5.5:macOS 12.0, iOS 15.0, watchOS 8.0, tvOS 15.0" -define-availability "SwiftStdlib 5.6:macOS 12.3, iOS 15.4, watchOS 8.5, tvOS 15.4" -define-availability "SwiftStdlib 5.7:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999" -disable-availability-checking -parse-as-library -module-name main -o /tmp/distributed_actor_func_calls_remoteCall_echo-f220f5.o
1.	Swift version 5.7-dev (LLVM 5f0021881119ab6, Swift 4088261a6916006)
2.	Compiling with effective version 4.1.50
3.	While evaluating request IRGenRequest(IR Generation for file "/home/build-user/swift/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift")
4.	While emitting IR SIL function "@$s4main7GreeterC4echo4nameS2S_tYaKFTE".
 for 'echo(name:)' (in module 'main')
 #0 0x00000000060e2d73 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/home/build-user/build/buildbot_linux/swift-linux-x86_64/bin/swift-frontend+0x60e2d73)
 #1 0x00000000060e0abe llvm::sys::RunSignalHandlers() (/home/build-user/build/buildbot_linux/swift-linux-x86_64/bin/swift-frontend+0x60e0abe)

in optimized linux builds it seems FAILED: test/CMakeFiles/check-swift-all-optimize-linux-x86_64 while the normal -- check-swift-all-linux-x86_64 finished seems to be okey...

Could I ask you to help out here @xedin ? 🙏

@xedin
Copy link
Contributor

xedin commented Apr 17, 2022

I should be able to take a look on Monday. Pretty sure that it’s not Linux specific, PR testing on macOS doesn’t run optimized tests if I remember correctly.

@xedin xedin force-pushed the wip-retain-dist-decode branch from cecbae2 to dacd40d Compare April 18, 2022 21:25
@xedin
Copy link
Contributor

xedin commented Apr 18, 2022

@swift-ci please test Linux platform

@xedin xedin force-pushed the wip-retain-dist-decode branch from dacd40d to fc662bc Compare April 19, 2022 00:28
@xedin
Copy link
Contributor

xedin commented Apr 19, 2022

@swift-ci please test

canBeCalledIndirectly(f->getRepresentation())),
mayHaveIndirectCallers(
f->getDynamicallyReplacedFunction() ||
f->getReferencedAdHocRequirementWitnessFunction() ||
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh i see... makes sense

Copy link
Contributor Author

@ktoso ktoso left a comment

Choose a reason for hiding this comment

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

Thank you so much @xedin ! 🙇

@@ -101,6 +101,9 @@ class DeadFunctionAndGlobalElimination {
if (F->isDynamicallyReplaceable())
return true;

if (F->getReferencedAdHocRequirementWitnessFunction())
return true;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah okey so here too, I thought it was an either or but Makes sense!

@@ -325,6 +328,9 @@ class DeadFunctionAndGlobalElimination {

LLVM_DEBUG(llvm::dbgs() << " scan function " << F->getName() << '\n');

if (auto *adHocWitness = F->getReferencedAdHocRequirementWitnessFunction())
ensureAlive(adHocWitness);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

<3

emitVirtualMethodValue(IGF, decoderTy, SILDeclRef(decodeFn), methodTy);
auto methodPtr = FunctionPointer::forDirect(
classifyFunctionPointerKind(decodeSIL), fnPtr,
/*secondaryValue=*/nullptr, signature);

return {decoder, decoderTy, witnessTable, methodPtr, methodTy};
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yess! 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
distributed Feature → concurrency: distributed actor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants