1 //===-- WebAssemblyCFGStackify.cpp - CFG Stackification -------------------===// 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 /// 10 /// \file 11 /// \brief This file implements a CFG stacking pass. 12 /// 13 /// This pass reorders the blocks in a function to put them into topological 14 /// order, ignoring loop backedges, and without any loop being interrupted 15 /// by a block not dominated by the loop header, with special care to keep the 16 /// order as similar as possible to the original order. 17 /// 18 /// Then, it inserts BLOCK and LOOP markers to mark the start of scopes, since 19 /// scope boundaries serve as the labels for WebAssembly's control transfers. 20 /// 21 /// This is sufficient to convert arbitrary CFGs into a form that works on 22 /// WebAssembly, provided that all loops are single-entry. 23 /// 24 //===----------------------------------------------------------------------===// 25 26 #include "WebAssembly.h" 27 #include "MCTargetDesc/WebAssemblyMCTargetDesc.h" 28 #include "WebAssemblyMachineFunctionInfo.h" 29 #include "WebAssemblySubtarget.h" 30 #include "llvm/ADT/PriorityQueue.h" 31 #include "llvm/ADT/SCCIterator.h" 32 #include "llvm/ADT/SetVector.h" 33 #include "llvm/CodeGen/MachineDominators.h" 34 #include "llvm/CodeGen/MachineFunction.h" 35 #include "llvm/CodeGen/MachineInstrBuilder.h" 36 #include "llvm/CodeGen/MachineLoopInfo.h" 37 #include "llvm/CodeGen/MachineRegisterInfo.h" 38 #include "llvm/CodeGen/Passes.h" 39 #include "llvm/Support/Debug.h" 40 #include "llvm/Support/raw_ostream.h" 41 using namespace llvm; 42 43 #define DEBUG_TYPE "wasm-cfg-stackify" 44 45 namespace { 46 class WebAssemblyCFGStackify final : public MachineFunctionPass { 47 const char *getPassName() const override { 48 return "WebAssembly CFG Stackify"; 49 } 50 51 void getAnalysisUsage(AnalysisUsage &AU) const override { 52 AU.setPreservesCFG(); 53 AU.addRequired<MachineDominatorTree>(); 54 AU.addPreserved<MachineDominatorTree>(); 55 AU.addRequired<MachineLoopInfo>(); 56 AU.addPreserved<MachineLoopInfo>(); 57 MachineFunctionPass::getAnalysisUsage(AU); 58 } 59 60 bool runOnMachineFunction(MachineFunction &MF) override; 61 62 public: 63 static char ID; // Pass identification, replacement for typeid 64 WebAssemblyCFGStackify() : MachineFunctionPass(ID) {} 65 }; 66 } // end anonymous namespace 67 68 char WebAssemblyCFGStackify::ID = 0; 69 FunctionPass *llvm::createWebAssemblyCFGStackify() { 70 return new WebAssemblyCFGStackify(); 71 } 72 73 static void EliminateMultipleEntryLoops(MachineFunction &MF, 74 const MachineLoopInfo &MLI) { 75 SmallPtrSet<MachineBasicBlock *, 8> InSet; 76 for (scc_iterator<MachineFunction *> I = scc_begin(&MF), E = scc_end(&MF); 77 I != E; ++I) { 78 const std::vector<MachineBasicBlock *> &CurrentSCC = *I; 79 80 // Skip trivial SCCs. 81 if (CurrentSCC.size() == 1) 82 continue; 83 84 InSet.insert(CurrentSCC.begin(), CurrentSCC.end()); 85 MachineBasicBlock *Header = nullptr; 86 for (MachineBasicBlock *MBB : CurrentSCC) { 87 for (MachineBasicBlock *Pred : MBB->predecessors()) { 88 if (InSet.count(Pred)) 89 continue; 90 if (!Header) { 91 Header = MBB; 92 break; 93 } 94 // TODO: Implement multiple-entry loops. 95 report_fatal_error("multiple-entry loops are not supported yet"); 96 } 97 } 98 assert(MLI.isLoopHeader(Header)); 99 100 InSet.clear(); 101 } 102 } 103 104 /// Return the "bottom" block of a loop. This differs from 105 /// MachineLoop::getBottomBlock in that it works even if the loop is 106 /// discontiguous. 107 static MachineBasicBlock *LoopBottom(const MachineLoop *Loop) { 108 MachineBasicBlock *Bottom = Loop->getHeader(); 109 for (MachineBasicBlock *MBB : Loop->blocks()) 110 if (MBB->getNumber() > Bottom->getNumber()) 111 Bottom = MBB; 112 return Bottom; 113 } 114 115 static void MaybeUpdateTerminator(MachineBasicBlock *MBB) { 116 #ifndef NDEBUG 117 bool AnyBarrier = false; 118 #endif 119 bool AllAnalyzable = true; 120 for (const MachineInstr &Term : MBB->terminators()) { 121 #ifndef NDEBUG 122 AnyBarrier |= Term.isBarrier(); 123 #endif 124 AllAnalyzable &= Term.isBranch() && !Term.isIndirectBranch(); 125 } 126 assert((AnyBarrier || AllAnalyzable) && 127 "AnalyzeBranch needs to analyze any block with a fallthrough"); 128 if (AllAnalyzable) 129 MBB->updateTerminator(); 130 } 131 132 namespace { 133 /// Sort blocks by their number. 134 struct CompareBlockNumbers { 135 bool operator()(const MachineBasicBlock *A, 136 const MachineBasicBlock *B) const { 137 return A->getNumber() > B->getNumber(); 138 } 139 }; 140 /// Sort blocks by their number in the opposite order.. 141 struct CompareBlockNumbersBackwards { 142 bool operator()(const MachineBasicBlock *A, 143 const MachineBasicBlock *B) const { 144 return A->getNumber() < B->getNumber(); 145 } 146 }; 147 /// Bookkeeping for a loop to help ensure that we don't mix blocks not dominated 148 /// by the loop header among the loop's blocks. 149 struct Entry { 150 const MachineLoop *Loop; 151 unsigned NumBlocksLeft; 152 153 /// List of blocks not dominated by Loop's header that are deferred until 154 /// after all of Loop's blocks have been seen. 155 std::vector<MachineBasicBlock *> Deferred; 156 157 explicit Entry(const MachineLoop *L) 158 : Loop(L), NumBlocksLeft(L->getNumBlocks()) {} 159 }; 160 } 161 162 /// Sort the blocks, taking special care to make sure that loops are not 163 /// interrupted by blocks not dominated by their header. 164 /// TODO: There are many opportunities for improving the heuristics here. 165 /// Explore them. 166 static void SortBlocks(MachineFunction &MF, const MachineLoopInfo &MLI, 167 const MachineDominatorTree &MDT) { 168 // Prepare for a topological sort: Record the number of predecessors each 169 // block has, ignoring loop backedges. 170 MF.RenumberBlocks(); 171 SmallVector<unsigned, 16> NumPredsLeft(MF.getNumBlockIDs(), 0); 172 for (MachineBasicBlock &MBB : MF) { 173 unsigned N = MBB.pred_size(); 174 if (MachineLoop *L = MLI.getLoopFor(&MBB)) 175 if (L->getHeader() == &MBB) 176 for (const MachineBasicBlock *Pred : MBB.predecessors()) 177 if (L->contains(Pred)) 178 --N; 179 NumPredsLeft[MBB.getNumber()] = N; 180 } 181 182 // Topological sort the CFG, with additional constraints: 183 // - Between a loop header and the last block in the loop, there can be 184 // no blocks not dominated by the loop header. 185 // - It's desirable to preserve the original block order when possible. 186 // We use two ready lists; Preferred and Ready. Preferred has recently 187 // processed sucessors, to help preserve block sequences from the original 188 // order. Ready has the remaining ready blocks. 189 PriorityQueue<MachineBasicBlock *, std::vector<MachineBasicBlock *>, 190 CompareBlockNumbers> 191 Preferred; 192 PriorityQueue<MachineBasicBlock *, std::vector<MachineBasicBlock *>, 193 CompareBlockNumbersBackwards> 194 Ready; 195 SmallVector<Entry, 4> Loops; 196 for (MachineBasicBlock *MBB = &MF.front();;) { 197 const MachineLoop *L = MLI.getLoopFor(MBB); 198 if (L) { 199 // If MBB is a loop header, add it to the active loop list. We can't put 200 // any blocks that it doesn't dominate until we see the end of the loop. 201 if (L->getHeader() == MBB) 202 Loops.push_back(Entry(L)); 203 // For each active loop the block is in, decrement the count. If MBB is 204 // the last block in an active loop, take it off the list and pick up any 205 // blocks deferred because the header didn't dominate them. 206 for (Entry &E : Loops) 207 if (E.Loop->contains(MBB) && --E.NumBlocksLeft == 0) 208 for (auto DeferredBlock : E.Deferred) 209 Ready.push(DeferredBlock); 210 while (!Loops.empty() && Loops.back().NumBlocksLeft == 0) 211 Loops.pop_back(); 212 } 213 // The main topological sort logic. 214 for (MachineBasicBlock *Succ : MBB->successors()) { 215 // Ignore backedges. 216 if (MachineLoop *SuccL = MLI.getLoopFor(Succ)) 217 if (SuccL->getHeader() == Succ && SuccL->contains(MBB)) 218 continue; 219 // Decrement the predecessor count. If it's now zero, it's ready. 220 if (--NumPredsLeft[Succ->getNumber()] == 0) 221 Preferred.push(Succ); 222 } 223 // Determine the block to follow MBB. First try to find a preferred block, 224 // to preserve the original block order when possible. 225 MachineBasicBlock *Next = nullptr; 226 while (!Preferred.empty()) { 227 Next = Preferred.top(); 228 Preferred.pop(); 229 // If X isn't dominated by the top active loop header, defer it until that 230 // loop is done. 231 if (!Loops.empty() && 232 !MDT.dominates(Loops.back().Loop->getHeader(), Next)) { 233 Loops.back().Deferred.push_back(Next); 234 Next = nullptr; 235 continue; 236 } 237 // If Next was originally ordered before MBB, and it isn't because it was 238 // loop-rotated above the header, it's not preferred. 239 if (Next->getNumber() < MBB->getNumber() && 240 (!L || !L->contains(Next) || 241 L->getHeader()->getNumber() < Next->getNumber())) { 242 Ready.push(Next); 243 Next = nullptr; 244 continue; 245 } 246 break; 247 } 248 // If we didn't find a suitable block in the Preferred list, check the 249 // general Ready list. 250 if (!Next) { 251 // If there are no more blocks to process, we're done. 252 if (Ready.empty()) { 253 MaybeUpdateTerminator(MBB); 254 break; 255 } 256 for (;;) { 257 Next = Ready.top(); 258 Ready.pop(); 259 // If Next isn't dominated by the top active loop header, defer it until 260 // that loop is done. 261 if (!Loops.empty() && 262 !MDT.dominates(Loops.back().Loop->getHeader(), Next)) { 263 Loops.back().Deferred.push_back(Next); 264 continue; 265 } 266 break; 267 } 268 } 269 // Move the next block into place and iterate. 270 Next->moveAfter(MBB); 271 MaybeUpdateTerminator(MBB); 272 MBB = Next; 273 } 274 assert(Loops.empty() && "Active loop list not finished"); 275 MF.RenumberBlocks(); 276 277 #ifndef NDEBUG 278 SmallSetVector<MachineLoop *, 8> OnStack; 279 280 // Insert a sentinel representing the degenerate loop that starts at the 281 // function entry block and includes the entire function as a "loop" that 282 // executes once. 283 OnStack.insert(nullptr); 284 285 for (auto &MBB : MF) { 286 assert(MBB.getNumber() >= 0 && "Renumbered blocks should be non-negative."); 287 288 MachineLoop *Loop = MLI.getLoopFor(&MBB); 289 if (Loop && &MBB == Loop->getHeader()) { 290 // Loop header. The loop predecessor should be sorted above, and the other 291 // predecessors should be backedges below. 292 for (auto Pred : MBB.predecessors()) 293 assert( 294 (Pred->getNumber() < MBB.getNumber() || Loop->contains(Pred)) && 295 "Loop header predecessors must be loop predecessors or backedges"); 296 assert(OnStack.insert(Loop) && "Loops should be declared at most once."); 297 } else { 298 // Not a loop header. All predecessors should be sorted above. 299 for (auto Pred : MBB.predecessors()) 300 assert(Pred->getNumber() < MBB.getNumber() && 301 "Non-loop-header predecessors should be topologically sorted"); 302 assert(OnStack.count(MLI.getLoopFor(&MBB)) && 303 "Blocks must be nested in their loops"); 304 } 305 while (OnStack.size() > 1 && &MBB == LoopBottom(OnStack.back())) 306 OnStack.pop_back(); 307 } 308 assert(OnStack.pop_back_val() == nullptr && 309 "The function entry block shouldn't actually be a loop header"); 310 assert(OnStack.empty() && 311 "Control flow stack pushes and pops should be balanced."); 312 #endif 313 } 314 315 /// Test whether Pred has any terminators explicitly branching to MBB, as 316 /// opposed to falling through. Note that it's possible (eg. in unoptimized 317 /// code) for a branch instruction to both branch to a block and fallthrough 318 /// to it, so we check the actual branch operands to see if there are any 319 /// explicit mentions. 320 static bool ExplicitlyBranchesTo(MachineBasicBlock *Pred, 321 MachineBasicBlock *MBB) { 322 for (MachineInstr &MI : Pred->terminators()) 323 for (MachineOperand &MO : MI.explicit_operands()) 324 if (MO.isMBB() && MO.getMBB() == MBB) 325 return true; 326 return false; 327 } 328 329 /// Test whether MI is a child of some other node in an expression tree. 330 static bool IsChild(const MachineInstr *MI, 331 const WebAssemblyFunctionInfo &MFI) { 332 if (MI->getNumOperands() == 0) 333 return false; 334 const MachineOperand &MO = MI->getOperand(0); 335 if (!MO.isReg() || MO.isImplicit() || !MO.isDef()) 336 return false; 337 unsigned Reg = MO.getReg(); 338 return TargetRegisterInfo::isVirtualRegister(Reg) && 339 MFI.isVRegStackified(Reg); 340 } 341 342 /// Insert a BLOCK marker for branches to MBB (if needed). 343 static void PlaceBlockMarker(MachineBasicBlock &MBB, MachineFunction &MF, 344 SmallVectorImpl<MachineBasicBlock *> &ScopeTops, 345 const WebAssemblyInstrInfo &TII, 346 const MachineLoopInfo &MLI, 347 MachineDominatorTree &MDT, 348 WebAssemblyFunctionInfo &MFI) { 349 // First compute the nearest common dominator of all forward non-fallthrough 350 // predecessors so that we minimize the time that the BLOCK is on the stack, 351 // which reduces overall stack height. 352 MachineBasicBlock *Header = nullptr; 353 bool IsBranchedTo = false; 354 int MBBNumber = MBB.getNumber(); 355 for (MachineBasicBlock *Pred : MBB.predecessors()) 356 if (Pred->getNumber() < MBBNumber) { 357 Header = Header ? MDT.findNearestCommonDominator(Header, Pred) : Pred; 358 if (ExplicitlyBranchesTo(Pred, &MBB)) 359 IsBranchedTo = true; 360 } 361 if (!Header) 362 return; 363 if (!IsBranchedTo) 364 return; 365 366 assert(&MBB != &MF.front() && "Header blocks shouldn't have predecessors"); 367 MachineBasicBlock *LayoutPred = &*prev(MachineFunction::iterator(&MBB)); 368 369 // If the nearest common dominator is inside a more deeply nested context, 370 // walk out to the nearest scope which isn't more deeply nested. 371 for (MachineFunction::iterator I(LayoutPred), E(Header); I != E; --I) { 372 if (MachineBasicBlock *ScopeTop = ScopeTops[I->getNumber()]) { 373 if (ScopeTop->getNumber() > Header->getNumber()) { 374 // Skip over an intervening scope. 375 I = next(MachineFunction::iterator(ScopeTop)); 376 } else { 377 // We found a scope level at an appropriate depth. 378 Header = ScopeTop; 379 break; 380 } 381 } 382 } 383 384 // If there's a loop which ends just before MBB which contains Header, we can 385 // reuse its label instead of inserting a new BLOCK. 386 for (MachineLoop *Loop = MLI.getLoopFor(LayoutPred); 387 Loop && Loop->contains(LayoutPred); Loop = Loop->getParentLoop()) 388 if (Loop && LoopBottom(Loop) == LayoutPred && Loop->contains(Header)) 389 return; 390 391 // Decide where in Header to put the BLOCK. 392 MachineBasicBlock::iterator InsertPos; 393 MachineLoop *HeaderLoop = MLI.getLoopFor(Header); 394 if (HeaderLoop && MBB.getNumber() > LoopBottom(HeaderLoop)->getNumber()) { 395 // Header is the header of a loop that does not lexically contain MBB, so 396 // the BLOCK needs to be above the LOOP, after any END constructs. 397 InsertPos = Header->begin(); 398 while (InsertPos->getOpcode() != WebAssembly::LOOP) 399 ++InsertPos; 400 } else { 401 // Otherwise, insert the BLOCK as late in Header as we can, but before the 402 // beginning of the local expression tree and any nested BLOCKs. 403 InsertPos = Header->getFirstTerminator(); 404 while (InsertPos != Header->begin() && IsChild(prev(InsertPos), MFI) && 405 prev(InsertPos)->getOpcode() != WebAssembly::LOOP && 406 prev(InsertPos)->getOpcode() != WebAssembly::END_BLOCK && 407 prev(InsertPos)->getOpcode() != WebAssembly::END_LOOP) 408 --InsertPos; 409 } 410 411 // Add the BLOCK. 412 BuildMI(*Header, InsertPos, DebugLoc(), TII.get(WebAssembly::BLOCK)); 413 414 // Mark the end of the block. 415 InsertPos = MBB.begin(); 416 while (InsertPos != MBB.end() && 417 InsertPos->getOpcode() == WebAssembly::END_LOOP) 418 ++InsertPos; 419 BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::END_BLOCK)); 420 421 // Track the farthest-spanning scope that ends at this point. 422 int Number = MBB.getNumber(); 423 if (!ScopeTops[Number] || 424 ScopeTops[Number]->getNumber() > Header->getNumber()) 425 ScopeTops[Number] = Header; 426 } 427 428 /// Insert a LOOP marker for a loop starting at MBB (if it's a loop header). 429 static void PlaceLoopMarker( 430 MachineBasicBlock &MBB, MachineFunction &MF, 431 SmallVectorImpl<MachineBasicBlock *> &ScopeTops, 432 DenseMap<const MachineInstr *, const MachineBasicBlock *> &LoopTops, 433 const WebAssemblyInstrInfo &TII, const MachineLoopInfo &MLI) { 434 MachineLoop *Loop = MLI.getLoopFor(&MBB); 435 if (!Loop || Loop->getHeader() != &MBB) 436 return; 437 438 // The operand of a LOOP is the first block after the loop. If the loop is the 439 // bottom of the function, insert a dummy block at the end. 440 MachineBasicBlock *Bottom = LoopBottom(Loop); 441 auto Iter = next(MachineFunction::iterator(Bottom)); 442 if (Iter == MF.end()) { 443 MachineBasicBlock *Label = MF.CreateMachineBasicBlock(); 444 // Give it a fake predecessor so that AsmPrinter prints its label. 445 Label->addSuccessor(Label); 446 MF.push_back(Label); 447 Iter = next(MachineFunction::iterator(Bottom)); 448 } 449 MachineBasicBlock *AfterLoop = &*Iter; 450 451 // Mark the beginning of the loop (after the end of any existing loop that 452 // ends here). 453 auto InsertPos = MBB.begin(); 454 while (InsertPos != MBB.end() && 455 InsertPos->getOpcode() == WebAssembly::END_LOOP) 456 ++InsertPos; 457 BuildMI(MBB, InsertPos, DebugLoc(), TII.get(WebAssembly::LOOP)); 458 459 // Mark the end of the loop. 460 MachineInstr *End = BuildMI(*AfterLoop, AfterLoop->begin(), DebugLoc(), 461 TII.get(WebAssembly::END_LOOP)); 462 LoopTops[End] = &MBB; 463 464 assert((!ScopeTops[AfterLoop->getNumber()] || 465 ScopeTops[AfterLoop->getNumber()]->getNumber() < MBB.getNumber()) && 466 "With block sorting the outermost loop for a block should be first."); 467 if (!ScopeTops[AfterLoop->getNumber()]) 468 ScopeTops[AfterLoop->getNumber()] = &MBB; 469 } 470 471 static unsigned 472 GetDepth(const SmallVectorImpl<const MachineBasicBlock *> &Stack, 473 const MachineBasicBlock *MBB) { 474 unsigned Depth = 0; 475 for (auto X : reverse(Stack)) { 476 if (X == MBB) 477 break; 478 ++Depth; 479 } 480 assert(Depth < Stack.size() && "Branch destination should be in scope"); 481 return Depth; 482 } 483 484 /// Insert LOOP and BLOCK markers at appropriate places. 485 static void PlaceMarkers(MachineFunction &MF, const MachineLoopInfo &MLI, 486 const WebAssemblyInstrInfo &TII, 487 MachineDominatorTree &MDT, 488 WebAssemblyFunctionInfo &MFI) { 489 // For each block whose label represents the end of a scope, record the block 490 // which holds the beginning of the scope. This will allow us to quickly skip 491 // over scoped regions when walking blocks. We allocate one more than the 492 // number of blocks in the function to accommodate for the possible fake block 493 // we may insert at the end. 494 SmallVector<MachineBasicBlock *, 8> ScopeTops(MF.getNumBlockIDs() + 1); 495 496 // For eacn LOOP_END, the corresponding LOOP. 497 DenseMap<const MachineInstr *, const MachineBasicBlock *> LoopTops; 498 499 for (auto &MBB : MF) { 500 // Place the LOOP for MBB if MBB is the header of a loop. 501 PlaceLoopMarker(MBB, MF, ScopeTops, LoopTops, TII, MLI); 502 503 // Place the BLOCK for MBB if MBB is branched to from above. 504 PlaceBlockMarker(MBB, MF, ScopeTops, TII, MLI, MDT, MFI); 505 } 506 507 // Now rewrite references to basic blocks to be depth immediates. 508 SmallVector<const MachineBasicBlock *, 8> Stack; 509 for (auto &MBB : reverse(MF)) { 510 for (auto &MI : reverse(MBB)) { 511 switch (MI.getOpcode()) { 512 case WebAssembly::BLOCK: 513 assert(ScopeTops[Stack.back()->getNumber()] == &MBB && 514 "Block should be balanced"); 515 Stack.pop_back(); 516 break; 517 case WebAssembly::LOOP: 518 assert(Stack.back() == &MBB && "Loop top should be balanced"); 519 Stack.pop_back(); 520 Stack.pop_back(); 521 break; 522 case WebAssembly::END_BLOCK: 523 Stack.push_back(&MBB); 524 break; 525 case WebAssembly::END_LOOP: 526 Stack.push_back(&MBB); 527 Stack.push_back(LoopTops[&MI]); 528 break; 529 default: 530 if (MI.isTerminator()) { 531 // Rewrite MBB operands to be depth immediates. 532 SmallVector<MachineOperand, 4> Ops(MI.operands()); 533 while (MI.getNumOperands() > 0) 534 MI.RemoveOperand(MI.getNumOperands() - 1); 535 for (auto MO : Ops) { 536 if (MO.isMBB()) 537 MO = MachineOperand::CreateImm(GetDepth(Stack, MO.getMBB())); 538 MI.addOperand(MF, MO); 539 } 540 } 541 break; 542 } 543 } 544 } 545 assert(Stack.empty() && "Control flow should be balanced"); 546 } 547 548 bool WebAssemblyCFGStackify::runOnMachineFunction(MachineFunction &MF) { 549 DEBUG(dbgs() << "********** CFG Stackifying **********\n" 550 "********** Function: " 551 << MF.getName() << '\n'); 552 553 const auto &MLI = getAnalysis<MachineLoopInfo>(); 554 auto &MDT = getAnalysis<MachineDominatorTree>(); 555 // Liveness is not tracked for EXPR_STACK physreg. 556 const auto &TII = *MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo(); 557 WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>(); 558 MF.getRegInfo().invalidateLiveness(); 559 560 // Sorting needs all loops to be single-entry. 561 EliminateMultipleEntryLoops(MF, MLI); 562 563 // Sort the blocks, with contiguous loops. 564 SortBlocks(MF, MLI, MDT); 565 566 // Place the BLOCK and LOOP markers to indicate the beginnings of scopes. 567 PlaceMarkers(MF, MLI, TII, MDT, MFI); 568 569 return true; 570 } 571