-
-
Notifications
You must be signed in to change notification settings - Fork 267
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
Emit struct TypeInfos in referencing compilation units only #3491
Conversation
7f842d9
to
cb6c3de
Compare
Thoughts and/or compile/runtime/size numbers would be appreciated. |
@JohanEngelen: This also eliminates some |
@kinke It will be a while before I can look at this and test it , sorry
What specific type of perf regression do you expect? |
I'm in no hurry wrt. this, so take your time. :)
I was thinking about cases where the optimizer might have been able to inline xtoHash/xopEquals/xopCmp/xtoString/xdtor[ti]/xpostblit indirections. But after looking at |
Okay to merge? The runtime performance concerns shouldn't apply as mentioned above; size-wise, I've noticed some slight increases for built executables, but nothing dramatic IIRC. - It's a prerequisite for a clean reboot of #3422. |
This does have quite an impact - some binary size numbers (in bytes) for Win64, based on the Azure packages:
So e.g. apparently lots of not-directly-used (in the same CU) struct TypeInfos in druntime which aren't stripped anymore with enabled optimizations (but e.g. also aren't emitted in user-code and Phobos CUs anymore if the structs aren't inside templates) and need to be stripped by the linker. |
And the debug lib sizes probably show that at least for druntime and Phobos, there are hardly any extra emissions in non-owning CUs. Maybe we should instead strive for emitting them only in referencing CUs as linkonce_odr, not in the owning one at all if not referenced therein. At least the TypeInfos themselves, not sure about the special member functions. |
I'll try this on weka's code this week. |
8250244
to
fbb03c7
Compare
Wrt. the 2nd approach in the 2nd commit, I don't have a good idea wrt. the missing dtor linker failure in
|
Looked at it (on Windows), and for some bizarre reason, the extra |
No linking errors at Weka, good news. Attribute deduction problems (the Some compilation size data from Weka:
That's a net size reduction across the board. Measuring compilation time will be very flawed, but at least there was no obvious slow down / speed up. |
Thx for the numbers! [And I'm surprised there were no linker errors...] Upstream, Walter and Andrei are working on getting rid of these compiler-built TypeInfos (struct TypeInfos at least) and replacing them by straight-forward templates in druntime. So I'm not sure how long that takes and whether getting to the bottom of this weird attributes-inference problem in the meantime is worth it. |
Analogous to ClassInfos, incl. normal linkage (external for non- templates, weak_odr for templates). This enables to get rid of frontend logic wrt. whether to add TypeInfoStructDeclarations to a module's members tree - previously, it was defined as linkonce_odr in the owning module and each referencing module (unless speculative) - and related extra semantic and codegen for the special member functions. I've gone a bit further and moved the entire TypeInfo emission for LDC to the codegen layer; no TypeInfoDeclarations are added to the module members anymore. Whenever we need a TypeInfo symbol during codegen, it is declared or defined, and we don't need to rely on brittle frontend logic with speculative-ness complications. This might slightly increase compilation speed due to less emitted TypeInfos and functions (possibly less work for the linker too). A slight drawback is that the job of stripping unused struct TypeInfos is fully delegated to the linker, as the TypeInfo is guaranteed to end up in the owning object file due to no linkonce_odr. Another theoretical drawback is that the optimizer can definitely not inline xtoHash/xopEquals/xopCmp/xtoString/xdtor[ti]/xpostblit function pointer indirections in non-owning CUs without LTO (neither the pointers nor the special member functions are defined anymore). These (public) members are probably hardly used directly though, and instead used by the virtual TypeInfo_Struct methods equals/compare/ getHash/destroy/postblit, which are exclusively defined in druntime's object.o (incl. the TypeInfo_Struct vtable) and aren't cross-module- inlined anyway (without LTO). Re-emitting the struct TypeInfos (and optionally the special member functions too) into each referencing CU could be handled in our codegen layer, which should be much simpler and more robust than the upstream scheme.
I.e., not in their owning CU if unused therein, but in all referencing CUs instead, as linkonce_odr. The special member functions are still only and unconditionally emitted in the owning CU.
This fixes dmd-testsuite's runnable/link15017.d, where the dtor checks were performed before it had been semantically analyzed, leading to it wrongly being marked as impure and non-safe, and thus a later linker error.
Found the reason for the failure; it was (deprecated) |
To elaborate a bit: when a function hasn't had its attributes inferred yet, but is checked for being pure/safe/..., it is set as impure/non-safe (wtf?), and a later sema doesn't infer them anymore... E.g., https://github.com/dlang/dmd/blob/b6526dfc9994049b386ab1da0e38d7655adedf73/src/dmd/func.d#L1337-L1338 and https://github.com/dlang/dmd/blob/b6526dfc9994049b386ab1da0e38d7655adedf73/src/dmd/func.d#L1376-L1381. |
We generally do have linking errors related to attribute inference. Weka's codebase has a bunch of explicit attributes on templates to fix those. |
That's why I elaborated a bit. The proposed upstream fix for this particular case is dlang/dmd#11854, maybe it sparks a deeper discussion about why things are being done this way. |
First commit only:
Analogous to ClassInfos, incl. normal linkage (external for non-templates, weak_odr for templates).
This enables to get rid of frontend logic wrt. whether to add
TypeInfoStructDeclarations
to a module's members tree - previously,it was defined as linkonce_odr in the owning module and each referencing module (unless speculative) - and related extra semantic and codegen for the special member functions.
I've gone a bit further and moved the entire TypeInfo emission for LDC to the codegen layer; no
TypeInfoDeclarations
are added to the module members anymore. Whenever we need a TypeInfo symbol during codegen, it is declared or defined, and we don't need to rely on brittle frontend logic with speculative-ness complications.This might slightly increase compilation speed due to less emitted TypeInfos and functions (possibly less work for the linker too).
It might require LTO to avoid performance regressions though and delegates the job of stripping unused struct TypeInfos to the linker, as the TypeInfo is guaranteed to end up in the owning object file due to no linkonce_odr.
Re-emitting the struct TypeInfos (and optionally the special member functions too) into each referencing CU could be handled in our codegen layer, which should be much simpler and more robust than the upstream scheme.