LLVM: lib/Target/AMDGPU/R600MachineCFGStructurizer.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

22

23using namespace llvm;

24

25#define DEBUG_TYPE "structcfg"

26

28

29

30

31

32

33

34

35

36

37STATISTIC(numSerialPatternMatch, "CFGStructurizer number of serial pattern "

38 "matched");

39STATISTIC(numIfPatternMatch, "CFGStructurizer number of if pattern "

40 "matched");

41STATISTIC(numClonedBlock, "CFGStructurizer cloned blocks");

42STATISTIC(numClonedInstr, "CFGStructurizer cloned instructions");

43

44namespace {

45

46

47

48

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

70

71

72

73class BlockInformation {

74public:

75 bool IsRetired = false;

77

78 BlockInformation() = default;

79};

80

81

82

83

84

85

86

88public:

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();

109 AU.addRequired();

110 AU.addRequired();

112 }

113

114

115 bool run();

116

117

118

119

121

122 bool runOnMachineFunction(MachineFunction &MF) override {

123

125

126 TII = MF.getSubtarget().getInstrInfo();

127 TRI = &TII->getRegisterInfo();

129 OrderedBlks.clear();

130 Visited.clear();

131 FuncRep = &MF;

132 MLI = &getAnalysis().getLI();

133 LLVM_DEBUG(dbgs() << "LoopInfo:\n"; PrintLoopinfo(*MLI););

134 MDT = &getAnalysis().getDomTree();

136 PDT = &getAnalysis().getPostDomTree();

141 return true;

142 }

143

144protected:

145 MachineDominatorTree *MDT;

146 MachinePostDominatorTree *PDT;

147 MachineLoopInfo *MLI;

148 const R600InstrInfo *TII = nullptr;

149 const R600RegisterInfo *TRI = nullptr;

150

151

152

153 void printOrderedBlocks() const {

154 size_t i = 0;

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

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;

182 bool needMigrateBlock(MachineBasicBlock *MBB) const;

183

184

186 MachineBasicBlock &MBB);

187

188 void orderBlocks(MachineFunction *MF);

189

190

191 void insertInstrEnd(MachineBasicBlock *MBB, int NewOpcode,

193 MachineInstr *insertInstrBefore(MachineBasicBlock *MBB, int NewOpcode,

198 void insertCondBranchBefore(MachineBasicBlock *MBB,

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

216

217

218

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

228

229

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

243

244

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

273

274

275

276

277

278

279

280 MachineBasicBlock *normalizeInfiniteLoopExit(MachineLoop *LoopRep);

281 void removeUnconditionalBranch(MachineBasicBlock *MBB);

282

283

284

285

286

287

288

289

290

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,

299 void recordSccnum(MachineBasicBlock *MBB, int SCCNum);

300 void retireBlock(MachineBasicBlock *MBB);

301

302private:

303 MBBInfoMap BlockInfoMap;

304 LoopLandInfoMap LLInfoMap;

305 std::map<MachineLoop *, bool> Visited;

306 MachineFunction *FuncRep;

308};

309

310}

311

312char R600MachineCFGStructurizer::ID = 0;

313

315 MBBInfoMap::const_iterator It = BlockInfoMap.find(MBB);

316 if (It == BlockInfoMap.end())

318 return (*It).second->SccNum;

319}

320

321MachineBasicBlock *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

329bool R600MachineCFGStructurizer::hasBackEdge(MachineBasicBlock *MBB) const {

331 if (!LoopRep)

332 return false;

333 MachineBasicBlock *LoopHeader = LoopRep->getHeader();

335}

336

337bool 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

344bool R600MachineCFGStructurizer::isActiveLoophead(MachineBasicBlock *MBB) const {

346 while (LoopRep && LoopRep->getHeader() == MBB) {

347 MachineBasicBlock *LoopLand = getLoopLandInfo(LoopRep);

348 if(!LoopLand)

349 return true;

350 if (!isRetiredBlock(LoopLand))

351 return true;

353 }

354 return false;

355}

