A lot of the reduced symbols is probably the avoidance of __compressed_pair right now.
Would there be some kind of compiler-provided construct (assuming all non-compiler-provided options to reduce the overhead have already been exhausted) that could reduce the overhead of __compressed_pair across the board/all/many of the uses in libc++? Is it just no_unique_address? Or other features that’d be necessary to express to avoid the extra templates/etc that are currently used, including __compressed_pair?
(if it’s non-portability of no_unique_address, could it be used in the unstable ABI?)
The extra template instantiations, in aggregate, seem like the add-up to quite a bit (though I don’t have specific numbers) and I certainly come across them a lot when looking at DWARF in non-trivial programs.
I don’t know whether there is a better way to write __compressed_pair, but [[no_unique_address]] would definitely be the way to go here. We don’t have it in the unstable ABI because that would result in duplicated code in a lot of places, causing maintainability concerns. Another problem is that this would massively regress libc++ on windows in the unstable ABI, since our symbols would become much larger (e.g. 16 bytes for a unique_ptr).
Probably the simplest thing to do here is implementing [[msvc::no_unique_address]] and replace __compressed_pair with that. I wouldn’t be surprised if that were actually easier for someone familiar with the Microsoft ABI than trying to implement [[no_unique_address]] versions of everything in libc++, and we really want to implement it anyways for feature parity between clang-cl and cl.
Modulo some ABI shenanigans, like final types (which should be solvable), yes. The only problem is that clang-cl doesn’t implement [[msvc::no_unique_address]] currently.
Seems like a lot to me when you just want a pointer.
We don’t have a lot of users on windows, but implementing [[msvc::no_unique_address]] can’t be that hard. Adding it seems to me like the way simpler approach than trying to fight the people who do use libc++ on windows. I don’t think the Chromium people would be very happy to trade regressed object size against a bit of debug improvement, especially if it’s not that hard to improve both.
Yeah, if implementing [[msvc::no_unique_address]] is the only compiler feature needed to remove __compressed_pair entirely - that sounds super awesome/worth giving a go & sounds like it’d reduce implementation/source complexity as well as compiler work (by reducing the number of template instantiations), ir gen (fewer functions), and dwarf (fewer types and functions)… sounds pretty great to me!
(please correct me if I’ve misunderstood anything here)
(I guess a side question: why do we need [[msvc::no_unique_address]] as distinct from [[no_unique_address]]… ah, think I’ve found it - the msvc variant has a slightly different behavior, so it’s a different ABI (it wouldn’t be sufficient to use [[no_unique_address]] for clang-cl and [[msvc::no_unique_address]] for real cl.exe) - fair enough then )
I very much support the direction of using [[no_unique_address]], mostly for the benefits in terms of compile time.
The only thing we should be careful about is that [[no_unique_address]] does nothing on objects of the same type, so it’s slightly different from __compressed_pair afaict.
I want to echo @EricWF. It may be nice for clang to support msvc::no_unique_address (afaik the reason we don’t is that its ABI is not documented), but i don’t think we should condition this work on that support.
After all, MSVC knew that their users would not get the benefits of [[no_unique_address]], and decided it was okay, so surely it is!
using _LIBCPP_NO_UNIQUE_ADDRESS wherever it make sense
extending _LIBCPP_NO_UNIQUE_ADDRESS at a later date to support more compilers
Maintainability. The patch linked above had serious maintainability issues. We can’t introduce that many #ifdefs in the middle of code logic to refer to different names based on the ABI macro. I think some refactoring in the affected classes might be able to resolve that concern.
ABI stability concerns. If we want to apply these changes even in the stable ABI (which should be possible), we’ll need to insert some padding between members sometimes to replicate the layout that used to be produced by __compressed_pair. I had expanded on that in this comment of D63744.
The lack of proper [[no_unique_address]] on Windows, but I think the path to fix that is well understood.
If we tackle those issues, I’m really happy to move forward. I think we all dislike __compressed_pair.
Two objects with overlapping lifetimes that are not bit-fields may have the
same address if one is nested within the other, or if at least one is a subobject of zero size and they are of different types; otherwise, they have distinct addresses and occupy disjoint bytes of storage
I think we have previously established that Windows users of libc++ don’t prioritize ABI stability because libc++ is not the system standard library there. The major use case for an alternative standard library is to be faster or better than the standard one in some way, so performance and compile time should be prioritzed over ABI stability. So, in conclusion, I don’t think we should worry about waiting too long after fixing the clang issue to start using the new attribute in libc++. Maybe a single release, but not two.