Skip to content

Commit 572cc8d

Browse files
committed
Revert "[C++20] [Coroutines] Mark await_suspend as noinline if the awaiter is not empty"
This reverts commit 9d9c25f. This reverts commit 19ab266. This reverts commit c467245. As the issue #65018 shows, the previous fix introduce a regression actually. So this commit reverts the fix by our policies.
1 parent beeb37a commit 572cc8d

File tree

6 files changed

+0
-382
lines changed

6 files changed

+0
-382
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,6 @@ Bug Fixes in This Version
174174
``abs`` builtins.
175175
(`#45129 <https://github.com/llvm/llvm-project/issues/45129>`_,
176176
`#45794 <https://github.com/llvm/llvm-project/issues/45794>`_)
177-
- Fixed an issue where accesses to the local variables of a coroutine during
178-
``await_suspend`` could be misoptimized, including accesses to the awaiter
179-
object itself.
180-
(`#56301 <https://github.com/llvm/llvm-project/issues/56301>`_)
181-
The current solution may bring performance regressions if the awaiters have
182-
non-static data members. See
183-
`#64945 <https://github.com/llvm/llvm-project/issues/64945>`_ for details.
184177
- Clang now prints unnamed members in diagnostic messages instead of giving an
185178
empty ''. Fixes
186179
(`#63759 <https://github.com/llvm/llvm-project/issues/63759>`_)

clang/lib/CodeGen/CGCall.cpp

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5527,34 +5527,6 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
55275527
Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::AlwaysInline);
55285528
}
55295529

5530-
// The await_suspend call performed by co_await is essentially asynchronous
5531-
// to the execution of the coroutine. Inlining it normally into an unsplit
5532-
// coroutine can cause miscompilation because the coroutine CFG misrepresents
5533-
// the true control flow of the program: things that happen in the
5534-
// await_suspend are not guaranteed to happen prior to the resumption of the
5535-
// coroutine, and things that happen after the resumption of the coroutine
5536-
// (including its exit and the potential deallocation of the coroutine frame)
5537-
// are not guaranteed to happen only after the end of await_suspend.
5538-
//
5539-
// The short-term solution to this problem is to mark the call as uninlinable.
5540-
// But we don't want to do this if the call is known to be trivial, which is
5541-
// very common.
5542-
//
5543-
// The long-term solution may introduce patterns like:
5544-
//
5545-
// call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle,
5546-
// ptr @awaitSuspendFn)
5547-
//
5548-
// Then it is much easier to perform the safety analysis in the middle end.
5549-
// If it is safe to inline the call to awaitSuspend, we can replace it in the
5550-
// CoroEarly pass. Otherwise we could replace it in the CoroSplit pass.
5551-
//
5552-
// If the `await_suspend()` function is marked as `always_inline` explicitly,
5553-
// we should give the user the right to control the codegen.
5554-
if (inSuspendBlock() && mayCoroHandleEscape() &&
5555-
!TargetDecl->hasAttr<AlwaysInlineAttr>())
5556-
Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);
5557-
55585530
// Disable inlining inside SEH __try blocks.
55595531
if (isSEHTryScope()) {
55605532
Attrs = Attrs.addFnAttribute(getLLVMContext(), llvm::Attribute::NoInline);

clang/lib/CodeGen/CGCoroutine.cpp

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -139,36 +139,6 @@ static bool memberCallExpressionCanThrow(const Expr *E) {
139139
return true;
140140
}
141141

142-
/// Return true when the coroutine handle may escape from the await-suspend
143-
/// (`awaiter.await_suspend(std::coroutine_handle)` expression).
144-
/// Return false only when the coroutine wouldn't escape in the await-suspend
145-
/// for sure.
146-
///
147-
/// While it is always safe to return true, return falses can bring better
148-
/// performances.
149-
///
150-
/// See https://github.com/llvm/llvm-project/issues/56301 and
151-
/// https://reviews.llvm.org/D157070 for the example and the full discussion.
152-
///
153-
/// FIXME: It will be much better to perform such analysis in the middle end.
154-
/// See the comments in `CodeGenFunction::EmitCall` for example.
155-
static bool MayCoroHandleEscape(CoroutineSuspendExpr const &S) {
156-
CXXRecordDecl *Awaiter =
157-
S.getCommonExpr()->getType().getNonReferenceType()->getAsCXXRecordDecl();
158-
159-
// Return true conservatively if the awaiter type is not a record type.
160-
if (!Awaiter)
161-
return true;
162-
163-
// In case the awaiter type is empty, the suspend wouldn't leak the coroutine
164-
// handle.
165-
//
166-
// TODO: We can improve this by looking into the implementation of
167-
// await-suspend and see if the coroutine handle is passed to foreign
168-
// functions.
169-
return !Awaiter->field_empty();
170-
}
171-
172142
// Emit suspend expression which roughly looks like:
173143
//
174144
// auto && x = CommonExpr();
@@ -229,11 +199,8 @@ static LValueOrRValue emitSuspendExpression(CodeGenFunction &CGF, CGCoroData &Co
229199
auto *SaveCall = Builder.CreateCall(CoroSave, {NullPtr});
230200

231201
CGF.CurCoro.InSuspendBlock = true;
232-
CGF.CurCoro.MayCoroHandleEscape = MayCoroHandleEscape(S);
233202
auto *SuspendRet = CGF.EmitScalarExpr(S.getSuspendExpr());
234203
CGF.CurCoro.InSuspendBlock = false;
235-
CGF.CurCoro.MayCoroHandleEscape = false;
236-
237204
if (SuspendRet != nullptr && SuspendRet->getType()->isIntegerTy(1)) {
238205
// Veto suspension if requested by bool returning await_suspend.
239206
BasicBlock *RealSuspendBlock =

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,6 @@ class CodeGenFunction : public CodeGenTypeCache {
334334
struct CGCoroInfo {
335335
std::unique_ptr<CGCoroData> Data;
336336
bool InSuspendBlock = false;
337-
bool MayCoroHandleEscape = false;
338337
CGCoroInfo();
339338
~CGCoroInfo();
340339
};
@@ -348,10 +347,6 @@ class CodeGenFunction : public CodeGenTypeCache {
348347
return isCoroutine() && CurCoro.InSuspendBlock;
349348
}
350349

351-
bool mayCoroHandleEscape() const {
352-
return isCoroutine() && CurCoro.MayCoroHandleEscape;
353-
}
354-
355350
/// CurGD - The GlobalDecl for the current function being compiled.
356351
GlobalDecl CurGD;
357352

clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp

Lines changed: 0 additions & 224 deletions
This file was deleted.

0 commit comments

Comments
 (0)