This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Optimize internal function in <system_error>
ClosedPublic

Authored by diamante0018 on Jul 20 2023, 5:23 AM.

Details

Summary

In the event the internal function __init is called with an empty string the code will take unnecessary extra steps, in addition, the code generated might be overall greater because, to my understanding, when initializing a string with an empty const char* "" (like in this case), the compiler might be unable to deduce the string is indeed empty at compile time and more code is generated.

The goal of this patch is to make a new internal function that will accept just an error code skipping the empty string argument. It should skip the unnecessary steps and in the event if (ec) is false, it will return an empty string using the correct ctor, avoiding any extra code generation issues.

After the conversation about this patch matured in the libcxx channel on the LLVM Discord server, the patch was analyzed quickly with "Compiler Explorer" and other tools and it was discovered that it does indeed reduce the amount of code generated when using the latest stable clang version (16) which in turn produces faster code.

This patch targets LLVM 18 as it will break the ABI by addressing https://github.com/llvm/llvm-project/issues/63985

Benchmark tests run on other machines as well show in the best case, that the new version without the extra string as an argument performs 10 times faster.
On the buildkite CI run it shows the new code takes less CPU time as well.
In conclusion, the new code should also just appear cleaner because there are fewer checks to do when there is no message.

Diff Detail

Event Timeline

diamante0018 created this revision.Jul 20 2023, 5:23 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 20 2023, 5:23 AM
diamante0018 requested review of this revision.Jul 20 2023, 5:23 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 20 2023, 5:23 AM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik requested changes to this revision.Jul 20 2023, 7:56 AM
philnik added a subscriber: philnik.

This definitely needs some benchmark, or at least show the difference in code gen. I would be very surprised if the compiler isn't able to optimize this case.

This revision now requires changes to proceed.Jul 20 2023, 7:56 AM
diamante0018 edited the summary of this revision. (Show Details)

After the conversation about this patch matured in the libcxx channel on the LLVM Discord server, the patch was analyzed quickly with "Compiler Explorer" and other tools and it was discovered that it does indeed reduce the amount of code generated when using the latest stable clang version (16) which in turn produces faster code.
In this updated diff, a new benchmark test file was added.

Use {} to construct system_error object.

Removed unused header include directive

Avoid breaking the ABI!

fix compilation when threads are disabled

diamante0018 edited the summary of this revision. (Show Details)Jul 21 2023, 5:08 AM
diamante0018 edited the summary of this revision. (Show Details)
ldionne added inline comments.Jul 21 2023, 9:53 AM
libcxx/src/system_error.cpp
53

Just to put things in perspective, system_error is an exception type. I don't think we should pursue changes just for the sake of optimizing the construction of exception types.

However, mixed with https://github.com/llvm/llvm-project/issues/63985, I think this change could be worthwhile since we would both make this faster (ok, whatever) but also remove an unused function from our ABI surface (which is nice).

So personally I think the approach we should take here is to remove __init from our ABI and replace it with a function that is internal to system_error.cpp like you did here. Removing __init from the ABI will require a bit of preparation work to make sure it's safe but that's something we can help with if you update this patch with the full changes.

Just to set expectations, I would target this for LLVM 18, not LLVM 17.

diamante0018 edited the summary of this revision. (Show Details)

As suggested, I will commit to making a diff that will address the issue with __init altogether.
Removing it should be the best option, I might need a few attempts to see how I can make CI turn green.

diamante0018 marked an inline comment as done.Jul 21 2023, 10:03 AM
diamante0018 added inline comments.
libcxx/src/system_error.cpp
53

Sounds good to me! I can wait until LLVM 18, no problem.
I pushed the full changes.

diamante0018 edited the summary of this revision. (Show Details)Jul 21 2023, 10:04 AM
diamante0018 marked an inline comment as done.

Try to fix tests

This basically LGTM with updated changelog and release note. I did an internal check and couldn't find anything that referenced this symbol, which seems to support the reasoning that this was never used outside of the dylib.

libcxx/benchmarks/CMakeLists.txt
188

Can you please also update libcxx/lib/abi/CHANGELOG.TXT and libcxx/docs/ReleaseNotes/18.rst (in the ABI affecting changes section).

Please make sure to mention the reasoning for why this removal from the ABI should not be a breaking change!

Address review comments: Add this patch to the changelog

This basically LGTM with updated changelog and release note. I did an internal check and couldn't find anything that referenced this symbol, which seems to support the reasoning that this was never used outside of the dylib.

Hi, Thanks for your guidance. This is my first interaction with the LLVM docs and changelogs so I hope I got it right. Let me know if my additions are fine, thanks.

diamante0018 marked an inline comment as done.Aug 7 2023, 1:22 PM
philnik accepted this revision.Aug 11 2023, 12:36 PM
This revision is now accepted and ready to land.Aug 11 2023, 12:36 PM

Thanks for approving, if you can could you land it for me?
My details are:

Edoardo Sanguineti <edoardo.sanguineti222@gmail.com>

This revision was landed with ongoing or failed builds.Aug 11 2023, 1:08 PM
This revision was automatically updated to reflect the committed changes.