This is an archive of the discontinued LLVM Phabricator instance.

[C++] [Coroutines] Prefer aligned (de)allocation for coroutines - implement the option2 of P2014R0
ClosedPublic

Authored by ChuanqiXu on Sep 6 2022, 1:10 AM.

Details

Summary

This implements the option2 of https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2014r0.pdf.

This also fixes https://github.com/llvm/llvm-project/issues/56671.

Although wg21 didn't get consensus for the direction of the problem, we're happy to have some implementation and user experience first. And from issue56671, the option2 should be the pursued one.

Diff Detail

Event Timeline

ChuanqiXu created this revision.Sep 6 2022, 1:10 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 6 2022, 1:10 AM
ChuanqiXu requested review of this revision.Sep 6 2022, 1:10 AM
ChuanqiXu updated this revision to Diff 458116.Sep 6 2022, 1:12 AM

Remove invisible character... there are always invisible characters in the paper..

I'm not a great reviewer for coroutines as I don't quite get them, so a vastly better commit/review message would be GREATLY appreciated.

Code seems fine, but I'd love for someone better at coroutines to take a look too.

clang/lib/CodeGen/CGCoroutine.cpp
688

Don't use 'auto' unless the RHS has the type in it clearly. SO this should be QualType I think? I also see you've broken that coding standard rule above.

689

Same here. ALSO, even when using 'auto', we need ot keep the '*' around.

ChuanqiXu updated this revision to Diff 458353.Sep 6 2022, 8:02 PM

Address comments.

ChuanqiXu marked 2 inline comments as done.Sep 6 2022, 8:03 PM
ChuanqiXu added inline comments.
clang/lib/CodeGen/CGCoroutine.cpp
688

Oh, sorry. I did move the code simply and didn't double check it. I've handled it in an separate NFC patch: https://github.com/llvm/llvm-project/commit/5f571eeb3f764c6d97b81822464ea420adef2cf7

ChuanqiXu marked an inline comment as done.Sep 12 2022, 7:42 PM
ychen added a comment.Sep 13 2022, 6:53 PM

It surprises me that Option 2 does not change https://eel.is/c++draft/dcl.fct.def.coroutine#10. For consistency, I think it should. And according to your test case, it deals with alignment as expected. Probably we should change the P2014R0 wording accordingly. Before that, let's just mention this difference in the Clang release notes.