356

357R600MachineCFGStructurizer::PathToKind R600MachineCFGStructurizer::singlePathTo(

358 MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB,

359 bool AllowSideEntry) const {

361 if (SrcMBB == DstMBB)

362 return SinglePath_InPath;

363 while (SrcMBB && SrcMBB->succ_size() == 1) {

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

378 while (It != E) {

379 if (!isRetiredBlock(*It))

381 ++It;

382 }

384}

385

386bool R600MachineCFGStructurizer::needMigrateBlock(MachineBasicBlock *MBB) const {

387 unsigned BlockSizeThreshold = 30;

388 unsigned CloneInstrThreshold = 100;

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

398void R600MachineCFGStructurizer::reversePredicateSetter(

400 assert(I.isValid() && "Expected valid iterator");

401 for (;; --I) {

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:

420 }

421 }

422 }

423}

424

425void R600MachineCFGStructurizer::insertInstrEnd(MachineBasicBlock *MBB,

427 MachineInstr *MI =

430

432}

433

434MachineInstr *R600MachineCFGStructurizer::insertInstrBefore(MachineBasicBlock *MBB,

435 int NewOpcode,

437 MachineInstr *MI =

441 else

444 return MI;

445}

446

447MachineInstr *R600MachineCFGStructurizer::insertInstrBefore(

449 MachineInstr *OldMI = &(*I);

451 MachineInstr *NewMBB =

454

456 return NewMBB;

457}

458

459void R600MachineCFGStructurizer::insertCondBranchBefore(

461 MachineInstr *OldMI = &(*I);

464 MachineInstr *NewMI = MF->CreateMachineInstr(TII->get(NewOpcode), DL);

466 MachineInstrBuilder MIB(*MF, NewMI);

469

470}

471

472void R600MachineCFGStructurizer::insertCondBranchBefore(

475 MachineFunction *MF = blk->getParent();

476 MachineInstr *NewInstr = MF->CreateMachineInstr(TII->get(NewOpcode), DL);

477

478 blk->insert(I, NewInstr);

479 MachineInstrBuilder(*MF, NewInstr).addReg(RegNum, false);

481}

482

483int 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;

490 }

491 return -1;

492}

493

494int 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;

501 }

502 return -1;

503}

504

505int R600MachineCFGStructurizer::getContinueNzeroOpcode(int OldOpcode) {

506 switch(OldOpcode) {

507 case R600::JUMP_COND:

508 case R600::JUMP: return R600::CONTINUE_LOGICALNZ_i32;

510 }

511 return -1;

512}

513

514int R600MachineCFGStructurizer::getContinueZeroOpcode(int OldOpcode) {

515 switch(OldOpcode) {

516 case R600::JUMP_COND:

517 case R600::JUMP: return R600::CONTINUE_LOGICALZ_i32;

519 }

520 return -1;

521}

522

523MachineBasicBlock *R600MachineCFGStructurizer::getTrueBranch(MachineInstr *MI) {

524 return MI->getOperand(0).getMBB();

525}

526

527void R600MachineCFGStructurizer::setTrueBranch(MachineInstr *MI,

528 MachineBasicBlock *MBB) {

529 MI->getOperand(0).setMBB(MBB);

530}

531

532MachineBasicBlock *

533R600MachineCFGStructurizer::getFalseBranch(MachineBasicBlock *MBB,

534 MachineInstr *MI) {

536 MachineBasicBlock *TrueBranch = getTrueBranch(MI);

540 return (*It == TrueBranch) ? *Next : *It;

541}

542

543bool 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

554bool 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

565DebugLoc R600MachineCFGStructurizer::getLastDebugLocInBB(MachineBasicBlock *MBB) {

566

568 for (MachineInstr &MI : *MBB)

569 if (MI.getDebugLoc())

570 DL = MI.getDebugLoc();

571 return DL;

572}

573

