llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (Andres-Salamanca) <details> <summary>Changes</summary> This PR upstreams support for the co_yield expression by emitting a cir.await op with the yield kind. --- Full diff: https://github.com/llvm/llvm-project/pull/173162.diff 5 Files Affected: - (modified) clang/include/clang/CIR/MissingFeatures.h (-1) - (modified) clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp (+8-1) - (modified) clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp (+3-2) - (modified) clang/lib/CIR/CodeGen/CIRGenFunction.h (+4) - (modified) clang/test/CIR/CodeGen/coro-task.cpp (+50) ``````````diff diff --git a/clang/include/clang/CIR/MissingFeatures.h b/clang/include/clang/CIR/MissingFeatures.h index acfc937a11993..cc0d2579d176b 100644 --- a/clang/include/clang/CIR/MissingFeatures.h +++ b/clang/include/clang/CIR/MissingFeatures.h @@ -153,7 +153,6 @@ struct MissingFeatures { static bool emitBodyAndFallthrough() { return false; } static bool coroOutsideFrameMD() { return false; } static bool coroCoReturn() { return false; } - static bool coroCoYield() { return false; } static bool coroutineExceptions() { return false; }; // Various handling of deferred processing in CIRGenModule. diff --git a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp index 9251106a641b1..db3bdec436b94 100644 --- a/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenCoroutine.cpp @@ -418,7 +418,7 @@ emitSuspendExpression(CIRGenFunction &cgf, CGCoroData &coro, // FIXME(cir): the alloca for the resume expr should be placed in the // enclosing cir.scope instead. if (forLValue) { - assert(!cir::MissingFeatures::coroCoYield()); + awaitRes.lv = cgf.emitLValue(s.getResumeExpr()); } else { awaitRes.rv = cgf.emitAnyExpr(s.getResumeExpr(), aggSlot, ignoreResult); @@ -486,6 +486,13 @@ RValue CIRGenFunction::emitCoawaitExpr(const CoawaitExpr &e, ignoreResult); } +RValue CIRGenFunction::emitCoyieldExpr(const CoyieldExpr &e, + AggValueSlot aggSlot, + bool ignoreResult) { + return emitSuspendExpr(*this, e, cir::AwaitKind::Yield, aggSlot, + ignoreResult); +} + mlir::LogicalResult CIRGenFunction::emitCoreturnStmt(CoreturnStmt const &s) { ++curCoro.data->coreturnCount; curLexScope->setCoreturn(); diff --git a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp index 60884aefbfb1f..210e13af7eb35 100644 --- a/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenExprScalar.cpp @@ -165,10 +165,11 @@ class ScalarExprEmitter : public StmtVisitor<ScalarExprEmitter, mlir::Value> { mlir::Value VisitCoawaitExpr(CoawaitExpr *s) { return cgf.emitCoawaitExpr(*s).getValue(); } + mlir::Value VisitCoyieldExpr(CoyieldExpr *e) { - cgf.cgm.errorNYI(e->getSourceRange(), "ScalarExprEmitter: coyield"); - return {}; + return cgf.emitCoyieldExpr(*e).getValue(); } + mlir::Value VisitUnaryCoawait(const UnaryOperator *e) { cgf.cgm.errorNYI(e->getSourceRange(), "ScalarExprEmitter: unary coawait"); return {}; diff --git a/clang/lib/CIR/CodeGen/CIRGenFunction.h b/clang/lib/CIR/CodeGen/CIRGenFunction.h index 254a8c5883d48..5c178c9265bb2 100644 --- a/clang/lib/CIR/CodeGen/CIRGenFunction.h +++ b/clang/lib/CIR/CodeGen/CIRGenFunction.h @@ -1656,6 +1656,10 @@ class CIRGenFunction : public CIRGenTypeCache { RValue emitCoawaitExpr(const CoawaitExpr &e, AggValueSlot aggSlot = AggValueSlot::ignored(), bool ignoreResult = false); + + RValue emitCoyieldExpr(const CoyieldExpr &e, + AggValueSlot aggSlot = AggValueSlot::ignored(), + bool ignoreResult = false); /// Emit the computation of the specified expression of complex type, /// returning the result. mlir::Value emitComplexExpr(const Expr *e); diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGen/coro-task.cpp index 6cd494317f2d8..d7b06e1f61aa7 100644 --- a/clang/test/CIR/CodeGen/coro-task.cpp +++ b/clang/test/CIR/CodeGen/coro-task.cpp @@ -322,3 +322,53 @@ folly::coro::Task<void> silly_coro() { // CIR: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv // CIR-NOT: cir.call @_ZN5folly4coro4TaskIvE12promise_type11return_voidEv // CIR: cir.await(final, ready : { + + +folly::coro::Task<void> yield(); +folly::coro::Task<void> yield1() { + auto t = yield(); + co_yield t; +} + +// CHECK: cir.func coroutine {{.*}} @_Z6yield1v() -> !rec_folly3A3Acoro3A3ATask3Cvoid3E + +// CIR: cir.await(init, ready : { +// CIR: }, suspend : { +// CIR: }, resume : { +// CIR: },) + +// CIR: cir.scope { +// CIR-NEXT: %[[SUSPEND_PTR:.*]] = cir.alloca ![[SuspendAlways]], !cir.ptr<![[SuspendAlways]]> +// CIR-NEXT: %[[AWAITER_PTR:.*]] = cir.alloca ![[VoidTask]], !cir.ptr<![[VoidTask]]> +// CIR-NEXT: %[[CORO_PTR:.*]] = cir.alloca ![[CoroHandleVoid]], !cir.ptr<![[CoroHandleVoid]]> +// CIR-NEXT: %[[CORO2_PTR:.*]] = cir.alloca ![[CoroHandlePromiseVoid]], !cir.ptr<![[CoroHandlePromiseVoid]]> +// CIR-NEXT: cir.copy {{.*}} to %[[AWAITER_PTR]] : !cir.ptr<![[VoidTask]]> +// CIR-NEXT: %[[AWAITER:.*]] = cir.load{{.*}} %[[AWAITER_PTR]] : !cir.ptr<![[VoidTask]]>, ![[VoidTask]] +// CIR-NEXT: %[[SUSPEND:.*]] = cir.call @_ZN5folly4coro4TaskIvE12promise_type11yield_valueES2_(%{{.+}}, %[[AWAITER]]) nothrow : (!cir.ptr<![[VoidPromisse]]>, ![[VoidTask]]) -> ![[SuspendAlways]] +// CIR-NEXT: cir.store{{.*}} %[[SUSPEND]], %[[SUSPEND_PTR]] : ![[SuspendAlways]], !cir.ptr<![[SuspendAlways]]> +// CIR-NEXT: cir.await(yield, ready : { +// CIR-NEXT: %[[READY:.*]] = cir.scope { +// CIR-NEXT: %[[A:.*]] = cir.call @_ZNSt14suspend_always11await_readyEv(%[[SUSPEND_PTR]]) nothrow : (!cir.ptr<![[SuspendAlways]]>) -> !cir.bool +// CIR-NEXT: cir.yield %[[A]] : !cir.bool +// CIR-NEXT: } : !cir.bool +// CIR-NEXT: cir.condition(%[[READY]]) +// CIR-NEXT: }, suspend : { +// CIR-NEXT: %[[CORO2:.*]] = cir.call @_ZNSt16coroutine_handleIN5folly4coro4TaskIvE12promise_typeEE12from_addressEPv(%9) nothrow : (!cir.ptr<!void>) -> ![[CoroHandlePromiseVoid]] +// CIR-NEXT: cir.store{{.*}} %[[CORO2]], %[[CORO2_PTR]] : ![[CoroHandlePromiseVoid]], !cir.ptr<![[CoroHandlePromiseVoid]]> +// CIR-NEXT: %[[B:.*]] = cir.load{{.*}} %[[CORO2_PTR]] : !cir.ptr<![[CoroHandlePromiseVoid]]>, ![[CoroHandlePromiseVoid]] +// CIR-NEXT: cir.call @_ZNSt16coroutine_handleIvEC1IN5folly4coro4TaskIvE12promise_typeEEES_IT_E(%[[CORO_PTR]], %[[B]]) nothrow : (!cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandlePromiseVoid]]) -> () +// CIR-NEXT: %[[C:.*]] = cir.load{{.*}} %[[CORO_PTR]] : !cir.ptr<![[CoroHandleVoid]]>, ![[CoroHandleVoid]] +// CIR-NEXT: cir.call @_ZNSt14suspend_always13await_suspendESt16coroutine_handleIvE(%[[SUSPEND_PTR]], %[[C]]) nothrow : (!cir.ptr<![[SuspendAlways]]>, ![[CoroHandleVoid]]) -> () +// CIR-NEXT: cir.yield +// CIR-NEXT: }, resume : { +// CIR-NEXT: cir.call @_ZNSt14suspend_always12await_resumeEv(%[[SUSPEND_PTR]]) nothrow : (!cir.ptr<![[SuspendAlways]]>) -> () +// CIR-NEXT: cir.yield +// CIR-NEXT: },) +// CIR-NEXT: } + +// CIR: cir.await(final, ready : { +// CIR: }, suspend : { +// CIR: }, resume : { +// CIR: },) + +// CHECK: } `````````` </details> https://github.com/llvm/llvm-project/pull/173162 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
