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