574MachineInstr *R600MachineCFGStructurizer::getNormalBlockBranchInstr(

575 MachineBasicBlock *MBB) {

577 MachineInstr *MI = &*It;

578 if (MI && (isCondBranch(MI) || isUncondBranch(MI)))

579 return MI;

580 return nullptr;

581}

582

583MachineInstr *R600MachineCFGStructurizer::getLoopendBlockBranchInstr(

584 MachineBasicBlock *MBB) {

586 It != E; ++It) {

587

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

599MachineInstr *R600MachineCFGStructurizer::getReturnInstr(MachineBasicBlock *MBB) {

602 MachineInstr *instr = &(*It);

603 if (instr->getOpcode() == R600::RETURN)

605 }

606 return nullptr;

607}

608

609bool R600MachineCFGStructurizer::isReturnBlock(MachineBasicBlock *MBB) {

610 MachineInstr *MI = getReturnInstr(MBB);

612 if (MI)

614 else if (IsReturn)

616 << " is return block without RETURN instr\n";);

617 return IsReturn;

618}

619

620void R600MachineCFGStructurizer::cloneSuccessorList(MachineBasicBlock *DstMBB,

621 MachineBasicBlock *SrcMBB) {

622 for (MachineBasicBlock *Succ : SrcMBB->successors())

623 DstMBB->addSuccessor(Succ);

624}

625

626MachineBasicBlock *R600MachineCFGStructurizer::clone(MachineBasicBlock *MBB) {

628 MachineBasicBlock *NewMBB = Func->CreateMachineBasicBlock();

629 Func->push_back(NewMBB);

630 for (const MachineInstr &It : *MBB)

632 return NewMBB;

633}

634

635void 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

644void R600MachineCFGStructurizer::wrapup(MachineBasicBlock *MBB) {

647 && "found a jump table");

648

649

654 while (It != E) {

655 if (Pre->getOpcode() == R600::CONTINUE

656 && It->getOpcode() == R600::ENDLOOP)

658 Pre = It;

659 ++It;

660 }

661

662

663 for (auto *MI : ContInstr)

664 MI->eraseFromParent();

665

666

667

668

669

670}

671

672bool R600MachineCFGStructurizer::prepare() {

674

675

676

677 LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::prepare\n";);

678

679 orderBlocks(FuncRep);

680

682

683

684 for (MachineLoop *LoopRep : *MLI) {

687

688 if (ExitingMBBs.size() == 0) {

689 MachineBasicBlock* DummyExitBlk = normalizeInfiniteLoopExit(LoopRep);

690 if (DummyExitBlk)

692 }

693 }

694

695

696

697 for (MachineBasicBlock *MBB : OrderedBlks) {

698 removeUnconditionalBranch(MBB);

699 removeRedundantConditionalBranch(MBB);

700 if (isReturnBlock(MBB)) {

702 }

704 }

705

706 if (RetBlks.size() >= 2) {

707 addDummyExitBlock(RetBlks);

709 }

710

712}

713

714bool R600MachineCFGStructurizer::run() {

715

716 LLVM_DEBUG(dbgs() << "R600MachineCFGStructurizer::run\n");

717

718#ifdef STRESSTEST

719

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;

734 << ", numRemaintedBlk = " << NumRemainedBlk << "\n";);

735 (void)NumIter;

736

738 OrderedBlks.begin();

740 OrderedBlks.end();

741

743 It;

744 MachineBasicBlock *SccBeginMBB = nullptr;

745 int SccNumBlk = 0;

746

747 int SccNumIter;

748

749 while (It != E) {

750 MBB = *It;

751

752 if (!SccBeginMBB) {

753 SccBeginIter = It;

754 SccBeginMBB = MBB;

755 SccNumIter = 0;

756 SccNumBlk = NumRemainedBlk;

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

770 ++SccNumIter;

771 int sccRemainedNumBlk = countActiveBlock(SccBeginIter, It);

772 if (sccRemainedNumBlk != 1 && sccRemainedNumBlk >= SccNumBlk) {

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;

783 << "sccNumIter = " << SccNumIter << '\n';);

784 } else {

785

786 ContNextScc = true;

787 }

788 } else {

789

790 ContNextScc = false;

791 }

