@@ -5153,6 +5153,35 @@ static llvm::Constant *getCoroAllocWrapperFn(IRGenModule &IGM) {
5153
5153
/* optionalLinkageOverride=*/ nullptr , llvm::CallingConv::SwiftCoro);
5154
5154
}
5155
5155
5156
+ static llvm::Constant *getCoroDeallocWrapperFn (IRGenModule &IGM) {
5157
+ return IGM.getOrCreateHelperFunction (
5158
+ " __swift_coro_dealloc_" , IGM.VoidTy ,
5159
+ {IGM.CoroAllocatorPtrTy , IGM.Int8PtrTy },
5160
+ [](IRGenFunction &IGF) {
5161
+ auto parameters = IGF.collectParameters ();
5162
+ auto *allocator = parameters.claimNext ();
5163
+ auto *ptr = parameters.claimNext ();
5164
+ auto *nullAllocator = IGF.Builder .CreateCmp (
5165
+ llvm::CmpInst::Predicate::ICMP_EQ, allocator,
5166
+ llvm::ConstantPointerNull::get (
5167
+ cast<llvm::PointerType>(allocator->getType ())));
5168
+ auto *bailBlock = IGF.createBasicBlock (" bail" );
5169
+ auto *forwardBlock = IGF.createBasicBlock (" forward" );
5170
+ IGF.Builder .CreateCondBr (nullAllocator, bailBlock, forwardBlock);
5171
+ IGF.Builder .emitBlock (bailBlock);
5172
+ // Emit the dynamic alloca.
5173
+ IGF.Builder .CreateRetVoid ();
5174
+ IGF.Builder .emitBlock (forwardBlock);
5175
+ IGF.Builder .CreateCall (
5176
+ IGF.IGM .getCoroDeallocFunctionPointer (), {allocator, ptr});
5177
+ IGF.Builder .CreateRetVoid ();
5178
+ },
5179
+ /* setIsNoInline=*/ false ,
5180
+ /* forPrologue=*/ false ,
5181
+ /* isPerformanceConstraint=*/ false ,
5182
+ /* optionalLinkageOverride=*/ nullptr , llvm::CallingConv::SwiftCoro);
5183
+ }
5184
+
5156
5185
void irgen::emitYieldOnce2CoroutineEntry (IRGenFunction &IGF,
5157
5186
CanSILFunctionType fnType,
5158
5187
llvm::Value *buffer,
@@ -5164,7 +5193,9 @@ void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF,
5164
5193
auto allocFn = IGF.IGM .getOpaquePtr (isSwiftCoroCCAvailable
5165
5194
? getCoroAllocWrapperFn (IGF.IGM )
5166
5195
: IGF.IGM .getCoroAllocFn ());
5167
- auto deallocFn = IGF.IGM .getOpaquePtr (IGF.IGM .getCoroDeallocFn ());
5196
+ auto deallocFn = IGF.IGM .getOpaquePtr (isSwiftCoroCCAvailable
5197
+ ? getCoroDeallocWrapperFn (IGF.IGM )
5198
+ : IGF.IGM .getCoroDeallocFn ());
5168
5199
emitRetconCoroutineEntry (
5169
5200
IGF, fnType, buffer, llvm::Intrinsic::coro_id_retcon_once_dynamic,
5170
5201
Size (-1 ) /* dynamic-to-IRGen size*/ , IGF.IGM .getCoroStaticFrameAlignment (),
@@ -5199,16 +5230,17 @@ Address irgen::emitAllocYieldManyCoroutineBuffer(IRGenFunction &IGF) {
5199
5230
getYieldManyCoroutineBufferAlignment (IGF.IGM ));
5200
5231
}
5201
5232
5202
- static llvm::Constant *getAddrOfGlobalCoroAllocator (IRGenModule &IGM,
5203
- CoroAllocatorKind kind,
5204
- llvm::Constant *allocFn,
5205
- llvm::Constant *deallocFn) {
5233
+ static llvm::Constant *getAddrOfGlobalCoroAllocator (
5234
+ IRGenModule &IGM, CoroAllocatorKind kind, bool shouldDeallocateImmediately,
5235
+ llvm::Constant *allocFn, llvm::Constant *deallocFn) {
5206
5236
auto entity = LinkEntity::forCoroAllocator (kind);
5207
5237
auto taskAllocator = IGM.getOrCreateLazyGlobalVariable (
5208
5238
entity,
5209
5239
[&](ConstantInitBuilder &builder) -> ConstantInitFuture {
5210
5240
auto allocator = builder.beginStruct (IGM.CoroAllocatorTy );
5211
- allocator.addInt32 (CoroAllocatorFlags (kind).getOpaqueValue ());
5241
+ auto flags = CoroAllocatorFlags (kind);
5242
+ flags.setShouldDeallocateImmediately (shouldDeallocateImmediately);
5243
+ allocator.addInt32 (flags.getOpaqueValue ());
5212
5244
allocator.add (allocFn);
5213
5245
allocator.add (deallocFn);
5214
5246
return allocator.finishAndCreateFuture ();
@@ -5218,10 +5250,12 @@ static llvm::Constant *getAddrOfGlobalCoroAllocator(IRGenModule &IGM,
5218
5250
}
5219
5251
llvm::Constant *IRGenModule::getAddrOfGlobalCoroMallocAllocator () {
5220
5252
return getAddrOfGlobalCoroAllocator (*this , CoroAllocatorKind::Malloc,
5253
+ /* shouldDeallocateImmediately=*/ true ,
5221
5254
getMallocFn (), getFreeFn ());
5222
5255
}
5223
5256
llvm::Constant *IRGenModule::getAddrOfGlobalCoroAsyncTaskAllocator () {
5224
5257
return getAddrOfGlobalCoroAllocator (*this , CoroAllocatorKind::Async,
5258
+ /* shouldDeallocateImmediately=*/ false ,
5225
5259
getTaskAllocFn (), getTaskDeallocFn ());
5226
5260
}
5227
5261
llvm::Value *
0 commit comments