1 //===- R600MachineCFGStructurizer.cpp - CFG Structurizer ------------------===// 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 9 #include "MCTargetDesc/R600MCTargetDesc.h" 10 #include "R600.h" 11 #include "R600RegisterInfo.h" 12 #include "R600Subtarget.h" 13 #include "llvm/ADT/DepthFirstIterator.h" 14 #include "llvm/ADT/SCCIterator.h" 15 #include "llvm/ADT/Statistic.h" 16 #include "llvm/CodeGen/MachineFunction.h" 17 #include "llvm/CodeGen/MachineFunctionPass.h" 18 #include "llvm/CodeGen/MachineJumpTableInfo.h" 19 #include "llvm/CodeGen/MachineLoopInfo.h" 20 #include "llvm/CodeGen/MachinePostDominators.h" 21 #include "llvm/InitializePasses.h" 22 23 using namespace llvm; 24 25 #define DEBUG_TYPE "structcfg" 26 27 enum { DEFAULT_VEC_SLOTS = 8 }; 28 29 // TODO: move-begin. 30 31 //===----------------------------------------------------------------------===// 32 // 33 // Statistics for CFGStructurizer. 34 // 35 //===----------------------------------------------------------------------===// 36 37 STATISTIC(numSerialPatternMatch, "CFGStructurizer number of serial pattern " 38 "matched"); 39 STATISTIC(numIfPatternMatch, "CFGStructurizer number of if pattern " 40 "matched"); 41 STATISTIC(numClonedBlock, "CFGStructurizer cloned blocks"); 42 STATISTIC(numClonedInstr, "CFGStructurizer cloned instructions"); 43 44 namespace { 45 46 //===----------------------------------------------------------------------===// 47 // 48 // Miscellaneous utility for CFGStructurizer. 49 // 50 //===----------------------------------------------------------------------===// 51 52 #define SHOWNEWINSTR(i) LLVM_DEBUG(dbgs() << "New instr: " << *i << "\n"); 53 54 #define SHOWNEWBLK(b, msg) \ 55 LLVM_DEBUG(dbgs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 56 dbgs() << "\n";); 57 58 #define SHOWBLK_DETAIL(b, msg) \ 59 LLVM_DEBUG(if (b) { \ 60 dbgs() << msg << "BB" << b->getNumber() << "size " << b->size(); \ 61 b->print(dbgs()); \ 62 dbgs() << "\n"; \ 63 }); 64 65 #define INVALIDSCCNUM -1 66 67 //===----------------------------------------------------------------------===// 68 // 69 // supporting data structure for CFGStructurizer 70 // 71 //===----------------------------------------------------------------------===// 72 73 class BlockInformation { 74 public: 75 bool IsRetired = false; 76 int SccNum = INVALIDSCCNUM; 77 78 BlockInformation() = default; 79 }; 80 81 //===----------------------------------------------------------------------===// 82 // 83 // CFGStructurizer 84 // 85 //===----------------------------------------------------------------------===// 86 87 class R600MachineCFGStructurizer : public MachineFunctionPass { 88 public: 89 using MBBVector = SmallVector<MachineBasicBlock *, 32>; 90 using MBBInfoMap = std::map<MachineBasicBlock *, BlockInformation *>; 91 using LoopLandInfoMap = std::map<MachineLoop *, MachineBasicBlock *>; 92 93 enum PathToKind { 94 Not_SinglePath = 0, 95 SinglePath_InPath = 1, 96 SinglePath_NotInPath = 2 97 }; 98 99 static char ID; 100 101 R600MachineCFGStructurizer() : MachineFunctionPass(ID) {} 102 103 StringRef getPassName() const override { 104 return "AMDGPU Control Flow Graph structurizer Pass"; 105 } 106 107 void getAnalysisUsage(AnalysisUsage &AU) const override { 108 AU.addRequired<MachineDominatorTreeWrapperPass>(); 109 AU.addRequired<MachinePostDominatorTreeWrapperPass>(); 110 AU.addRequired<MachineLoopInfoWrapperPass>(); 111 MachineFunctionPass::getAnalysisUsage(AU); 112 } 113 114 /// Perform the CFG structurization 115 bool run(); 116 117 /// Perform the CFG preparation 118 /// This step will remove every unconditionnal/dead jump instructions and make 119 /// sure all loops have an exit block 120 bool prepare(); 121 122 bool runOnMachineFunction(MachineFunction &MF) override { 123 // FIXME: This pass causes verification failures. 124 MF.getProperties().setFailsVerification(); 125 126 TII = MF.getSubtarget<R600Subtarget>().getInstrInfo(); 127 TRI = &TII->getRegisterInfo(); 128 LLVM_DEBUG(MF.dump();); 129 OrderedBlks.clear(); 130 Visited.clear(); 131 FuncRep = &MF; 132 MLI = &getAnalysis<MachineLoopInfoWrapperPass>().getLI(); 133 LLVM_DEBUG(dbgs() << "LoopInfo:\n"; PrintLoopinfo(*MLI);); 134 MDT = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree(); 135 LLVM_DEBUG(MDT->print(dbgs());); 136 PDT = &getAnalysis<MachinePostDominatorTreeWrapperPass>().getPostDomTree(); 137 LLVM_DEBUG(PDT->print(dbgs());); 138 prepare(); 139 run(); 140 LLVM_DEBUG(MF.dump();); 141 return true; 142 } 143 144 protected: 145 MachineDominatorTree *MDT; 146 MachinePostDominatorTree *PDT; 147 MachineLoopInfo *MLI; 148 const R600InstrInfo *TII = nullptr; 149 const R600RegisterInfo *TRI = nullptr; 150 151 // PRINT FUNCTIONS 152 /// Print the ordered Blocks. 153 void printOrderedBlocks() const { 154 size_t i = 0; 155 for (MBBVector::const_iterator iterBlk = OrderedBlks.begin(), 156 iterBlkEnd = OrderedBlks.end(); iterBlk != iterBlkEnd; ++iterBlk, ++i) { 157 dbgs() << "BB" << (*iterBlk)->getNumber(); 158 dbgs() << "(" << getSCCNum(*iterBlk) << "," << (*iterBlk)->size() << ")"; 159 if (i != 0 && i % 10 == 0) { 160 dbgs() << "\n"; 161 } else { 162 dbgs() << " "; 163 } 164 } 165 } 166 167 static void PrintLoopinfo(const MachineLoopInfo &LoopInfo) { 168 for (const MachineLoop *L : LoopInfo) 169 L->print(dbgs()); 170 } 171 172 // UTILITY FUNCTIONS 173 int getSCCNum(MachineBasicBlock *MBB) const; 174 MachineBasicBlock *getLoopLandInfo(MachineLoop *LoopRep) const; 175 bool hasBackEdge(MachineBasicBlock *MBB) const; 176 bool isRetiredBlock(MachineBasicBlock *MBB) const; 177 bool isActiveLoophead(MachineBasicBlock *MBB) const; 178 PathToKind singlePathTo(MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB, 179 bool AllowSideEntry = true) const; 180 int countActiveBlock(MBBVector::const_iterator It, 181 MBBVector::const_iterator E) const; 182 bool needMigrateBlock(MachineBasicBlock *MBB) const; 183 184 // Utility Functions 185 void reversePredicateSetter(MachineBasicBlock::iterator I, 186 MachineBasicBlock &MBB); 187 /// Compute the reversed DFS post order of Blocks 188 void orderBlocks(MachineFunction *MF); 189 190 // Function originally from CFGStructTraits 191 void insertInstrEnd(MachineBasicBlock *MBB, int NewOpcode, 192 const DebugLoc &DL = DebugLoc()); 193 MachineInstr *insertInstrBefore(MachineBasicBlock *MBB, int NewOpcode, 194 const DebugLoc &DL = DebugLoc()); 195 MachineInstr *insertInstrBefore(MachineBasicBlock::iterator I, int NewOpcode); 196 void insertCondBranchBefore(MachineBasicBlock::iterator I, int NewOpcode, 197 const DebugLoc &DL); 198 void insertCondBranchBefore(MachineBasicBlock *MBB, 199 MachineBasicBlock::iterator I, int NewOpcode, 200 int RegNum, const DebugLoc &DL); 201 202 static int getBranchNzeroOpcode(int OldOpcode); 203 static int getBranchZeroOpcode(int OldOpcode); 204 static int getContinueNzeroOpcode(int OldOpcode); 205 static int getContinueZeroOpcode(int OldOpcode); 206 static MachineBasicBlock *getTrueBranch(MachineInstr *MI); 207 static void setTrueBranch(MachineInstr *MI, MachineBasicBlock *MBB); 208 static MachineBasicBlock *getFalseBranch(MachineBasicBlock *MBB, 209 MachineInstr *MI); 210 static bool isCondBranch(MachineInstr *MI); 211 static bool isUncondBranch(MachineInstr *MI); 212 static DebugLoc getLastDebugLocInBB(MachineBasicBlock *MBB); 213 static MachineInstr *getNormalBlockBranchInstr(MachineBasicBlock *MBB); 214 215 /// The correct naming for this is getPossibleLoopendBlockBranchInstr. 216 /// 217 /// BB with backward-edge could have move instructions after the branch 218 /// instruction. Such move instruction "belong to" the loop backward-edge. 219 MachineInstr *getLoopendBlockBranchInstr(MachineBasicBlock *MBB); 220 221 static MachineInstr *getReturnInstr(MachineBasicBlock *MBB); 222 static bool isReturnBlock(MachineBasicBlock *MBB); 223 static void cloneSuccessorList(MachineBasicBlock *DstMBB, 224 MachineBasicBlock *SrcMBB); 225 static MachineBasicBlock *clone(MachineBasicBlock *MBB); 226 227 /// MachineBasicBlock::ReplaceUsesOfBlockWith doesn't serve the purpose 228 /// because the AMDGPU instruction is not recognized as terminator fix this 229 /// and retire this routine 230 void replaceInstrUseOfBlockWith(MachineBasicBlock *SrcMBB, 231 MachineBasicBlock *OldMBB, MachineBasicBlock *NewBlk); 232 233 static void wrapup(MachineBasicBlock *MBB); 234 235 int patternMatch(MachineBasicBlock *MBB); 236 int patternMatchGroup(MachineBasicBlock *MBB); 237 int serialPatternMatch(MachineBasicBlock *MBB); 238 int ifPatternMatch(MachineBasicBlock *MBB); 239 int loopendPatternMatch(); 240 int mergeLoop(MachineLoop *LoopRep); 241 242 /// return true iff src1Blk->succ_empty() && src1Blk and src2Blk are in 243 /// the same loop with LoopLandInfo without explicitly keeping track of 244 /// loopContBlks and loopBreakBlks, this is a method to get the information. 245 bool isSameloopDetachedContbreak(MachineBasicBlock *Src1MBB, 246 MachineBasicBlock *Src2MBB); 247 int handleJumpintoIf(MachineBasicBlock *HeadMBB, 248 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB); 249 int handleJumpintoIfImp(MachineBasicBlock *HeadMBB, 250 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB); 251 int improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB, 252 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, 253 MachineBasicBlock **LandMBBPtr); 254 void showImproveSimpleJumpintoIf(MachineBasicBlock *HeadMBB, 255 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, 256 MachineBasicBlock *LandMBB, bool Detail = false); 257 int cloneOnSideEntryTo(MachineBasicBlock *PreMBB, 258 MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB); 259 void mergeSerialBlock(MachineBasicBlock *DstMBB, 260 MachineBasicBlock *SrcMBB); 261 262 void mergeIfthenelseBlock(MachineInstr *BranchMI, 263 MachineBasicBlock *MBB, MachineBasicBlock *TrueMBB, 264 MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB); 265 void mergeLooplandBlock(MachineBasicBlock *DstMBB, 266 MachineBasicBlock *LandMBB); 267 void mergeLoopbreakBlock(MachineBasicBlock *ExitingMBB, 268 MachineBasicBlock *LandMBB); 269 void settleLoopcontBlock(MachineBasicBlock *ContingMBB, 270 MachineBasicBlock *ContMBB); 271 272 /// normalizeInfiniteLoopExit change 273 /// B1: 274 /// uncond_br LoopHeader 275 /// 276 /// to 277 /// B1: 278 /// cond_br 1 LoopHeader dummyExit 279 /// and return the newly added dummy exit block 280 MachineBasicBlock *normalizeInfiniteLoopExit(MachineLoop *LoopRep); 281 void removeUnconditionalBranch(MachineBasicBlock *MBB); 282 283 /// Remove duplicate branches instructions in a block. 284 /// For instance 285 /// B0: 286 /// cond_br X B1 B2 287 /// cond_br X B1 B2 288 /// is transformed to 289 /// B0: 290 /// cond_br X B1 B2 291 void removeRedundantConditionalBranch(MachineBasicBlock *MBB); 292 293 void addDummyExitBlock(SmallVectorImpl<MachineBasicBlock *> &RetMBB); 294 void removeSuccessor(MachineBasicBlock *MBB); 295 MachineBasicBlock *cloneBlockForPredecessor(MachineBasicBlock *MBB, 296 MachineBasicBlock *PredMBB); 297 void migrateInstruction(MachineBasicBlock *SrcMBB, 298 MachineBasicBlock *DstMBB, MachineBasicBlock::iterator I); 299 void recordSccnum(MachineBasicBlock *MBB, int SCCNum); 300 void retireBlock(MachineBasicBlock *MBB); 301 302 private: 303 MBBInfoMap BlockInfoMap; 304 LoopLandInfoMap LLInfoMap; 305 std::map<MachineLoop *, bool> Visited; 306 MachineFunction *FuncRep; 307 SmallVector<MachineBasicBlock *, DEFAULT_VEC_SLOTS> OrderedBlks; 308 }; 309 310 } // end anonymous namespace 311 312 char R600MachineCFGStructurizer::ID = 0; 313 314 int R600MachineCFGStructurizer::getSCCNum(MachineBasicBlock *MBB) const { 315 MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB); 316 if (It == BlockInfoMap.end()) 317 return INVALIDSCCNUM; 318 return (*It).second->SccNum; 319 } 320 321 MachineBasicBlock *R600MachineCFGStructurizer::getLoopLandInfo(MachineLoop *LoopRep) 322 const { 323 LoopLandInfoMap::const_iterator It = LLInfoMap.find(LoopRep); 324 if (It == LLInfoMap.end()) 325 return nullptr; 326 return (*It).second; 327 } 328 329 bool R600MachineCFGStructurizer::hasBackEdge(MachineBasicBlock *MBB) const { 330 MachineLoop *LoopRep = MLI->getLoopFor(MBB); 331 if (!LoopRep) 332 return false; 333 MachineBasicBlock *LoopHeader = LoopRep->getHeader(); 334 return MBB->isSuccessor(LoopHeader); 335 } 336 337 bool R600MachineCFGStructurizer::isRetiredBlock(MachineBasicBlock *MBB) const { 338 MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB); 339 if (It == BlockInfoMap.end()) 340 return false; 341 return (*It).second->IsRetired; 342 } 343 344 bool R600MachineCFGStructurizer::isActiveLoophead(MachineBasicBlock *MBB) const { 345 MachineLoop *LoopRep = MLI->getLoopFor(MBB); 346 while (LoopRep && LoopRep->getHeader() == MBB) { 347 MachineBasicBlock *LoopLand = getLoopLandInfo(LoopRep); 348 if(!LoopLand) 349 return true; 350 if (!isRetiredBlock(LoopLand)) 351 return true; 352 LoopRep = LoopRep->getParentLoop(); 353 } 354 return false; 355 } 356 357 R600MachineCFGStructurizer::PathToKind R600MachineCFGStructurizer::singlePathTo( 358 MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB, 359 bool AllowSideEntry) const { 360 assert(DstMBB); 361 if (SrcMBB == DstMBB) 362 return SinglePath_InPath; 363 while (SrcMBB && SrcMBB->succ_size() == 1) { 364 SrcMBB = *SrcMBB->succ_begin(); 365 if (SrcMBB == DstMBB) 366 return SinglePath_InPath; 367 if (!AllowSideEntry && SrcMBB->pred_size() > 1) 368 return Not_SinglePath; 369 } 370 if (SrcMBB && SrcMBB->succ_size()==0) 371 return SinglePath_NotInPath; 372 return Not_SinglePath; 373 } 374 375 int R600MachineCFGStructurizer::countActiveBlock(MBBVector::const_iterator It, 376 MBBVector::const_iterator E) const { 377 int Count = 0; 378 while (It != E) { 379 if (!isRetiredBlock(*It)) 380 ++Count; 381 ++It; 382 } 383 return Count; 384 } 385 386 bool R600MachineCFGStructurizer::needMigrateBlock(MachineBasicBlock *MBB) const { 387 unsigned BlockSizeThreshold = 30; 388 unsigned CloneInstrThreshold = 100; 389 bool MultiplePreds = MBB && (MBB->pred_size() > 1); 390 391 if(!MultiplePreds) 392 return false; 393 unsigned BlkSize = MBB->size(); 394 return ((BlkSize > BlockSizeThreshold) && 395 (BlkSize * (MBB->pred_size() - 1) > CloneInstrThreshold)); 396 } 397 398 void R600MachineCFGStructurizer::reversePredicateSetter( 399 MachineBasicBlock::iterator I, MachineBasicBlock &MBB) { 400 assert(I.isValid() && "Expected valid iterator"); 401 for (;; --I) { 402 if (I == MBB.end()) 403 continue; 404 if (I->getOpcode() == R600::PRED_X) { 405 switch (I->getOperand(2).getImm()) { 406 case R600::PRED_SETE_INT: 407 I->getOperand(2).setImm(R600::PRED_SETNE_INT); 408 return; 409 case R600::PRED_SETNE_INT: 410 I->getOperand(2).setImm(R600::PRED_SETE_INT); 411 return; 412 case R600::PRED_SETE: 413 I->getOperand(2).setImm(R600::PRED_SETNE); 414 return; 415 case R600::PRED_SETNE: 416 I->getOperand(2).setImm(R600::PRED_SETE); 417 return; 418 default: 419 llvm_unreachable("PRED_X Opcode invalid!"); 420 } 421 } 422 } 423 } 424 425 void R600MachineCFGStructurizer::insertInstrEnd(MachineBasicBlock *MBB, 426 int NewOpcode, const DebugLoc &DL) { 427 MachineInstr *MI = 428 MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DL); 429 MBB->push_back(MI); 430 //assume the instruction doesn't take any reg operand ... 431 SHOWNEWINSTR(MI); 432 } 433 434 MachineInstr *R600MachineCFGStructurizer::insertInstrBefore(MachineBasicBlock *MBB, 435 int NewOpcode, 436 const DebugLoc &DL) { 437 MachineInstr *MI = 438 MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DL); 439 if (!MBB->empty()) 440 MBB->insert(MBB->begin(), MI); 441 else 442 MBB->push_back(MI); 443 SHOWNEWINSTR(MI); 444 return MI; 445 } 446 447 MachineInstr *R600MachineCFGStructurizer::insertInstrBefore( 448 MachineBasicBlock::iterator I, int NewOpcode) { 449 MachineInstr *OldMI = &(*I); 450 MachineBasicBlock *MBB = OldMI->getParent(); 451 MachineInstr *NewMBB = 452 MBB->getParent()->CreateMachineInstr(TII->get(NewOpcode), DebugLoc()); 453 MBB->insert(I, NewMBB); 454 //assume the instruction doesn't take any reg operand ... 455 SHOWNEWINSTR(NewMBB); 456 return NewMBB; 457 } 458 459 void R600MachineCFGStructurizer::insertCondBranchBefore( 460 MachineBasicBlock::iterator I, int NewOpcode, const DebugLoc &DL) { 461 MachineInstr *OldMI = &(*I); 462 MachineBasicBlock *MBB = OldMI->getParent(); 463 MachineFunction *MF = MBB->getParent(); 464 MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(NewOpcode), DL); 465 MBB->insert(I, NewMI); 466 MachineInstrBuilder MIB(*MF, NewMI); 467 MIB.addReg(OldMI->getOperand(1).getReg(), false); 468 SHOWNEWINSTR(NewMI); 469 //erase later oldInstr->eraseFromParent(); 470 } 471 472 void R600MachineCFGStructurizer::insertCondBranchBefore( 473 MachineBasicBlock *blk, MachineBasicBlock::iterator I, int NewOpcode, 474 int RegNum, const DebugLoc &DL) { 475 MachineFunction *MF = blk->getParent(); 476 MachineInstr *NewInstr = MF->CreateMachineInstr(TII->get(NewOpcode), DL); 477 //insert before 478 blk->insert(I, NewInstr); 479 MachineInstrBuilder(*MF, NewInstr).addReg(RegNum, false); 480 SHOWNEWINSTR(NewInstr); 481 } 482 483 int R600MachineCFGStructurizer::getBranchNzeroOpcode(int OldOpcode) { 484 switch(OldOpcode) { 485 case R600::JUMP_COND: 486 case R600::JUMP: return R600::IF_PREDICATE_SET; 487 case R600::BRANCH_COND_i32: 488 case R600::BRANCH_COND_f32: return R600::IF_LOGICALNZ_f32; 489 default: llvm_unreachable("internal error"); 490 } 491 return -1; 492 } 493 494 int R600MachineCFGStructurizer::getBranchZeroOpcode(int OldOpcode) { 495 switch(OldOpcode) { 496 case R600::JUMP_COND: 497 case R600::JUMP: return R600::IF_PREDICATE_SET; 498 case R600::BRANCH_COND_i32: 499 case R600::BRANCH_COND_f32: return R600::IF_LOGICALZ_f32; 500 default: llvm_unreachable("internal error"); 501 } 502 return -1; 503 } 504 505 int R600MachineCFGStructurizer::getContinueNzeroOpcode(int OldOpcode) { 506 switch(OldOpcode) { 507 case R600::JUMP_COND: 508 case R600::JUMP: return R600::CONTINUE_LOGICALNZ_i32; 509 default: llvm_unreachable("internal error"); 510 } 511 return -1; 512 } 513 514 int R600MachineCFGStructurizer::getContinueZeroOpcode(int OldOpcode) { 515 switch(OldOpcode) { 516 case R600::JUMP_COND: 517 case R600::JUMP: return R600::CONTINUE_LOGICALZ_i32; 518 default: llvm_unreachable("internal error"); 519 } 520 return -1; 521 } 522 523 MachineBasicBlock *R600MachineCFGStructurizer::getTrueBranch(MachineInstr *MI) { 524 return MI->getOperand(0).getMBB(); 525 } 526 527 void R600MachineCFGStructurizer::setTrueBranch(MachineInstr *MI, 528 MachineBasicBlock *MBB) { 529 MI->getOperand(0).setMBB(MBB); 530 } 531 532 MachineBasicBlock * 533 R600MachineCFGStructurizer::getFalseBranch(MachineBasicBlock *MBB, 534 MachineInstr *MI) { 535 assert(MBB->succ_size() == 2); 536 MachineBasicBlock *TrueBranch = getTrueBranch(MI); 537 MachineBasicBlock::succ_iterator It = MBB->succ_begin(); 538 MachineBasicBlock::succ_iterator Next = It; 539 ++Next; 540 return (*It == TrueBranch) ? *Next : *It; 541 } 542 543 bool R600MachineCFGStructurizer::isCondBranch(MachineInstr *MI) { 544 switch (MI->getOpcode()) { 545 case R600::JUMP_COND: 546 case R600::BRANCH_COND_i32: 547 case R600::BRANCH_COND_f32: return true; 548 default: 549 return false; 550 } 551 return false; 552 } 553 554 bool R600MachineCFGStructurizer::isUncondBranch(MachineInstr *MI) { 555 switch (MI->getOpcode()) { 556 case R600::JUMP: 557 case R600::BRANCH: 558 return true; 559 default: 560 return false; 561 } 562 return false; 563 } 564 565 DebugLoc R600MachineCFGStructurizer::getLastDebugLocInBB(MachineBasicBlock *MBB) { 566 //get DebugLoc from the first MachineBasicBlock instruction with debug info 567 DebugLoc DL; 568 for (MachineInstr &MI : *MBB) 569 if (MI.getDebugLoc()) 570 DL = MI.getDebugLoc(); 571 return DL; 572 } 573 574 MachineInstr *R600MachineCFGStructurizer::getNormalBlockBranchInstr( 575 MachineBasicBlock *MBB) { 576 MachineBasicBlock::reverse_iterator It = MBB->rbegin(); 577 MachineInstr *MI = &*It; 578 if (MI && (isCondBranch(MI) || isUncondBranch(MI))) 579 return MI; 580 return nullptr; 581 } 582 583 MachineInstr *R600MachineCFGStructurizer::getLoopendBlockBranchInstr( 584 MachineBasicBlock *MBB) { 585 for (MachineBasicBlock::reverse_iterator It = MBB->rbegin(), E = MBB->rend(); 586 It != E; ++It) { 587 // FIXME: Simplify 588 MachineInstr *MI = &*It; 589 if (MI) { 590 if (isCondBranch(MI) || isUncondBranch(MI)) 591 return MI; 592 if (!TII->isMov(MI->getOpcode())) 593 break; 594 } 595 } 596 return nullptr; 597 } 598 599 MachineInstr *R600MachineCFGStructurizer::getReturnInstr(MachineBasicBlock *MBB) { 600 MachineBasicBlock::reverse_iterator It = MBB->rbegin(); 601 if (It != MBB->rend()) { 602 MachineInstr *instr = &(*It); 603 if (instr->getOpcode() == R600::RETURN) 604 return instr; 605 } 606 return nullptr; 607 } 608 609 bool R600MachineCFGStructurizer::isReturnBlock(MachineBasicBlock *MBB) { 610 MachineInstr *MI = getReturnInstr(MBB); 611 bool IsReturn = MBB->succ_empty(); 612 if (MI) 613 assert(IsReturn); 614 else if (IsReturn) 615 LLVM_DEBUG(dbgs() << "BB" << MBB->getNumber() 616 << " is return block without RETURN instr\n";); 617 return IsReturn; 618 } 619 620 void R600MachineCFGStructurizer::cloneSuccessorList(MachineBasicBlock *DstMBB, 621 MachineBasicBlock *SrcMBB) { 622 for (MachineBasicBlock *Succ : SrcMBB->successors()) 623 DstMBB->addSuccessor(Succ); // *iter's predecessor is also taken care of 624 } 625 626 MachineBasicBlock *R600MachineCFGStructurizer::clone(MachineBasicBlock *MBB) { 627 MachineFunction *Func = MBB->getParent(); 628 MachineBasicBlock *NewMBB = Func->CreateMachineBasicBlock(); 629 Func->push_back(NewMBB); //insert to function 630 for (const MachineInstr &It : *MBB) 631 NewMBB->push_back(Func->CloneMachineInstr(&It)); 632 return NewMBB; 633 } 634 635 void R600MachineCFGStructurizer::replaceInstrUseOfBlockWith( 636 MachineBasicBlock *SrcMBB, MachineBasicBlock *OldMBB, 637 MachineBasicBlock *NewBlk) { 638 MachineInstr *BranchMI = getLoopendBlockBranchInstr(SrcMBB); 639 if (BranchMI && isCondBranch(BranchMI) && 640 getTrueBranch(BranchMI) == OldMBB) 641 setTrueBranch(BranchMI, NewBlk); 642 } 643 644 void R600MachineCFGStructurizer::wrapup(MachineBasicBlock *MBB) { 645 assert((!MBB->getParent()->getJumpTableInfo() 646 || MBB->getParent()->getJumpTableInfo()->isEmpty()) 647 && "found a jump table"); 648 649 //collect continue right before endloop 650 SmallVector<MachineInstr *, DEFAULT_VEC_SLOTS> ContInstr; 651 MachineBasicBlock::iterator Pre = MBB->begin(); 652 MachineBasicBlock::iterator E = MBB->end(); 653 MachineBasicBlock::iterator It = Pre; 654 while (It != E) { 655 if (Pre->getOpcode() == R600::CONTINUE 656 && It->getOpcode() == R600::ENDLOOP) 657 ContInstr.push_back(&*Pre); 658 Pre = It; 659 ++It; 660 } 661 662 //delete continue right before endloop 663 for (auto *MI : ContInstr) 664 MI->eraseFromParent(); 665 666 // TODO to fix up jump table so later phase won't be confused. if 667 // (jumpTableInfo->isEmpty() == false) { need to clean the jump table, but 668 // there isn't such an interface yet. alternatively, replace all the other 669 // blocks in the jump table with the entryBlk //} 670 } 671 672 bool R600MachineCFGStructurizer::prepare() { 673 bool Changed = false; 674 675 //FIXME: if not reducible flow graph, make it so ??? 676 677 LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::prepare\n";); 678 679 orderBlocks(FuncRep); 680 681 SmallVector<MachineBasicBlock *, DEFAULT_VEC_SLOTS> RetBlks; 682 683 // Add an ExitBlk to loop that don't have one 684 for (MachineLoop *LoopRep : *MLI) { 685 MBBVector ExitingMBBs; 686 LoopRep->getExitingBlocks(ExitingMBBs); 687 688 if (ExitingMBBs.size() == 0) { 689 MachineBasicBlock* DummyExitBlk = normalizeInfiniteLoopExit(LoopRep); 690 if (DummyExitBlk) 691 RetBlks.push_back(DummyExitBlk); 692 } 693 } 694 695 // Remove unconditional branch instr. 696 // Add dummy exit block iff there are multiple returns. 697 for (MachineBasicBlock *MBB : OrderedBlks) { 698 removeUnconditionalBranch(MBB); 699 removeRedundantConditionalBranch(MBB); 700 if (isReturnBlock(MBB)) { 701 RetBlks.push_back(MBB); 702 } 703 assert(MBB->succ_size() <= 2); 704 } 705 706 if (RetBlks.size() >= 2) { 707 addDummyExitBlock(RetBlks); 708 Changed = true; 709 } 710 711 return Changed; 712 } 713 714 bool R600MachineCFGStructurizer::run() { 715 //Assume reducible CFG... 716 LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::run\n"); 717 718 #ifdef STRESSTEST 719 //Use the worse block ordering to test the algorithm. 720 ReverseVector(orderedBlks); 721 #endif 722 723 LLVM_DEBUG(dbgs() << "Ordered blocks:\n"; printOrderedBlocks();); 724 int NumIter = 0; 725 bool Finish = false; 726 MachineBasicBlock *MBB; 727 bool MakeProgress = false; 728 int NumRemainedBlk = countActiveBlock(OrderedBlks.begin(), 729 OrderedBlks.end()); 730 731 do { 732 ++NumIter; 733 LLVM_DEBUG(dbgs() << "numIter = " << NumIter 734 << ", numRemaintedBlk = " << NumRemainedBlk << "\n";); 735 (void)NumIter; 736 737 SmallVectorImpl<MachineBasicBlock *>::const_iterator It = 738 OrderedBlks.begin(); 739 SmallVectorImpl<MachineBasicBlock *>::const_iterator E = 740 OrderedBlks.end(); 741 742 SmallVectorImpl<MachineBasicBlock *>::const_iterator SccBeginIter = 743 It; 744 MachineBasicBlock *SccBeginMBB = nullptr; 745 int SccNumBlk = 0; // The number of active blocks, init to a 746 // maximum possible number. 747 int SccNumIter; // Number of iteration in this SCC. 748 749 while (It != E) { 750 MBB = *It; 751 752 if (!SccBeginMBB) { 753 SccBeginIter = It; 754 SccBeginMBB = MBB; 755 SccNumIter = 0; 756 SccNumBlk = NumRemainedBlk; // Init to maximum possible number. 757 LLVM_DEBUG(dbgs() << "start processing SCC" << getSCCNum(SccBeginMBB); 758 dbgs() << "\n";); 759 } 760 761 if (!isRetiredBlock(MBB)) 762 patternMatch(MBB); 763 764 ++It; 765 766 bool ContNextScc = true; 767 if (It == E 768 || getSCCNum(SccBeginMBB) != getSCCNum(*It)) { 769 // Just finish one scc. 770 ++SccNumIter; 771 int sccRemainedNumBlk = countActiveBlock(SccBeginIter, It); 772 if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= SccNumBlk) { 773 LLVM_DEBUG(dbgs() << "Can't reduce SCC " << getSCCNum(MBB) 774 << ", sccNumIter = " << SccNumIter; 775 dbgs() << "doesn't make any progress\n";); 776 (void)SccNumIter; 777 ContNextScc = true; 778 } else if (sccRemainedNumBlk != 1 && sccRemainedNumBlk < SccNumBlk) { 779 SccNumBlk = sccRemainedNumBlk; 780 It = SccBeginIter; 781 ContNextScc = false; 782 LLVM_DEBUG(dbgs() << "repeat processing SCC" << getSCCNum(MBB) 783 << "sccNumIter = " << SccNumIter << '\n';); 784 } else { 785 // Finish the current scc. 786 ContNextScc = true; 787 } 788 } else { 789 // Continue on next component in the current scc. 790 ContNextScc = false; 791 } 792 793 if (ContNextScc) 794 SccBeginMBB = nullptr; 795 } //while, "one iteration" over the function. 796 797 MachineBasicBlock *EntryMBB = 798 *GraphTraits<MachineFunction *>::nodes_begin(FuncRep); 799 if (EntryMBB->succ_empty()) { 800 Finish = true; 801 LLVM_DEBUG(dbgs() << "Reduce to one block\n";); 802 } else { 803 int NewnumRemainedBlk 804 = countActiveBlock(OrderedBlks.begin(), OrderedBlks.end()); 805 // consider cloned blocks ?? 806 if (NewnumRemainedBlk == 1 || NewnumRemainedBlk < NumRemainedBlk) { 807 MakeProgress = true; 808 NumRemainedBlk = NewnumRemainedBlk; 809 } else { 810 MakeProgress = false; 811 LLVM_DEBUG(dbgs() << "No progress\n";); 812 } 813 } 814 } while (!Finish && MakeProgress); 815 816 // Misc wrap up to maintain the consistency of the Function representation. 817 wrapup(*GraphTraits<MachineFunction *>::nodes_begin(FuncRep)); 818 819 // Detach retired Block, release memory. 820 for (auto &It : BlockInfoMap) { 821 if (It.second && It.second->IsRetired) { 822 assert((It.first)->getNumber() != -1); 823 LLVM_DEBUG(dbgs() << "Erase BB" << (It.first)->getNumber() << "\n";); 824 It.first->eraseFromParent(); // Remove from the parent Function. 825 } 826 delete It.second; 827 } 828 BlockInfoMap.clear(); 829 LLInfoMap.clear(); 830 831 if (!Finish) { 832 LLVM_DEBUG(FuncRep->viewCFG()); 833 report_fatal_error("IRREDUCIBLE_CFG"); 834 } 835 836 return true; 837 } 838 839 void R600MachineCFGStructurizer::orderBlocks(MachineFunction *MF) { 840 int SccNum = 0; 841 for (scc_iterator<MachineFunction *> It = scc_begin(MF); !It.isAtEnd(); 842 ++It, ++SccNum) { 843 const std::vector<MachineBasicBlock *> &SccNext = *It; 844 for (MachineBasicBlock *MBB : SccNext) { 845 OrderedBlks.push_back(MBB); 846 recordSccnum(MBB, SccNum); 847 } 848 } 849 850 // walk through all the block in func to check for unreachable 851 for (auto *MBB : nodes(MF)) { 852 SccNum = getSCCNum(MBB); 853 if (SccNum == INVALIDSCCNUM) 854 dbgs() << "unreachable block BB" << MBB->getNumber() << "\n"; 855 } 856 } 857 858 int R600MachineCFGStructurizer::patternMatch(MachineBasicBlock *MBB) { 859 int NumMatch = 0; 860 int CurMatch; 861 862 LLVM_DEBUG(dbgs() << "Begin patternMatch BB" << MBB->getNumber() << "\n";); 863 864 while ((CurMatch = patternMatchGroup(MBB)) > 0) 865 NumMatch += CurMatch; 866 867 LLVM_DEBUG(dbgs() << "End patternMatch BB" << MBB->getNumber() 868 << ", numMatch = " << NumMatch << "\n";); 869 870 return NumMatch; 871 } 872 873 int R600MachineCFGStructurizer::patternMatchGroup(MachineBasicBlock *MBB) { 874 int NumMatch = 0; 875 NumMatch += loopendPatternMatch(); 876 NumMatch += serialPatternMatch(MBB); 877 NumMatch += ifPatternMatch(MBB); 878 return NumMatch; 879 } 880 881 int R600MachineCFGStructurizer::serialPatternMatch(MachineBasicBlock *MBB) { 882 if (MBB->succ_size() != 1) 883 return 0; 884 885 MachineBasicBlock *childBlk = *MBB->succ_begin(); 886 if (childBlk->pred_size() != 1 || isActiveLoophead(childBlk)) 887 return 0; 888 889 mergeSerialBlock(MBB, childBlk); 890 ++numSerialPatternMatch; 891 return 1; 892 } 893 894 int R600MachineCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) { 895 //two edges 896 if (MBB->succ_size() != 2) 897 return 0; 898 if (hasBackEdge(MBB)) 899 return 0; 900 MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB); 901 if (!BranchMI) 902 return 0; 903 904 assert(isCondBranch(BranchMI)); 905 int NumMatch = 0; 906 907 MachineBasicBlock *TrueMBB = getTrueBranch(BranchMI); 908 NumMatch += serialPatternMatch(TrueMBB); 909 NumMatch += ifPatternMatch(TrueMBB); 910 MachineBasicBlock *FalseMBB = getFalseBranch(MBB, BranchMI); 911 NumMatch += serialPatternMatch(FalseMBB); 912 NumMatch += ifPatternMatch(FalseMBB); 913 MachineBasicBlock *LandBlk; 914 int Cloned = 0; 915 916 assert (!TrueMBB->succ_empty() || !FalseMBB->succ_empty()); 917 // TODO: Simplify 918 if (TrueMBB->succ_size() == 1 && FalseMBB->succ_size() == 1 919 && *TrueMBB->succ_begin() == *FalseMBB->succ_begin()) { 920 // Diamond pattern 921 LandBlk = *TrueMBB->succ_begin(); 922 } else if (TrueMBB->succ_size() == 1 && *TrueMBB->succ_begin() == FalseMBB) { 923 // Triangle pattern, false is empty 924 LandBlk = FalseMBB; 925 FalseMBB = nullptr; 926 } else if (FalseMBB->succ_size() == 1 927 && *FalseMBB->succ_begin() == TrueMBB) { 928 // Triangle pattern, true is empty 929 // We reverse the predicate to make a triangle, empty false pattern; 930 std::swap(TrueMBB, FalseMBB); 931 reversePredicateSetter(MBB->end(), *MBB); 932 LandBlk = FalseMBB; 933 FalseMBB = nullptr; 934 } else if (FalseMBB->succ_size() == 1 935 && isSameloopDetachedContbreak(TrueMBB, FalseMBB)) { 936 LandBlk = *FalseMBB->succ_begin(); 937 } else if (TrueMBB->succ_size() == 1 938 && isSameloopDetachedContbreak(FalseMBB, TrueMBB)) { 939 LandBlk = *TrueMBB->succ_begin(); 940 } else { 941 return NumMatch + handleJumpintoIf(MBB, TrueMBB, FalseMBB); 942 } 943 944 // improveSimpleJumpinfoIf can handle the case where landBlk == NULL but the 945 // new BB created for landBlk==NULL may introduce new challenge to the 946 // reduction process. 947 if (LandBlk && 948 ((TrueMBB && TrueMBB->pred_size() > 1) 949 || (FalseMBB && FalseMBB->pred_size() > 1))) { 950 Cloned += improveSimpleJumpintoIf(MBB, TrueMBB, FalseMBB, &LandBlk); 951 } 952 953 if (TrueMBB && TrueMBB->pred_size() > 1) { 954 TrueMBB = cloneBlockForPredecessor(TrueMBB, MBB); 955 ++Cloned; 956 } 957 958 if (FalseMBB && FalseMBB->pred_size() > 1) { 959 FalseMBB = cloneBlockForPredecessor(FalseMBB, MBB); 960 ++Cloned; 961 } 962 963 mergeIfthenelseBlock(BranchMI, MBB, TrueMBB, FalseMBB, LandBlk); 964 965 ++numIfPatternMatch; 966 967 numClonedBlock += Cloned; 968 969 return 1 + Cloned + NumMatch; 970 } 971 972 int R600MachineCFGStructurizer::loopendPatternMatch() { 973 std::deque<MachineLoop *> NestedLoops; 974 for (auto &It: *MLI) 975 for (MachineLoop *ML : depth_first(It)) 976 NestedLoops.push_front(ML); 977 978 if (NestedLoops.empty()) 979 return 0; 980 981 // Process nested loop outside->inside (we did push_front), 982 // so "continue" to a outside loop won't be mistaken as "break" 983 // of the current loop. 984 int Num = 0; 985 for (MachineLoop *ExaminedLoop : NestedLoops) { 986 if (ExaminedLoop->getNumBlocks() == 0 || Visited[ExaminedLoop]) 987 continue; 988 LLVM_DEBUG(dbgs() << "Processing:\n"; ExaminedLoop->dump();); 989 int NumBreak = mergeLoop(ExaminedLoop); 990 if (NumBreak == -1) 991 break; 992 Num += NumBreak; 993 } 994 return Num; 995 } 996 997 int R600MachineCFGStructurizer::mergeLoop(MachineLoop *LoopRep) { 998 MachineBasicBlock *LoopHeader = LoopRep->getHeader(); 999 MBBVector ExitingMBBs; 1000 LoopRep->getExitingBlocks(ExitingMBBs); 1001 assert(!ExitingMBBs.empty() && "Infinite Loop not supported"); 1002 LLVM_DEBUG(dbgs() << "Loop has " << ExitingMBBs.size() 1003 << " exiting blocks\n";); 1004 // We assume a single ExitBlk 1005 MBBVector ExitBlks; 1006 LoopRep->getExitBlocks(ExitBlks); 1007 SmallPtrSet<MachineBasicBlock *, 2> ExitBlkSet(llvm::from_range, ExitBlks); 1008 assert(ExitBlkSet.size() == 1); 1009 MachineBasicBlock *ExitBlk = *ExitBlks.begin(); 1010 assert(ExitBlk && "Loop has several exit block"); 1011 MBBVector LatchBlks; 1012 for (auto *LB : inverse_children<MachineBasicBlock*>(LoopHeader)) 1013 if (LoopRep->contains(LB)) 1014 LatchBlks.push_back(LB); 1015 1016 for (MachineBasicBlock *MBB : ExitingMBBs) 1017 mergeLoopbreakBlock(MBB, ExitBlk); 1018 for (MachineBasicBlock *MBB : LatchBlks) 1019 settleLoopcontBlock(MBB, LoopHeader); 1020 int Match = 0; 1021 do { 1022 Match = 0; 1023 Match += serialPatternMatch(LoopHeader); 1024 Match += ifPatternMatch(LoopHeader); 1025 } while (Match > 0); 1026 mergeLooplandBlock(LoopHeader, ExitBlk); 1027 MachineLoop *ParentLoop = LoopRep->getParentLoop(); 1028 if (ParentLoop) 1029 MLI->changeLoopFor(LoopHeader, ParentLoop); 1030 else 1031 MLI->removeBlock(LoopHeader); 1032 Visited[LoopRep] = true; 1033 return 1; 1034 } 1035 1036 bool R600MachineCFGStructurizer::isSameloopDetachedContbreak( 1037 MachineBasicBlock *Src1MBB, MachineBasicBlock *Src2MBB) { 1038 if (Src1MBB->succ_empty()) { 1039 MachineLoop *LoopRep = MLI->getLoopFor(Src1MBB); 1040 if (LoopRep&& LoopRep == MLI->getLoopFor(Src2MBB)) { 1041 MachineBasicBlock *&TheEntry = LLInfoMap[LoopRep]; 1042 if (TheEntry) { 1043 LLVM_DEBUG(dbgs() << "isLoopContBreakBlock yes src1 = BB" 1044 << Src1MBB->getNumber() << " src2 = BB" 1045 << Src2MBB->getNumber() << "\n";); 1046 return true; 1047 } 1048 } 1049 } 1050 return false; 1051 } 1052 1053 int R600MachineCFGStructurizer::handleJumpintoIf(MachineBasicBlock *HeadMBB, 1054 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB) { 1055 int Num = handleJumpintoIfImp(HeadMBB, TrueMBB, FalseMBB); 1056 if (Num == 0) { 1057 LLVM_DEBUG(dbgs() << "handleJumpintoIf swap trueBlk and FalseBlk" 1058 << "\n";); 1059 Num = handleJumpintoIfImp(HeadMBB, FalseMBB, TrueMBB); 1060 } 1061 return Num; 1062 } 1063 1064 int R600MachineCFGStructurizer::handleJumpintoIfImp(MachineBasicBlock *HeadMBB, 1065 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB) { 1066 int Num = 0; 1067 MachineBasicBlock *DownBlk; 1068 1069 //trueBlk could be the common post dominator 1070 DownBlk = TrueMBB; 1071 1072 LLVM_DEBUG(dbgs() << "handleJumpintoIfImp head = BB" << HeadMBB->getNumber() 1073 << " true = BB" << TrueMBB->getNumber() 1074 << ", numSucc=" << TrueMBB->succ_size() << " false = BB" 1075 << FalseMBB->getNumber() << "\n";); 1076 1077 while (DownBlk) { 1078 LLVM_DEBUG(dbgs() << "check down = BB" << DownBlk->getNumber();); 1079 1080 if (singlePathTo(FalseMBB, DownBlk) == SinglePath_InPath) { 1081 LLVM_DEBUG(dbgs() << " working\n";); 1082 1083 Num += cloneOnSideEntryTo(HeadMBB, TrueMBB, DownBlk); 1084 Num += cloneOnSideEntryTo(HeadMBB, FalseMBB, DownBlk); 1085 1086 numClonedBlock += Num; 1087 Num += serialPatternMatch(*HeadMBB->succ_begin()); 1088 Num += serialPatternMatch(*std::next(HeadMBB->succ_begin())); 1089 Num += ifPatternMatch(HeadMBB); 1090 assert(Num > 0); 1091 1092 break; 1093 } 1094 LLVM_DEBUG(dbgs() << " not working\n";); 1095 DownBlk = (DownBlk->succ_size() == 1) ? (*DownBlk->succ_begin()) : nullptr; 1096 } // walk down the postDomTree 1097 1098 return Num; 1099 } 1100 1101 #ifndef NDEBUG 1102 void R600MachineCFGStructurizer::showImproveSimpleJumpintoIf( 1103 MachineBasicBlock *HeadMBB, MachineBasicBlock *TrueMBB, 1104 MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB, bool Detail) { 1105 dbgs() << "head = BB" << HeadMBB->getNumber() 1106 << " size = " << HeadMBB->size(); 1107 if (Detail) { 1108 dbgs() << "\n"; 1109 HeadMBB->print(dbgs()); 1110 dbgs() << "\n"; 1111 } 1112 1113 if (TrueMBB) { 1114 dbgs() << ", true = BB" << TrueMBB->getNumber() << " size = " 1115 << TrueMBB->size() << " numPred = " << TrueMBB->pred_size(); 1116 if (Detail) { 1117 dbgs() << "\n"; 1118 TrueMBB->print(dbgs()); 1119 dbgs() << "\n"; 1120 } 1121 } 1122 if (FalseMBB) { 1123 dbgs() << ", false = BB" << FalseMBB->getNumber() << " size = " 1124 << FalseMBB->size() << " numPred = " << FalseMBB->pred_size(); 1125 if (Detail) { 1126 dbgs() << "\n"; 1127 FalseMBB->print(dbgs()); 1128 dbgs() << "\n"; 1129 } 1130 } 1131 if (LandMBB) { 1132 dbgs() << ", land = BB" << LandMBB->getNumber() << " size = " 1133 << LandMBB->size() << " numPred = " << LandMBB->pred_size(); 1134 if (Detail) { 1135 dbgs() << "\n"; 1136 LandMBB->print(dbgs()); 1137 dbgs() << "\n"; 1138 } 1139 } 1140 1141 dbgs() << "\n"; 1142 } 1143 #endif 1144 1145 int R600MachineCFGStructurizer::improveSimpleJumpintoIf(MachineBasicBlock *HeadMBB, 1146 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB, 1147 MachineBasicBlock **LandMBBPtr) { 1148 bool MigrateTrue = false; 1149 bool MigrateFalse = false; 1150 1151 MachineBasicBlock *LandBlk = *LandMBBPtr; 1152 1153 assert((!TrueMBB || TrueMBB->succ_size() <= 1) 1154 && (!FalseMBB || FalseMBB->succ_size() <= 1)); 1155 1156 if (TrueMBB == FalseMBB) 1157 return 0; 1158 1159 MigrateTrue = needMigrateBlock(TrueMBB); 1160 MigrateFalse = needMigrateBlock(FalseMBB); 1161 1162 if (!MigrateTrue && !MigrateFalse) 1163 return 0; 1164 1165 // If we need to migrate either trueBlk and falseBlk, migrate the rest that 1166 // have more than one predecessors. without doing this, its predecessor 1167 // rather than headBlk will have undefined value in initReg. 1168 if (!MigrateTrue && TrueMBB && TrueMBB->pred_size() > 1) 1169 MigrateTrue = true; 1170 if (!MigrateFalse && FalseMBB && FalseMBB->pred_size() > 1) 1171 MigrateFalse = true; 1172 1173 LLVM_DEBUG( 1174 dbgs() << "before improveSimpleJumpintoIf: "; 1175 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0);); 1176 1177 // org: headBlk => if () {trueBlk} else {falseBlk} => landBlk 1178 // 1179 // new: headBlk => if () {initReg = 1; org trueBlk branch} else 1180 // {initReg = 0; org falseBlk branch } 1181 // => landBlk => if (initReg) {org trueBlk} else {org falseBlk} 1182 // => org landBlk 1183 // if landBlk->pred_size() > 2, put the about if-else inside 1184 // if (initReg !=2) {...} 1185 // 1186 // add initReg = initVal to headBlk 1187 1188 const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32); 1189 if (!MigrateTrue || !MigrateFalse) { 1190 // XXX: We have an opportunity here to optimize the "branch into if" case 1191 // here. Branch into if looks like this: 1192 // entry 1193 // / | 1194 // diamond_head branch_from 1195 // / \ | 1196 // diamond_false diamond_true 1197 // \ / 1198 // done 1199 // 1200 // The diamond_head block begins the "if" and the diamond_true block 1201 // is the block being "branched into". 1202 // 1203 // If MigrateTrue is true, then TrueBB is the block being "branched into" 1204 // and if MigrateFalse is true, then FalseBB is the block being 1205 // "branched into" 1206 // 1207 // Here is the pseudo code for how I think the optimization should work: 1208 // 1. Insert MOV GPR0, 0 before the branch instruction in diamond_head. 1209 // 2. Insert MOV GPR0, 1 before the branch instruction in branch_from. 1210 // 3. Move the branch instruction from diamond_head into its own basic 1211 // block (new_block). 1212 // 4. Add an unconditional branch from diamond_head to new_block 1213 // 5. Replace the branch instruction in branch_from with an unconditional 1214 // branch to new_block. If branch_from has multiple predecessors, then 1215 // we need to replace the True/False block in the branch 1216 // instruction instead of replacing it. 1217 // 6. Change the condition of the branch instruction in new_block from 1218 // COND to (COND || GPR0) 1219 // 1220 // In order insert these MOV instruction, we will need to use the 1221 // RegisterScavenger. Usually liveness stops being tracked during 1222 // the late machine optimization passes, however if we implement 1223 // bool TargetRegisterInfo::requiresRegisterScavenging( 1224 // const MachineFunction &MF) 1225 // and have it return true, liveness will be tracked correctly 1226 // by generic optimization passes. We will also need to make sure that 1227 // all of our target-specific passes that run after regalloc and before 1228 // the CFGStructurizer track liveness and we will need to modify this pass 1229 // to correctly track liveness. 1230 // 1231 // After the above changes, the new CFG should look like this: 1232 // entry 1233 // / | 1234 // diamond_head branch_from 1235 // \ / 1236 // new_block 1237 // / | 1238 // diamond_false diamond_true 1239 // \ / 1240 // done 1241 // 1242 // Without this optimization, we are forced to duplicate the diamond_true 1243 // block and we will end up with a CFG like this: 1244 // 1245 // entry 1246 // / | 1247 // diamond_head branch_from 1248 // / \ | 1249 // diamond_false diamond_true diamond_true (duplicate) 1250 // \ / | 1251 // done --------------------| 1252 // 1253 // Duplicating diamond_true can be very costly especially if it has a 1254 // lot of instructions. 1255 return 0; 1256 } 1257 1258 int NumNewBlk = 0; 1259 1260 bool LandBlkHasOtherPred = (LandBlk->pred_size() > 2); 1261 1262 //insert R600::ENDIF to avoid special case "input landBlk == NULL" 1263 MachineBasicBlock::iterator I = insertInstrBefore(LandBlk, R600::ENDIF); 1264 1265 if (LandBlkHasOtherPred) { 1266 report_fatal_error("Extra register needed to handle CFG"); 1267 Register CmpResReg = 1268 HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC); 1269 report_fatal_error("Extra compare instruction needed to handle CFG"); 1270 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET, 1271 CmpResReg, DebugLoc()); 1272 } 1273 1274 // XXX: We are running this after RA, so creating virtual registers will 1275 // cause an assertion failure in the PostRA scheduling pass. 1276 Register InitReg = 1277 HeadMBB->getParent()->getRegInfo().createVirtualRegister(I32RC); 1278 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET, InitReg, 1279 DebugLoc()); 1280 1281 if (MigrateTrue) { 1282 migrateInstruction(TrueMBB, LandBlk, I); 1283 // need to uncondionally insert the assignment to ensure a path from its 1284 // predecessor rather than headBlk has valid value in initReg if 1285 // (initVal != 1). 1286 report_fatal_error("Extra register needed to handle CFG"); 1287 } 1288 insertInstrBefore(I, R600::ELSE); 1289 1290 if (MigrateFalse) { 1291 migrateInstruction(FalseMBB, LandBlk, I); 1292 // need to uncondionally insert the assignment to ensure a path from its 1293 // predecessor rather than headBlk has valid value in initReg if 1294 // (initVal != 0) 1295 report_fatal_error("Extra register needed to handle CFG"); 1296 } 1297 1298 if (LandBlkHasOtherPred) { 1299 // add endif 1300 insertInstrBefore(I, R600::ENDIF); 1301 1302 // put initReg = 2 to other predecessors of landBlk 1303 for (MachineBasicBlock *MBB : LandBlk->predecessors()) 1304 if (MBB != TrueMBB && MBB != FalseMBB) 1305 report_fatal_error("Extra register needed to handle CFG"); 1306 } 1307 LLVM_DEBUG( 1308 dbgs() << "result from improveSimpleJumpintoIf: "; 1309 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0);); 1310 1311 // update landBlk 1312 *LandMBBPtr = LandBlk; 1313 1314 return NumNewBlk; 1315 } 1316 1317 void R600MachineCFGStructurizer::mergeSerialBlock(MachineBasicBlock *DstMBB, 1318 MachineBasicBlock *SrcMBB) { 1319 LLVM_DEBUG(dbgs() << "serialPattern BB" << DstMBB->getNumber() << " <= BB" 1320 << SrcMBB->getNumber() << "\n";); 1321 DstMBB->splice(DstMBB->end(), SrcMBB, SrcMBB->begin(), SrcMBB->end()); 1322 1323 DstMBB->removeSuccessor(SrcMBB, true); 1324 cloneSuccessorList(DstMBB, SrcMBB); 1325 1326 removeSuccessor(SrcMBB); 1327 MLI->removeBlock(SrcMBB); 1328 retireBlock(SrcMBB); 1329 } 1330 1331 void R600MachineCFGStructurizer::mergeIfthenelseBlock(MachineInstr *BranchMI, 1332 MachineBasicBlock *MBB, MachineBasicBlock *TrueMBB, 1333 MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB) { 1334 assert (TrueMBB); 1335 LLVM_DEBUG(dbgs() << "ifPattern BB" << MBB->getNumber(); dbgs() << "{ "; 1336 if (TrueMBB) { dbgs() << "BB" << TrueMBB->getNumber(); } dbgs() 1337 << " } else "; 1338 dbgs() << "{ "; if (FalseMBB) { 1339 dbgs() << "BB" << FalseMBB->getNumber(); 1340 } dbgs() << " }\n "; 1341 dbgs() << "landBlock: "; if (!LandMBB) { dbgs() << "NULL"; } else { 1342 dbgs() << "BB" << LandMBB->getNumber(); 1343 } dbgs() << "\n";); 1344 1345 int OldOpcode = BranchMI->getOpcode(); 1346 DebugLoc BranchDL = BranchMI->getDebugLoc(); 1347 1348 // transform to 1349 // if cond 1350 // trueBlk 1351 // else 1352 // falseBlk 1353 // endif 1354 // landBlk 1355 1356 MachineBasicBlock::iterator I = BranchMI; 1357 insertCondBranchBefore(I, getBranchNzeroOpcode(OldOpcode), 1358 BranchDL); 1359 1360 if (TrueMBB) { 1361 MBB->splice(I, TrueMBB, TrueMBB->begin(), TrueMBB->end()); 1362 MBB->removeSuccessor(TrueMBB, true); 1363 if (LandMBB && TrueMBB->succ_size()!=0) 1364 TrueMBB->removeSuccessor(LandMBB, true); 1365 retireBlock(TrueMBB); 1366 MLI->removeBlock(TrueMBB); 1367 } 1368 1369 if (FalseMBB) { 1370 insertInstrBefore(I, R600::ELSE); 1371 MBB->splice(I, FalseMBB, FalseMBB->begin(), 1372 FalseMBB->end()); 1373 MBB->removeSuccessor(FalseMBB, true); 1374 if (LandMBB && !FalseMBB->succ_empty()) 1375 FalseMBB->removeSuccessor(LandMBB, true); 1376 retireBlock(FalseMBB); 1377 MLI->removeBlock(FalseMBB); 1378 } 1379 insertInstrBefore(I, R600::ENDIF); 1380 1381 BranchMI->eraseFromParent(); 1382 1383 if (LandMBB && TrueMBB && FalseMBB) 1384 MBB->addSuccessor(LandMBB); 1385 } 1386 1387 void R600MachineCFGStructurizer::mergeLooplandBlock(MachineBasicBlock *DstBlk, 1388 MachineBasicBlock *LandMBB) { 1389 LLVM_DEBUG(dbgs() << "loopPattern header = BB" << DstBlk->getNumber() 1390 << " land = BB" << LandMBB->getNumber() << "\n";); 1391 1392 insertInstrBefore(DstBlk, R600::WHILELOOP, DebugLoc()); 1393 insertInstrEnd(DstBlk, R600::ENDLOOP, DebugLoc()); 1394 DstBlk->replaceSuccessor(DstBlk, LandMBB); 1395 } 1396 1397 void R600MachineCFGStructurizer::mergeLoopbreakBlock(MachineBasicBlock *ExitingMBB, 1398 MachineBasicBlock *LandMBB) { 1399 LLVM_DEBUG(dbgs() << "loopbreakPattern exiting = BB" 1400 << ExitingMBB->getNumber() << " land = BB" 1401 << LandMBB->getNumber() << "\n";); 1402 MachineInstr *BranchMI = getLoopendBlockBranchInstr(ExitingMBB); 1403 assert(BranchMI && isCondBranch(BranchMI)); 1404 DebugLoc DL = BranchMI->getDebugLoc(); 1405 MachineBasicBlock *TrueBranch = getTrueBranch(BranchMI); 1406 MachineBasicBlock::iterator I = BranchMI; 1407 if (TrueBranch != LandMBB) 1408 reversePredicateSetter(I, *I->getParent()); 1409 insertCondBranchBefore(ExitingMBB, I, R600::IF_PREDICATE_SET, R600::PREDICATE_BIT, DL); 1410 insertInstrBefore(I, R600::BREAK); 1411 insertInstrBefore(I, R600::ENDIF); 1412 //now branchInst can be erase safely 1413 BranchMI->eraseFromParent(); 1414 //now take care of successors, retire blocks 1415 ExitingMBB->removeSuccessor(LandMBB, true); 1416 } 1417 1418 void R600MachineCFGStructurizer::settleLoopcontBlock(MachineBasicBlock *ContingMBB, 1419 MachineBasicBlock *ContMBB) { 1420 LLVM_DEBUG(dbgs() << "settleLoopcontBlock conting = BB" 1421 << ContingMBB->getNumber() << ", cont = BB" 1422 << ContMBB->getNumber() << "\n";); 1423 1424 MachineInstr *MI = getLoopendBlockBranchInstr(ContingMBB); 1425 if (MI) { 1426 assert(isCondBranch(MI)); 1427 MachineBasicBlock::iterator I = MI; 1428 MachineBasicBlock *TrueBranch = getTrueBranch(MI); 1429 int OldOpcode = MI->getOpcode(); 1430 DebugLoc DL = MI->getDebugLoc(); 1431 1432 bool UseContinueLogical = ((&*ContingMBB->rbegin()) == MI); 1433 1434 if (!UseContinueLogical) { 1435 int BranchOpcode = 1436 TrueBranch == ContMBB ? getBranchNzeroOpcode(OldOpcode) : 1437 getBranchZeroOpcode(OldOpcode); 1438 insertCondBranchBefore(I, BranchOpcode, DL); 1439 // insertEnd to ensure phi-moves, if exist, go before the continue-instr. 1440 insertInstrEnd(ContingMBB, R600::CONTINUE, DL); 1441 insertInstrEnd(ContingMBB, R600::ENDIF, DL); 1442 } else { 1443 int BranchOpcode = 1444 TrueBranch == ContMBB ? getContinueNzeroOpcode(OldOpcode) : 1445 getContinueZeroOpcode(OldOpcode); 1446 insertCondBranchBefore(I, BranchOpcode, DL); 1447 } 1448 1449 MI->eraseFromParent(); 1450 } else { 1451 // if we've arrived here then we've already erased the branch instruction 1452 // travel back up the basic block to see the last reference of our debug 1453 // location we've just inserted that reference here so it should be 1454 // representative insertEnd to ensure phi-moves, if exist, go before the 1455 // continue-instr. 1456 insertInstrEnd(ContingMBB, R600::CONTINUE, 1457 getLastDebugLocInBB(ContingMBB)); 1458 } 1459 } 1460 1461 int R600MachineCFGStructurizer::cloneOnSideEntryTo(MachineBasicBlock *PreMBB, 1462 MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB) { 1463 int Cloned = 0; 1464 assert(PreMBB->isSuccessor(SrcMBB)); 1465 while (SrcMBB && SrcMBB != DstMBB) { 1466 assert(SrcMBB->succ_size() == 1); 1467 if (SrcMBB->pred_size() > 1) { 1468 SrcMBB = cloneBlockForPredecessor(SrcMBB, PreMBB); 1469 ++Cloned; 1470 } 1471 1472 PreMBB = SrcMBB; 1473 SrcMBB = *SrcMBB->succ_begin(); 1474 } 1475 1476 return Cloned; 1477 } 1478 1479 MachineBasicBlock * 1480 R600MachineCFGStructurizer::cloneBlockForPredecessor(MachineBasicBlock *MBB, 1481 MachineBasicBlock *PredMBB) { 1482 assert(PredMBB->isSuccessor(MBB) && "succBlk is not a predecessor of curBlk"); 1483 1484 MachineBasicBlock *CloneMBB = clone(MBB); //clone instructions 1485 replaceInstrUseOfBlockWith(PredMBB, MBB, CloneMBB); 1486 //srcBlk, oldBlk, newBlk 1487 1488 PredMBB->replaceSuccessor(MBB, CloneMBB); 1489 1490 // add all successor to cloneBlk 1491 cloneSuccessorList(CloneMBB, MBB); 1492 1493 numClonedInstr += MBB->size(); 1494 1495 LLVM_DEBUG(dbgs() << "Cloned block: " 1496 << "BB" << MBB->getNumber() << "size " << MBB->size() 1497 << "\n";); 1498 1499 SHOWNEWBLK(CloneMBB, "result of Cloned block: "); 1500 1501 return CloneMBB; 1502 } 1503 1504 void R600MachineCFGStructurizer::migrateInstruction(MachineBasicBlock *SrcMBB, 1505 MachineBasicBlock *DstMBB, MachineBasicBlock::iterator I) { 1506 MachineBasicBlock::iterator SpliceEnd; 1507 //look for the input branchinstr, not the AMDGPU branchinstr 1508 MachineInstr *BranchMI = getNormalBlockBranchInstr(SrcMBB); 1509 if (!BranchMI) { 1510 LLVM_DEBUG(dbgs() << "migrateInstruction don't see branch instr\n";); 1511 SpliceEnd = SrcMBB->end(); 1512 } else { 1513 LLVM_DEBUG(dbgs() << "migrateInstruction see branch instr: " << *BranchMI); 1514 SpliceEnd = BranchMI; 1515 } 1516 LLVM_DEBUG(dbgs() << "migrateInstruction before splice dstSize = " 1517 << DstMBB->size() << "srcSize = " << SrcMBB->size() 1518 << "\n";); 1519 1520 //splice insert before insertPos 1521 DstMBB->splice(I, SrcMBB, SrcMBB->begin(), SpliceEnd); 1522 1523 LLVM_DEBUG(dbgs() << "migrateInstruction after splice dstSize = " 1524 << DstMBB->size() << "srcSize = " << SrcMBB->size() 1525 << '\n';); 1526 } 1527 1528 MachineBasicBlock * 1529 R600MachineCFGStructurizer::normalizeInfiniteLoopExit(MachineLoop* LoopRep) { 1530 MachineBasicBlock *LoopHeader = LoopRep->getHeader(); 1531 MachineBasicBlock *LoopLatch = LoopRep->getLoopLatch(); 1532 1533 if (!LoopHeader || !LoopLatch) 1534 return nullptr; 1535 MachineInstr *BranchMI = getLoopendBlockBranchInstr(LoopLatch); 1536 // Is LoopRep an infinite loop ? 1537 if (!BranchMI || !isUncondBranch(BranchMI)) 1538 return nullptr; 1539 1540 MachineBasicBlock *DummyExitBlk = FuncRep->CreateMachineBasicBlock(); 1541 FuncRep->push_back(DummyExitBlk); //insert to function 1542 SHOWNEWBLK(DummyExitBlk, "DummyExitBlock to normalize infiniteLoop: "); 1543 LLVM_DEBUG(dbgs() << "Old branch instr: " << *BranchMI << "\n";); 1544 LLVMContext &Ctx = LoopHeader->getParent()->getFunction().getContext(); 1545 Ctx.emitError("Extra register needed to handle CFG"); 1546 return nullptr; 1547 } 1548 1549 void R600MachineCFGStructurizer::removeUnconditionalBranch(MachineBasicBlock *MBB) { 1550 MachineInstr *BranchMI; 1551 1552 // I saw two unconditional branch in one basic block in example 1553 // test_fc_do_while_or.c need to fix the upstream on this to remove the loop. 1554 while ((BranchMI = getLoopendBlockBranchInstr(MBB)) 1555 && isUncondBranch(BranchMI)) { 1556 LLVM_DEBUG(dbgs() << "Removing uncond branch instr: " << *BranchMI); 1557 BranchMI->eraseFromParent(); 1558 } 1559 } 1560 1561 void R600MachineCFGStructurizer::removeRedundantConditionalBranch( 1562 MachineBasicBlock *MBB) { 1563 if (MBB->succ_size() != 2) 1564 return; 1565 MachineBasicBlock *MBB1 = *MBB->succ_begin(); 1566 MachineBasicBlock *MBB2 = *std::next(MBB->succ_begin()); 1567 if (MBB1 != MBB2) 1568 return; 1569 1570 MachineInstr *BranchMI = getNormalBlockBranchInstr(MBB); 1571 assert(BranchMI && isCondBranch(BranchMI)); 1572 LLVM_DEBUG(dbgs() << "Removing unneeded cond branch instr: " << *BranchMI); 1573 BranchMI->eraseFromParent(); 1574 SHOWNEWBLK(MBB1, "Removing redundant successor"); 1575 MBB->removeSuccessor(MBB1, true); 1576 } 1577 1578 void R600MachineCFGStructurizer::addDummyExitBlock( 1579 SmallVectorImpl<MachineBasicBlock*> &RetMBB) { 1580 MachineBasicBlock *DummyExitBlk = FuncRep->CreateMachineBasicBlock(); 1581 FuncRep->push_back(DummyExitBlk); //insert to function 1582 insertInstrEnd(DummyExitBlk, R600::RETURN); 1583 1584 for (MachineBasicBlock *MBB : RetMBB) { 1585 if (MachineInstr *MI = getReturnInstr(MBB)) 1586 MI->eraseFromParent(); 1587 MBB->addSuccessor(DummyExitBlk); 1588 LLVM_DEBUG(dbgs() << "Add dummyExitBlock to BB" << MBB->getNumber() 1589 << " successors\n";); 1590 } 1591 SHOWNEWBLK(DummyExitBlk, "DummyExitBlock: "); 1592 } 1593 1594 void R600MachineCFGStructurizer::removeSuccessor(MachineBasicBlock *MBB) { 1595 while (MBB->succ_size()) 1596 MBB->removeSuccessor(*MBB->succ_begin()); 1597 } 1598 1599 void R600MachineCFGStructurizer::recordSccnum(MachineBasicBlock *MBB, 1600 int SccNum) { 1601 BlockInformation *&srcBlkInfo = BlockInfoMap[MBB]; 1602 if (!srcBlkInfo) 1603 srcBlkInfo = new BlockInformation(); 1604 srcBlkInfo->SccNum = SccNum; 1605 } 1606 1607 void R600MachineCFGStructurizer::retireBlock(MachineBasicBlock *MBB) { 1608 LLVM_DEBUG(dbgs() << "Retiring BB" << MBB->getNumber() << "\n";); 1609 1610 BlockInformation *&SrcBlkInfo = BlockInfoMap[MBB]; 1611 1612 if (!SrcBlkInfo) 1613 SrcBlkInfo = new BlockInformation(); 1614 1615 SrcBlkInfo->IsRetired = true; 1616 assert(MBB->succ_empty() && MBB->pred_empty() && "can't retire block yet"); 1617 } 1618 1619 INITIALIZE_PASS_BEGIN(R600MachineCFGStructurizer, "amdgpustructurizer", 1620 "AMDGPU CFG Structurizer", false, false) 1621 INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass) 1622 INITIALIZE_PASS_DEPENDENCY(MachinePostDominatorTreeWrapperPass) 1623 INITIALIZE_PASS_DEPENDENCY(MachineLoopInfoWrapperPass) 1624 INITIALIZE_PASS_END(R600MachineCFGStructurizer, "amdgpustructurizer", 1625 "AMDGPU CFG Structurizer", false, false) 1626 1627 FunctionPass *llvm::createR600MachineCFGStructurizerPass() { 1628 return new R600MachineCFGStructurizer(); 1629 } 1630