792

793 if (ContNextScc)

794 SccBeginMBB = nullptr;

795 }

796

797 MachineBasicBlock *EntryMBB =

800 Finish = true;

802 } else {

803 int NewnumRemainedBlk

804 = countActiveBlock(OrderedBlks.begin(), OrderedBlks.end());

805

806 if (NewnumRemainedBlk == 1 || NewnumRemainedBlk < NumRemainedBlk) {

807 MakeProgress = true;

808 NumRemainedBlk = NewnumRemainedBlk;

809 } else {

810 MakeProgress = false;

812 }

813 }

814 } while (!Finish && MakeProgress);

815

816

818

819

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();

825 }

826 delete It.second;

827 }

828 BlockInfoMap.clear();

829 LLInfoMap.clear();

830

831 if (!Finish) {

834 }

835

836 return true;

837}

838

839void 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

851 for (auto *MBB : nodes(MF)) {

852 SccNum = getSCCNum(MBB);

854 dbgs() << "unreachable block BB" << MBB->getNumber() << "\n";

855 }

856}

857

858int R600MachineCFGStructurizer::patternMatch(MachineBasicBlock *MBB) {

859 int NumMatch = 0;

860 int CurMatch;

861

863

864 while ((CurMatch = patternMatchGroup(MBB)) > 0)

865 NumMatch += CurMatch;

866

868 << ", numMatch = " << NumMatch << "\n";);

869

870 return NumMatch;

871}

872

873int R600MachineCFGStructurizer::patternMatchGroup(MachineBasicBlock *MBB) {

874 int NumMatch = 0;

875 NumMatch += loopendPatternMatch();

876 NumMatch += serialPatternMatch(MBB);

877 NumMatch += ifPatternMatch(MBB);

878 return NumMatch;

879}

880

881int R600MachineCFGStructurizer::serialPatternMatch(MachineBasicBlock *MBB) {

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

894int R600MachineCFGStructurizer::ifPatternMatch(MachineBasicBlock *MBB) {

895

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

917

920

922 } else if (TrueMBB->succ_size() == 1 && *TrueMBB->succ_begin() == FalseMBB) {

923

924 LandBlk = FalseMBB;

925 FalseMBB = nullptr;

926 } else if (FalseMBB->succ_size() == 1

927 && *FalseMBB->succ_begin() == TrueMBB) {

928

929

931 reversePredicateSetter(MBB->end(), *MBB);

932 LandBlk = FalseMBB;

933 FalseMBB = nullptr;

934 } else if (FalseMBB->succ_size() == 1

935 && isSameloopDetachedContbreak(TrueMBB, FalseMBB)) {

937 } else if (TrueMBB->succ_size() == 1

938 && isSameloopDetachedContbreak(FalseMBB, TrueMBB)) {

940 } else {

941 return NumMatch + handleJumpintoIf(MBB, TrueMBB, FalseMBB);

942 }

943

944

945

946

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

972int R600MachineCFGStructurizer::loopendPatternMatch() {

973 std::deque<MachineLoop *> NestedLoops;

974 for (auto &It: *MLI)

976 NestedLoops.push_front(ML);

977

978 if (NestedLoops.empty())

979 return 0;

980

981

982

983

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

997int R600MachineCFGStructurizer::mergeLoop(MachineLoop *LoopRep) {

998 MachineBasicBlock *LoopHeader = LoopRep->getHeader();

1001 assert(!ExitingMBBs.empty() && "Infinite Loop not supported");

1003 << " exiting blocks\n";);

1004

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");

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

1036bool R600MachineCFGStructurizer::isSameloopDetachedContbreak(

1037 MachineBasicBlock *Src1MBB, MachineBasicBlock *Src2MBB) {

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

1053int 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

1064int R600MachineCFGStructurizer::handleJumpintoIfImp(MachineBasicBlock *HeadMBB,

1065 MachineBasicBlock *TrueMBB, MachineBasicBlock *FalseMBB) {

1066 int Num = 0;

1067 MachineBasicBlock *DownBlk;

1068

1069

1070 DownBlk = TrueMBB;

1071

1073 << " true = BB" << TrueMBB->getNumber()

1074 << ", numSucc=" << TrueMBB->succ_size() << " false = BB"

1075 << FalseMBB->getNumber() << "\n";);

1076

1077 while (DownBlk) {

1079

1080 if (singlePathTo(FalseMBB, DownBlk) == SinglePath_InPath) {

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);

1091

1092 break;

1093 }

1095 DownBlk = (DownBlk->succ_size() == 1) ? (*DownBlk->succ_begin()) : nullptr;

1096 }

1097

1098 return Num;

1099}

1100

1101#ifndef NDEBUG

1102void R600MachineCFGStructurizer::showImproveSimpleJumpintoIf(

1103 MachineBasicBlock *HeadMBB, MachineBasicBlock *TrueMBB,

1104 MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB, bool Detail) {

1106 << " size = " << HeadMBB->size();

1107 if (Detail) {

1108 dbgs() << "\n";

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";

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";

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";

1137 dbgs() << "\n";

1138 }

1139 }

1140

1141 dbgs() << "\n";

1142}