clang/docs/ClangCommandLineReference.rst
1580 ↗(On Diff #458353)
clang/docs/ReleaseNotes.rst
230–232
clang/include/clang/Basic/DiagnosticSemaKinds.td
11283

Since we're digressing from the usual operator new/delete look-up rules per Option 2, I think it might be easier to just *not* respect -fno-aligned-allocation and -fno-sized-deallocation. Using '-fcoro-aligned-allocation' explicitly should permit us to assume these functions could be found.

clang/include/clang/Basic/LangOptions.def
157
clang/lib/Sema/SemaCoroutine.cpp
1302–1318

Update comment here.

1449

Option 2's order of look-up is

void* T::operator new  ( std::size_t count, std::align_val_t al, user-defined-args... );
void* T::operator new  ( std::size_t count, std::align_val_t al);
void* T::operator new  ( std::size_t count, user-defined-args... );
void* T::operator new  ( std::size_t count);
void* operator new  ( std::size_t count, std::align_val_t al );

Why not allow void* T::operator new ( std::size_t count); here?

clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp
95

Please add test cases for

void operator delete  ( void* ptr, std::size_t, std::align_val_t);
void operator delete  ( void* ptr, std::size_t);
void operator delete  ( void* ptr);
void ::operator delete  ( void* ptr, std::size_t, std::align_val_t);
void ::operator delete  ( void* ptr, std::size_t);
void ::operator delete  ( void* ptr);

in that lookup order, and makes sure the look-up order is expected.

ychen added inline comments.Sep 13 2022, 6:58 PM
clang/test/SemaCXX/coroutine-alloc-4.cpp
50

Like this test case, please add additional test cases to check the expected look-up order, one test for each consecutive pair should be good.

void* T::operator new  ( std::size_t count, std::align_val_t al, user-defined-args... );
void* T::operator new  ( std::size_t count, std::align_val_t al);
void* T::operator new  ( std::size_t count, user-defined-args... );
void* T::operator new  ( std::size_t count);
void* operator new  ( std::size_t count, std::align_val_t al );
ChuanqiXu marked 5 inline comments as done.

Address comments.

ChuanqiXu marked 2 inline comments as done.Sep 14 2022, 12:38 AM

It surprises me that Option 2 does not change https://eel.is/c++draft/dcl.fct.def.coroutine#10. For consistency, I think it should. And according to your test case, it deals with alignment as expected. Probably we should change the P2014R0 wording accordingly. Before that, let's just mention this difference in the Clang release notes.

Yeah, in fact due to the wording of coroutine allocation has changed slightly recently, the wording of P2014 must be updated before merged. And I agree it should be consistent.

clang/include/clang/Basic/DiagnosticSemaKinds.td
11283

I guess it may not be good to enable -fsized-deallocation automatically if -fcoro-aligned-allocation enabled. Since it looks like there are other reasons why we disabled -fsized-deallocation before. And it looks it will block our users to use -fcoro-aligned-allocation. For the -faligned-allocation flag, this is enabled by default but people could disable it explicitly. So the check here is for that.

clang/lib/Sema/SemaCoroutine.cpp
1302–1318

Since P2014 is not standardized, I feel it might not be good to edit them here.

1449

My original thought is to be as strict as we can. But now I feel a warning may be good enough.

clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp
95

I've tried my best. But it looks hard to test these operator delete under global namespace since they are automatically declared by the compiler.

clang/test/SemaCXX/coroutine-alloc-4.cpp
50

Yeah, I'm testing this in CodeGenCoroutines. (It is hard to test the selection in Sema Test)

ychen added a comment.Sep 14 2022, 6:40 PM

Looks great. Just a few more nits.

clang/include/clang/Basic/DiagnosticSemaKinds.td
11280

"under -fcoro-aligned-allocation, the non-aligned allocation function for the promise type %0 has higher precedence than the global aligned allocation function"

11283

You're right. It is better to diagnose the conflicting intent.

clang/lib/Sema/SemaCoroutine.cpp
1426

Micro-optimization: instead of recomputing this, add a flag bool WithoutPlacementArgs to LookupAllocationFunction to switch between an empty vector and PlacementArgs.

clang/test/CodeGenCoroutines/coro-aligned-alloc.cpp
95

Thanks for adding these. It looks great! I wouldn't worry about the global ones since this patch did not change their look-up order.

clang/test/SemaCXX/coroutine-alloc-4.cpp
50

Thanks for adding the overload. I think the noexcept on operator new is not necessary. Strictly speaking, it is not a conforming API.

ChuanqiXu marked 6 inline comments as done.

Address comments.

ChuanqiXu marked 2 inline comments as done.Sep 15 2022, 12:45 AM
ChuanqiXu added inline comments.
clang/test/SemaCXX/coroutine-alloc-4.cpp
50

The noexcept here is necessary. The specs says the allocation function should have a noexcept specifier if get_return_object_on_allocation_failure presents.

ychen accepted this revision.Sep 15 2022, 8:51 PM

LGTM. Give it a few days in case @rjmccall have comments.

clang/test/SemaCXX/coroutine-alloc-4.cpp
50

I see. I didn't realize that, before P2014, the way class-specific operator new/delete are looked up is already different between coroutine and regular routine. Basically, with the normal operator new/delete lookup rules, the no-throw and potentially-throw allocation functions may overload, so the throw function type must have std::throw_t parameter; with the coroutine operator new/delete lookup rules, the no-throw and potentially-throw allocation functions do not overload since get_return_object_on_allocation_failure is either found or not found, thus the std::throw_t parameter is not necessary for the potentially-throw allocation function.

This revision is now accepted and ready to land.Sep 15 2022, 8:51 PM
ChuanqiXu added inline comments.Sep 15 2022, 9:50 PM
clang/test/SemaCXX/coroutine-alloc-4.cpp
50

Yeah, thanks for the explanation.