1 //===- CoroFrame.cpp - Builds and manipulates coroutine frame -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // This file contains classes used to discover if for a particular value 10 // there from sue to definition that crosses a suspend block. 11 // 12 // Using the information discovered we form a Coroutine Frame structure to 13 // contain those values. All uses of those values are replaced with appropriate 14 // GEP + load from the coroutine frame. At the point of the definition we spill 15 // the value into the coroutine frame. 16 // 17 // TODO: pack values tightly using liveness info. 18 //===----------------------------------------------------------------------===// 19 20 #include "CoroInternal.h" 21 #include "llvm/ADT/BitVector.h" 22 #include "llvm/IR/CFG.h" 23 #include "llvm/IR/Dominators.h" 24 #include "llvm/IR/IRBuilder.h" 25 #include "llvm/IR/InstIterator.h" 26 #include "llvm/Support/Debug.h" 27 #include "llvm/Support/MathExtras.h" 28 #include "llvm/Support/circular_raw_ostream.h" 29 #include "llvm/Transforms/Utils/BasicBlockUtils.h" 30 31 using namespace llvm; 32 33 // The "coro-suspend-crossing" flag is very noisy. There is another debug type, 34 // "coro-frame", which results in leaner debug spew. 35 #define DEBUG_TYPE "coro-suspend-crossing" 36 37 enum { SmallVectorThreshold = 32 }; 38 39 // Provides two way mapping between the blocks and numbers. 40 namespace { 41 class BlockToIndexMapping { 42 SmallVector<BasicBlock *, SmallVectorThreshold> V; 43 44 public: 45 size_t size() const { return V.size(); } 46 47 BlockToIndexMapping(Function &F) { 48 for (BasicBlock &BB : F) 49 V.push_back(&BB); 50 std::sort(V.begin(), V.end()); 51 } 52 53 size_t blockToIndex(BasicBlock *BB) const { 54 auto *I = std::lower_bound(V.begin(), V.end(), BB); 55 assert(I != V.end() && *I == BB && "BasicBlockNumberng: Unknown block"); 56 return I - V.begin(); 57 } 58 59 BasicBlock *indexToBlock(unsigned Index) const { return V[Index]; } 60 }; 61 } // end anonymous namespace 62 63 // The SuspendCrossingInfo maintains data that allows to answer a question 64 // whether given two BasicBlocks A and B there is a path from A to B that 65 // passes through a suspend point. 66 // 67 // For every basic block 'i' it maintains a BlockData that consists of: 68 // Consumes: a bit vector which contains a set of indicies of blocks that can 69 // reach block 'i' 70 // Kills: a bit vector which contains a set of indicies of blocks that can 71 // reach block 'i', but one of the path will cross a suspend point 72 // Suspend: a boolean indicating whether block 'i' contains a suspend point. 73 // End: a boolean indicating whether block 'i' contains a coro.end intrinsic. 74 // 75 namespace { 76 struct SuspendCrossingInfo { 77 BlockToIndexMapping Mapping; 78 79 struct BlockData { 80 BitVector Consumes; 81 BitVector Kills; 82 bool Suspend = false; 83 bool End = false; 84 }; 85 SmallVector<BlockData, SmallVectorThreshold> Block; 86 87 iterator_range<succ_iterator> successors(BlockData const &BD) const { 88 BasicBlock *BB = Mapping.indexToBlock(&BD - &Block[0]); 89 return llvm::successors(BB); 90 } 91 92 BlockData &getBlockData(BasicBlock *BB) { 93 return Block[Mapping.blockToIndex(BB)]; 94 } 95 96 void dump() const; 97 void dump(StringRef Label, BitVector const &BV) const; 98 99 SuspendCrossingInfo(Function &F, coro::Shape &Shape); 100 101 bool hasPathCrossingSuspendPoint(BasicBlock *DefBB, BasicBlock *UseBB) const { 102 size_t const DefIndex = Mapping.blockToIndex(DefBB); 103 size_t const UseIndex = Mapping.blockToIndex(UseBB); 104 105 assert(Block[UseIndex].Consumes[DefIndex] && "use must consume def"); 106 bool const Result = Block[UseIndex].Kills[DefIndex]; 107 DEBUG(dbgs() << UseBB->getName() << " => " << DefBB->getName() 108 << " answer is " << Result << "\n"); 109 return Result; 110 } 111 112 bool isDefinitionAcrossSuspend(BasicBlock *DefBB, User *U) const { 113 auto *I = cast<Instruction>(U); 114 115 // We rewrote PHINodes, so that only the ones with exactly one incoming 116 // value need to be analyzed. 117 if (auto *PN = dyn_cast<PHINode>(I)) 118 if (PN->getNumIncomingValues() > 1) 119 return false; 120 121 BasicBlock *UseBB = I->getParent(); 122 return hasPathCrossingSuspendPoint(DefBB, UseBB); 123 } 124 125 bool isDefinitionAcrossSuspend(Argument &A, User *U) const { 126 return isDefinitionAcrossSuspend(&A.getParent()->getEntryBlock(), U); 127 } 128 129 bool isDefinitionAcrossSuspend(Instruction &I, User *U) const { 130 return isDefinitionAcrossSuspend(I.getParent(), U); 131 } 132 }; 133 } // end anonymous namespace 134 135 LLVM_DUMP_METHOD void SuspendCrossingInfo::dump(StringRef Label, 136 BitVector const &BV) const { 137 dbgs() << Label << ":"; 138 for (size_t I = 0, N = BV.size(); I < N; ++I) 139 if (BV[I]) 140 dbgs() << " " << Mapping.indexToBlock(I)->getName(); 141 dbgs() << "\n"; 142 } 143 144 LLVM_DUMP_METHOD void SuspendCrossingInfo::dump() const { 145 for (size_t I = 0, N = Block.size(); I < N; ++I) { 146 BasicBlock *const B = Mapping.indexToBlock(I); 147 dbgs() << B->getName() << ":\n"; 148 dump(" Consumes", Block[I].Consumes); 149 dump(" Kills", Block[I].Kills); 150 } 151 dbgs() << "\n"; 152 } 153 154 SuspendCrossingInfo::SuspendCrossingInfo(Function &F, coro::Shape &Shape) 155 : Mapping(F) { 156 const size_t N = Mapping.size(); 157 Block.resize(N); 158 159 // Initialize every block so that it consumes itself 160 for (size_t I = 0; I < N; ++I) { 161 auto &B = Block[I]; 162 B.Consumes.resize(N); 163 B.Kills.resize(N); 164 B.Consumes.set(I); 165 } 166 167 // Mark all CoroEnd Blocks. We do not propagate Kills beyond coro.ends as 168 // the code beyond coro.end is reachable during initial invocation of the 169 // coroutine. 170 for (auto *CE : Shape.CoroEnds) 171 getBlockData(CE->getParent()).End = true; 172 173 // Mark all suspend blocks and indicate that kill everything they consume. 174 // Note, that crossing coro.save is used to indicate suspend, as any code 175 // between coro.save and coro.suspend may resume the coroutine and all of the 176 // state needs to be saved by that time. 177 for (CoroSuspendInst *CSI : Shape.CoroSuspends) { 178 CoroSaveInst *const CoroSave = CSI->getCoroSave(); 179 BasicBlock *const CoroSaveBB = CoroSave->getParent(); 180 auto &B = getBlockData(CoroSaveBB); 181 B.Suspend = true; 182 B.Kills |= B.Consumes; 183 } 184 185 // Iterate propagating consumes and kills until they stop changing 186 int Iteration = 0; 187 (void)Iteration; 188 189 bool Changed; 190 do { 191 DEBUG(dbgs() << "iteration " << ++Iteration); 192 DEBUG(dbgs() << "==============\n"); 193 194 Changed = false; 195 for (size_t I = 0; I < N; ++I) { 196 auto &B = Block[I]; 197 for (BasicBlock *SI : successors(B)) { 198 199 auto SuccNo = Mapping.blockToIndex(SI); 200 201 // Saved Consumes and Kills bitsets so that it is easy to see 202 // if anything changed after propagation. 203 auto &S = Block[SuccNo]; 204 auto SavedConsumes = S.Consumes; 205 auto SavedKills = S.Kills; 206 207 // Propagate Kills and Consumes from block B into its successor S. 208 S.Consumes |= B.Consumes; 209 S.Kills |= B.Kills; 210 211 // If block B is a suspend block, it should propagate kills into the 212 // its successor for every block B consumes. 213 if (B.Suspend) { 214 S.Kills |= B.Consumes; 215 } 216 if (S.Suspend) { 217 // If block S is a suspend block, it should kill all of the blocks it 218 // consumes. 219 S.Kills |= S.Consumes; 220 } else if (S.End) { 221 // If block S is an end block, it should not propagate kills as the 222 // blocks following coro.end() are reached during initial invocation 223 // of the coroutine while all the data are still available on the 224 // stack or in the registers. 225 S.Kills.reset(); 226 } else { 227 // This is reached when S block it not Suspend nor coro.end and it 228 // need to make sure that it is not in the kill set. 229 S.Kills.reset(SuccNo); 230 } 231 232 // See if anything changed. 233 Changed |= (S.Kills != SavedKills) || (S.Consumes != SavedConsumes); 234 235 if (S.Kills != SavedKills) { 236 DEBUG(dbgs() << "\nblock " << I << " follower " << SI->getName() 237 << "\n"); 238 DEBUG(dump("S.Kills", S.Kills)); 239 DEBUG(dump("SavedKills", SavedKills)); 240 } 241 if (S.Consumes != SavedConsumes) { 242 DEBUG(dbgs() << "\nblock " << I << " follower " << SI << "\n"); 243 DEBUG(dump("S.Consume", S.Consumes)); 244 DEBUG(dump("SavedCons", SavedConsumes)); 245 } 246 } 247 } 248 } while (Changed); 249 DEBUG(dump()); 250 } 251 252 #undef DEBUG_TYPE // "coro-suspend-crossing" 253 #define DEBUG_TYPE "coro-frame" 254 255 // We build up the list of spills for every case where a use is separated 256 // from the definition by a suspend point. 257 258 struct Spill : std::pair<Value *, Instruction *> { 259 using base = std::pair<Value *, Instruction *>; 260 261 Spill(Value *Def, User *U) : base(Def, cast<Instruction>(U)) {} 262 263 Value *def() const { return first; } 264 Instruction *user() const { return second; } 265 BasicBlock *userBlock() const { return second->getParent(); } 266 267 std::pair<Value *, BasicBlock *> getKey() const { 268 return {def(), userBlock()}; 269 } 270 271 bool operator<(Spill const &rhs) const { return getKey() < rhs.getKey(); } 272 }; 273 274 // Note that there may be more than one record with the same value of Def in 275 // the SpillInfo vector. 276 using SpillInfo = SmallVector<Spill, 8>; 277 278 #ifndef NDEBUG 279 static void dump(StringRef Title, SpillInfo const &Spills) { 280 dbgs() << "------------- " << Title << "--------------\n"; 281 Value *CurrentValue = nullptr; 282 for (auto const &E : Spills) { 283 if (CurrentValue != E.def()) { 284 CurrentValue = E.def(); 285 CurrentValue->dump(); 286 } 287 dbgs() << " user: "; 288 E.user()->dump(); 289 } 290 } 291 #endif 292 293 // Build a struct that will keep state for an active coroutine. 294 // struct f.frame { 295 // ResumeFnTy ResumeFnAddr; 296 // ResumeFnTy DestroyFnAddr; 297 // int ResumeIndex; 298 // ... promise (if present) ... 299 // ... spills ... 300 // }; 301 static StructType *buildFrameType(Function &F, coro::Shape &Shape, 302 SpillInfo &Spills) { 303 LLVMContext &C = F.getContext(); 304 SmallString<32> Name(F.getName()); 305 Name.append(".Frame"); 306 StructType *FrameTy = StructType::create(C, Name); 307 auto *FramePtrTy = FrameTy->getPointerTo(); 308 auto *FnTy = FunctionType::get(Type::getVoidTy(C), FramePtrTy, 309 /*IsVarArgs=*/false); 310 auto *FnPtrTy = FnTy->getPointerTo(); 311 312 // Figure out how wide should be an integer type storing the suspend index. 313 unsigned IndexBits = std::max(1U, Log2_64_Ceil(Shape.CoroSuspends.size())); 314 Type *PromiseType = Shape.PromiseAlloca 315 ? Shape.PromiseAlloca->getType()->getElementType() 316 : Type::getInt1Ty(C); 317 SmallVector<Type *, 8> Types{FnPtrTy, FnPtrTy, PromiseType, 318 Type::getIntNTy(C, IndexBits)}; 319 Value *CurrentDef = nullptr; 320 321 // Create an entry for every spilled value. 322 for (auto const &S : Spills) { 323 if (CurrentDef == S.def()) 324 continue; 325 326 CurrentDef = S.def(); 327 // PromiseAlloca was already added to Types array earlier. 328 if (CurrentDef == Shape.PromiseAlloca) 329 continue; 330 331 Type *Ty = nullptr; 332 if (auto *AI = dyn_cast<AllocaInst>(CurrentDef)) 333 Ty = AI->getAllocatedType(); 334 else 335 Ty = CurrentDef->getType(); 336 337 Types.push_back(Ty); 338 } 339 FrameTy->setBody(Types); 340 341 return FrameTy; 342 } 343 344 // Replace all alloca and SSA values that are accessed across suspend points 345 // with GetElementPointer from coroutine frame + loads and stores. Create an 346 // AllocaSpillBB that will become the new entry block for the resume parts of 347 // the coroutine: 348 // 349 // %hdl = coro.begin(...) 350 // whatever 351 // 352 // becomes: 353 // 354 // %hdl = coro.begin(...) 355 // %FramePtr = bitcast i8* hdl to %f.frame* 356 // br label %AllocaSpillBB 357 // 358 // AllocaSpillBB: 359 // ; geps corresponding to allocas that were moved to coroutine frame 360 // br label PostSpill 361 // 362 // PostSpill: 363 // whatever 364 // 365 // 366 static Instruction *insertSpills(SpillInfo &Spills, coro::Shape &Shape) { 367 auto *CB = Shape.CoroBegin; 368 IRBuilder<> Builder(CB->getNextNode()); 369 PointerType *FramePtrTy = Shape.FrameTy->getPointerTo(); 370 auto *FramePtr = 371 cast<Instruction>(Builder.CreateBitCast(CB, FramePtrTy, "FramePtr")); 372 Type *FrameTy = FramePtrTy->getElementType(); 373 374 Value *CurrentValue = nullptr; 375 BasicBlock *CurrentBlock = nullptr; 376 Value *CurrentReload = nullptr; 377 unsigned Index = coro::Shape::LastKnownField; 378 379 // We need to keep track of any allocas that need "spilling" 380 // since they will live in the coroutine frame now, all access to them 381 // need to be changed, not just the access across suspend points 382 // we remember allocas and their indices to be handled once we processed 383 // all the spills. 384 SmallVector<std::pair<AllocaInst *, unsigned>, 4> Allocas; 385 // Promise alloca (if present) has a fixed field number (Shape::PromiseField) 386 if (Shape.PromiseAlloca) 387 Allocas.emplace_back(Shape.PromiseAlloca, coro::Shape::PromiseField); 388 389 // Create a load instruction to reload the spilled value from the coroutine 390 // frame. 391 auto CreateReload = [&](Instruction *InsertBefore) { 392 Builder.SetInsertPoint(InsertBefore); 393 auto *G = Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, Index, 394 CurrentValue->getName() + 395 Twine(".reload.addr")); 396 return isa<AllocaInst>(CurrentValue) 397 ? G 398 : Builder.CreateLoad(G, 399 CurrentValue->getName() + Twine(".reload")); 400 }; 401 402 for (auto const &E : Spills) { 403 // If we have not seen the value, generate a spill. 404 if (CurrentValue != E.def()) { 405 CurrentValue = E.def(); 406 CurrentBlock = nullptr; 407 CurrentReload = nullptr; 408 409 ++Index; 410 411 if (auto *AI = dyn_cast<AllocaInst>(CurrentValue)) { 412 // Spilled AllocaInst will be replaced with GEP from the coroutine frame 413 // there is no spill required. 414 Allocas.emplace_back(AI, Index); 415 if (!AI->isStaticAlloca()) 416 report_fatal_error("Coroutines cannot handle non static allocas yet"); 417 } else { 418 // Otherwise, create a store instruction storing the value into the 419 // coroutine frame. For, argument, we will place the store instruction 420 // right after the coroutine frame pointer instruction, i.e. bitcase of 421 // coro.begin from i8* to %f.frame*. For all other values, the spill is 422 // placed immediately after the definition. 423 Builder.SetInsertPoint( 424 isa<Argument>(CurrentValue) 425 ? FramePtr->getNextNode() 426 : dyn_cast<Instruction>(E.def())->getNextNode()); 427 428 auto *G = Builder.CreateConstInBoundsGEP2_32( 429 FrameTy, FramePtr, 0, Index, 430 CurrentValue->getName() + Twine(".spill.addr")); 431 Builder.CreateStore(CurrentValue, G); 432 } 433 } 434 435 // If we have not seen the use block, generate a reload in it. 436 if (CurrentBlock != E.userBlock()) { 437 CurrentBlock = E.userBlock(); 438 CurrentReload = CreateReload(&*CurrentBlock->getFirstInsertionPt()); 439 } 440 441 // If we have a single edge PHINode, remove it and replace it with a reload 442 // from the coroutine frame. (We already took care of multi edge PHINodes 443 // by rewriting them in the rewritePHIs function). 444 if (auto *PN = dyn_cast<PHINode>(E.user())) { 445 assert(PN->getNumIncomingValues() == 1 && "unexpected number of incoming " 446 "values in the PHINode"); 447 PN->replaceAllUsesWith(CurrentReload); 448 PN->eraseFromParent(); 449 continue; 450 } 451 452 // Replace all uses of CurrentValue in the current instruction with reload. 453 E.user()->replaceUsesOfWith(CurrentValue, CurrentReload); 454 } 455 456 BasicBlock *FramePtrBB = FramePtr->getParent(); 457 Shape.AllocaSpillBlock = 458 FramePtrBB->splitBasicBlock(FramePtr->getNextNode(), "AllocaSpillBB"); 459 Shape.AllocaSpillBlock->splitBasicBlock(&Shape.AllocaSpillBlock->front(), 460 "PostSpill"); 461 462 Builder.SetInsertPoint(&Shape.AllocaSpillBlock->front()); 463 // If we found any allocas, replace all of their remaining uses with Geps. 464 for (auto &P : Allocas) { 465 auto *G = 466 Builder.CreateConstInBoundsGEP2_32(FrameTy, FramePtr, 0, P.second); 467 // We are not using ReplaceInstWithInst(P.first, cast<Instruction>(G)) here, 468 // as we are changing location of the instruction. 469 G->takeName(P.first); 470 P.first->replaceAllUsesWith(G); 471 P.first->eraseFromParent(); 472 } 473 return FramePtr; 474 } 475 476 static void rewritePHIs(BasicBlock &BB) { 477 // For every incoming edge we will create a block holding all 478 // incoming values in a single PHI nodes. 479 // 480 // loop: 481 // %n.val = phi i32[%n, %entry], [%inc, %loop] 482 // 483 // It will create: 484 // 485 // loop.from.entry: 486 // %n.loop.pre = phi i32 [%n, %entry] 487 // br %label loop 488 // loop.from.loop: 489 // %inc.loop.pre = phi i32 [%inc, %loop] 490 // br %label loop 491 // 492 // After this rewrite, further analysis will ignore any phi nodes with more 493 // than one incoming edge. 494 495 // TODO: Simplify PHINodes in the basic block to remove duplicate 496 // predecessors. 497 498 SmallVector<BasicBlock *, 8> Preds(pred_begin(&BB), pred_end(&BB)); 499 for (BasicBlock *Pred : Preds) { 500 auto *IncomingBB = SplitEdge(Pred, &BB); 501 IncomingBB->setName(BB.getName() + Twine(".from.") + Pred->getName()); 502 auto *PN = cast<PHINode>(&BB.front()); 503 do { 504 int Index = PN->getBasicBlockIndex(IncomingBB); 505 Value *V = PN->getIncomingValue(Index); 506 PHINode *InputV = PHINode::Create( 507 V->getType(), 1, V->getName() + Twine(".") + BB.getName(), 508 &IncomingBB->front()); 509 InputV->addIncoming(V, Pred); 510 PN->setIncomingValue(Index, InputV); 511 PN = dyn_cast<PHINode>(PN->getNextNode()); 512 } while (PN); 513 } 514 } 515 516 static void rewritePHIs(Function &F) { 517 SmallVector<BasicBlock *, 8> WorkList; 518 519 for (BasicBlock &BB : F) 520 if (auto *PN = dyn_cast<PHINode>(&BB.front())) 521 if (PN->getNumIncomingValues() > 1) 522 WorkList.push_back(&BB); 523 524 for (BasicBlock *BB : WorkList) 525 rewritePHIs(*BB); 526 } 527 528 // Check for instructions that we can recreate on resume as opposed to spill 529 // the result into a coroutine frame. 530 static bool materializable(Instruction &V) { 531 return isa<CastInst>(&V) || isa<GetElementPtrInst>(&V) || 532 isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<SelectInst>(&V); 533 } 534 535 // For every use of the value that is across suspend point, recreate that value 536 // after a suspend point. 537 static void rewriteMaterializableInstructions(IRBuilder<> &IRB, 538 SpillInfo const &Spills) { 539 BasicBlock *CurrentBlock = nullptr; 540 Instruction *CurrentMaterialization = nullptr; 541 Instruction *CurrentDef = nullptr; 542 543 for (auto const &E : Spills) { 544 // If it is a new definition, update CurrentXXX variables. 545 if (CurrentDef != E.def()) { 546 CurrentDef = cast<Instruction>(E.def()); 547 CurrentBlock = nullptr; 548 CurrentMaterialization = nullptr; 549 } 550 551 // If we have not seen this block, materialize the value. 552 if (CurrentBlock != E.userBlock()) { 553 CurrentBlock = E.userBlock(); 554 CurrentMaterialization = cast<Instruction>(CurrentDef)->clone(); 555 CurrentMaterialization->setName(CurrentDef->getName()); 556 CurrentMaterialization->insertBefore( 557 &*CurrentBlock->getFirstInsertionPt()); 558 } 559 560 if (auto *PN = dyn_cast<PHINode>(E.user())) { 561 assert(PN->getNumIncomingValues() == 1 && "unexpected number of incoming " 562 "values in the PHINode"); 563 PN->replaceAllUsesWith(CurrentMaterialization); 564 PN->eraseFromParent(); 565 continue; 566 } 567 568 // Replace all uses of CurrentDef in the current instruction with the 569 // CurrentMaterialization for the block. 570 E.user()->replaceUsesOfWith(CurrentDef, CurrentMaterialization); 571 } 572 } 573 574 // Move early uses of spilled variable after CoroBegin. 575 // For example, if a parameter had address taken, we may end up with the code 576 // like: 577 // define @f(i32 %n) { 578 // %n.addr = alloca i32 579 // store %n, %n.addr 580 // ... 581 // call @coro.begin 582 // we need to move the store after coro.begin 583 static void moveSpillUsesAfterCoroBegin(Function &F, SpillInfo const &Spills, 584 CoroBeginInst *CoroBegin) { 585 DominatorTree DT(F); 586 SmallVector<Instruction *, 8> NeedsMoving; 587 588 Value *CurrentValue = nullptr; 589 590 for (auto const &E : Spills) { 591 if (CurrentValue == E.def()) 592 continue; 593 594 CurrentValue = E.def(); 595 596 for (User *U : CurrentValue->users()) { 597 Instruction *I = cast<Instruction>(U); 598 if (!DT.dominates(CoroBegin, I)) { 599 // TODO: Make this more robust. Currently if we run into a situation 600 // where simple instruction move won't work we panic and 601 // report_fatal_error. 602 for (User *UI : I->users()) { 603 if (!DT.dominates(CoroBegin, cast<Instruction>(UI))) 604 report_fatal_error("cannot move instruction since its users are not" 605 " dominated by CoroBegin"); 606 } 607 608 DEBUG(dbgs() << "will move: " << *I << "\n"); 609 NeedsMoving.push_back(I); 610 } 611 } 612 } 613 614 Instruction *InsertPt = CoroBegin->getNextNode(); 615 for (Instruction *I : NeedsMoving) 616 I->moveBefore(InsertPt); 617 } 618 619 // Splits the block at a particular instruction unless it is the first 620 // instruction in the block with a single predecessor. 621 static BasicBlock *splitBlockIfNotFirst(Instruction *I, const Twine &Name) { 622 auto *BB = I->getParent(); 623 if (&BB->front() == I) { 624 if (BB->getSinglePredecessor()) { 625 BB->setName(Name); 626 return BB; 627 } 628 } 629 return BB->splitBasicBlock(I, Name); 630 } 631 632 // Split above and below a particular instruction so that it 633 // will be all alone by itself in a block. 634 static void splitAround(Instruction *I, const Twine &Name) { 635 splitBlockIfNotFirst(I, Name); 636 splitBlockIfNotFirst(I->getNextNode(), "After" + Name); 637 } 638 639 void coro::buildCoroutineFrame(Function &F, Shape &Shape) { 640 Shape.PromiseAlloca = Shape.CoroBegin->getId()->getPromise(); 641 if (Shape.PromiseAlloca) { 642 Shape.CoroBegin->getId()->clearPromise(); 643 } 644 645 // Make sure that all coro.saves and the fallthrough coro.end are in their 646 // own block to simplify the logic of building up SuspendCrossing data. 647 for (CoroSuspendInst *CSI : Shape.CoroSuspends) 648 splitAround(CSI->getCoroSave(), "CoroSave"); 649 650 // Put fallthrough CoroEnd into its own block. Note: Shape::buildFrom places 651 // the fallthrough coro.end as the first element of CoroEnds array. 652 splitAround(Shape.CoroEnds.front(), "CoroEnd"); 653 654 // Transforms multi-edge PHI Nodes, so that any value feeding into a PHI will 655 // never has its definition separated from the PHI by the suspend point. 656 rewritePHIs(F); 657 658 // Build suspend crossing info. 659 SuspendCrossingInfo Checker(F, Shape); 660 661 IRBuilder<> Builder(F.getContext()); 662 SpillInfo Spills; 663 664 // See if there are materializable instructions across suspend points. 665 for (Instruction &I : instructions(F)) 666 if (materializable(I)) 667 for (User *U : I.users()) 668 if (Checker.isDefinitionAcrossSuspend(I, U)) 669 Spills.emplace_back(&I, U); 670 671 // Rewrite materializable instructions to be materialized at the use point. 672 std::sort(Spills.begin(), Spills.end()); 673 DEBUG(dump("Materializations", Spills)); 674 rewriteMaterializableInstructions(Builder, Spills); 675 676 // Collect the spills for arguments and other not-materializable values. 677 Spills.clear(); 678 for (Argument &A : F.getArgumentList()) 679 for (User *U : A.users()) 680 if (Checker.isDefinitionAcrossSuspend(A, U)) 681 Spills.emplace_back(&A, U); 682 683 for (Instruction &I : instructions(F)) { 684 // token returned by CoroSave is an artifact of how we build save/suspend 685 // pairs and should not be part of the Coroutine Frame 686 if (isa<CoroSaveInst>(&I)) 687 continue; 688 // CoroBeginInst returns a handle to a coroutine which is passed as a sole 689 // parameter to .resume and .cleanup parts and should not go into coroutine 690 // frame. 691 if (isa<CoroBeginInst>(&I)) 692 continue; 693 // A token returned CoroIdInst is used to tie together structural intrinsics 694 // in a coroutine. It should not be saved to the coroutine frame. 695 if (isa<CoroIdInst>(&I)) 696 continue; 697 // The Coroutine Promise always included into coroutine frame, no need to 698 // check for suspend crossing. 699 if (Shape.PromiseAlloca == &I) 700 continue; 701 702 for (User *U : I.users()) 703 if (Checker.isDefinitionAcrossSuspend(I, U)) { 704 // We cannot spill a token. 705 if (I.getType()->isTokenTy()) 706 report_fatal_error( 707 "token definition is separated from the use by a suspend point"); 708 assert(!materializable(I) && 709 "rewriteMaterializable did not do its job"); 710 Spills.emplace_back(&I, U); 711 } 712 } 713 std::sort(Spills.begin(), Spills.end()); 714 DEBUG(dump("Spills", Spills)); 715 moveSpillUsesAfterCoroBegin(F, Spills, Shape.CoroBegin); 716 Shape.FrameTy = buildFrameType(F, Shape, Spills); 717 Shape.FramePtr = insertSpills(Spills, Shape); 718 } 719