1143#endif

1144

1145int 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

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

1166

1167

1168 if (!MigrateTrue && TrueMBB && TrueMBB->pred_size() > 1)

1169 MigrateTrue = true;

1170 if (!MigrateFalse && FalseMBB && FalseMBB->pred_size() > 1)

1171 MigrateFalse = true;

1172

1174 dbgs() << "before improveSimpleJumpintoIf: ";

1175 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););

1176

1177

1178

1179

1180

1181

1182

1183

1184

1185

1186

1187

1188 const TargetRegisterClass * I32RC = TRI->getCFGStructurizerRegClass(MVT::i32);

1189 if (!MigrateTrue || !MigrateFalse) {

1190

1191

1192

1193

1194

1195

1196

1197

1198

1199

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209

1210

1211

1212

1213

1214

1215

1216

1217

1218

1219

1220

1221

1222

1223

1224

1225

1226

1227

1228

1229

1230

1231

1232

1233

1234

1235

1236

1237

1238

1239

1240

1241

1242

1243

1244

1245

1246

1247

1248

1249

1250

1251

1252

1253

1254

1255 return 0;

1256 }

1257

1258 int NumNewBlk = 0;

1259

1260 bool LandBlkHasOtherPred = (LandBlk->pred_size() > 2);

1261

1262

1264

1265 if (LandBlkHasOtherPred) {

1269 report_fatal_error("Extra compare instruction needed to handle CFG");

1270 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET,

1272 }

1273

1274

1275

1278 insertCondBranchBefore(LandBlk, I, R600::IF_PREDICATE_SET, InitReg,

1280

1281 if (MigrateTrue) {

1282 migrateInstruction(TrueMBB, LandBlk, I);

1283

1284

1285

1287 }

1288 insertInstrBefore(I, R600::ELSE);

1289

1290 if (MigrateFalse) {

1291 migrateInstruction(FalseMBB, LandBlk, I);

1292

1293

1294

1296 }

1297

1298 if (LandBlkHasOtherPred) {

1299

1300 insertInstrBefore(I, R600::ENDIF);

1301

1302

1304 if (MBB != TrueMBB && MBB != FalseMBB)

1306 }

1308 dbgs() << "result from improveSimpleJumpintoIf: ";

1309 showImproveSimpleJumpintoIf(HeadMBB, TrueMBB, FalseMBB, LandBlk, 0););

1310

1311

1312 *LandMBBPtr = LandBlk;

1313

1314 return NumNewBlk;

1315}

1316

1317void R600MachineCFGStructurizer::mergeSerialBlock(MachineBasicBlock *DstMBB,

1318 MachineBasicBlock *SrcMBB) {

1320 << SrcMBB->getNumber() << "\n";);

