You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
The text was updated successfully, but these errors were encountered:
@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?
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.
Additional Detail from JIRA
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
The text was updated successfully, but these errors were encountered: