This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Recategorize additional instantiations in the dylib as availability macros
ClosedPublic

Authored by philnik on Jul 9 2023, 11:21 AM.

Details

Summary

Adding additional instantiations to the dylib isn't actually an ABI break as long as programs targeting an older dylib don't start to depend on them. Making additional instantiations a matter of availability allows us to add them without an ABI break.

Diff Detail

Event Timeline

philnik created this revision.Jul 9 2023, 11:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 9 2023, 11:21 AM
philnik requested review of this revision.Jul 9 2023, 11:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 9 2023, 11:21 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
Mordante retitled this revision from [libc++] Recategorize additional instnatiations in the dylib as availability macros to [libc++] Recategorize additional instantiations in the dylib as availability macros.Jul 10 2023, 8:48 AM

No objection to this approach, but I would like to see the CI pass.

ldionne requested changes to this revision.Jul 10 2023, 11:20 AM
ldionne added a subscriber: ldionne.

Nice! I don't know why we didn't do those using availability in the first place, it seems strictly better.

libcxx/include/__availability
180

I would turn these conditions around instead and use HAS_NO_XXX like all the other availability macros.

181

This macro needs a separate comment.

338

Let's add an entry here for _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_KEY_FUNCTION. Those are the macros you should check to determine that the dylib *did not yet* contain the key function:

defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120000
defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000
defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000
defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000
libcxx/include/__config
187–192

This needs to be translated to the availability, or it'll fail on FreeBSD. FreeBSD doesn't currently enable availability markup, but that is probably needed as a pre-requisite. We could start by unconditionally pretending that all the _LIBCPP_AVAILABILITY_XXXXXXXX are enabled on FreeBSD, which would be equivalent to what they have today.

This revision now requires changes to proceed.Jul 10 2023, 11:20 AM
philnik updated this revision to Diff 539248.Jul 11 2023, 12:34 PM
philnik marked 2 inline comments as done.

Address comments

libcxx/include/__availability
180

I think it makes sense to do it this way, since these are "we added them later" instead of "this is the minimum OS version for this feature".

libcxx/include/__config
187–192

I'm a bit confused. This has nothing to do with FreeBSD.

philnik updated this revision to Diff 540493.Jul 14 2023, 10:42 AM

Try to fix CI

Mordante accepted this revision as: Mordante.Jul 17 2023, 9:18 AM

LGTM, but I like @ldionne to give the final approval.

I would like to split the good-what-message part of this change into its own patch, since it's significantly different from the other changes. But apart from that, this change makes sense to me.

libcxx/include/__availability
183

This comment should probably be copied from the original one?

371

First, this doesn't match the macro above (which is _LIBCPP_AVAILABILITY_ENABLE_BAD_FUNCTION_CALL_GOOD_WHAT_MESSAGE_AND_KEY_FUNCTION). Second, I would like us to split the good-what-message part of this change into its own patch since it is more tricky to get right, and in fact it *is* an ABI break (it might just be one that we can do in case it only affects arm64e).

libcxx/include/__config
187–192

I think I meant AIX here. The comment makes sense if you re-read and say AIX in your head.

philnik updated this revision to Diff 551280.Aug 17 2023, 2:45 PM
philnik marked 4 inline comments as done.

Address comments

philnik edited the summary of this revision. (Show Details)Aug 18 2023, 8:59 AM
ldionne requested changes to this revision.Aug 18 2023, 9:37 AM
ldionne added inline comments.
libcxx/include/__availability
1

The commit message should be updated to be specific to the additional iostream instantiations.

367–372
#  if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 120000)   || \
      (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ < 150000) || \
      (defined(__ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_TV_OS_VERSION_MIN_REQUIRED__ < 150000)         || \
      (defined(__ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_WATCH_OS_VERSION_MIN_REQUIRED__ < 80000)
#    define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
#  endif

This would be more consistent with the other availability macros. If we want to invert the logic and instead use _LIBCPP_AVAILABILITY_HAS_FOO, let's do it for all the macros in a separate patch (I think it would be a reasonable change since it would avoid breaking vendors when adding new availability macros).

This revision now requires changes to proceed.Aug 18 2023, 9:37 AM
philnik updated this revision to Diff 555640.Sep 3 2023, 4:09 PM
philnik marked 2 inline comments as done.

Address comments

ldionne accepted this revision.Sep 14 2023, 9:21 AM

Can you rebase to poke the CI? Also, please remove the reference to the radar from the commit message, since the radar was about bad_function_call (which we will handle separately).

Other than that, LGTM.

This revision is now accepted and ready to land.Sep 14 2023, 9:21 AM
philnik edited the summary of this revision. (Show Details)Sep 14 2023, 12:17 PM
philnik updated this revision to Diff 556926.Sep 17 2023, 11:26 PM
philnik edited the summary of this revision. (Show Details)

Try to fix CI

philnik updated this revision to Diff 556955.Sep 18 2023, 8:48 AM

Try to fix CI

philnik updated this revision to Diff 556994.Sep 18 2023, 8:52 PM

Try to fix CI

philnik updated this revision to Diff 557001.Sep 18 2023, 11:01 PM

Try to fix CI

ldionne requested changes to this revision.Sep 21 2023, 2:35 PM

Requesting changes since I'd like to discuss the latest changes to the patch during our next 1:1

This revision now requires changes to proceed.Sep 21 2023, 2:35 PM
ldionne added inline comments.Sep 28 2023, 9:01 AM
libcxx/include/__availability
185

Here, let's do this instead:

// Enable additional explicit instantiations of iostreams components. This
// reduces the number of weak definitions generated in programs that use
// iostreams by providing a single strong definition in the shared library.
//
// TODO: Enable additional explicit instantiations on GCC once it supports 
//           exclude_from_explicit_instantiation, or once libc++ doesn't use the attribute anymore.
// TODO: Enable them on Windows once https://llvm.org/PR41018 has been fixed.
#if defined(_LIBCPP_COMPILER_GCC) || defined(_WIN32)
#  define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
#else
// # define _LIBCPP_AVAILABILITY_HAS_NO_ADDITIONAL_IOSTREAM_EXPLICIT_INSTANTIATIONS_1
#endif

Then you can remove the workarounds in libcxx/include/sstream.

philnik updated this revision to Diff 557519.Oct 1 2023, 6:13 AM
philnik marked an inline comment as done.

Address comments

ldionne accepted this revision.Oct 5 2023, 8:44 AM
This revision is now accepted and ready to land.Oct 5 2023, 8:44 AM
This revision was landed with ongoing or failed builds.Oct 6 2023, 2:21 AM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Oct 6 2023, 8:23 PM

Does settings _LIBCPP_ABI_VERSION to 2 still opt in to this after this change?

Does settings _LIBCPP_ABI_VERSION to 2 still opt in to this after this change?

I guess it doesn't anymore for Windows or GCC. That definitely wasn't intended, but I'm not sure that's such a bad thing, since we ran into multiple bugs when trying to enable it in ABIv1 there.

This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?

This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?

Thanks for the heads-up! Could you check whether e9c101a fixes it?

This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?

Thanks for the heads-up! Could you check whether e9c101a fixes it?

I’ve had some issues building stage2 builds on my machine, so I’ve struggled reproducing it locally. If you’re certain the new include should be there regardless, I’d say the fastest way to learn whether it fixes this particular problem would be to commit it and wait for CI to build, tbh. Otherwise I’ll give it another go in the morning.

This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?

Thanks for the heads-up! Could you check whether e9c101a fixes it?

I’ve had some issues building stage2 builds on my machine, so I’ve struggled reproducing it locally. If you’re certain the new include should be there regardless, I’d say the fastest way to learn whether it fixes this particular problem would be to commit it and wait for CI to build, tbh. Otherwise I’ll give it another go in the morning.

I've committed it already, since it's definitely missing. I wasn't sure whether the bot was building from trunk or not.

This patch is currently our main suspect for this stage2 linker error. @philnik Do you have any ideas off the top of your head for what might cause this?

Thanks for the heads-up! Could you check whether e9c101a fixes it?

I’ve had some issues building stage2 builds on my machine, so I’ve struggled reproducing it locally. If you’re certain the new include should be there regardless, I’d say the fastest way to learn whether it fixes this particular problem would be to commit it and wait for CI to build, tbh. Otherwise I’ll give it another go in the morning.

I've committed it already, since it's definitely missing. I wasn't sure whether the bot was building from trunk or not.

Hmm, unfortunately it seems like the issue still persists. This build should contain your fix for both the stage1 and stage2 builds: https://green.lab.llvm.org/green/job/clang-stage2-Rthinlto/7627/console. I still haven't been able to do a stage2 build locally to replicate.