1321 DstMBB->splice(DstMBB->end(), SrcMBB, SrcMBB->begin(), SrcMBB->end());

1322

1324 cloneSuccessorList(DstMBB, SrcMBB);

1325

1326 removeSuccessor(SrcMBB);

1327 MLI->removeBlock(SrcMBB);

1328 retireBlock(SrcMBB);

1329}

1330

1331void R600MachineCFGStructurizer::mergeIfthenelseBlock(MachineInstr *BranchMI,

1332 MachineBasicBlock *MBB, MachineBasicBlock *TrueMBB,

1333 MachineBasicBlock *FalseMBB, MachineBasicBlock *LandMBB) {

1337 << " } else ";

1338 dbgs() << "{ "; if (FalseMBB) {

1340 } dbgs() << " }\n ";

1341 dbgs() << "landBlock: "; if (!LandMBB) { dbgs() << "NULL"; } else {

1343 } dbgs() << "\n";);

1344

1345 int OldOpcode = BranchMI->getOpcode();

1347

1348

1349

1350

1351

1352

1353

1354

1355

1357 insertCondBranchBefore(I, getBranchNzeroOpcode(OldOpcode),

1358 BranchDL);

1359

1360 if (TrueMBB) {

1363 if (LandMBB && TrueMBB->succ_size()!=0)

1365 retireBlock(TrueMBB);

1366 MLI->removeBlock(TrueMBB);

1367 }

1368

1369 if (FalseMBB) {

1370 insertInstrBefore(I, R600::ELSE);

1372 FalseMBB->end());

1374 if (LandMBB && !FalseMBB->succ_empty())

1376 retireBlock(FalseMBB);

1377 MLI->removeBlock(FalseMBB);

1378 }

1379 insertInstrBefore(I, R600::ENDIF);

1380

1382

1383 if (LandMBB && TrueMBB && FalseMBB)

1385}

1386

1387void R600MachineCFGStructurizer::mergeLooplandBlock(MachineBasicBlock *DstBlk,

1388 MachineBasicBlock *LandMBB) {

1390 << " land = BB" << LandMBB->getNumber() << "\n";);

1391

1392 insertInstrBefore(DstBlk, R600::WHILELOOP, DebugLoc());

1393 insertInstrEnd(DstBlk, R600::ENDLOOP, DebugLoc());

1395}

1396

1397void 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));

1405 MachineBasicBlock *TrueBranch = getTrueBranch(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

1414

1416}

1417

1418void 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) {

1428 MachineBasicBlock *TrueBranch = getTrueBranch(MI);

1429 int OldOpcode = MI->getOpcode();

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

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

1452

1453

1454

1455

1456 insertInstrEnd(ContingMBB, R600::CONTINUE,

1457 getLastDebugLocInBB(ContingMBB));

1458 }

1459}

1460

1461int R600MachineCFGStructurizer::cloneOnSideEntryTo(MachineBasicBlock *PreMBB,

1462 MachineBasicBlock *SrcMBB, MachineBasicBlock *DstMBB) {

1463 int Cloned = 0;

1465 while (SrcMBB && SrcMBB != DstMBB) {

1468 SrcMBB = cloneBlockForPredecessor(SrcMBB, PreMBB);

1469 ++Cloned;

1470 }

1471

1472 PreMBB = SrcMBB;

1474 }

1475

1476 return Cloned;

1477}

1478

1479MachineBasicBlock *

1480R600MachineCFGStructurizer::cloneBlockForPredecessor(MachineBasicBlock *MBB,

1481 MachineBasicBlock *PredMBB) {

1482 assert(PredMBB->isSuccessor(MBB) && "succBlk is not a predecessor of curBlk");

1483

1484 MachineBasicBlock *CloneMBB = clone(MBB);

1485 replaceInstrUseOfBlockWith(PredMBB, MBB, CloneMBB);

1486

1487

1489

1490

1491 cloneSuccessorList(CloneMBB, MBB);

1492

1493 numClonedInstr += MBB->size();

1494

1497 << "\n";);

