@@ -221,7 +221,11 @@ IRGenFunction::getDefaultCoroutineAllocatorKind() {
221221 return CoroAllocatorKind::Async;
222222 }
223223 if (isCoroutine ()) {
224- return CoroAllocatorKind::Malloc;
224+ if (getOptions ().EmitTypeMallocForCoroFrame ) {
225+ return CoroAllocatorKind::TypedMalloc;
226+ } else {
227+ return CoroAllocatorKind::Malloc;
228+ }
225229 }
226230 if (IGM.SwiftCoroCC != llvm::CallingConv::SwiftCoro) {
227231 // If the swiftcorocc isn't available, fall back to malloc.
@@ -2707,17 +2711,14 @@ irgen::getAsyncFunctionAndSize(IRGenFunction &IGF,
27072711 return {fn, size};
27082712}
27092713
2710- std::pair<llvm::Value *, llvm::Value *>
2711- irgen::getCoroFunctionAndSize (IRGenFunction &IGF,
2712- FunctionPointer functionPointer,
2713- std::pair<bool , bool > values) {
2714- assert (values.first || values.second );
2714+ std::tuple<llvm::Value *, llvm::Value *, llvm::Value *>
2715+ irgen::getCoroFunctionValues (IRGenFunction &IGF,
2716+ FunctionPointer functionPointer,
2717+ std::tuple<bool , bool , bool > values) {
2718+ auto [emitFunction, emitSize, emitTypeID] = values;
2719+ assert (emitFunction || emitSize || emitTypeID);
27152720 assert (functionPointer.getKind () != FunctionPointer::Kind::Function);
27162721
2717- bool emitFunction = values.first ;
2718- bool emitSize = values.second ;
2719- assert (emitFunction || emitSize);
2720-
27212722 // Ensure that the CoroFunctionPointer is not auth'd if it is not used and
27222723 // that it is not auth'd more than once if it is needed.
27232724 //
@@ -2770,7 +2771,15 @@ irgen::getCoroFunctionAndSize(IRGenFunction &IGF,
27702771 size = IGF.Builder .CreateLoad (sizePtr, IGF.IGM .Int32Ty ,
27712772 IGF.IGM .getPointerAlignment ());
27722773 }
2773- return {fn, size};
2774+
2775+ llvm::Value *typeID = nullptr ;
2776+ if (emitTypeID) {
2777+ auto *sizePtr = IGF.Builder .CreateStructGEP (IGF.IGM .CoroFunctionPointerTy ,
2778+ getCoroPtr (), 2 );
2779+ typeID = IGF.Builder .CreateLoad (sizePtr, IGF.IGM .Int64Ty ,
2780+ IGF.IGM .getPointerAlignment ());
2781+ }
2782+ return {fn, size, typeID};
27742783}
27752784
27762785namespace {
@@ -2810,16 +2819,17 @@ class SyncCallEmission final : public CallEmission {
28102819 assert (!coroAllocator);
28112820
28122821 if (IsCalleeAllocatedCoroutine) {
2813- llvm::Value *bufferSize32;
2814- std::tie (calleeFunction, bufferSize32) =
2815- getCoroFunctionAndSize (IGF, CurCallee.getFunctionPointer ());
2822+ auto kind = IGF.getDefaultCoroutineAllocatorKind ();
2823+ llvm::Value *bufferSize32, *mallocTypeId;
2824+ std::tie (calleeFunction, bufferSize32, mallocTypeId) =
2825+ getCoroFunctionValues (IGF, CurCallee.getFunctionPointer ());
28162826 auto *bufferSize = IGF.Builder .CreateZExt (bufferSize32, IGF.IGM .SizeTy );
2817- coroStaticFrame = emitAllocYieldOnce2CoroutineFrame (IGF, bufferSize);
2827+ coroStaticFrame =
2828+ emitAllocYieldOnce2CoroutineFrame (IGF, bufferSize, mallocTypeId);
28182829 // TODO: CoroutineAccessors: Optimize allocator kind (e.g. async callers
28192830 // only need to use the TaskAllocator if the
28202831 // coroutine is suspended across an await).
2821- coroAllocator = emitYieldOnce2CoroutineAllocator (
2822- IGF, IGF.getDefaultCoroutineAllocatorKind ());
2832+ coroAllocator = emitYieldOnce2CoroutineAllocator (IGF, kind);
28232833 }
28242834 }
28252835 void end () override { super::end (); }
@@ -5185,10 +5195,12 @@ void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
51855195 auto deallocFn = IGF.IGM .getOpaquePtr (getCoroDeallocFn (IGF.IGM ));
51865196 auto allocFrameFn = IGF.IGM .getOpaquePtr (getCoroAllocFrameFn (IGF.IGM ));
51875197 auto deallocFrameFn = IGF.IGM .getOpaquePtr (getCoroDeallocFrameFn (IGF.IGM ));
5198+ auto *typeID = IGF.getMallocTypeId ();
51885199 emitRetconCoroutineEntry (
51895200 IGF, fnType, buffer, llvm::Intrinsic::coro_id_retcon_once_dynamic,
51905201 Size (-1 ) /* dynamic-to-IRGen size*/ , IGF.IGM .getCoroStaticFrameAlignment (),
5191- {cfp, allocator}, allocFn, deallocFn, {allocFrameFn, deallocFrameFn});
5202+ {cfp, allocator}, allocFn, deallocFn,
5203+ {allocFrameFn, deallocFrameFn, typeID});
51925204}
51935205void irgen::emitYieldOnce2CoroutineEntry (
51945206 IRGenFunction &IGF, LinkEntity coroFunction, CanSILFunctionType fnType,
@@ -5219,9 +5231,10 @@ Address irgen::emitAllocYieldManyCoroutineBuffer(IRGenFunction &IGF) {
52195231 getYieldManyCoroutineBufferAlignment (IGF.IGM ));
52205232}
52215233
5222- StackAddress irgen::emitAllocYieldOnce2CoroutineFrame (IRGenFunction &IGF,
5223- llvm::Value *size) {
5224- return emitAllocCoroStaticFrame (IGF, size);
5234+ StackAddress
5235+ irgen::emitAllocYieldOnce2CoroutineFrame (IRGenFunction &IGF, llvm::Value *size,
5236+ llvm::Value *mallocTypeId) {
5237+ return emitAllocCoroStaticFrame (IGF, size, mallocTypeId);
52255238}
52265239
52275240void irgen::emitDeallocYieldOnceCoroutineBuffer (IRGenFunction &IGF,
@@ -5270,14 +5283,15 @@ void irgen::emitStaticDeallocAsyncContext(IRGenFunction &IGF, Address context,
52705283}
52715284
52725285StackAddress irgen::emitAllocCoroStaticFrame (IRGenFunction &IGF,
5273- llvm::Value *size) {
5286+ llvm::Value *size,
5287+ llvm::Value *mallocTypeId) {
5288+ ASSERT (mallocTypeId);
52745289 // TODO: Avoid swift_task_alloc (async) and malloc (yield_once) if the
52755290 // suspension doesn't span an apply of an async function or a yield
52765291 // respectively.
5277- auto retval = IGF.emitDynamicAlloca (
5278- IGF.IGM .Int8Ty , size, Alignment (MaximumAlignment), AllowsTaskAlloc,
5279- IsForCalleeCoroutineFrame_t (IGF.isCalleeAllocatedCoroutine ()),
5280- " callee-coro-frame" );
5292+ auto retval =
5293+ IGF.emitDynamicAlloca (IGF.IGM .Int8Ty , size, Alignment (MaximumAlignment),
5294+ AllowsTaskAlloc, mallocTypeId, " callee-coro-frame" );
52815295 IGF.Builder .CreateLifetimeStart (retval.getAddress (),
52825296 Size (-1 ) /* dynamic size*/ );
52835297 return retval;
0 commit comments