Skip to content
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

[SR-14509] Pre-emptive testing for emit-dead-strippable work #56861

Open
swift-ci opened this issue Apr 19, 2021 · 2 comments
Open

[SR-14509] Pre-emptive testing for emit-dead-strippable work #56861

swift-ci opened this issue Apr 19, 2021 · 2 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-14509
Radar None
Original Reporter mren (JIRA User)
Type Bug
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug
Assignee None
Priority Medium

md5: 9a43f214c5ecb7b52410c36f2eb50cd1

Issue Description:

Some high level information about emit-dead-strippable:

Kuba is working on stripping Swift symbols if they are not used statically via a LTO pass GlobalDCE, which is guarded by emit-dead-strippable flag. This optimization has a great potential to reduce binary size. While testing this with an iOS app, we are hitting a few runtime crashes.

The goal is to figure out cases of dynamic references to Swift symbols without a static reference, because that will break GlobalDCE in the sense it will incorrectly strip off symbols that are needed at runtime. objc_classes and objc_categories are such Swift symbols that we may need to selectively keep. Protocol conformances are another case, where instantiateConcreteTypeFromMangledName seems to need some conformance data at runtime where there are no static references to them and they are stripped off by GlobalDCE. Another potential case for runtime protocol conformance check is `as? Protocol` casts.

We had some email exchanges about this, a quick summary of the issues and potential fixes:

1> Dynamic lookup of Swift classes via ObjC interop

Potential solution: symbolic encoding for ObjC classes as suggested by Joe: Currently we always refer to ObjC classes in mangled names by their runtime name, but we could introduce an escape code to embed a relative reference to the classref, which should be a small performance win for instantiation and also help the linker statically understand the dependency on the classref.

2> Dynamic lookup of Swift symbols in objc_categories

Potential solution: keep them for now

3> Dynamic lookup of protocol conformances

Joe has been working on an encoding for protocol conformances. Joe suggested a shorter-term hack that could unblock dead-stripping in the near-term: what if we emit the mangled strings, but then after the `\0` terminator, we can append relative references to all of the runtime entities that the mangled name needs but doesn't directly reference, like ObjC classrefs and protocol conformances? That way we don't need to implement type decoder support for new manglings, and for a nominal cost of 4 const bytes per reference, we prevent the linker from dead-stripping.

We have a standalone test case that seems to cause runtime issue when checking conformance at runtime. The test case is currently on a private branch, specifically this commit: 1337554

Thanks,

Manman

@swift-ci
Copy link
Collaborator Author

Comment by Manman Ren (JIRA)

@compnerd @kateinoigakukun: wondering if you hit similar issues when stripping off symbols with Swift/SIL LTO work. Does Swift LTO remove statically unused class metadata and protocol conformances?

Thanks!

@swift-ci
Copy link
Collaborator Author

Comment by Manman Ren (JIRA)

@kubamracek: For the crash related to runtime check of protocol conformances, I uploaded a fix manman-ren@e0e9b8e)

You already marked the protocol conformance with conditional use of the protocol and the type descriptor. Just need to fix GlobalDCE to repeatedly convert conditional uses to llvm.uses.

With this fix and the fix for objc classes/category (manman-ren@d4aba1f1e875a892c1e33df291f547f42a4fb8d7), a small app with over 100K lines of code seems to start up fine, with only emit-dead-strippable-symbols, no vtable/wtable-method-elimination. The binary size win is roughly 9% compressed size.

Manman

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself
Projects
None yet
Development

No branches or pull requests

1 participant