|
48 | 48 | #include "EntryPointArgumentEmission.h" |
49 | 49 | #include "Explosion.h" |
50 | 50 | #include "GenCall.h" |
| 51 | +#include "GenCoro.h" |
51 | 52 | #include "GenFunc.h" |
52 | 53 | #include "GenHeap.h" |
53 | 54 | #include "GenKeyPath.h" |
@@ -5169,141 +5170,6 @@ void irgen::emitYieldManyCoroutineEntry( |
5169 | 5170 | allocFn, deallocFn, {}); |
5170 | 5171 | } |
5171 | 5172 |
|
5172 | | -static llvm::Constant *getCoroAllocFn(IRGenModule &IGM) { |
5173 | | - auto isSwiftCoroCCAvailable = IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro; |
5174 | | - return IGM.getOrCreateHelperFunction( |
5175 | | - "_swift_coro_alloc", IGM.Int8PtrTy, {IGM.CoroAllocatorPtrTy, IGM.SizeTy}, |
5176 | | - [isSwiftCoroCCAvailable](IRGenFunction &IGF) { |
5177 | | - auto parameters = IGF.collectParameters(); |
5178 | | - auto *allocator = parameters.claimNext(); |
5179 | | - auto *size = parameters.claimNext(); |
5180 | | - if (isSwiftCoroCCAvailable) { |
5181 | | - // swiftcorocc is available, so if there's no allocator pointer, |
5182 | | - // allocate storage on the stack and return a pointer to it without |
5183 | | - // popping the stack. |
5184 | | - auto *nullAllocator = IGF.Builder.CreateCmp( |
5185 | | - llvm::CmpInst::Predicate::ICMP_EQ, allocator, |
5186 | | - llvm::ConstantPointerNull::get( |
5187 | | - cast<llvm::PointerType>(allocator->getType()))); |
5188 | | - auto *poplessReturn = IGF.createBasicBlock("popless"); |
5189 | | - auto *normalReturn = IGF.createBasicBlock("normal"); |
5190 | | - IGF.Builder.CreateCondBr(nullAllocator, poplessReturn, normalReturn); |
5191 | | - IGF.Builder.emitBlock(poplessReturn); |
5192 | | - // Emit the dynamic alloca. |
5193 | | - auto *alloca = |
5194 | | - IGF.Builder.IRBuilderBase::CreateAlloca(IGF.IGM.Int8Ty, size); |
5195 | | - alloca->setAlignment(llvm::Align(MaximumAlignment)); |
5196 | | - auto *retPopless = IGF.Builder.CreateIntrinsic( |
5197 | | - IGF.IGM.VoidTy, llvm::Intrinsic::ret_popless, {}); |
5198 | | - retPopless->setTailCallKind( |
5199 | | - llvm::CallInst::TailCallKind::TCK_MustTail); |
5200 | | - IGF.Builder.CreateRet(alloca); |
5201 | | - // Start emitting the "normal" block. |
5202 | | - IGF.Builder.emitBlock(normalReturn); |
5203 | | - } |
5204 | | - auto *calleePtr = IGF.Builder.CreateInBoundsGEP( |
5205 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5206 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5207 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 1)}); |
5208 | | - auto *callee = IGF.Builder.CreateLoad( |
5209 | | - Address(calleePtr, IGF.IGM.PtrTy, IGF.IGM.getPointerAlignment()), |
5210 | | - "allocate_fn"); |
5211 | | - auto fnPtr = FunctionPointer::createUnsigned( |
5212 | | - FunctionPointer::Kind::Function, callee, |
5213 | | - Signature(cast<llvm::FunctionType>(IGF.IGM.CoroAllocateFnTy), {}, |
5214 | | - IGF.IGM.SwiftCC)); |
5215 | | - auto *call = IGF.Builder.CreateCall(fnPtr, {size}); |
5216 | | - call->setDoesNotThrow(); |
5217 | | - call->setCallingConv(IGF.IGM.SwiftCC); |
5218 | | - IGF.Builder.CreateRet(call); |
5219 | | - }, |
5220 | | - /*setIsNoInline=*/true, |
5221 | | - /*forPrologue=*/false, |
5222 | | - /*isPerformanceConstraint=*/false, |
5223 | | - /*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC, |
5224 | | - /*transformAttributes=*/ |
5225 | | - [&IGM](llvm::AttributeList &attrs) { |
5226 | | - IGM.addSwiftCoroAttributes(attrs, 0); |
5227 | | - }); |
5228 | | -} |
5229 | | - |
5230 | | -static llvm::Constant *getCoroDeallocFn(IRGenModule &IGM) { |
5231 | | - auto isSwiftCoroCCAvailable = IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro; |
5232 | | - return IGM.getOrCreateHelperFunction( |
5233 | | - "_swift_coro_dealloc", IGM.VoidTy, |
5234 | | - {IGM.CoroAllocatorPtrTy, IGM.Int8PtrTy}, |
5235 | | - [isSwiftCoroCCAvailable](IRGenFunction &IGF) { |
5236 | | - auto parameters = IGF.collectParameters(); |
5237 | | - auto *allocator = parameters.claimNext(); |
5238 | | - auto *ptr = parameters.claimNext(); |
5239 | | - if (isSwiftCoroCCAvailable) { |
5240 | | - // swiftcorocc is available, so if there's no allocator pointer, |
5241 | | - // storage was allocated on the stack which will be naturally cleaned |
5242 | | - // up when the coroutine's frame is "freed". |
5243 | | - auto *nullAllocator = IGF.Builder.CreateCmp( |
5244 | | - llvm::CmpInst::Predicate::ICMP_EQ, allocator, |
5245 | | - llvm::ConstantPointerNull::get( |
5246 | | - cast<llvm::PointerType>(allocator->getType()))); |
5247 | | - auto *bailBlock = IGF.createBasicBlock("null_allocator"); |
5248 | | - auto *normalBlock = IGF.createBasicBlock("nonnull_allocator"); |
5249 | | - IGF.Builder.CreateCondBr(nullAllocator, bailBlock, normalBlock); |
5250 | | - IGF.Builder.emitBlock(bailBlock); |
5251 | | - // Nothing to do here. |
5252 | | - IGF.Builder.CreateRetVoid(); |
5253 | | - // Start emitting the "normal" block. |
5254 | | - IGF.Builder.emitBlock(normalBlock); |
5255 | | - } |
5256 | | - auto shouldDeallocateImmediatelyFlag = CoroAllocatorFlags(0); |
5257 | | - shouldDeallocateImmediatelyFlag.setShouldDeallocateImmediately(true); |
5258 | | - auto *flagsPtr = IGF.Builder.CreateInBoundsGEP( |
5259 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5260 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5261 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0)}); |
5262 | | - auto *flags = IGF.Builder.CreateLoad( |
5263 | | - Address(flagsPtr, IGF.IGM.Int32Ty, Alignment(4)), ""); |
5264 | | - auto *deallocDeferringAllocator = IGF.Builder.CreateAnd( |
5265 | | - flags, |
5266 | | - llvm::APInt(IGF.IGM.Int32Ty->getBitWidth(), |
5267 | | - shouldDeallocateImmediatelyFlag.getOpaqueValue())); |
5268 | | - auto *isDeallocDeferringAllocator = IGF.Builder.CreateICmpNE( |
5269 | | - deallocDeferringAllocator, |
5270 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0)); |
5271 | | - auto *deferringAllocatorBlock = |
5272 | | - IGF.createBasicBlock("deferring_allocator"); |
5273 | | - auto *normalBlock = IGF.createBasicBlock("normal"); |
5274 | | - IGF.Builder.CreateCondBr(isDeallocDeferringAllocator, |
5275 | | - deferringAllocatorBlock, normalBlock); |
5276 | | - IGF.Builder.emitBlock(deferringAllocatorBlock); |
5277 | | - // Nothing to do here. |
5278 | | - IGF.Builder.CreateRetVoid(); |
5279 | | - // Start emitting the "normal" block. |
5280 | | - IGF.Builder.emitBlock(normalBlock); |
5281 | | - auto *calleePtr = IGF.Builder.CreateInBoundsGEP( |
5282 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5283 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5284 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 2)}); |
5285 | | - auto *callee = IGF.Builder.CreateLoad( |
5286 | | - Address(calleePtr, IGF.IGM.PtrTy, IGF.IGM.getPointerAlignment()), |
5287 | | - "deallocate_fn"); |
5288 | | - auto fnPtr = FunctionPointer::createUnsigned( |
5289 | | - FunctionPointer::Kind::Function, callee, |
5290 | | - Signature(cast<llvm::FunctionType>(IGF.IGM.CoroDeallocateFnTy), {}, |
5291 | | - IGF.IGM.SwiftCC)); |
5292 | | - auto *call = IGF.Builder.CreateCall(fnPtr, {ptr}); |
5293 | | - call->setDoesNotThrow(); |
5294 | | - call->setCallingConv(IGF.IGM.SwiftCC); |
5295 | | - IGF.Builder.CreateRetVoid(); |
5296 | | - }, |
5297 | | - /*setIsNoInline=*/true, |
5298 | | - /*forPrologue=*/false, |
5299 | | - /*isPerformanceConstraint=*/false, |
5300 | | - /*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC, |
5301 | | - /*transformAttributes=*/ |
5302 | | - [&IGM](llvm::AttributeList &attrs) { |
5303 | | - IGM.addSwiftCoroAttributes(attrs, 0); |
5304 | | - }); |
5305 | | -} |
5306 | | - |
5307 | 5173 | void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF, |
5308 | 5174 | CanSILFunctionType fnType, |
5309 | 5175 | llvm::Value *buffer, |
@@ -5346,85 +5212,6 @@ Address irgen::emitAllocYieldManyCoroutineBuffer(IRGenFunction &IGF) { |
5346 | 5212 | getYieldManyCoroutineBufferAlignment(IGF.IGM)); |
5347 | 5213 | } |
5348 | 5214 |
|
5349 | | -static llvm::Constant *getAddrOfSwiftCCMalloc(IRGenModule &IGM) { |
5350 | | - auto mallocFnPtr = IGM.getMallocFunctionPointer(); |
5351 | | - auto sig = mallocFnPtr.getSignature(); |
5352 | | - if (sig.getCallingConv() == IGM.SwiftCC) { |
5353 | | - return IGM.getMallocFn(); |
5354 | | - } |
5355 | | - return IGM.getOrCreateHelperFunction( |
5356 | | - "_swift_malloc", sig.getType()->getReturnType(), sig.getType()->params(), |
5357 | | - [](IRGenFunction &IGF) { |
5358 | | - auto parameters = IGF.collectParameters(); |
5359 | | - auto *size = parameters.claimNext(); |
5360 | | - auto malloc = IGF.IGM.getMallocFunctionPointer(); |
5361 | | - auto *call = IGF.Builder.CreateCall(malloc, {size}); |
5362 | | - IGF.Builder.CreateRet(call); |
5363 | | - }); |
5364 | | -} |
5365 | | - |
5366 | | -static llvm::Constant *getAddrOfSwiftCCFree(IRGenModule &IGM) { |
5367 | | - auto freeFnPtr = IGM.getFreeFunctionPointer(); |
5368 | | - auto sig = freeFnPtr.getSignature(); |
5369 | | - if (sig.getCallingConv() == IGM.SwiftCC) { |
5370 | | - return IGM.getFreeFn(); |
5371 | | - } |
5372 | | - return IGM.getOrCreateHelperFunction( |
5373 | | - "_swift_free", sig.getType()->getReturnType(), sig.getType()->params(), |
5374 | | - [](IRGenFunction &IGF) { |
5375 | | - auto parameters = IGF.collectParameters(); |
5376 | | - auto *ptr = parameters.claimNext(); |
5377 | | - auto free = IGF.IGM.getFreeFunctionPointer(); |
5378 | | - IGF.Builder.CreateCall(free, {ptr}); |
5379 | | - IGF.Builder.CreateRetVoid(); |
5380 | | - }); |
5381 | | -} |
5382 | | - |
5383 | | -static llvm::Constant *getAddrOfGlobalCoroAllocator( |
5384 | | - IRGenModule &IGM, CoroAllocatorKind kind, bool shouldDeallocateImmediately, |
5385 | | - llvm::Constant *allocFn, llvm::Constant *deallocFn) { |
5386 | | - auto entity = LinkEntity::forCoroAllocator(kind); |
5387 | | - auto taskAllocator = IGM.getOrCreateLazyGlobalVariable( |
5388 | | - entity, |
5389 | | - [&](ConstantInitBuilder &builder) -> ConstantInitFuture { |
5390 | | - auto allocator = builder.beginStruct(IGM.CoroAllocatorTy); |
5391 | | - auto flags = CoroAllocatorFlags(kind); |
5392 | | - flags.setShouldDeallocateImmediately(shouldDeallocateImmediately); |
5393 | | - allocator.addInt32(flags.getOpaqueValue()); |
5394 | | - allocator.add(allocFn); |
5395 | | - allocator.add(deallocFn); |
5396 | | - return allocator.finishAndCreateFuture(); |
5397 | | - }, |
5398 | | - [&](llvm::GlobalVariable *var) { var->setConstant(true); }); |
5399 | | - return taskAllocator; |
5400 | | -} |
5401 | | -llvm::Constant *IRGenModule::getAddrOfGlobalCoroMallocAllocator() { |
5402 | | - return getAddrOfGlobalCoroAllocator(*this, CoroAllocatorKind::Malloc, |
5403 | | - /*shouldDeallocateImmediately=*/true, |
5404 | | - getAddrOfSwiftCCMalloc(*this), |
5405 | | - getAddrOfSwiftCCFree(*this)); |
5406 | | -} |
5407 | | -llvm::Constant *IRGenModule::getAddrOfGlobalCoroAsyncTaskAllocator() { |
5408 | | - return getAddrOfGlobalCoroAllocator(*this, CoroAllocatorKind::Async, |
5409 | | - /*shouldDeallocateImmediately=*/false, |
5410 | | - getTaskAllocFn(), getTaskDeallocFn()); |
5411 | | -} |
5412 | | -llvm::Value * |
5413 | | -irgen::emitYieldOnce2CoroutineAllocator(IRGenFunction &IGF, |
5414 | | - std::optional<CoroAllocatorKind> kind) { |
5415 | | - if (!kind) { |
5416 | | - return IGF.getCoroutineAllocator(); |
5417 | | - } |
5418 | | - switch (*kind) { |
5419 | | - case CoroAllocatorKind::Stack: |
5420 | | - return llvm::ConstantPointerNull::get(IGF.IGM.CoroAllocatorPtrTy); |
5421 | | - case CoroAllocatorKind::Async: |
5422 | | - return IGF.IGM.getAddrOfGlobalCoroAsyncTaskAllocator(); |
5423 | | - case CoroAllocatorKind::Malloc: |
5424 | | - return IGF.IGM.getAddrOfGlobalCoroMallocAllocator(); |
5425 | | - } |
5426 | | - llvm_unreachable("unhandled case"); |
5427 | | -} |
5428 | 5215 | StackAddress irgen::emitAllocYieldOnce2CoroutineFrame(IRGenFunction &IGF, |
5429 | 5216 | llvm::Value *size) { |
5430 | 5217 | return emitAllocCoroStaticFrame(IGF, size); |
|
0 commit comments