1515#include " clang/AST/StmtCXX.h"
1616#include " clang/Basic/TargetInfo.h"
1717#include " clang/CIR/Dialect/IR/CIRTypes.h"
18+ #include " clang/CIR/MissingFeatures.h"
1819
1920using namespace clang ;
2021using namespace clang ::CIRGen;
@@ -23,6 +24,9 @@ struct clang::CIRGen::CGCoroData {
2324 // Stores the __builtin_coro_id emitted in the function so that we can supply
2425 // it as the first argument to other builtins.
2526 cir::CallOp coroId = nullptr ;
27+
28+ // Stores the result of __builtin_coro_begin call.
29+ mlir::Value coroBegin = nullptr ;
2630};
2731
2832// Defining these here allows to keep CGCoroData private to this file.
@@ -63,6 +67,48 @@ cir::CallOp CIRGenFunction::emitCoroIDBuiltinCall(mlir::Location loc,
6367 nullPtr, nullPtr, nullPtr});
6468}
6569
70+ cir::CallOp CIRGenFunction::emitCoroAllocBuiltinCall (mlir::Location loc) {
71+ cir::BoolType boolTy = builder.getBoolTy ();
72+ cir::IntType int32Ty = builder.getUInt32Ty ();
73+
74+ mlir::Operation *builtin = cgm.getGlobalValue (cgm.builtinCoroAlloc );
75+
76+ cir::FuncOp fnOp;
77+ if (!builtin) {
78+ fnOp = cgm.createCIRBuiltinFunction (loc, cgm.builtinCoroAlloc ,
79+ cir::FuncType::get ({int32Ty}, boolTy),
80+ /* FD=*/ nullptr );
81+ assert (fnOp && " should always succeed" );
82+ } else {
83+ fnOp = cast<cir::FuncOp>(builtin);
84+ }
85+
86+ return builder.createCallOp (
87+ loc, fnOp, mlir::ValueRange{curCoro.data ->coroId .getResult ()});
88+ }
89+
90+ cir::CallOp
91+ CIRGenFunction::emitCoroBeginBuiltinCall (mlir::Location loc,
92+ mlir::Value coroframeAddr) {
93+ cir::IntType int32Ty = builder.getUInt32Ty ();
94+ mlir::Operation *builtin = cgm.getGlobalValue (cgm.builtinCoroBegin );
95+
96+ cir::FuncOp fnOp;
97+ if (!builtin) {
98+ fnOp = cgm.createCIRBuiltinFunction (
99+ loc, cgm.builtinCoroBegin ,
100+ cir::FuncType::get ({int32Ty, VoidPtrTy}, VoidPtrTy),
101+ /* FD=*/ nullptr );
102+ assert (fnOp && " should always succeed" );
103+ } else {
104+ fnOp = cast<cir::FuncOp>(builtin);
105+ }
106+
107+ return builder.createCallOp (
108+ loc, fnOp,
109+ mlir::ValueRange{curCoro.data ->coroId .getResult (), coroframeAddr});
110+ }
111+
66112mlir::LogicalResult
67113CIRGenFunction::emitCoroutineBody (const CoroutineBodyStmt &s) {
68114 mlir::Location openCurlyLoc = getLoc (s.getBeginLoc ());
@@ -73,10 +119,39 @@ CIRGenFunction::emitCoroutineBody(const CoroutineBodyStmt &s) {
73119 cir::CallOp coroId = emitCoroIDBuiltinCall (openCurlyLoc, nullPtrCst);
74120 createCoroData (*this , curCoro, coroId);
75121
76- assert (!cir::MissingFeatures::coroAllocBuiltinCall ());
77-
78- assert (!cir::MissingFeatures::coroBeginBuiltinCall ());
122+ // Backend is allowed to elide memory allocations, to help it, emit
123+ // auto mem = coro.alloc() ? 0 : ... allocation code ...;
124+ cir::CallOp coroAlloc = emitCoroAllocBuiltinCall (openCurlyLoc);
125+
126+ // Initialize address of coroutine frame to null
127+ CanQualType astVoidPtrTy = cgm.getASTContext ().VoidPtrTy ;
128+ mlir::Type allocaTy = convertTypeForMem (astVoidPtrTy);
129+ Address coroFrame =
130+ createTempAlloca (allocaTy, getContext ().getTypeAlignInChars (astVoidPtrTy),
131+ openCurlyLoc, " __coro_frame_addr" ,
132+ /* ArraySize=*/ nullptr );
133+
134+ mlir::Value storeAddr = coroFrame.getPointer ();
135+ builder.CIRBaseBuilderTy ::createStore (openCurlyLoc, nullPtrCst, storeAddr);
136+ cir::IfOp::create (
137+ builder, openCurlyLoc, coroAlloc.getResult (),
138+ /* withElseRegion=*/ false ,
139+ /* thenBuilder=*/ [&](mlir::OpBuilder &b, mlir::Location loc) {
140+ builder.CIRBaseBuilderTy ::createStore (
141+ loc, emitScalarExpr (s.getAllocate ()), storeAddr);
142+ builder.create <cir::YieldOp>(loc);
143+ });
144+ curCoro.data ->coroBegin =
145+ emitCoroBeginBuiltinCall (
146+ openCurlyLoc,
147+ builder.create <cir::LoadOp>(openCurlyLoc, allocaTy, storeAddr))
148+ .getResult ();
149+
150+ // Handle allocation failure if 'ReturnStmtOnAllocFailure' was provided.
151+ if (s.getReturnStmtOnAllocFailure ())
152+ cgm.errorNYI (" NYI" );
79153
80154 assert (!cir::MissingFeatures::generateDebugInfo ());
155+ assert (!cir::MissingFeatures::emitBodyAndFallthrough ());
81156 return mlir::success ();
82157}
0 commit comments