1498

1499 SHOWNEWBLK(CloneMBB, "result of Cloned block: ");

1500

1501 return CloneMBB;

1502}

1503

1504void R600MachineCFGStructurizer::migrateInstruction(MachineBasicBlock *SrcMBB,

1507

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

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

1528MachineBasicBlock *

1529R600MachineCFGStructurizer::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

1537 if (!BranchMI || !isUncondBranch(BranchMI))

1538 return nullptr;

1539

1541 FuncRep->push_back(DummyExitBlk);

1542 SHOWNEWBLK(DummyExitBlk, "DummyExitBlock to normalize infiniteLoop: ");

1543 LLVM_DEBUG(dbgs() << "Old branch instr: " << *BranchMI << "\n";);

1545 Ctx.emitError("Extra register needed to handle CFG");

1546 return nullptr;

1547}

1548

1549void R600MachineCFGStructurizer::removeUnconditionalBranch(MachineBasicBlock *MBB) {

1550 MachineInstr *BranchMI;

1551

1552

1553

1554 while ((BranchMI = getLoopendBlockBranchInstr(MBB))

1555 && isUncondBranch(BranchMI)) {

1556 LLVM_DEBUG(dbgs() << "Removing uncond branch instr: " << *BranchMI);

1558 }

1559}

1560

1561void R600MachineCFGStructurizer::removeRedundantConditionalBranch(

1562 MachineBasicBlock *MBB) {

1564 return;

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);

1574 SHOWNEWBLK(MBB1, "Removing redundant successor");

1576}

1577

1578void R600MachineCFGStructurizer::addDummyExitBlock(

1579 SmallVectorImpl<MachineBasicBlock*> &RetMBB) {

1581 FuncRep->push_back(DummyExitBlk);

1582 insertInstrEnd(DummyExitBlk, R600::RETURN);

1583

1584 for (MachineBasicBlock *MBB : RetMBB) {

1585 if (MachineInstr *MI = getReturnInstr(MBB))

1586 MI->eraseFromParent();

1589 << " successors\n";);

1590 }

1591 SHOWNEWBLK(DummyExitBlk, "DummyExitBlock: ");

1592}

1593

1594void R600MachineCFGStructurizer::removeSuccessor(MachineBasicBlock *MBB) {

1597}

1598

1599void 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

1607void R600MachineCFGStructurizer::retireBlock(MachineBasicBlock *MBB) {

1609

1610 BlockInformation *&SrcBlkInfo = BlockInfoMap[MBB];

1611

1612 if (!SrcBlkInfo)

1613 SrcBlkInfo = new BlockInformation();

1614

1615 SrcBlkInfo->IsRetired = true;

1617}

1618

1620 "AMDGPU CFG Structurizer", false, false)

1626

1628 return new R600MachineCFGStructurizer();

1629}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

Unify divergent function exit nodes

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")

This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.

const HexagonInstrInfo * TII

Register const TargetRegisterInfo * TRI

Promote Memory to Register

#define INITIALIZE_PASS_DEPENDENCY(depName)

#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)

#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)

SmallVector< MachineBasicBlock *, 4 > MBBVector

Provides R600 specific target descriptions.

#define SHOWNEWBLK(b, msg)

Definition R600MachineCFGStructurizer.cpp:54

#define SHOWNEWINSTR(i)

Definition R600MachineCFGStructurizer.cpp:52

@ DEFAULT_VEC_SLOTS

Definition R600MachineCFGStructurizer.cpp:27

#define INVALIDSCCNUM

Definition R600MachineCFGStructurizer.cpp:65

Interface definition for R600RegisterInfo.

AMDGPU R600 specific subclass of TargetSubtarget.

This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...

static uint32_t blk(uint32_t *Buf, int I)

This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...

#define STATISTIC(VARNAME, DESC)

AnalysisUsage & addRequired()

FunctionPass class - This class is used to implement most global optimizations.

LLVMContext & getContext() const

