@@ -181,6 +181,9 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF,
181181 llvm::Value *localContextInfo,
182182 llvm::Value *localResultBuffer,
183183 SubstitutionMap subs) {
184+ localContextInfo = IGF.Builder .CreateBitCast (localContextInfo,
185+ IGF.IGM .OpaquePtrTy );
186+
184187 // stack allocate AsyncLet, and begin lifetime for it (until EndAsyncLet)
185188 auto ty = llvm::ArrayType::get (IGF.IGM .Int8PtrTy , NumWords_AsyncLet);
186189 auto address = IGF.createAlloca (ty, Alignment (Alignment_AsyncLet));
@@ -204,31 +207,35 @@ llvm::Value *irgen::emitBuiltinStartAsyncLet(IRGenFunction &IGF,
204207 auto deploymentAvailability
205208 = AvailabilityContext::forDeploymentTarget (IGF.IGM .Context );
206209 if (!deploymentAvailability.isContainedIn (
207- IGF.IGM .Context .getSwift57Availability ())) {
210+ IGF.IGM .Context .getSwift57Availability ()))
211+ {
208212 auto taskAsyncFunctionPointer
209213 = cast<llvm::GlobalVariable>(taskFunction->stripPointerCasts ());
210214
211- auto taskAsyncIDIter = IGF.IGM .AsyncCoroIDs .find (taskAsyncFunctionPointer);
212- assert (taskAsyncIDIter != IGF.IGM .AsyncCoroIDs .end ()
213- && " async let entry point not emitted locally" );
214- auto taskAsyncID = taskAsyncIDIter->second ;
215-
216- // Pad out the initial context size in the async function pointer record
217- // and ID intrinsic so that it will never fit in the preallocated space.
218- uint64_t origSize = cast<llvm::ConstantInt>(taskAsyncID->getArgOperand (0 ))
219- ->getValue ().getLimitedValue ();
220-
221- uint64_t paddedSize = std::max (origSize,
215+ if (auto taskAsyncID
216+ = IGF.IGM .getAsyncCoroIDMapping (taskAsyncFunctionPointer)) {
217+ // If the entry point function has already been emitted, retroactively
218+ // pad out the initial context size in the async function pointer record
219+ // and ID intrinsic so that it will never fit in the preallocated space.
220+ uint64_t origSize = cast<llvm::ConstantInt>(taskAsyncID->getArgOperand (0 ))
221+ ->getValue ().getLimitedValue ();
222+
223+ uint64_t paddedSize = std::max (origSize,
222224 (NumWords_AsyncLet * IGF.IGM .getPointerSize ()).getValue ());
223- auto paddedSizeVal = llvm::ConstantInt::get (IGF.IGM .Int32Ty , paddedSize);
224- taskAsyncID->setArgOperand (0 , paddedSizeVal);
225-
226- auto origInit = taskAsyncFunctionPointer->getInitializer ();
227- auto newInit = llvm::ConstantStruct::get (
225+ auto paddedSizeVal = llvm::ConstantInt::get (IGF.IGM .Int32Ty , paddedSize);
226+ taskAsyncID->setArgOperand (0 , paddedSizeVal);
227+
228+ auto origInit = taskAsyncFunctionPointer->getInitializer ();
229+ auto newInit = llvm::ConstantStruct::get (
228230 cast<llvm::StructType>(origInit->getType ()),
229231 origInit->getAggregateElement (0u ),
230232 paddedSizeVal);
231- taskAsyncFunctionPointer->setInitializer (newInit);
233+ taskAsyncFunctionPointer->setInitializer (newInit);
234+ } else {
235+ // If it hasn't been emitted yet, mark it to get the padding when it does
236+ // get emitted.
237+ IGF.IGM .markAsyncFunctionPointerForPadding (taskAsyncFunctionPointer);
238+ }
232239 }
233240
234241 llvm::CallInst *call;
0 commit comments