[llvm-dev] Utilising no-unique-address

79 views
Skip to first unread message

Nathan James via llvm-dev

unread,
Feb 9, 2021, 12:52:16 PM2/9/21
to LLVM Developers Mailing List
Hi,

About a month ago I pushed a patch to change BumpPtrAllocatorImpl to
use the empty base optimization to reduce the size of the
allocator(always a win). However looking at clangs support for the
c++20 attribute `no_unique_address`, It appears that we support that in
previous standards (including c++14).

Can anyone see any issue to utilizing this attribute throughout the
codebase behind a macro in `llvm/Support/Compiler.h`.
`
#if LLVM_HAS_CPP_ATTRIBUTE(no_unique_address)
#define LLVM_NO_UNIQUE_ADDRESS [[no_unique_address]]
#else
#define LLVM_NO_UNIQUE_ADDRESS
#endif
`

This approach is much cleaner than empty base classes and has fewer
restrictions on the type.

This feature is enabled in c++14 mode starting from clang(9.0.0),
gcc(9.1) and icc(21.1.8). MSVC knows about the attribute since 19.15,
but unfortunately there is no way to utilize it unless using
`c++latest` mode. Fortunately, using the feature macro MSVC won't
complain about this. I'm also uncertain on how clang-cl would handle
this as it tries to maintain MSVC compatibility. It may be wise to also
put this behind a _MSC_VER/_WIN32 flag as altering class layouts could
cause some ABI compatibility issues.

Thanks for reading,
Nathan James

_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev

David Blaikie via llvm-dev

unread,
Feb 9, 2021, 2:32:11 PM2/9/21
to Nathan James, LLVM Developers Mailing List
Hmm - though might this have problematic ABI implications? (If the
attribute isn't supported on all our supported compilers - then a
binary release of LLVM wouldn't be ABI compatible with all compilers?)

yao zhongxiao via llvm-dev

unread,
Feb 18, 2021, 10:51:33 PM2/18/21
to llvm...@lists.llvm.org
I had the issue related to abi compatibility while using gcc > 10;
here is the changelog, hope to be helpful.

https://gcc.gnu.org/gcc-10/changes.html

```
  • The ABI of passing and returning certain C++ classes by value changed on several targets in GCC 10, including AArch64ARMPowerPC ELFv2S/390 and Itanium. These changes affect classes with a zero-sized subobject (an empty base class, or data member with the [[no_unique_address]] attribute) where all other non-static data members have the same type (this is called a "homogeneous aggregate" in some ABI specifications, or if there is only one such member, a "single element"). In -std=c++17 and -std=c++20 modes, classes with an empty base class were not considered to have a single element or to be a homogeneous aggregate, and so could be passed differently (in the wrong registers or at the wrong stack address). This could make code compiled with -std=c++17 and -std=c++14 ABI incompatible. This has been corrected and the empty bases are ignored in those ABI decisions, so functions compiled with -std=c++14 and -std=c++17 are now ABI compatible again. Example: struct empty {}; struct S : empty { float f; }; void f(S);. Similarly, in classes containing non-static data members with empty class types using the C++20 [[no_unique_address]] attribute, those members weren't ignored in the ABI argument passing decisions as they should be. Both of these ABI changes are now diagnosed with -Wpsabi.
```

--
Name: zhongxiao yao

David Blaikie via llvm-dev

unread,
Mar 1, 2021, 12:13:02 PM3/1/21
to yao zhongxiao, Richard Smith, John McCall, llvm...@lists.llvm.org
+Richard & John in case there's anything we need to do on the Clang side to ensure Clang is consistent with whichever ABI decision GCC took here.

Reply all
Reply to author
Forward
0 new messages