1 //===- CoroSplit.cpp - Converts a coroutine into a state machine ----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // This pass builds the coroutine frame and outlines resume and destroy parts 9 // of the coroutine into separate functions. 10 // 11 // We present a coroutine to an LLVM as an ordinary function with suspension 12 // points marked up with intrinsics. We let the optimizer party on the coroutine 13 // as a single function for as long as possible. Shortly before the coroutine is 14 // eligible to be inlined into its callers, we split up the coroutine into parts 15 // corresponding to an initial, resume and destroy invocations of the coroutine, 16 // add them to the current SCC and restart the IPO pipeline to optimize the 17 // coroutine subfunctions we extracted before proceeding to the caller of the 18 // coroutine. 19 //===----------------------------------------------------------------------===// 20 21 #include "llvm/Transforms/Coroutines/CoroSplit.h" 22 #include "CoroInstr.h" 23 #include "CoroInternal.h" 24 #include "llvm/ADT/DenseMap.h" 25 #include "llvm/ADT/SmallPtrSet.h" 26 #include "llvm/ADT/SmallVector.h" 27 #include "llvm/ADT/StringRef.h" 28 #include "llvm/ADT/Twine.h" 29 #include "llvm/Analysis/CallGraph.h" 30 #include "llvm/Analysis/CallGraphSCCPass.h" 31 #include "llvm/IR/Argument.h" 32 #include "llvm/IR/Attributes.h" 33 #include "llvm/IR/BasicBlock.h" 34 #include "llvm/IR/CFG.h" 35 #include "llvm/IR/CallingConv.h" 36 #include "llvm/IR/Constants.h" 37 #include "llvm/IR/DataLayout.h" 38 #include "llvm/IR/DerivedTypes.h" 39 #include "llvm/IR/Function.h" 40 #include "llvm/IR/GlobalValue.h" 41 #include "llvm/IR/GlobalVariable.h" 42 #include "llvm/IR/IRBuilder.h" 43 #include "llvm/IR/InstIterator.h" 44 #include "llvm/IR/InstrTypes.h" 45 #include "llvm/IR/Instruction.h" 46 #include "llvm/IR/Instructions.h" 47 #include "llvm/IR/IntrinsicInst.h" 48 #include "llvm/IR/LLVMContext.h" 49 #include "llvm/IR/LegacyPassManager.h" 50 #include "llvm/IR/Module.h" 51 #include "llvm/IR/Type.h" 52 #include "llvm/IR/Value.h" 53 #include "llvm/IR/Verifier.h" 54 #include "llvm/InitializePasses.h" 55 #include "llvm/Pass.h" 56 #include "llvm/Support/Casting.h" 57 #include "llvm/Support/Debug.h" 58 #include "llvm/Support/PrettyStackTrace.h" 59 #include "llvm/Support/raw_ostream.h" 60 #include "llvm/Transforms/Scalar.h" 61 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 62 #include "llvm/Transforms/Utils/CallGraphUpdater.h" 63 #include "llvm/Transforms/Utils/Cloning.h" 64 #include "llvm/Transforms/Utils/Local.h" 65 #include "llvm/Transforms/Utils/ValueMapper.h" 66 #include <cassert> 67 #include <cstddef> 68 #include <cstdint> 69 #include <initializer_list> 70 #include <iterator> 71 72 using namespace llvm; 73 74 #define DEBUG_TYPE "coro-split" 75 76 namespace { 77 78 /// A little helper class for building 79 class CoroCloner { 80 public: 81 enum class Kind { 82 /// The shared resume function for a switch lowering. 83 SwitchResume, 84 85 /// The shared unwind function for a switch lowering. 86 SwitchUnwind, 87 88 /// The shared cleanup function for a switch lowering. 89 SwitchCleanup, 90 91 /// An individual continuation function. 92 Continuation, 93 94 /// An async resume function. 95 Async, 96 }; 97 98 private: 99 Function &OrigF; 100 Function *NewF; 101 const Twine &Suffix; 102 coro::Shape &Shape; 103 Kind FKind; 104 ValueToValueMapTy VMap; 105 IRBuilder<> Builder; 106 Value *NewFramePtr = nullptr; 107 108 /// The active suspend instruction; meaningful only for continuation and async 109 /// ABIs. 110 AnyCoroSuspendInst *ActiveSuspend = nullptr; 111 112 public: 113 /// Create a cloner for a switch lowering. 114 CoroCloner(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, 115 Kind FKind) 116 : OrigF(OrigF), NewF(nullptr), Suffix(Suffix), Shape(Shape), 117 FKind(FKind), Builder(OrigF.getContext()) { 118 assert(Shape.ABI == coro::ABI::Switch); 119 } 120 121 /// Create a cloner for a continuation lowering. 122 CoroCloner(Function &OrigF, const Twine &Suffix, coro::Shape &Shape, 123 Function *NewF, AnyCoroSuspendInst *ActiveSuspend) 124 : OrigF(OrigF), NewF(NewF), Suffix(Suffix), Shape(Shape), 125 FKind(Shape.ABI == coro::ABI::Async ? Kind::Async : Kind::Continuation), 126 Builder(OrigF.getContext()), ActiveSuspend(ActiveSuspend) { 127 assert(Shape.ABI == coro::ABI::Retcon || 128 Shape.ABI == coro::ABI::RetconOnce || Shape.ABI == coro::ABI::Async); 129 assert(NewF && "need existing function for continuation"); 130 assert(ActiveSuspend && "need active suspend point for continuation"); 131 } 132 133 Function *getFunction() const { 134 assert(NewF != nullptr && "declaration not yet set"); 135 return NewF; 136 } 137 138 void create(); 139 140 private: 141 bool isSwitchDestroyFunction() { 142 switch (FKind) { 143 case Kind::Async: 144 case Kind::Continuation: 145 case Kind::SwitchResume: 146 return false; 147 case Kind::SwitchUnwind: 148 case Kind::SwitchCleanup: 149 return true; 150 } 151 llvm_unreachable("Unknown CoroCloner::Kind enum"); 152 } 153 154 void replaceEntryBlock(); 155 Value *deriveNewFramePointer(); 156 void replaceRetconOrAsyncSuspendUses(); 157 void replaceCoroSuspends(); 158 void replaceCoroEnds(); 159 void replaceSwiftErrorOps(); 160 void handleFinalSuspend(); 161 }; 162 163 } // end anonymous namespace 164 165 static void maybeFreeRetconStorage(IRBuilder<> &Builder, 166 const coro::Shape &Shape, Value *FramePtr, 167 CallGraph *CG) { 168 assert(Shape.ABI == coro::ABI::Retcon || 169 Shape.ABI == coro::ABI::RetconOnce); 170 if (Shape.RetconLowering.IsFrameInlineInStorage) 171 return; 172 173 Shape.emitDealloc(Builder, FramePtr, CG); 174 } 175 176 /// Replace a non-unwind call to llvm.coro.end. 177 static void replaceFallthroughCoroEnd(CoroEndInst *End, 178 const coro::Shape &Shape, Value *FramePtr, 179 bool InResume, CallGraph *CG) { 180 // Start inserting right before the coro.end. 181 IRBuilder<> Builder(End); 182 183 // Create the return instruction. 184 switch (Shape.ABI) { 185 // The cloned functions in switch-lowering always return void. 186 case coro::ABI::Switch: 187 // coro.end doesn't immediately end the coroutine in the main function 188 // in this lowering, because we need to deallocate the coroutine. 189 if (!InResume) 190 return; 191 Builder.CreateRetVoid(); 192 break; 193 194 // In async lowering this returns. 195 case coro::ABI::Async: 196 Builder.CreateRetVoid(); 197 break; 198 199 // In unique continuation lowering, the continuations always return void. 200 // But we may have implicitly allocated storage. 201 case coro::ABI::RetconOnce: 202 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG); 203 Builder.CreateRetVoid(); 204 break; 205 206 // In non-unique continuation lowering, we signal completion by returning 207 // a null continuation. 208 case coro::ABI::Retcon: { 209 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG); 210 auto RetTy = Shape.getResumeFunctionType()->getReturnType(); 211 auto RetStructTy = dyn_cast<StructType>(RetTy); 212 PointerType *ContinuationTy = 213 cast<PointerType>(RetStructTy ? RetStructTy->getElementType(0) : RetTy); 214 215 Value *ReturnValue = ConstantPointerNull::get(ContinuationTy); 216 if (RetStructTy) { 217 ReturnValue = Builder.CreateInsertValue(UndefValue::get(RetStructTy), 218 ReturnValue, 0); 219 } 220 Builder.CreateRet(ReturnValue); 221 break; 222 } 223 } 224 225 // Remove the rest of the block, by splitting it into an unreachable block. 226 auto *BB = End->getParent(); 227 BB->splitBasicBlock(End); 228 BB->getTerminator()->eraseFromParent(); 229 } 230 231 /// Replace an unwind call to llvm.coro.end. 232 static void replaceUnwindCoroEnd(CoroEndInst *End, const coro::Shape &Shape, 233 Value *FramePtr, bool InResume, CallGraph *CG){ 234 IRBuilder<> Builder(End); 235 236 switch (Shape.ABI) { 237 // In switch-lowering, this does nothing in the main function. 238 case coro::ABI::Switch: 239 if (!InResume) 240 return; 241 break; 242 // In async lowering this does nothing. 243 case coro::ABI::Async: 244 break; 245 // In continuation-lowering, this frees the continuation storage. 246 case coro::ABI::Retcon: 247 case coro::ABI::RetconOnce: 248 maybeFreeRetconStorage(Builder, Shape, FramePtr, CG); 249 break; 250 } 251 252 // If coro.end has an associated bundle, add cleanupret instruction. 253 if (auto Bundle = End->getOperandBundle(LLVMContext::OB_funclet)) { 254 auto *FromPad = cast<CleanupPadInst>(Bundle->Inputs[0]); 255 auto *CleanupRet = Builder.CreateCleanupRet(FromPad, nullptr); 256 End->getParent()->splitBasicBlock(End); 257 CleanupRet->getParent()->getTerminator()->eraseFromParent(); 258 } 259 } 260 261 static void replaceCoroEnd(CoroEndInst *End, const coro::Shape &Shape, 262 Value *FramePtr, bool InResume, CallGraph *CG) { 263 if (End->isUnwind()) 264 replaceUnwindCoroEnd(End, Shape, FramePtr, InResume, CG); 265 else 266 replaceFallthroughCoroEnd(End, Shape, FramePtr, InResume, CG); 267 268 auto &Context = End->getContext(); 269 End->replaceAllUsesWith(InResume ? ConstantInt::getTrue(Context) 270 : ConstantInt::getFalse(Context)); 271 End->eraseFromParent(); 272 } 273 274 // Create an entry block for a resume function with a switch that will jump to 275 // suspend points. 276 static void createResumeEntryBlock(Function &F, coro::Shape &Shape) { 277 assert(Shape.ABI == coro::ABI::Switch); 278 LLVMContext &C = F.getContext(); 279 280 // resume.entry: 281 // %index.addr = getelementptr inbounds %f.Frame, %f.Frame* %FramePtr, i32 0, 282 // i32 2 283 // % index = load i32, i32* %index.addr 284 // switch i32 %index, label %unreachable [ 285 // i32 0, label %resume.0 286 // i32 1, label %resume.1 287 // ... 288 // ] 289 290 auto *NewEntry = BasicBlock::Create(C, "resume.entry", &F); 291 auto *UnreachBB = BasicBlock::Create(C, "unreachable", &F); 292 293 IRBuilder<> Builder(NewEntry); 294 auto *FramePtr = Shape.FramePtr; 295 auto *FrameTy = Shape.FrameTy; 296 auto *GepIndex = Builder.CreateStructGEP( 297 FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr"); 298 auto *Index = Builder.CreateLoad(Shape.getIndexType(), GepIndex, "index"); 299 auto *Switch = 300 Builder.CreateSwitch(Index, UnreachBB, Shape.CoroSuspends.size()); 301 Shape.SwitchLowering.ResumeSwitch = Switch; 302 303 size_t SuspendIndex = 0; 304 for (auto *AnyS : Shape.CoroSuspends) { 305 auto *S = cast<CoroSuspendInst>(AnyS); 306 ConstantInt *IndexVal = Shape.getIndex(SuspendIndex); 307 308 // Replace CoroSave with a store to Index: 309 // %index.addr = getelementptr %f.frame... (index field number) 310 // store i32 0, i32* %index.addr1 311 auto *Save = S->getCoroSave(); 312 Builder.SetInsertPoint(Save); 313 if (S->isFinal()) { 314 // Final suspend point is represented by storing zero in ResumeFnAddr. 315 auto *GepIndex = Builder.CreateStructGEP(FrameTy, FramePtr, 316 coro::Shape::SwitchFieldIndex::Resume, 317 "ResumeFn.addr"); 318 auto *NullPtr = ConstantPointerNull::get(cast<PointerType>( 319 cast<PointerType>(GepIndex->getType())->getElementType())); 320 Builder.CreateStore(NullPtr, GepIndex); 321 } else { 322 auto *GepIndex = Builder.CreateStructGEP( 323 FrameTy, FramePtr, Shape.getSwitchIndexField(), "index.addr"); 324 Builder.CreateStore(IndexVal, GepIndex); 325 } 326 Save->replaceAllUsesWith(ConstantTokenNone::get(C)); 327 Save->eraseFromParent(); 328 329 // Split block before and after coro.suspend and add a jump from an entry 330 // switch: 331 // 332 // whateverBB: 333 // whatever 334 // %0 = call i8 @llvm.coro.suspend(token none, i1 false) 335 // switch i8 %0, label %suspend[i8 0, label %resume 336 // i8 1, label %cleanup] 337 // becomes: 338 // 339 // whateverBB: 340 // whatever 341 // br label %resume.0.landing 342 // 343 // resume.0: ; <--- jump from the switch in the resume.entry 344 // %0 = tail call i8 @llvm.coro.suspend(token none, i1 false) 345 // br label %resume.0.landing 346 // 347 // resume.0.landing: 348 // %1 = phi i8[-1, %whateverBB], [%0, %resume.0] 349 // switch i8 % 1, label %suspend [i8 0, label %resume 350 // i8 1, label %cleanup] 351 352 auto *SuspendBB = S->getParent(); 353 auto *ResumeBB = 354 SuspendBB->splitBasicBlock(S, "resume." + Twine(SuspendIndex)); 355 auto *LandingBB = ResumeBB->splitBasicBlock( 356 S->getNextNode(), ResumeBB->getName() + Twine(".landing")); 357 Switch->addCase(IndexVal, ResumeBB); 358 359 cast<BranchInst>(SuspendBB->getTerminator())->setSuccessor(0, LandingBB); 360 auto *PN = PHINode::Create(Builder.getInt8Ty(), 2, "", &LandingBB->front()); 361 S->replaceAllUsesWith(PN); 362 PN->addIncoming(Builder.getInt8(-1), SuspendBB); 363 PN->addIncoming(S, ResumeBB); 364 365 ++SuspendIndex; 366 } 367 368 Builder.SetInsertPoint(UnreachBB); 369 Builder.CreateUnreachable(); 370 371 Shape.SwitchLowering.ResumeEntryBlock = NewEntry; 372 } 373 374 375 // Rewrite final suspend point handling. We do not use suspend index to 376 // represent the final suspend point. Instead we zero-out ResumeFnAddr in the 377 // coroutine frame, since it is undefined behavior to resume a coroutine 378 // suspended at the final suspend point. Thus, in the resume function, we can 379 // simply remove the last case (when coro::Shape is built, the final suspend 380 // point (if present) is always the last element of CoroSuspends array). 381 // In the destroy function, we add a code sequence to check if ResumeFnAddress 382 // is Null, and if so, jump to the appropriate label to handle cleanup from the 383 // final suspend point. 384 void CoroCloner::handleFinalSuspend() { 385 assert(Shape.ABI == coro::ABI::Switch && 386 Shape.SwitchLowering.HasFinalSuspend); 387 auto *Switch = cast<SwitchInst>(VMap[Shape.SwitchLowering.ResumeSwitch]); 388 auto FinalCaseIt = std::prev(Switch->case_end()); 389 BasicBlock *ResumeBB = FinalCaseIt->getCaseSuccessor(); 390 Switch->removeCase(FinalCaseIt); 391 if (isSwitchDestroyFunction()) { 392 BasicBlock *OldSwitchBB = Switch->getParent(); 393 auto *NewSwitchBB = OldSwitchBB->splitBasicBlock(Switch, "Switch"); 394 Builder.SetInsertPoint(OldSwitchBB->getTerminator()); 395 auto *GepIndex = Builder.CreateStructGEP(Shape.FrameTy, NewFramePtr, 396 coro::Shape::SwitchFieldIndex::Resume, 397 "ResumeFn.addr"); 398 auto *Load = Builder.CreateLoad(Shape.getSwitchResumePointerType(), 399 GepIndex); 400 auto *Cond = Builder.CreateIsNull(Load); 401 Builder.CreateCondBr(Cond, ResumeBB, NewSwitchBB); 402 OldSwitchBB->getTerminator()->eraseFromParent(); 403 } 404 } 405 406 static Function *createCloneDeclaration(Function &OrigF, coro::Shape &Shape, 407 const Twine &Suffix, 408 Module::iterator InsertBefore) { 409 Module *M = OrigF.getParent(); 410 auto *FnTy = Shape.getResumeFunctionType(); 411 412 Function *NewF = 413 Function::Create(FnTy, GlobalValue::LinkageTypes::InternalLinkage, 414 OrigF.getName() + Suffix); 415 NewF->addParamAttr(0, Attribute::NonNull); 416 417 // For the async lowering ABI we can't guarantee that the context argument is 418 // not access via a different pointer not based on the argument. 419 if (Shape.ABI != coro::ABI::Async) 420 NewF->addParamAttr(0, Attribute::NoAlias); 421 422 M->getFunctionList().insert(InsertBefore, NewF); 423 424 return NewF; 425 } 426 427 /// Replace uses of the active llvm.coro.suspend.retcon/async call with the 428 /// arguments to the continuation function. 429 /// 430 /// This assumes that the builder has a meaningful insertion point. 431 void CoroCloner::replaceRetconOrAsyncSuspendUses() { 432 assert(Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce || 433 Shape.ABI == coro::ABI::Async); 434 435 auto NewS = VMap[ActiveSuspend]; 436 if (NewS->use_empty()) return; 437 438 // Copy out all the continuation arguments after the buffer pointer into 439 // an easily-indexed data structure for convenience. 440 SmallVector<Value*, 8> Args; 441 // The async ABI includes all arguments -- including the first argument. 442 bool IsAsyncABI = Shape.ABI == coro::ABI::Async; 443 for (auto I = IsAsyncABI ? NewF->arg_begin() : std::next(NewF->arg_begin()), 444 E = NewF->arg_end(); 445 I != E; ++I) 446 Args.push_back(&*I); 447 448 // If the suspend returns a single scalar value, we can just do a simple 449 // replacement. 450 if (!isa<StructType>(NewS->getType())) { 451 assert(Args.size() == 1); 452 NewS->replaceAllUsesWith(Args.front()); 453 return; 454 } 455 456 // Try to peephole extracts of an aggregate return. 457 for (auto UI = NewS->use_begin(), UE = NewS->use_end(); UI != UE; ) { 458 auto EVI = dyn_cast<ExtractValueInst>((UI++)->getUser()); 459 if (!EVI || EVI->getNumIndices() != 1) 460 continue; 461 462 EVI->replaceAllUsesWith(Args[EVI->getIndices().front()]); 463 EVI->eraseFromParent(); 464 } 465 466 // If we have no remaining uses, we're done. 467 if (NewS->use_empty()) return; 468 469 // Otherwise, we need to create an aggregate. 470 Value *Agg = UndefValue::get(NewS->getType()); 471 for (size_t I = 0, E = Args.size(); I != E; ++I) 472 Agg = Builder.CreateInsertValue(Agg, Args[I], I); 473 474 NewS->replaceAllUsesWith(Agg); 475 } 476 477 void CoroCloner::replaceCoroSuspends() { 478 Value *SuspendResult; 479 480 switch (Shape.ABI) { 481 // In switch lowering, replace coro.suspend with the appropriate value 482 // for the type of function we're extracting. 483 // Replacing coro.suspend with (0) will result in control flow proceeding to 484 // a resume label associated with a suspend point, replacing it with (1) will 485 // result in control flow proceeding to a cleanup label associated with this 486 // suspend point. 487 case coro::ABI::Switch: 488 SuspendResult = Builder.getInt8(isSwitchDestroyFunction() ? 1 : 0); 489 break; 490 491 // In async lowering there are no uses of the result. 492 case coro::ABI::Async: 493 return; 494 495 // In returned-continuation lowering, the arguments from earlier 496 // continuations are theoretically arbitrary, and they should have been 497 // spilled. 498 case coro::ABI::RetconOnce: 499 case coro::ABI::Retcon: 500 return; 501 } 502 503 for (AnyCoroSuspendInst *CS : Shape.CoroSuspends) { 504 // The active suspend was handled earlier. 505 if (CS == ActiveSuspend) continue; 506 507 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[CS]); 508 MappedCS->replaceAllUsesWith(SuspendResult); 509 MappedCS->eraseFromParent(); 510 } 511 } 512 513 void CoroCloner::replaceCoroEnds() { 514 for (CoroEndInst *CE : Shape.CoroEnds) { 515 // We use a null call graph because there's no call graph node for 516 // the cloned function yet. We'll just be rebuilding that later. 517 auto NewCE = cast<CoroEndInst>(VMap[CE]); 518 replaceCoroEnd(NewCE, Shape, NewFramePtr, /*in resume*/ true, nullptr); 519 } 520 } 521 522 static void replaceSwiftErrorOps(Function &F, coro::Shape &Shape, 523 ValueToValueMapTy *VMap) { 524 Value *CachedSlot = nullptr; 525 auto getSwiftErrorSlot = [&](Type *ValueTy) -> Value * { 526 if (CachedSlot) { 527 assert(CachedSlot->getType()->getPointerElementType() == ValueTy && 528 "multiple swifterror slots in function with different types"); 529 return CachedSlot; 530 } 531 532 // Check if the function has a swifterror argument. 533 for (auto &Arg : F.args()) { 534 if (Arg.isSwiftError()) { 535 CachedSlot = &Arg; 536 assert(Arg.getType()->getPointerElementType() == ValueTy && 537 "swifterror argument does not have expected type"); 538 return &Arg; 539 } 540 } 541 542 // Create a swifterror alloca. 543 IRBuilder<> Builder(F.getEntryBlock().getFirstNonPHIOrDbg()); 544 auto Alloca = Builder.CreateAlloca(ValueTy); 545 Alloca->setSwiftError(true); 546 547 CachedSlot = Alloca; 548 return Alloca; 549 }; 550 551 for (CallInst *Op : Shape.SwiftErrorOps) { 552 auto MappedOp = VMap ? cast<CallInst>((*VMap)[Op]) : Op; 553 IRBuilder<> Builder(MappedOp); 554 555 // If there are no arguments, this is a 'get' operation. 556 Value *MappedResult; 557 if (Op->getNumArgOperands() == 0) { 558 auto ValueTy = Op->getType(); 559 auto Slot = getSwiftErrorSlot(ValueTy); 560 MappedResult = Builder.CreateLoad(ValueTy, Slot); 561 } else { 562 assert(Op->getNumArgOperands() == 1); 563 auto Value = MappedOp->getArgOperand(0); 564 auto ValueTy = Value->getType(); 565 auto Slot = getSwiftErrorSlot(ValueTy); 566 Builder.CreateStore(Value, Slot); 567 MappedResult = Slot; 568 } 569 570 MappedOp->replaceAllUsesWith(MappedResult); 571 MappedOp->eraseFromParent(); 572 } 573 574 // If we're updating the original function, we've invalidated SwiftErrorOps. 575 if (VMap == nullptr) { 576 Shape.SwiftErrorOps.clear(); 577 } 578 } 579 580 void CoroCloner::replaceSwiftErrorOps() { 581 ::replaceSwiftErrorOps(*NewF, Shape, &VMap); 582 } 583 584 void CoroCloner::replaceEntryBlock() { 585 // In the original function, the AllocaSpillBlock is a block immediately 586 // following the allocation of the frame object which defines GEPs for 587 // all the allocas that have been moved into the frame, and it ends by 588 // branching to the original beginning of the coroutine. Make this 589 // the entry block of the cloned function. 590 auto *Entry = cast<BasicBlock>(VMap[Shape.AllocaSpillBlock]); 591 auto *OldEntry = &NewF->getEntryBlock(); 592 Entry->setName("entry" + Suffix); 593 Entry->moveBefore(OldEntry); 594 Entry->getTerminator()->eraseFromParent(); 595 596 // Clear all predecessors of the new entry block. There should be 597 // exactly one predecessor, which we created when splitting out 598 // AllocaSpillBlock to begin with. 599 assert(Entry->hasOneUse()); 600 auto BranchToEntry = cast<BranchInst>(Entry->user_back()); 601 assert(BranchToEntry->isUnconditional()); 602 Builder.SetInsertPoint(BranchToEntry); 603 Builder.CreateUnreachable(); 604 BranchToEntry->eraseFromParent(); 605 606 // Branch from the entry to the appropriate place. 607 Builder.SetInsertPoint(Entry); 608 switch (Shape.ABI) { 609 case coro::ABI::Switch: { 610 // In switch-lowering, we built a resume-entry block in the original 611 // function. Make the entry block branch to this. 612 auto *SwitchBB = 613 cast<BasicBlock>(VMap[Shape.SwitchLowering.ResumeEntryBlock]); 614 Builder.CreateBr(SwitchBB); 615 break; 616 } 617 case coro::ABI::Async: 618 case coro::ABI::Retcon: 619 case coro::ABI::RetconOnce: { 620 // In continuation ABIs, we want to branch to immediately after the 621 // active suspend point. Earlier phases will have put the suspend in its 622 // own basic block, so just thread our jump directly to its successor. 623 assert((Shape.ABI == coro::ABI::Async && 624 isa<CoroSuspendAsyncInst>(ActiveSuspend)) || 625 ((Shape.ABI == coro::ABI::Retcon || 626 Shape.ABI == coro::ABI::RetconOnce) && 627 isa<CoroSuspendRetconInst>(ActiveSuspend))); 628 auto *MappedCS = cast<AnyCoroSuspendInst>(VMap[ActiveSuspend]); 629 auto Branch = cast<BranchInst>(MappedCS->getNextNode()); 630 assert(Branch->isUnconditional()); 631 Builder.CreateBr(Branch->getSuccessor(0)); 632 break; 633 } 634 } 635 636 // Any alloca that's still being used but not reachable from the new entry 637 // needs to be moved to the new entry. 638 Function *F = OldEntry->getParent(); 639 DominatorTree DT{*F}; 640 for (auto IT = inst_begin(F), End = inst_end(F); IT != End;) { 641 Instruction &I = *IT++; 642 if (!isa<AllocaInst>(&I) || I.use_empty()) 643 continue; 644 if (DT.isReachableFromEntry(I.getParent())) 645 continue; 646 I.moveBefore(*Entry, Entry->getFirstInsertionPt()); 647 } 648 } 649 650 /// Derive the value of the new frame pointer. 651 Value *CoroCloner::deriveNewFramePointer() { 652 // Builder should be inserting to the front of the new entry block. 653 654 switch (Shape.ABI) { 655 // In switch-lowering, the argument is the frame pointer. 656 case coro::ABI::Switch: 657 return &*NewF->arg_begin(); 658 // In async-lowering, one of the arguments is an async context as determined 659 // by the `llvm.coro.id.async` intrinsic. We can retrieve the async context of 660 // the resume function from the async context projection function associated 661 // with the active suspend. The frame is located as a tail to the async 662 // context header. 663 case coro::ABI::Async: { 664 auto *CalleeContext = NewF->getArg(Shape.AsyncLowering.ContextArgNo); 665 auto *FramePtrTy = Shape.FrameTy->getPointerTo(); 666 auto *ProjectionFunc = cast<CoroSuspendAsyncInst>(ActiveSuspend) 667 ->getAsyncContextProjectionFunction(); 668 auto DbgLoc = 669 cast<CoroSuspendAsyncInst>(VMap[ActiveSuspend])->getDebugLoc(); 670 // Calling i8* (i8*) 671 auto *CallerContext = Builder.CreateCall( 672 cast<FunctionType>(ProjectionFunc->getType()->getPointerElementType()), 673 ProjectionFunc, CalleeContext); 674 CallerContext->setCallingConv(ProjectionFunc->getCallingConv()); 675 CallerContext->setDebugLoc(DbgLoc); 676 // The frame is located after the async_context header. 677 auto &Context = Builder.getContext(); 678 auto *FramePtrAddr = Builder.CreateConstInBoundsGEP1_32( 679 Type::getInt8Ty(Context), CallerContext, 680 Shape.AsyncLowering.FrameOffset, "async.ctx.frameptr"); 681 // Inline the projection function. 682 InlineFunctionInfo InlineInfo; 683 auto InlineRes = InlineFunction(*CallerContext, InlineInfo); 684 assert(InlineRes.isSuccess()); 685 (void)InlineRes; 686 return Builder.CreateBitCast(FramePtrAddr, FramePtrTy); 687 } 688 // In continuation-lowering, the argument is the opaque storage. 689 case coro::ABI::Retcon: 690 case coro::ABI::RetconOnce: { 691 Argument *NewStorage = &*NewF->arg_begin(); 692 auto FramePtrTy = Shape.FrameTy->getPointerTo(); 693 694 // If the storage is inline, just bitcast to the storage to the frame type. 695 if (Shape.RetconLowering.IsFrameInlineInStorage) 696 return Builder.CreateBitCast(NewStorage, FramePtrTy); 697 698 // Otherwise, load the real frame from the opaque storage. 699 auto FramePtrPtr = 700 Builder.CreateBitCast(NewStorage, FramePtrTy->getPointerTo()); 701 return Builder.CreateLoad(FramePtrTy, FramePtrPtr); 702 } 703 } 704 llvm_unreachable("bad ABI"); 705 } 706 707 static void addFramePointerAttrs(AttributeList &Attrs, LLVMContext &Context, 708 unsigned ParamIndex, 709 uint64_t Size, Align Alignment) { 710 AttrBuilder ParamAttrs; 711 ParamAttrs.addAttribute(Attribute::NonNull); 712 ParamAttrs.addAttribute(Attribute::NoAlias); 713 ParamAttrs.addAlignmentAttr(Alignment); 714 ParamAttrs.addDereferenceableAttr(Size); 715 Attrs = Attrs.addParamAttributes(Context, ParamIndex, ParamAttrs); 716 } 717 718 /// Clone the body of the original function into a resume function of 719 /// some sort. 720 void CoroCloner::create() { 721 // Create the new function if we don't already have one. 722 if (!NewF) { 723 NewF = createCloneDeclaration(OrigF, Shape, Suffix, 724 OrigF.getParent()->end()); 725 } 726 727 // Replace all args with undefs. The buildCoroutineFrame algorithm already 728 // rewritten access to the args that occurs after suspend points with loads 729 // and stores to/from the coroutine frame. 730 for (Argument &A : OrigF.args()) 731 VMap[&A] = UndefValue::get(A.getType()); 732 733 SmallVector<ReturnInst *, 4> Returns; 734 735 // Ignore attempts to change certain attributes of the function. 736 // TODO: maybe there should be a way to suppress this during cloning? 737 auto savedVisibility = NewF->getVisibility(); 738 auto savedUnnamedAddr = NewF->getUnnamedAddr(); 739 auto savedDLLStorageClass = NewF->getDLLStorageClass(); 740 741 // NewF's linkage (which CloneFunctionInto does *not* change) might not 742 // be compatible with the visibility of OrigF (which it *does* change), 743 // so protect against that. 744 auto savedLinkage = NewF->getLinkage(); 745 NewF->setLinkage(llvm::GlobalValue::ExternalLinkage); 746 747 CloneFunctionInto(NewF, &OrigF, VMap, /*ModuleLevelChanges=*/true, Returns); 748 749 NewF->setLinkage(savedLinkage); 750 NewF->setVisibility(savedVisibility); 751 NewF->setUnnamedAddr(savedUnnamedAddr); 752 NewF->setDLLStorageClass(savedDLLStorageClass); 753 754 auto &Context = NewF->getContext(); 755 756 // Replace the attributes of the new function: 757 auto OrigAttrs = NewF->getAttributes(); 758 auto NewAttrs = AttributeList(); 759 760 switch (Shape.ABI) { 761 case coro::ABI::Switch: 762 // Bootstrap attributes by copying function attributes from the 763 // original function. This should include optimization settings and so on. 764 NewAttrs = NewAttrs.addAttributes(Context, AttributeList::FunctionIndex, 765 OrigAttrs.getFnAttributes()); 766 767 addFramePointerAttrs(NewAttrs, Context, 0, 768 Shape.FrameSize, Shape.FrameAlign); 769 break; 770 case coro::ABI::Async: 771 break; 772 case coro::ABI::Retcon: 773 case coro::ABI::RetconOnce: 774 // If we have a continuation prototype, just use its attributes, 775 // full-stop. 776 NewAttrs = Shape.RetconLowering.ResumePrototype->getAttributes(); 777 778 addFramePointerAttrs(NewAttrs, Context, 0, 779 Shape.getRetconCoroId()->getStorageSize(), 780 Shape.getRetconCoroId()->getStorageAlignment()); 781 break; 782 } 783 784 switch (Shape.ABI) { 785 // In these ABIs, the cloned functions always return 'void', and the 786 // existing return sites are meaningless. Note that for unique 787 // continuations, this includes the returns associated with suspends; 788 // this is fine because we can't suspend twice. 789 case coro::ABI::Switch: 790 case coro::ABI::RetconOnce: 791 // Remove old returns. 792 for (ReturnInst *Return : Returns) 793 changeToUnreachable(Return, /*UseLLVMTrap=*/false); 794 break; 795 796 // With multi-suspend continuations, we'll already have eliminated the 797 // original returns and inserted returns before all the suspend points, 798 // so we want to leave any returns in place. 799 case coro::ABI::Retcon: 800 break; 801 // Async lowering will insert musttail call functions at all suspend points 802 // followed by a return. 803 // Don't change returns to unreachable because that will trip up the verifier. 804 // These returns should be unreachable from the clone. 805 case coro::ABI::Async: 806 break; 807 } 808 809 NewF->setAttributes(NewAttrs); 810 NewF->setCallingConv(Shape.getResumeFunctionCC()); 811 812 // Set up the new entry block. 813 replaceEntryBlock(); 814 815 Builder.SetInsertPoint(&NewF->getEntryBlock().front()); 816 NewFramePtr = deriveNewFramePointer(); 817 818 // Remap frame pointer. 819 Value *OldFramePtr = VMap[Shape.FramePtr]; 820 NewFramePtr->takeName(OldFramePtr); 821 OldFramePtr->replaceAllUsesWith(NewFramePtr); 822 823 // Remap vFrame pointer. 824 auto *NewVFrame = Builder.CreateBitCast( 825 NewFramePtr, Type::getInt8PtrTy(Builder.getContext()), "vFrame"); 826 Value *OldVFrame = cast<Value>(VMap[Shape.CoroBegin]); 827 OldVFrame->replaceAllUsesWith(NewVFrame); 828 829 switch (Shape.ABI) { 830 case coro::ABI::Switch: 831 // Rewrite final suspend handling as it is not done via switch (allows to 832 // remove final case from the switch, since it is undefined behavior to 833 // resume the coroutine suspended at the final suspend point. 834 if (Shape.SwitchLowering.HasFinalSuspend) 835 handleFinalSuspend(); 836 break; 837 case coro::ABI::Async: 838 case coro::ABI::Retcon: 839 case coro::ABI::RetconOnce: 840 // Replace uses of the active suspend with the corresponding 841 // continuation-function arguments. 842 assert(ActiveSuspend != nullptr && 843 "no active suspend when lowering a continuation-style coroutine"); 844 replaceRetconOrAsyncSuspendUses(); 845 break; 846 } 847 848 // Handle suspends. 849 replaceCoroSuspends(); 850 851 // Handle swifterror. 852 replaceSwiftErrorOps(); 853 854 // Remove coro.end intrinsics. 855 replaceCoroEnds(); 856 857 // Eliminate coro.free from the clones, replacing it with 'null' in cleanup, 858 // to suppress deallocation code. 859 if (Shape.ABI == coro::ABI::Switch) 860 coro::replaceCoroFree(cast<CoroIdInst>(VMap[Shape.CoroBegin->getId()]), 861 /*Elide=*/ FKind == CoroCloner::Kind::SwitchCleanup); 862 } 863 864 // Create a resume clone by cloning the body of the original function, setting 865 // new entry block and replacing coro.suspend an appropriate value to force 866 // resume or cleanup pass for every suspend point. 867 static Function *createClone(Function &F, const Twine &Suffix, 868 coro::Shape &Shape, CoroCloner::Kind FKind) { 869 CoroCloner Cloner(F, Suffix, Shape, FKind); 870 Cloner.create(); 871 return Cloner.getFunction(); 872 } 873 874 /// Remove calls to llvm.coro.end in the original function. 875 static void removeCoroEnds(const coro::Shape &Shape, CallGraph *CG) { 876 for (auto End : Shape.CoroEnds) { 877 replaceCoroEnd(End, Shape, Shape.FramePtr, /*in resume*/ false, CG); 878 } 879 } 880 881 static void updateAsyncFuncPointerContextSize(coro::Shape &Shape) { 882 assert(Shape.ABI == coro::ABI::Async); 883 884 auto *FuncPtrStruct = cast<ConstantStruct>( 885 Shape.AsyncLowering.AsyncFuncPointer->getInitializer()); 886 auto *OrigRelativeFunOffset = FuncPtrStruct->getOperand(0); 887 auto *OrigContextSize = FuncPtrStruct->getOperand(1); 888 auto *NewContextSize = ConstantInt::get(OrigContextSize->getType(), 889 Shape.AsyncLowering.ContextSize); 890 auto *NewFuncPtrStruct = ConstantStruct::get( 891 FuncPtrStruct->getType(), OrigRelativeFunOffset, NewContextSize); 892 893 Shape.AsyncLowering.AsyncFuncPointer->setInitializer(NewFuncPtrStruct); 894 } 895 896 static void replaceFrameSize(coro::Shape &Shape) { 897 if (Shape.ABI == coro::ABI::Async) 898 updateAsyncFuncPointerContextSize(Shape); 899 900 if (Shape.CoroSizes.empty()) 901 return; 902 903 // In the same function all coro.sizes should have the same result type. 904 auto *SizeIntrin = Shape.CoroSizes.back(); 905 Module *M = SizeIntrin->getModule(); 906 const DataLayout &DL = M->getDataLayout(); 907 auto Size = DL.getTypeAllocSize(Shape.FrameTy); 908 auto *SizeConstant = ConstantInt::get(SizeIntrin->getType(), Size); 909 910 for (CoroSizeInst *CS : Shape.CoroSizes) { 911 CS->replaceAllUsesWith(SizeConstant); 912 CS->eraseFromParent(); 913 } 914 } 915 916 // Create a global constant array containing pointers to functions provided and 917 // set Info parameter of CoroBegin to point at this constant. Example: 918 // 919 // @f.resumers = internal constant [2 x void(%f.frame*)*] 920 // [void(%f.frame*)* @f.resume, void(%f.frame*)* @f.destroy] 921 // define void @f() { 922 // ... 923 // call i8* @llvm.coro.begin(i8* null, i32 0, i8* null, 924 // i8* bitcast([2 x void(%f.frame*)*] * @f.resumers to i8*)) 925 // 926 // Assumes that all the functions have the same signature. 927 static void setCoroInfo(Function &F, coro::Shape &Shape, 928 ArrayRef<Function *> Fns) { 929 // This only works under the switch-lowering ABI because coro elision 930 // only works on the switch-lowering ABI. 931 assert(Shape.ABI == coro::ABI::Switch); 932 933 SmallVector<Constant *, 4> Args(Fns.begin(), Fns.end()); 934 assert(!Args.empty()); 935 Function *Part = *Fns.begin(); 936 Module *M = Part->getParent(); 937 auto *ArrTy = ArrayType::get(Part->getType(), Args.size()); 938 939 auto *ConstVal = ConstantArray::get(ArrTy, Args); 940 auto *GV = new GlobalVariable(*M, ConstVal->getType(), /*isConstant=*/true, 941 GlobalVariable::PrivateLinkage, ConstVal, 942 F.getName() + Twine(".resumers")); 943 944 // Update coro.begin instruction to refer to this constant. 945 LLVMContext &C = F.getContext(); 946 auto *BC = ConstantExpr::getPointerCast(GV, Type::getInt8PtrTy(C)); 947 Shape.getSwitchCoroId()->setInfo(BC); 948 } 949 950 // Store addresses of Resume/Destroy/Cleanup functions in the coroutine frame. 951 static void updateCoroFrame(coro::Shape &Shape, Function *ResumeFn, 952 Function *DestroyFn, Function *CleanupFn) { 953 assert(Shape.ABI == coro::ABI::Switch); 954 955 IRBuilder<> Builder(Shape.FramePtr->getNextNode()); 956 auto *ResumeAddr = Builder.CreateStructGEP( 957 Shape.FrameTy, Shape.FramePtr, coro::Shape::SwitchFieldIndex::Resume, 958 "resume.addr"); 959 Builder.CreateStore(ResumeFn, ResumeAddr); 960 961 Value *DestroyOrCleanupFn = DestroyFn; 962 963 CoroIdInst *CoroId = Shape.getSwitchCoroId(); 964 if (CoroAllocInst *CA = CoroId->getCoroAlloc()) { 965 // If there is a CoroAlloc and it returns false (meaning we elide the 966 // allocation, use CleanupFn instead of DestroyFn). 967 DestroyOrCleanupFn = Builder.CreateSelect(CA, DestroyFn, CleanupFn); 968 } 969 970 auto *DestroyAddr = Builder.CreateStructGEP( 971 Shape.FrameTy, Shape.FramePtr, coro::Shape::SwitchFieldIndex::Destroy, 972 "destroy.addr"); 973 Builder.CreateStore(DestroyOrCleanupFn, DestroyAddr); 974 } 975 976 static void postSplitCleanup(Function &F) { 977 removeUnreachableBlocks(F); 978 979 // For now, we do a mandatory verification step because we don't 980 // entirely trust this pass. Note that we don't want to add a verifier 981 // pass to FPM below because it will also verify all the global data. 982 if (verifyFunction(F, &errs())) 983 report_fatal_error("Broken function"); 984 985 legacy::FunctionPassManager FPM(F.getParent()); 986 987 FPM.add(createSCCPPass()); 988 FPM.add(createCFGSimplificationPass()); 989 FPM.add(createEarlyCSEPass()); 990 FPM.add(createCFGSimplificationPass()); 991 992 FPM.doInitialization(); 993 FPM.run(F); 994 FPM.doFinalization(); 995 } 996 997 // Assuming we arrived at the block NewBlock from Prev instruction, store 998 // PHI's incoming values in the ResolvedValues map. 999 static void 1000 scanPHIsAndUpdateValueMap(Instruction *Prev, BasicBlock *NewBlock, 1001 DenseMap<Value *, Value *> &ResolvedValues) { 1002 auto *PrevBB = Prev->getParent(); 1003 for (PHINode &PN : NewBlock->phis()) { 1004 auto V = PN.getIncomingValueForBlock(PrevBB); 1005 // See if we already resolved it. 1006 auto VI = ResolvedValues.find(V); 1007 if (VI != ResolvedValues.end()) 1008 V = VI->second; 1009 // Remember the value. 1010 ResolvedValues[&PN] = V; 1011 } 1012 } 1013 1014 // Replace a sequence of branches leading to a ret, with a clone of a ret 1015 // instruction. Suspend instruction represented by a switch, track the PHI 1016 // values and select the correct case successor when possible. 1017 static bool simplifyTerminatorLeadingToRet(Instruction *InitialInst) { 1018 DenseMap<Value *, Value *> ResolvedValues; 1019 BasicBlock *UnconditionalSucc = nullptr; 1020 1021 Instruction *I = InitialInst; 1022 while (I->isTerminator() || 1023 (isa<CmpInst>(I) && I->getNextNode()->isTerminator())) { 1024 if (isa<ReturnInst>(I)) { 1025 if (I != InitialInst) { 1026 // If InitialInst is an unconditional branch, 1027 // remove PHI values that come from basic block of InitialInst 1028 if (UnconditionalSucc) 1029 UnconditionalSucc->removePredecessor(InitialInst->getParent(), true); 1030 ReplaceInstWithInst(InitialInst, I->clone()); 1031 } 1032 return true; 1033 } 1034 if (auto *BR = dyn_cast<BranchInst>(I)) { 1035 if (BR->isUnconditional()) { 1036 BasicBlock *BB = BR->getSuccessor(0); 1037 if (I == InitialInst) 1038 UnconditionalSucc = BB; 1039 scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); 1040 I = BB->getFirstNonPHIOrDbgOrLifetime(); 1041 continue; 1042 } 1043 } else if (auto *CondCmp = dyn_cast<CmpInst>(I)) { 1044 auto *BR = dyn_cast<BranchInst>(I->getNextNode()); 1045 if (BR && BR->isConditional() && CondCmp == BR->getCondition()) { 1046 // If the case number of suspended switch instruction is reduced to 1047 // 1, then it is simplified to CmpInst in llvm::ConstantFoldTerminator. 1048 // And the comparsion looks like : %cond = icmp eq i8 %V, constant. 1049 ConstantInt *CondConst = dyn_cast<ConstantInt>(CondCmp->getOperand(1)); 1050 if (CondConst && CondCmp->getPredicate() == CmpInst::ICMP_EQ) { 1051 Value *V = CondCmp->getOperand(0); 1052 auto it = ResolvedValues.find(V); 1053 if (it != ResolvedValues.end()) 1054 V = it->second; 1055 1056 if (ConstantInt *Cond0 = dyn_cast<ConstantInt>(V)) { 1057 BasicBlock *BB = Cond0->equalsInt(CondConst->getZExtValue()) 1058 ? BR->getSuccessor(0) 1059 : BR->getSuccessor(1); 1060 scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); 1061 I = BB->getFirstNonPHIOrDbgOrLifetime(); 1062 continue; 1063 } 1064 } 1065 } 1066 } else if (auto *SI = dyn_cast<SwitchInst>(I)) { 1067 Value *V = SI->getCondition(); 1068 auto it = ResolvedValues.find(V); 1069 if (it != ResolvedValues.end()) 1070 V = it->second; 1071 if (ConstantInt *Cond = dyn_cast<ConstantInt>(V)) { 1072 BasicBlock *BB = SI->findCaseValue(Cond)->getCaseSuccessor(); 1073 scanPHIsAndUpdateValueMap(I, BB, ResolvedValues); 1074 I = BB->getFirstNonPHIOrDbgOrLifetime(); 1075 continue; 1076 } 1077 } 1078 return false; 1079 } 1080 return false; 1081 } 1082 1083 // Check whether CI obeys the rules of musttail attribute. 1084 static bool shouldBeMustTail(const CallInst &CI, const Function &F) { 1085 if (CI.isInlineAsm()) 1086 return false; 1087 1088 // Match prototypes and calling conventions of resume function. 1089 FunctionType *CalleeTy = CI.getFunctionType(); 1090 if (!CalleeTy->getReturnType()->isVoidTy() || (CalleeTy->getNumParams() != 1)) 1091 return false; 1092 1093 Type *CalleeParmTy = CalleeTy->getParamType(0); 1094 if (!CalleeParmTy->isPointerTy() || 1095 (CalleeParmTy->getPointerAddressSpace() != 0)) 1096 return false; 1097 1098 if (CI.getCallingConv() != F.getCallingConv()) 1099 return false; 1100 1101 // CI should not has any ABI-impacting function attributes. 1102 static const Attribute::AttrKind ABIAttrs[] = { 1103 Attribute::StructRet, Attribute::ByVal, Attribute::InAlloca, 1104 Attribute::Preallocated, Attribute::InReg, Attribute::Returned, 1105 Attribute::SwiftSelf, Attribute::SwiftError}; 1106 AttributeList Attrs = CI.getAttributes(); 1107 for (auto AK : ABIAttrs) 1108 if (Attrs.hasParamAttribute(0, AK)) 1109 return false; 1110 1111 return true; 1112 } 1113 1114 // Add musttail to any resume instructions that is immediately followed by a 1115 // suspend (i.e. ret). We do this even in -O0 to support guaranteed tail call 1116 // for symmetrical coroutine control transfer (C++ Coroutines TS extension). 1117 // This transformation is done only in the resume part of the coroutine that has 1118 // identical signature and calling convention as the coro.resume call. 1119 static void addMustTailToCoroResumes(Function &F) { 1120 bool changed = false; 1121 1122 // Collect potential resume instructions. 1123 SmallVector<CallInst *, 4> Resumes; 1124 for (auto &I : instructions(F)) 1125 if (auto *Call = dyn_cast<CallInst>(&I)) 1126 if (shouldBeMustTail(*Call, F)) 1127 Resumes.push_back(Call); 1128 1129 // Set musttail on those that are followed by a ret instruction. 1130 for (CallInst *Call : Resumes) 1131 if (simplifyTerminatorLeadingToRet(Call->getNextNode())) { 1132 Call->setTailCallKind(CallInst::TCK_MustTail); 1133 changed = true; 1134 } 1135 1136 if (changed) 1137 removeUnreachableBlocks(F); 1138 } 1139 1140 // Coroutine has no suspend points. Remove heap allocation for the coroutine 1141 // frame if possible. 1142 static void handleNoSuspendCoroutine(coro::Shape &Shape) { 1143 auto *CoroBegin = Shape.CoroBegin; 1144 auto *CoroId = CoroBegin->getId(); 1145 auto *AllocInst = CoroId->getCoroAlloc(); 1146 switch (Shape.ABI) { 1147 case coro::ABI::Switch: { 1148 auto SwitchId = cast<CoroIdInst>(CoroId); 1149 coro::replaceCoroFree(SwitchId, /*Elide=*/AllocInst != nullptr); 1150 if (AllocInst) { 1151 IRBuilder<> Builder(AllocInst); 1152 auto *Frame = Builder.CreateAlloca(Shape.FrameTy); 1153 Frame->setAlignment(Shape.FrameAlign); 1154 auto *VFrame = Builder.CreateBitCast(Frame, Builder.getInt8PtrTy()); 1155 AllocInst->replaceAllUsesWith(Builder.getFalse()); 1156 AllocInst->eraseFromParent(); 1157 CoroBegin->replaceAllUsesWith(VFrame); 1158 } else { 1159 CoroBegin->replaceAllUsesWith(CoroBegin->getMem()); 1160 } 1161 break; 1162 } 1163 case coro::ABI::Async: 1164 case coro::ABI::Retcon: 1165 case coro::ABI::RetconOnce: 1166 CoroBegin->replaceAllUsesWith(UndefValue::get(CoroBegin->getType())); 1167 break; 1168 } 1169 1170 CoroBegin->eraseFromParent(); 1171 } 1172 1173 // SimplifySuspendPoint needs to check that there is no calls between 1174 // coro_save and coro_suspend, since any of the calls may potentially resume 1175 // the coroutine and if that is the case we cannot eliminate the suspend point. 1176 static bool hasCallsInBlockBetween(Instruction *From, Instruction *To) { 1177 for (Instruction *I = From; I != To; I = I->getNextNode()) { 1178 // Assume that no intrinsic can resume the coroutine. 1179 if (isa<IntrinsicInst>(I)) 1180 continue; 1181 1182 if (isa<CallBase>(I)) 1183 return true; 1184 } 1185 return false; 1186 } 1187 1188 static bool hasCallsInBlocksBetween(BasicBlock *SaveBB, BasicBlock *ResDesBB) { 1189 SmallPtrSet<BasicBlock *, 8> Set; 1190 SmallVector<BasicBlock *, 8> Worklist; 1191 1192 Set.insert(SaveBB); 1193 Worklist.push_back(ResDesBB); 1194 1195 // Accumulate all blocks between SaveBB and ResDesBB. Because CoroSaveIntr 1196 // returns a token consumed by suspend instruction, all blocks in between 1197 // will have to eventually hit SaveBB when going backwards from ResDesBB. 1198 while (!Worklist.empty()) { 1199 auto *BB = Worklist.pop_back_val(); 1200 Set.insert(BB); 1201 for (auto *Pred : predecessors(BB)) 1202 if (Set.count(Pred) == 0) 1203 Worklist.push_back(Pred); 1204 } 1205 1206 // SaveBB and ResDesBB are checked separately in hasCallsBetween. 1207 Set.erase(SaveBB); 1208 Set.erase(ResDesBB); 1209 1210 for (auto *BB : Set) 1211 if (hasCallsInBlockBetween(BB->getFirstNonPHI(), nullptr)) 1212 return true; 1213 1214 return false; 1215 } 1216 1217 static bool hasCallsBetween(Instruction *Save, Instruction *ResumeOrDestroy) { 1218 auto *SaveBB = Save->getParent(); 1219 auto *ResumeOrDestroyBB = ResumeOrDestroy->getParent(); 1220 1221 if (SaveBB == ResumeOrDestroyBB) 1222 return hasCallsInBlockBetween(Save->getNextNode(), ResumeOrDestroy); 1223 1224 // Any calls from Save to the end of the block? 1225 if (hasCallsInBlockBetween(Save->getNextNode(), nullptr)) 1226 return true; 1227 1228 // Any calls from begging of the block up to ResumeOrDestroy? 1229 if (hasCallsInBlockBetween(ResumeOrDestroyBB->getFirstNonPHI(), 1230 ResumeOrDestroy)) 1231 return true; 1232 1233 // Any calls in all of the blocks between SaveBB and ResumeOrDestroyBB? 1234 if (hasCallsInBlocksBetween(SaveBB, ResumeOrDestroyBB)) 1235 return true; 1236 1237 return false; 1238 } 1239 1240 // If a SuspendIntrin is preceded by Resume or Destroy, we can eliminate the 1241 // suspend point and replace it with nornal control flow. 1242 static bool simplifySuspendPoint(CoroSuspendInst *Suspend, 1243 CoroBeginInst *CoroBegin) { 1244 Instruction *Prev = Suspend->getPrevNode(); 1245 if (!Prev) { 1246 auto *Pred = Suspend->getParent()->getSinglePredecessor(); 1247 if (!Pred) 1248 return false; 1249 Prev = Pred->getTerminator(); 1250 } 1251 1252 CallBase *CB = dyn_cast<CallBase>(Prev); 1253 if (!CB) 1254 return false; 1255 1256 auto *Callee = CB->getCalledOperand()->stripPointerCasts(); 1257 1258 // See if the callsite is for resumption or destruction of the coroutine. 1259 auto *SubFn = dyn_cast<CoroSubFnInst>(Callee); 1260 if (!SubFn) 1261 return false; 1262 1263 // Does not refer to the current coroutine, we cannot do anything with it. 1264 if (SubFn->getFrame() != CoroBegin) 1265 return false; 1266 1267 // See if the transformation is safe. Specifically, see if there are any 1268 // calls in between Save and CallInstr. They can potenitally resume the 1269 // coroutine rendering this optimization unsafe. 1270 auto *Save = Suspend->getCoroSave(); 1271 if (hasCallsBetween(Save, CB)) 1272 return false; 1273 1274 // Replace llvm.coro.suspend with the value that results in resumption over 1275 // the resume or cleanup path. 1276 Suspend->replaceAllUsesWith(SubFn->getRawIndex()); 1277 Suspend->eraseFromParent(); 1278 Save->eraseFromParent(); 1279 1280 // No longer need a call to coro.resume or coro.destroy. 1281 if (auto *Invoke = dyn_cast<InvokeInst>(CB)) { 1282 BranchInst::Create(Invoke->getNormalDest(), Invoke); 1283 } 1284 1285 // Grab the CalledValue from CB before erasing the CallInstr. 1286 auto *CalledValue = CB->getCalledOperand(); 1287 CB->eraseFromParent(); 1288 1289 // If no more users remove it. Usually it is a bitcast of SubFn. 1290 if (CalledValue != SubFn && CalledValue->user_empty()) 1291 if (auto *I = dyn_cast<Instruction>(CalledValue)) 1292 I->eraseFromParent(); 1293 1294 // Now we are good to remove SubFn. 1295 if (SubFn->user_empty()) 1296 SubFn->eraseFromParent(); 1297 1298 return true; 1299 } 1300 1301 // Remove suspend points that are simplified. 1302 static void simplifySuspendPoints(coro::Shape &Shape) { 1303 // Currently, the only simplification we do is switch-lowering-specific. 1304 if (Shape.ABI != coro::ABI::Switch) 1305 return; 1306 1307 auto &S = Shape.CoroSuspends; 1308 size_t I = 0, N = S.size(); 1309 if (N == 0) 1310 return; 1311 while (true) { 1312 auto SI = cast<CoroSuspendInst>(S[I]); 1313 // Leave final.suspend to handleFinalSuspend since it is undefined behavior 1314 // to resume a coroutine suspended at the final suspend point. 1315 if (!SI->isFinal() && simplifySuspendPoint(SI, Shape.CoroBegin)) { 1316 if (--N == I) 1317 break; 1318 std::swap(S[I], S[N]); 1319 continue; 1320 } 1321 if (++I == N) 1322 break; 1323 } 1324 S.resize(N); 1325 } 1326 1327 static void splitSwitchCoroutine(Function &F, coro::Shape &Shape, 1328 SmallVectorImpl<Function *> &Clones) { 1329 assert(Shape.ABI == coro::ABI::Switch); 1330 1331 createResumeEntryBlock(F, Shape); 1332 auto ResumeClone = createClone(F, ".resume", Shape, 1333 CoroCloner::Kind::SwitchResume); 1334 auto DestroyClone = createClone(F, ".destroy", Shape, 1335 CoroCloner::Kind::SwitchUnwind); 1336 auto CleanupClone = createClone(F, ".cleanup", Shape, 1337 CoroCloner::Kind::SwitchCleanup); 1338 1339 postSplitCleanup(*ResumeClone); 1340 postSplitCleanup(*DestroyClone); 1341 postSplitCleanup(*CleanupClone); 1342 1343 addMustTailToCoroResumes(*ResumeClone); 1344 1345 // Store addresses resume/destroy/cleanup functions in the coroutine frame. 1346 updateCoroFrame(Shape, ResumeClone, DestroyClone, CleanupClone); 1347 1348 assert(Clones.empty()); 1349 Clones.push_back(ResumeClone); 1350 Clones.push_back(DestroyClone); 1351 Clones.push_back(CleanupClone); 1352 1353 // Create a constant array referring to resume/destroy/clone functions pointed 1354 // by the last argument of @llvm.coro.info, so that CoroElide pass can 1355 // determined correct function to call. 1356 setCoroInfo(F, Shape, Clones); 1357 } 1358 1359 static void replaceAsyncResumeFunction(CoroSuspendAsyncInst *Suspend, 1360 Value *Continuation) { 1361 auto *ResumeIntrinsic = Suspend->getResumeFunction(); 1362 auto &Context = Suspend->getParent()->getParent()->getContext(); 1363 auto *Int8PtrTy = Type::getInt8PtrTy(Context); 1364 1365 IRBuilder<> Builder(ResumeIntrinsic); 1366 auto *Val = Builder.CreateBitOrPointerCast(Continuation, Int8PtrTy); 1367 ResumeIntrinsic->replaceAllUsesWith(Val); 1368 ResumeIntrinsic->eraseFromParent(); 1369 Suspend->setOperand(0, UndefValue::get(Int8PtrTy)); 1370 } 1371 1372 /// Coerce the arguments in \p FnArgs according to \p FnTy in \p CallArgs. 1373 static void coerceArguments(IRBuilder<> &Builder, FunctionType *FnTy, 1374 ArrayRef<Value *> FnArgs, 1375 SmallVectorImpl<Value *> &CallArgs) { 1376 size_t ArgIdx = 0; 1377 for (auto paramTy : FnTy->params()) { 1378 assert(ArgIdx < FnArgs.size()); 1379 if (paramTy != FnArgs[ArgIdx]->getType()) 1380 CallArgs.push_back( 1381 Builder.CreateBitOrPointerCast(FnArgs[ArgIdx], paramTy)); 1382 else 1383 CallArgs.push_back(FnArgs[ArgIdx]); 1384 ++ArgIdx; 1385 } 1386 } 1387 1388 static void splitAsyncCoroutine(Function &F, coro::Shape &Shape, 1389 SmallVectorImpl<Function *> &Clones) { 1390 assert(Shape.ABI == coro::ABI::Async); 1391 assert(Clones.empty()); 1392 // Reset various things that the optimizer might have decided it 1393 // "knows" about the coroutine function due to not seeing a return. 1394 F.removeFnAttr(Attribute::NoReturn); 1395 F.removeAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); 1396 F.removeAttribute(AttributeList::ReturnIndex, Attribute::NonNull); 1397 1398 auto &Context = F.getContext(); 1399 auto *Int8PtrTy = Type::getInt8PtrTy(Context); 1400 1401 auto *Id = cast<CoroIdAsyncInst>(Shape.CoroBegin->getId()); 1402 IRBuilder<> Builder(Id); 1403 1404 auto *FramePtr = Id->getStorage(); 1405 FramePtr = Builder.CreateBitOrPointerCast(FramePtr, Int8PtrTy); 1406 FramePtr = Builder.CreateConstInBoundsGEP1_32( 1407 Type::getInt8Ty(Context), FramePtr, Shape.AsyncLowering.FrameOffset, 1408 "async.ctx.frameptr"); 1409 1410 // Map all uses of llvm.coro.begin to the allocated frame pointer. 1411 { 1412 // Make sure we don't invalidate Shape.FramePtr. 1413 TrackingVH<Instruction> Handle(Shape.FramePtr); 1414 Shape.CoroBegin->replaceAllUsesWith(FramePtr); 1415 Shape.FramePtr = Handle.getValPtr(); 1416 } 1417 1418 // Create all the functions in order after the main function. 1419 auto NextF = std::next(F.getIterator()); 1420 1421 // Create a continuation function for each of the suspend points. 1422 Clones.reserve(Shape.CoroSuspends.size()); 1423 for (size_t Idx = 0, End = Shape.CoroSuspends.size(); Idx != End; ++Idx) { 1424 auto *Suspend = cast<CoroSuspendAsyncInst>(Shape.CoroSuspends[Idx]); 1425 1426 // Create the clone declaration. 1427 auto *Continuation = 1428 createCloneDeclaration(F, Shape, ".resume." + Twine(Idx), NextF); 1429 Clones.push_back(Continuation); 1430 1431 // Insert a branch to a new return block immediately before the suspend 1432 // point. 1433 auto *SuspendBB = Suspend->getParent(); 1434 auto *NewSuspendBB = SuspendBB->splitBasicBlock(Suspend); 1435 auto *Branch = cast<BranchInst>(SuspendBB->getTerminator()); 1436 1437 // Place it before the first suspend. 1438 auto *ReturnBB = 1439 BasicBlock::Create(F.getContext(), "coro.return", &F, NewSuspendBB); 1440 Branch->setSuccessor(0, ReturnBB); 1441 1442 IRBuilder<> Builder(ReturnBB); 1443 1444 // Insert the call to the tail call function and inline it. 1445 auto *Fn = Suspend->getMustTailCallFunction(); 1446 auto DbgLoc = Suspend->getDebugLoc(); 1447 SmallVector<Value *, 8> Args(Suspend->operand_values()); 1448 auto FnArgs = ArrayRef<Value *>(Args).drop_front(3).drop_back(1); 1449 auto FnTy = cast<FunctionType>(Fn->getType()->getPointerElementType()); 1450 // Coerce the arguments, llvm optimizations seem to ignore the types in 1451 // vaarg functions and throws away casts in optimized mode. 1452 SmallVector<Value *, 8> CallArgs; 1453 coerceArguments(Builder, FnTy, FnArgs, CallArgs); 1454 auto *TailCall = Builder.CreateCall(FnTy, Fn, CallArgs); 1455 TailCall->setDebugLoc(DbgLoc); 1456 TailCall->setTailCall(); 1457 TailCall->setCallingConv(Fn->getCallingConv()); 1458 Builder.CreateRetVoid(); 1459 InlineFunctionInfo FnInfo; 1460 auto InlineRes = InlineFunction(*TailCall, FnInfo); 1461 assert(InlineRes.isSuccess() && "Expected inlining to succeed"); 1462 (void)InlineRes; 1463 1464 // Replace the lvm.coro.async.resume intrisic call. 1465 replaceAsyncResumeFunction(Suspend, Continuation); 1466 } 1467 1468 assert(Clones.size() == Shape.CoroSuspends.size()); 1469 for (size_t Idx = 0, End = Shape.CoroSuspends.size(); Idx != End; ++Idx) { 1470 auto *Suspend = Shape.CoroSuspends[Idx]; 1471 auto *Clone = Clones[Idx]; 1472 1473 CoroCloner(F, "resume." + Twine(Idx), Shape, Clone, Suspend).create(); 1474 } 1475 } 1476 1477 static void splitRetconCoroutine(Function &F, coro::Shape &Shape, 1478 SmallVectorImpl<Function *> &Clones) { 1479 assert(Shape.ABI == coro::ABI::Retcon || 1480 Shape.ABI == coro::ABI::RetconOnce); 1481 assert(Clones.empty()); 1482 1483 // Reset various things that the optimizer might have decided it 1484 // "knows" about the coroutine function due to not seeing a return. 1485 F.removeFnAttr(Attribute::NoReturn); 1486 F.removeAttribute(AttributeList::ReturnIndex, Attribute::NoAlias); 1487 F.removeAttribute(AttributeList::ReturnIndex, Attribute::NonNull); 1488 1489 // Allocate the frame. 1490 auto *Id = cast<AnyCoroIdRetconInst>(Shape.CoroBegin->getId()); 1491 Value *RawFramePtr; 1492 if (Shape.RetconLowering.IsFrameInlineInStorage) { 1493 RawFramePtr = Id->getStorage(); 1494 } else { 1495 IRBuilder<> Builder(Id); 1496 1497 // Determine the size of the frame. 1498 const DataLayout &DL = F.getParent()->getDataLayout(); 1499 auto Size = DL.getTypeAllocSize(Shape.FrameTy); 1500 1501 // Allocate. We don't need to update the call graph node because we're 1502 // going to recompute it from scratch after splitting. 1503 // FIXME: pass the required alignment 1504 RawFramePtr = Shape.emitAlloc(Builder, Builder.getInt64(Size), nullptr); 1505 RawFramePtr = 1506 Builder.CreateBitCast(RawFramePtr, Shape.CoroBegin->getType()); 1507 1508 // Stash the allocated frame pointer in the continuation storage. 1509 auto Dest = Builder.CreateBitCast(Id->getStorage(), 1510 RawFramePtr->getType()->getPointerTo()); 1511 Builder.CreateStore(RawFramePtr, Dest); 1512 } 1513 1514 // Map all uses of llvm.coro.begin to the allocated frame pointer. 1515 { 1516 // Make sure we don't invalidate Shape.FramePtr. 1517 TrackingVH<Instruction> Handle(Shape.FramePtr); 1518 Shape.CoroBegin->replaceAllUsesWith(RawFramePtr); 1519 Shape.FramePtr = Handle.getValPtr(); 1520 } 1521 1522 // Create a unique return block. 1523 BasicBlock *ReturnBB = nullptr; 1524 SmallVector<PHINode *, 4> ReturnPHIs; 1525 1526 // Create all the functions in order after the main function. 1527 auto NextF = std::next(F.getIterator()); 1528 1529 // Create a continuation function for each of the suspend points. 1530 Clones.reserve(Shape.CoroSuspends.size()); 1531 for (size_t i = 0, e = Shape.CoroSuspends.size(); i != e; ++i) { 1532 auto Suspend = cast<CoroSuspendRetconInst>(Shape.CoroSuspends[i]); 1533 1534 // Create the clone declaration. 1535 auto Continuation = 1536 createCloneDeclaration(F, Shape, ".resume." + Twine(i), NextF); 1537 Clones.push_back(Continuation); 1538 1539 // Insert a branch to the unified return block immediately before 1540 // the suspend point. 1541 auto SuspendBB = Suspend->getParent(); 1542 auto NewSuspendBB = SuspendBB->splitBasicBlock(Suspend); 1543 auto Branch = cast<BranchInst>(SuspendBB->getTerminator()); 1544 1545 // Create the unified return block. 1546 if (!ReturnBB) { 1547 // Place it before the first suspend. 1548 ReturnBB = BasicBlock::Create(F.getContext(), "coro.return", &F, 1549 NewSuspendBB); 1550 Shape.RetconLowering.ReturnBlock = ReturnBB; 1551 1552 IRBuilder<> Builder(ReturnBB); 1553 1554 // Create PHIs for all the return values. 1555 assert(ReturnPHIs.empty()); 1556 1557 // First, the continuation. 1558 ReturnPHIs.push_back(Builder.CreatePHI(Continuation->getType(), 1559 Shape.CoroSuspends.size())); 1560 1561 // Next, all the directly-yielded values. 1562 for (auto ResultTy : Shape.getRetconResultTypes()) 1563 ReturnPHIs.push_back(Builder.CreatePHI(ResultTy, 1564 Shape.CoroSuspends.size())); 1565 1566 // Build the return value. 1567 auto RetTy = F.getReturnType(); 1568 1569 // Cast the continuation value if necessary. 1570 // We can't rely on the types matching up because that type would 1571 // have to be infinite. 1572 auto CastedContinuationTy = 1573 (ReturnPHIs.size() == 1 ? RetTy : RetTy->getStructElementType(0)); 1574 auto *CastedContinuation = 1575 Builder.CreateBitCast(ReturnPHIs[0], CastedContinuationTy); 1576 1577 Value *RetV; 1578 if (ReturnPHIs.size() == 1) { 1579 RetV = CastedContinuation; 1580 } else { 1581 RetV = UndefValue::get(RetTy); 1582 RetV = Builder.CreateInsertValue(RetV, CastedContinuation, 0); 1583 for (size_t I = 1, E = ReturnPHIs.size(); I != E; ++I) 1584 RetV = Builder.CreateInsertValue(RetV, ReturnPHIs[I], I); 1585 } 1586 1587 Builder.CreateRet(RetV); 1588 } 1589 1590 // Branch to the return block. 1591 Branch->setSuccessor(0, ReturnBB); 1592 ReturnPHIs[0]->addIncoming(Continuation, SuspendBB); 1593 size_t NextPHIIndex = 1; 1594 for (auto &VUse : Suspend->value_operands()) 1595 ReturnPHIs[NextPHIIndex++]->addIncoming(&*VUse, SuspendBB); 1596 assert(NextPHIIndex == ReturnPHIs.size()); 1597 } 1598 1599 assert(Clones.size() == Shape.CoroSuspends.size()); 1600 for (size_t i = 0, e = Shape.CoroSuspends.size(); i != e; ++i) { 1601 auto Suspend = Shape.CoroSuspends[i]; 1602 auto Clone = Clones[i]; 1603 1604 CoroCloner(F, "resume." + Twine(i), Shape, Clone, Suspend).create(); 1605 } 1606 } 1607 1608 namespace { 1609 class PrettyStackTraceFunction : public PrettyStackTraceEntry { 1610 Function &F; 1611 public: 1612 PrettyStackTraceFunction(Function &F) : F(F) {} 1613 void print(raw_ostream &OS) const override { 1614 OS << "While splitting coroutine "; 1615 F.printAsOperand(OS, /*print type*/ false, F.getParent()); 1616 OS << "\n"; 1617 } 1618 }; 1619 } 1620 1621 static coro::Shape splitCoroutine(Function &F, 1622 SmallVectorImpl<Function *> &Clones, 1623 bool ReuseFrameSlot) { 1624 PrettyStackTraceFunction prettyStackTrace(F); 1625 1626 // The suspend-crossing algorithm in buildCoroutineFrame get tripped 1627 // up by uses in unreachable blocks, so remove them as a first pass. 1628 removeUnreachableBlocks(F); 1629 1630 coro::Shape Shape(F, ReuseFrameSlot); 1631 if (!Shape.CoroBegin) 1632 return Shape; 1633 1634 simplifySuspendPoints(Shape); 1635 buildCoroutineFrame(F, Shape); 1636 replaceFrameSize(Shape); 1637 1638 // If there are no suspend points, no split required, just remove 1639 // the allocation and deallocation blocks, they are not needed. 1640 if (Shape.CoroSuspends.empty()) { 1641 handleNoSuspendCoroutine(Shape); 1642 } else { 1643 switch (Shape.ABI) { 1644 case coro::ABI::Switch: 1645 splitSwitchCoroutine(F, Shape, Clones); 1646 break; 1647 case coro::ABI::Async: 1648 splitAsyncCoroutine(F, Shape, Clones); 1649 break; 1650 case coro::ABI::Retcon: 1651 case coro::ABI::RetconOnce: 1652 splitRetconCoroutine(F, Shape, Clones); 1653 break; 1654 } 1655 } 1656 1657 // Replace all the swifterror operations in the original function. 1658 // This invalidates SwiftErrorOps in the Shape. 1659 replaceSwiftErrorOps(F, Shape, nullptr); 1660 1661 return Shape; 1662 } 1663 1664 static void 1665 updateCallGraphAfterCoroutineSplit(Function &F, const coro::Shape &Shape, 1666 const SmallVectorImpl<Function *> &Clones, 1667 CallGraph &CG, CallGraphSCC &SCC) { 1668 if (!Shape.CoroBegin) 1669 return; 1670 1671 removeCoroEnds(Shape, &CG); 1672 postSplitCleanup(F); 1673 1674 // Update call graph and add the functions we created to the SCC. 1675 coro::updateCallGraph(F, Clones, CG, SCC); 1676 } 1677 1678 static void updateCallGraphAfterCoroutineSplit( 1679 LazyCallGraph::Node &N, const coro::Shape &Shape, 1680 const SmallVectorImpl<Function *> &Clones, LazyCallGraph::SCC &C, 1681 LazyCallGraph &CG, CGSCCAnalysisManager &AM, CGSCCUpdateResult &UR, 1682 FunctionAnalysisManager &FAM) { 1683 if (!Shape.CoroBegin) 1684 return; 1685 1686 for (llvm::CoroEndInst *End : Shape.CoroEnds) { 1687 auto &Context = End->getContext(); 1688 End->replaceAllUsesWith(ConstantInt::getFalse(Context)); 1689 End->eraseFromParent(); 1690 } 1691 1692 postSplitCleanup(N.getFunction()); 1693 1694 // We've inserted instructions into coroutine 'f' that reference the three new 1695 // coroutine funclets. We must now update the call graph so that reference 1696 // edges between 'f' and its funclets are added to it. LazyCallGraph only 1697 // allows CGSCC passes to insert "trivial" reference edges. We've ensured 1698 // above, by inserting the funclets into the same SCC as the corutine, that 1699 // the edges are trivial. 1700 // 1701 // N.B.: If we didn't update the call graph here, a CGSCCToFunctionPassAdaptor 1702 // later in this CGSCC pass pipeline may be run, triggering a call graph 1703 // update of its own. Function passes run by the adaptor are not permitted to 1704 // add new edges of any kind to the graph, and the new edges inserted by this 1705 // pass would be misattributed to that unrelated function pass. 1706 updateCGAndAnalysisManagerForCGSCCPass(CG, C, N, AM, UR, FAM); 1707 } 1708 1709 // When we see the coroutine the first time, we insert an indirect call to a 1710 // devirt trigger function and mark the coroutine that it is now ready for 1711 // split. 1712 // Async lowering uses this after it has split the function to restart the 1713 // pipeline. 1714 static void prepareForSplit(Function &F, CallGraph &CG, 1715 bool MarkForAsyncRestart = false) { 1716 Module &M = *F.getParent(); 1717 LLVMContext &Context = F.getContext(); 1718 #ifndef NDEBUG 1719 Function *DevirtFn = M.getFunction(CORO_DEVIRT_TRIGGER_FN); 1720 assert(DevirtFn && "coro.devirt.trigger function not found"); 1721 #endif 1722 1723 F.addFnAttr(CORO_PRESPLIT_ATTR, MarkForAsyncRestart 1724 ? ASYNC_RESTART_AFTER_SPLIT 1725 : PREPARED_FOR_SPLIT); 1726 1727 // Insert an indirect call sequence that will be devirtualized by CoroElide 1728 // pass: 1729 // %0 = call i8* @llvm.coro.subfn.addr(i8* null, i8 -1) 1730 // %1 = bitcast i8* %0 to void(i8*)* 1731 // call void %1(i8* null) 1732 coro::LowererBase Lowerer(M); 1733 Instruction *InsertPt = 1734 MarkForAsyncRestart ? F.getEntryBlock().getFirstNonPHIOrDbgOrLifetime() 1735 : F.getEntryBlock().getTerminator(); 1736 auto *Null = ConstantPointerNull::get(Type::getInt8PtrTy(Context)); 1737 auto *DevirtFnAddr = 1738 Lowerer.makeSubFnCall(Null, CoroSubFnInst::RestartTrigger, InsertPt); 1739 FunctionType *FnTy = FunctionType::get(Type::getVoidTy(Context), 1740 {Type::getInt8PtrTy(Context)}, false); 1741 auto *IndirectCall = CallInst::Create(FnTy, DevirtFnAddr, Null, "", InsertPt); 1742 1743 // Update CG graph with an indirect call we just added. 1744 CG[&F]->addCalledFunction(IndirectCall, CG.getCallsExternalNode()); 1745 } 1746 1747 // Make sure that there is a devirtualization trigger function that the 1748 // coro-split pass uses to force a restart of the CGSCC pipeline. If the devirt 1749 // trigger function is not found, we will create one and add it to the current 1750 // SCC. 1751 static void createDevirtTriggerFunc(CallGraph &CG, CallGraphSCC &SCC) { 1752 Module &M = CG.getModule(); 1753 if (M.getFunction(CORO_DEVIRT_TRIGGER_FN)) 1754 return; 1755 1756 LLVMContext &C = M.getContext(); 1757 auto *FnTy = FunctionType::get(Type::getVoidTy(C), Type::getInt8PtrTy(C), 1758 /*isVarArg=*/false); 1759 Function *DevirtFn = 1760 Function::Create(FnTy, GlobalValue::LinkageTypes::PrivateLinkage, 1761 CORO_DEVIRT_TRIGGER_FN, &M); 1762 DevirtFn->addFnAttr(Attribute::AlwaysInline); 1763 auto *Entry = BasicBlock::Create(C, "entry", DevirtFn); 1764 ReturnInst::Create(C, Entry); 1765 1766 auto *Node = CG.getOrInsertFunction(DevirtFn); 1767 1768 SmallVector<CallGraphNode *, 8> Nodes(SCC.begin(), SCC.end()); 1769 Nodes.push_back(Node); 1770 SCC.initialize(Nodes); 1771 } 1772 1773 /// Replace a call to llvm.coro.prepare.retcon. 1774 static void replacePrepare(CallInst *Prepare, LazyCallGraph &CG, 1775 LazyCallGraph::SCC &C) { 1776 auto CastFn = Prepare->getArgOperand(0); // as an i8* 1777 auto Fn = CastFn->stripPointerCasts(); // as its original type 1778 1779 // Attempt to peephole this pattern: 1780 // %0 = bitcast [[TYPE]] @some_function to i8* 1781 // %1 = call @llvm.coro.prepare.retcon(i8* %0) 1782 // %2 = bitcast %1 to [[TYPE]] 1783 // ==> 1784 // %2 = @some_function 1785 for (auto UI = Prepare->use_begin(), UE = Prepare->use_end(); UI != UE;) { 1786 // Look for bitcasts back to the original function type. 1787 auto *Cast = dyn_cast<BitCastInst>((UI++)->getUser()); 1788 if (!Cast || Cast->getType() != Fn->getType()) 1789 continue; 1790 1791 // Replace and remove the cast. 1792 Cast->replaceAllUsesWith(Fn); 1793 Cast->eraseFromParent(); 1794 } 1795 1796 // Replace any remaining uses with the function as an i8*. 1797 // This can never directly be a callee, so we don't need to update CG. 1798 Prepare->replaceAllUsesWith(CastFn); 1799 Prepare->eraseFromParent(); 1800 1801 // Kill dead bitcasts. 1802 while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) { 1803 if (!Cast->use_empty()) 1804 break; 1805 CastFn = Cast->getOperand(0); 1806 Cast->eraseFromParent(); 1807 } 1808 } 1809 /// Replace a call to llvm.coro.prepare.retcon. 1810 static void replacePrepare(CallInst *Prepare, CallGraph &CG) { 1811 auto CastFn = Prepare->getArgOperand(0); // as an i8* 1812 auto Fn = CastFn->stripPointerCasts(); // as its original type 1813 1814 // Find call graph nodes for the preparation. 1815 CallGraphNode *PrepareUserNode = nullptr, *FnNode = nullptr; 1816 if (auto ConcreteFn = dyn_cast<Function>(Fn)) { 1817 PrepareUserNode = CG[Prepare->getFunction()]; 1818 FnNode = CG[ConcreteFn]; 1819 } 1820 1821 // Attempt to peephole this pattern: 1822 // %0 = bitcast [[TYPE]] @some_function to i8* 1823 // %1 = call @llvm.coro.prepare.retcon(i8* %0) 1824 // %2 = bitcast %1 to [[TYPE]] 1825 // ==> 1826 // %2 = @some_function 1827 for (auto UI = Prepare->use_begin(), UE = Prepare->use_end(); 1828 UI != UE; ) { 1829 // Look for bitcasts back to the original function type. 1830 auto *Cast = dyn_cast<BitCastInst>((UI++)->getUser()); 1831 if (!Cast || Cast->getType() != Fn->getType()) continue; 1832 1833 // Check whether the replacement will introduce new direct calls. 1834 // If so, we'll need to update the call graph. 1835 if (PrepareUserNode) { 1836 for (auto &Use : Cast->uses()) { 1837 if (auto *CB = dyn_cast<CallBase>(Use.getUser())) { 1838 if (!CB->isCallee(&Use)) 1839 continue; 1840 PrepareUserNode->removeCallEdgeFor(*CB); 1841 PrepareUserNode->addCalledFunction(CB, FnNode); 1842 } 1843 } 1844 } 1845 1846 // Replace and remove the cast. 1847 Cast->replaceAllUsesWith(Fn); 1848 Cast->eraseFromParent(); 1849 } 1850 1851 // Replace any remaining uses with the function as an i8*. 1852 // This can never directly be a callee, so we don't need to update CG. 1853 Prepare->replaceAllUsesWith(CastFn); 1854 Prepare->eraseFromParent(); 1855 1856 // Kill dead bitcasts. 1857 while (auto *Cast = dyn_cast<BitCastInst>(CastFn)) { 1858 if (!Cast->use_empty()) break; 1859 CastFn = Cast->getOperand(0); 1860 Cast->eraseFromParent(); 1861 } 1862 } 1863 1864 static bool replaceAllPrepares(Function *PrepareFn, LazyCallGraph &CG, 1865 LazyCallGraph::SCC &C) { 1866 bool Changed = false; 1867 for (auto PI = PrepareFn->use_begin(), PE = PrepareFn->use_end(); PI != PE;) { 1868 // Intrinsics can only be used in calls. 1869 auto *Prepare = cast<CallInst>((PI++)->getUser()); 1870 replacePrepare(Prepare, CG, C); 1871 Changed = true; 1872 } 1873 1874 return Changed; 1875 } 1876 1877 /// Remove calls to llvm.coro.prepare.retcon, a barrier meant to prevent 1878 /// IPO from operating on calls to a retcon coroutine before it's been 1879 /// split. This is only safe to do after we've split all retcon 1880 /// coroutines in the module. We can do that this in this pass because 1881 /// this pass does promise to split all retcon coroutines (as opposed to 1882 /// switch coroutines, which are lowered in multiple stages). 1883 static bool replaceAllPrepares(Function *PrepareFn, CallGraph &CG) { 1884 bool Changed = false; 1885 for (auto PI = PrepareFn->use_begin(), PE = PrepareFn->use_end(); 1886 PI != PE; ) { 1887 // Intrinsics can only be used in calls. 1888 auto *Prepare = cast<CallInst>((PI++)->getUser()); 1889 replacePrepare(Prepare, CG); 1890 Changed = true; 1891 } 1892 1893 return Changed; 1894 } 1895 1896 static bool declaresCoroSplitIntrinsics(const Module &M) { 1897 return coro::declaresIntrinsics(M, {"llvm.coro.begin", 1898 "llvm.coro.prepare.retcon", 1899 "llvm.coro.prepare.async"}); 1900 } 1901 1902 static void addPrepareFunction(const Module &M, 1903 SmallVectorImpl<Function *> &Fns, 1904 StringRef Name) { 1905 auto *PrepareFn = M.getFunction(Name); 1906 if (PrepareFn && !PrepareFn->use_empty()) 1907 Fns.push_back(PrepareFn); 1908 } 1909 1910 PreservedAnalyses CoroSplitPass::run(LazyCallGraph::SCC &C, 1911 CGSCCAnalysisManager &AM, 1912 LazyCallGraph &CG, CGSCCUpdateResult &UR) { 1913 // NB: One invariant of a valid LazyCallGraph::SCC is that it must contain a 1914 // non-zero number of nodes, so we assume that here and grab the first 1915 // node's function's module. 1916 Module &M = *C.begin()->getFunction().getParent(); 1917 auto &FAM = 1918 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager(); 1919 1920 if (!declaresCoroSplitIntrinsics(M)) 1921 return PreservedAnalyses::all(); 1922 1923 // Check for uses of llvm.coro.prepare.retcon/async. 1924 SmallVector<Function *, 2> PrepareFns; 1925 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon"); 1926 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async"); 1927 1928 // Find coroutines for processing. 1929 SmallVector<LazyCallGraph::Node *, 4> Coroutines; 1930 for (LazyCallGraph::Node &N : C) 1931 if (N.getFunction().hasFnAttribute(CORO_PRESPLIT_ATTR)) 1932 Coroutines.push_back(&N); 1933 1934 if (Coroutines.empty() && PrepareFns.empty()) 1935 return PreservedAnalyses::all(); 1936 1937 if (Coroutines.empty()) { 1938 for (auto *PrepareFn : PrepareFns) { 1939 replaceAllPrepares(PrepareFn, CG, C); 1940 } 1941 } 1942 1943 // Split all the coroutines. 1944 for (LazyCallGraph::Node *N : Coroutines) { 1945 Function &F = N->getFunction(); 1946 Attribute Attr = F.getFnAttribute(CORO_PRESPLIT_ATTR); 1947 StringRef Value = Attr.getValueAsString(); 1948 LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F.getName() 1949 << "' state: " << Value << "\n"); 1950 if (Value == UNPREPARED_FOR_SPLIT) { 1951 // Enqueue a second iteration of the CGSCC pipeline. 1952 // N.B.: 1953 // The CoroSplitLegacy pass "triggers" a restart of the CGSCC pass 1954 // pipeline by inserting an indirect function call that the 1955 // CoroElideLegacy pass then replaces with a direct function call. The 1956 // legacy CGSCC pipeline's implicit behavior was as if wrapped in the new 1957 // pass manager abstraction DevirtSCCRepeatedPass. 1958 // 1959 // This pass does not need to "trigger" another run of the pipeline. 1960 // Instead, it simply enqueues the same RefSCC onto the pipeline's 1961 // worklist. 1962 UR.CWorklist.insert(&C); 1963 F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT); 1964 continue; 1965 } 1966 F.removeFnAttr(CORO_PRESPLIT_ATTR); 1967 1968 SmallVector<Function *, 4> Clones; 1969 const coro::Shape Shape = splitCoroutine(F, Clones, ReuseFrameSlot); 1970 updateCallGraphAfterCoroutineSplit(*N, Shape, Clones, C, CG, AM, UR, FAM); 1971 1972 if (Shape.ABI == coro::ABI::Async && !Shape.CoroSuspends.empty()) { 1973 // We want the inliner to be run on the newly inserted functions. 1974 UR.CWorklist.insert(&C); 1975 } 1976 } 1977 1978 if (!PrepareFns.empty()) { 1979 for (auto *PrepareFn : PrepareFns) { 1980 replaceAllPrepares(PrepareFn, CG, C); 1981 } 1982 } 1983 1984 return PreservedAnalyses::none(); 1985 } 1986 1987 namespace { 1988 1989 // We present a coroutine to LLVM as an ordinary function with suspension 1990 // points marked up with intrinsics. We let the optimizer party on the coroutine 1991 // as a single function for as long as possible. Shortly before the coroutine is 1992 // eligible to be inlined into its callers, we split up the coroutine into parts 1993 // corresponding to initial, resume and destroy invocations of the coroutine, 1994 // add them to the current SCC and restart the IPO pipeline to optimize the 1995 // coroutine subfunctions we extracted before proceeding to the caller of the 1996 // coroutine. 1997 struct CoroSplitLegacy : public CallGraphSCCPass { 1998 static char ID; // Pass identification, replacement for typeid 1999 2000 CoroSplitLegacy(bool ReuseFrameSlot = false) 2001 : CallGraphSCCPass(ID), ReuseFrameSlot(ReuseFrameSlot) { 2002 initializeCoroSplitLegacyPass(*PassRegistry::getPassRegistry()); 2003 } 2004 2005 bool Run = false; 2006 bool ReuseFrameSlot; 2007 2008 // A coroutine is identified by the presence of coro.begin intrinsic, if 2009 // we don't have any, this pass has nothing to do. 2010 bool doInitialization(CallGraph &CG) override { 2011 Run = declaresCoroSplitIntrinsics(CG.getModule()); 2012 return CallGraphSCCPass::doInitialization(CG); 2013 } 2014 2015 bool runOnSCC(CallGraphSCC &SCC) override { 2016 if (!Run) 2017 return false; 2018 2019 // Check for uses of llvm.coro.prepare.retcon. 2020 SmallVector<Function *, 2> PrepareFns; 2021 auto &M = SCC.getCallGraph().getModule(); 2022 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.retcon"); 2023 addPrepareFunction(M, PrepareFns, "llvm.coro.prepare.async"); 2024 2025 // Find coroutines for processing. 2026 SmallVector<Function *, 4> Coroutines; 2027 for (CallGraphNode *CGN : SCC) 2028 if (auto *F = CGN->getFunction()) 2029 if (F->hasFnAttribute(CORO_PRESPLIT_ATTR)) 2030 Coroutines.push_back(F); 2031 2032 if (Coroutines.empty() && PrepareFns.empty()) 2033 return false; 2034 2035 CallGraph &CG = getAnalysis<CallGraphWrapperPass>().getCallGraph(); 2036 2037 if (Coroutines.empty()) { 2038 bool Changed = false; 2039 for (auto *PrepareFn : PrepareFns) 2040 Changed |= replaceAllPrepares(PrepareFn, CG); 2041 return Changed; 2042 } 2043 2044 createDevirtTriggerFunc(CG, SCC); 2045 2046 // Split all the coroutines. 2047 for (Function *F : Coroutines) { 2048 Attribute Attr = F->getFnAttribute(CORO_PRESPLIT_ATTR); 2049 StringRef Value = Attr.getValueAsString(); 2050 LLVM_DEBUG(dbgs() << "CoroSplit: Processing coroutine '" << F->getName() 2051 << "' state: " << Value << "\n"); 2052 // Async lowering marks coroutines to trigger a restart of the pipeline 2053 // after it has split them. 2054 if (Value == ASYNC_RESTART_AFTER_SPLIT) { 2055 F->removeFnAttr(CORO_PRESPLIT_ATTR); 2056 continue; 2057 } 2058 if (Value == UNPREPARED_FOR_SPLIT) { 2059 prepareForSplit(*F, CG); 2060 continue; 2061 } 2062 F->removeFnAttr(CORO_PRESPLIT_ATTR); 2063 2064 SmallVector<Function *, 4> Clones; 2065 const coro::Shape Shape = splitCoroutine(*F, Clones, ReuseFrameSlot); 2066 updateCallGraphAfterCoroutineSplit(*F, Shape, Clones, CG, SCC); 2067 if (Shape.ABI == coro::ABI::Async) { 2068 // Restart SCC passes. 2069 // Mark function for CoroElide pass. It will devirtualize causing a 2070 // restart of the SCC pipeline. 2071 prepareForSplit(*F, CG, true /*MarkForAsyncRestart*/); 2072 } 2073 } 2074 2075 for (auto *PrepareFn : PrepareFns) 2076 replaceAllPrepares(PrepareFn, CG); 2077 2078 return true; 2079 } 2080 2081 void getAnalysisUsage(AnalysisUsage &AU) const override { 2082 CallGraphSCCPass::getAnalysisUsage(AU); 2083 } 2084 2085 StringRef getPassName() const override { return "Coroutine Splitting"; } 2086 }; 2087 2088 } // end anonymous namespace 2089 2090 char CoroSplitLegacy::ID = 0; 2091 2092 INITIALIZE_PASS_BEGIN( 2093 CoroSplitLegacy, "coro-split", 2094 "Split coroutine into a set of functions driving its state machine", false, 2095 false) 2096 INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) 2097 INITIALIZE_PASS_END( 2098 CoroSplitLegacy, "coro-split", 2099 "Split coroutine into a set of functions driving its state machine", false, 2100 false) 2101 2102 Pass *llvm::createCoroSplitLegacyPass(bool ReuseFrameSlot) { 2103 return new CoroSplitLegacy(ReuseFrameSlot); 2104 } 2105