|
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" |
@@ -5131,141 +5132,6 @@ void irgen::emitYieldManyCoroutineEntry( |
5131 | 5132 | allocFn, deallocFn, {}); |
5132 | 5133 | } |
5133 | 5134 |
|
5134 | | -static llvm::Constant *getCoroAllocFn(IRGenModule &IGM) { |
5135 | | - auto isSwiftCoroCCAvailable = IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro; |
5136 | | - return IGM.getOrCreateHelperFunction( |
5137 | | - "_swift_coro_alloc", IGM.Int8PtrTy, {IGM.CoroAllocatorPtrTy, IGM.SizeTy}, |
5138 | | - [isSwiftCoroCCAvailable](IRGenFunction &IGF) { |
5139 | | - auto parameters = IGF.collectParameters(); |
5140 | | - auto *allocator = parameters.claimNext(); |
5141 | | - auto *size = parameters.claimNext(); |
5142 | | - if (isSwiftCoroCCAvailable) { |
5143 | | - // swiftcorocc is available, so if there's no allocator pointer, |
5144 | | - // allocate storage on the stack and return a pointer to it without |
5145 | | - // popping the stack. |
5146 | | - auto *nullAllocator = IGF.Builder.CreateCmp( |
5147 | | - llvm::CmpInst::Predicate::ICMP_EQ, allocator, |
5148 | | - llvm::ConstantPointerNull::get( |
5149 | | - cast<llvm::PointerType>(allocator->getType()))); |
5150 | | - auto *poplessReturn = IGF.createBasicBlock("popless"); |
5151 | | - auto *normalReturn = IGF.createBasicBlock("normal"); |
5152 | | - IGF.Builder.CreateCondBr(nullAllocator, poplessReturn, normalReturn); |
5153 | | - IGF.Builder.emitBlock(poplessReturn); |
5154 | | - // Emit the dynamic alloca. |
5155 | | - auto *alloca = |
5156 | | - IGF.Builder.IRBuilderBase::CreateAlloca(IGF.IGM.Int8Ty, size); |
5157 | | - alloca->setAlignment(llvm::Align(MaximumAlignment)); |
5158 | | - auto *retPopless = IGF.Builder.CreateIntrinsic( |
5159 | | - IGF.IGM.VoidTy, llvm::Intrinsic::ret_popless, {}); |
5160 | | - retPopless->setTailCallKind( |
5161 | | - llvm::CallInst::TailCallKind::TCK_MustTail); |
5162 | | - IGF.Builder.CreateRet(alloca); |
5163 | | - // Start emitting the "normal" block. |
5164 | | - IGF.Builder.emitBlock(normalReturn); |
5165 | | - } |
5166 | | - auto *calleePtr = IGF.Builder.CreateInBoundsGEP( |
5167 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5168 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5169 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 1)}); |
5170 | | - auto *callee = IGF.Builder.CreateLoad( |
5171 | | - Address(calleePtr, IGF.IGM.PtrTy, IGF.IGM.getPointerAlignment()), |
5172 | | - "allocate_fn"); |
5173 | | - auto fnPtr = FunctionPointer::createUnsigned( |
5174 | | - FunctionPointer::Kind::Function, callee, |
5175 | | - Signature(cast<llvm::FunctionType>(IGF.IGM.CoroAllocateFnTy), {}, |
5176 | | - IGF.IGM.SwiftCC)); |
5177 | | - auto *call = IGF.Builder.CreateCall(fnPtr, {size}); |
5178 | | - call->setDoesNotThrow(); |
5179 | | - call->setCallingConv(IGF.IGM.SwiftCC); |
5180 | | - IGF.Builder.CreateRet(call); |
5181 | | - }, |
5182 | | - /*setIsNoInline=*/true, |
5183 | | - /*forPrologue=*/false, |
5184 | | - /*isPerformanceConstraint=*/false, |
5185 | | - /*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC, |
5186 | | - /*transformAttributes=*/ |
5187 | | - [&IGM](llvm::AttributeList &attrs) { |
5188 | | - IGM.addSwiftCoroAttributes(attrs, 0); |
5189 | | - }); |
5190 | | -} |
5191 | | - |
5192 | | -static llvm::Constant *getCoroDeallocFn(IRGenModule &IGM) { |
5193 | | - auto isSwiftCoroCCAvailable = IGM.SwiftCoroCC == llvm::CallingConv::SwiftCoro; |
5194 | | - return IGM.getOrCreateHelperFunction( |
5195 | | - "_swift_coro_dealloc", IGM.VoidTy, |
5196 | | - {IGM.CoroAllocatorPtrTy, IGM.Int8PtrTy}, |
5197 | | - [isSwiftCoroCCAvailable](IRGenFunction &IGF) { |
5198 | | - auto parameters = IGF.collectParameters(); |
5199 | | - auto *allocator = parameters.claimNext(); |
5200 | | - auto *ptr = parameters.claimNext(); |
5201 | | - if (isSwiftCoroCCAvailable) { |
5202 | | - // swiftcorocc is available, so if there's no allocator pointer, |
5203 | | - // storage was allocated on the stack which will be naturally cleaned |
5204 | | - // up when the coroutine's frame is "freed". |
5205 | | - auto *nullAllocator = IGF.Builder.CreateCmp( |
5206 | | - llvm::CmpInst::Predicate::ICMP_EQ, allocator, |
5207 | | - llvm::ConstantPointerNull::get( |
5208 | | - cast<llvm::PointerType>(allocator->getType()))); |
5209 | | - auto *bailBlock = IGF.createBasicBlock("null_allocator"); |
5210 | | - auto *normalBlock = IGF.createBasicBlock("nonnull_allocator"); |
5211 | | - IGF.Builder.CreateCondBr(nullAllocator, bailBlock, normalBlock); |
5212 | | - IGF.Builder.emitBlock(bailBlock); |
5213 | | - // Nothing to do here. |
5214 | | - IGF.Builder.CreateRetVoid(); |
5215 | | - // Start emitting the "normal" block. |
5216 | | - IGF.Builder.emitBlock(normalBlock); |
5217 | | - } |
5218 | | - auto shouldDeallocateImmediatelyFlag = CoroAllocatorFlags(0); |
5219 | | - shouldDeallocateImmediatelyFlag.setShouldDeallocateImmediately(true); |
5220 | | - auto *flagsPtr = IGF.Builder.CreateInBoundsGEP( |
5221 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5222 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5223 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0)}); |
5224 | | - auto *flags = IGF.Builder.CreateLoad( |
5225 | | - Address(flagsPtr, IGF.IGM.Int32Ty, Alignment(4)), ""); |
5226 | | - auto *deallocDeferringAllocator = IGF.Builder.CreateAnd( |
5227 | | - flags, |
5228 | | - llvm::APInt(IGF.IGM.Int32Ty->getBitWidth(), |
5229 | | - shouldDeallocateImmediatelyFlag.getOpaqueValue())); |
5230 | | - auto *isDeallocDeferringAllocator = IGF.Builder.CreateICmpNE( |
5231 | | - deallocDeferringAllocator, |
5232 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0)); |
5233 | | - auto *deferringAllocatorBlock = |
5234 | | - IGF.createBasicBlock("deferring_allocator"); |
5235 | | - auto *normalBlock = IGF.createBasicBlock("normal"); |
5236 | | - IGF.Builder.CreateCondBr(isDeallocDeferringAllocator, |
5237 | | - deferringAllocatorBlock, normalBlock); |
5238 | | - IGF.Builder.emitBlock(deferringAllocatorBlock); |
5239 | | - // Nothing to do here. |
5240 | | - IGF.Builder.CreateRetVoid(); |
5241 | | - // Start emitting the "normal" block. |
5242 | | - IGF.Builder.emitBlock(normalBlock); |
5243 | | - auto *calleePtr = IGF.Builder.CreateInBoundsGEP( |
5244 | | - IGF.IGM.CoroAllocatorTy, allocator, |
5245 | | - {llvm::ConstantInt::get(IGF.IGM.Int32Ty, 0), |
5246 | | - llvm::ConstantInt::get(IGF.IGM.Int32Ty, 2)}); |
5247 | | - auto *callee = IGF.Builder.CreateLoad( |
5248 | | - Address(calleePtr, IGF.IGM.PtrTy, IGF.IGM.getPointerAlignment()), |
5249 | | - "deallocate_fn"); |
5250 | | - auto fnPtr = FunctionPointer::createUnsigned( |
5251 | | - FunctionPointer::Kind::Function, callee, |
5252 | | - Signature(cast<llvm::FunctionType>(IGF.IGM.CoroDeallocateFnTy), {}, |
5253 | | - IGF.IGM.SwiftCC)); |
5254 | | - auto *call = IGF.Builder.CreateCall(fnPtr, {ptr}); |
5255 | | - call->setDoesNotThrow(); |
5256 | | - call->setCallingConv(IGF.IGM.SwiftCC); |
5257 | | - IGF.Builder.CreateRetVoid(); |
5258 | | - }, |
5259 | | - /*setIsNoInline=*/true, |
5260 | | - /*forPrologue=*/false, |
5261 | | - /*isPerformanceConstraint=*/false, |
5262 | | - /*optionalLinkageOverride=*/nullptr, IGM.SwiftCoroCC, |
5263 | | - /*transformAttributes=*/ |
5264 | | - [&IGM](llvm::AttributeList &attrs) { |
5265 | | - IGM.addSwiftCoroAttributes(attrs, 0); |
5266 | | - }); |
5267 | | -} |
5268 | | - |
5269 | 5135 | void irgen::emitYieldOnce2CoroutineEntry(IRGenFunction &IGF, |
5270 | 5136 | CanSILFunctionType fnType, |
5271 | 5137 | llvm::Value *buffer, |
|
0 commit comments