getContext - Return a reference to the LLVMContext associated with this function.

LLVM_ABI void emitError(const Instruction *I, const Twine &ErrorStr)

emitError - Emit an error message to the currently installed error handler with optional location inf...

bool contains(const LoopT *L) const

Return true if the specified loop is contained within in this loop.

BlockT * getLoopLatch() const

If there is a single latch block for this loop, return it.

void getExitBlocks(SmallVectorImpl< BlockT * > &ExitBlocks) const

Return all of the successor blocks of this loop.

void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const

Return all blocks inside the loop that have successors outside of the loop.

BlockT * getHeader() const

LoopT * getParentLoop() const

Return the parent loop if it exists or nullptr for top level loops.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

unsigned pred_size() const

LLVM_ABI void replaceSuccessor(MachineBasicBlock *Old, MachineBasicBlock *New)

Replace successor OLD with NEW and update probability info.

LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)

Insert MI into the instruction list before I, possibly inside a bundle.

int getNumber() const

MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...

void push_back(MachineInstr *MI)

succ_iterator succ_begin()

unsigned succ_size() const

LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())

Add Succ as a successor of this MachineBasicBlock.

SmallVectorImpl< MachineBasicBlock * >::iterator succ_iterator

LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)

Remove successor from the successors list of this MachineBasicBlock.

LLVM_ABI void print(raw_ostream &OS, const SlotIndexes *=nullptr, bool IsStandalone=true) const

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

iterator_range< succ_iterator > successors()

reverse_iterator rbegin()

LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB is a successor of this block.

iterator_range< pred_iterator > predecessors()

void splice(iterator Where, MachineBasicBlock *Other, iterator From)

Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...

MachineInstrBundleIterator< MachineInstr > iterator

Analysis pass which computes a MachineDominatorTree.

MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const TargetSubtargetInfo & getSubtarget() const

getSubtarget - Return the subtarget for which this machine code is being compiled.

void dump() const

dump - Print the current MachineFunction to cerr, useful for debugger use.

void push_back(MachineBasicBlock *MBB)

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

void viewCFG() const

viewCFG - This function is meant for use from the debugger.

const MachineFunctionProperties & getProperties() const

Get the function properties.

const MachineJumpTableInfo * getJumpTableInfo() const

getJumpTableInfo - Return the jump table info object for the current function.

MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)

CreateMachineInstr - Allocate a new MachineInstr.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

LLVM_ABI void eraseFromParent()

Unlink 'this' from the containing basic block and delete it.

const MachineOperand & getOperand(unsigned i) const

bool isEmpty() const

isEmpty - Return true if there are no jump tables.

Register getReg() const

getReg - Returns the register number.

LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")

createVirtualRegister - Create and return a new virtual register in the function with the specified r...

typename SuperClass::const_iterator const_iterator

void push_back(const T &Elt)

#define llvm_unreachable(msg)

Marks that the current location is not supposed to be reachable.

PointerTypeMap run(const Module &M)

Compute the PointerTypeMap for the module M.

NodeAddr< FuncNode * > Func

This is an optimization pass for GlobalISel generic memory operations.

constexpr from_range_t from_range

scc_iterator< T > scc_begin(const T &G)

Construct the begin iterator for a deduced graph type T.

LLVM_ABI raw_ostream & dbgs()

dbgs() - This returns a reference to a raw_ostream for debugging messages.

LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)

FunctionAddr VTableAddr Count

class LLVM_GSL_OWNER SmallVector

Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...

iterator_range< typename GraphTraits< Inverse< GraphType > >::ChildIteratorType > inverse_children(const typename GraphTraits< GraphType >::NodeRef &G)

FunctionAddr VTableAddr Next

iterator_range< df_iterator< T > > depth_first(const T &G)

FunctionPass * createR600MachineCFGStructurizerPass()

Definition R600MachineCFGStructurizer.cpp:1627

void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)

Implement std::swap in terms of BitVector swap.

static nodes_iterator nodes_begin(MachineFunction *F)