LLVM: lib/Target/Hexagon/HexagonEarlyIfConv.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

87#include

88#include

89

90#define DEBUG_TYPE "hexagon-eif"

91

92using namespace llvm;

93

97 cl::desc("Size limit in Hexagon early if-conversion"));

99 cl::Hidden, cl::desc("Do not convert branches that may exit the loop"));

100

101namespace {

102

103 struct PrintMB {

105

106 const MachineBasicBlock *MB;

107 };

109 if (P.MB)

110 return OS << "";

111 return OS << '#' << P.MB->getNumber();

112 }

113

114 struct FlowPattern {

115 FlowPattern() = default;

116 FlowPattern(MachineBasicBlock *B, unsigned PR, MachineBasicBlock *TB,

117 MachineBasicBlock *FB, MachineBasicBlock *JB)

118 : SplitB(B), TrueB(TB), FalseB(FB), JoinB(JB), PredR(PR) {}

119

120 MachineBasicBlock *SplitB = nullptr;

121 MachineBasicBlock *TrueB = nullptr;

122 MachineBasicBlock *FalseB = nullptr;

123 MachineBasicBlock *JoinB = nullptr;

124 unsigned PredR = 0;

125 };

126

127 struct PrintFP {

128 PrintFP(const FlowPattern &P, const TargetRegisterInfo &T)

129 : FP(P), TRI(T) {}

130

131 const FlowPattern &FP;

132 const TargetRegisterInfo &TRI;

133 friend raw_ostream &operator<< (raw_ostream &OS, const PrintFP &P);

134 };

137 OS << "{ SplitB:" << PrintMB(P.FP.SplitB)

138 << ", PredR:" << printReg(P.FP.PredR, &P.TRI)

139 << ", TrueB:" << PrintMB(P.FP.TrueB)

140 << ", FalseB:" << PrintMB(P.FP.FalseB)

141 << ", JoinB:" << PrintMB(P.FP.JoinB) << " }";

142 return OS;

143 }

144

146 public:

147 static char ID;

148

149 HexagonEarlyIfConversion() : MachineFunctionPass(ID) {}

150

151 StringRef getPassName() const override {

152 return "Hexagon early if conversion";

153 }

154

155 void getAnalysisUsage(AnalysisUsage &AU) const override {

156 AU.addRequired();

157 AU.addRequired();

158 AU.addPreserved();

159 AU.addRequired();

161 }

162

163 bool runOnMachineFunction(MachineFunction &MF) override;

164

165 private:

166 using BlockSetType = DenseSet<MachineBasicBlock *>;

167

168 bool isPreheader(const MachineBasicBlock *B) const;

169 bool matchFlowPattern(MachineBasicBlock *B, MachineLoop *L,

170 FlowPattern &FP);

171 bool visitBlock(MachineBasicBlock *B, MachineLoop *L);

172 bool visitLoop(MachineLoop *L);

173

174 bool hasEHLabel(const MachineBasicBlock *B) const;

175 bool hasUncondBranch(const MachineBasicBlock *B) const;

176 bool isValidCandidate(const MachineBasicBlock *B) const;

177 bool usesUndefVReg(const MachineInstr *MI) const;

178 bool isValid(const FlowPattern &FP) const;

179 unsigned countPredicateDefs(const MachineBasicBlock *B) const;

180 unsigned computePhiCost(const MachineBasicBlock *B,

181 const FlowPattern &FP) const;

183 bool isPredicableStore(const MachineInstr *MI) const;

184 bool isSafeToSpeculate(const MachineInstr *MI) const;

185 bool isPredicate(unsigned R) const;

186

187 unsigned getCondStoreOpcode(unsigned Opc, bool IfTrue) const;

189 MachineInstr *MI, unsigned PredR, bool IfTrue);

190 void predicateBlockNB(MachineBasicBlock *ToB,

192 unsigned PredR, bool IfTrue);

193

195 const TargetRegisterClass *DRC, unsigned PredR, unsigned TR,

196 unsigned TSR, unsigned FR, unsigned FSR);

197 void updatePhiNodes(MachineBasicBlock *WhereB, const FlowPattern &FP);

198 void convert(const FlowPattern &FP);

199

200 void removeBlock(MachineBasicBlock *B);

201 void eliminatePhis(MachineBasicBlock *B);

202 void mergeBlocks(MachineBasicBlock *PredB, MachineBasicBlock *SuccB);

203 void simplifyFlowGraph(const FlowPattern &FP);

204

205 const HexagonInstrInfo *HII = nullptr;

206 const TargetRegisterInfo *TRI = nullptr;

207 MachineFunction *MFN = nullptr;

208 MachineRegisterInfo *MRI = nullptr;

209 MachineDominatorTree *MDT = nullptr;

210 MachineLoopInfo *MLI = nullptr;

211 BlockSetType Deleted;

212 const MachineBranchProbabilityInfo *MBPI = nullptr;

213 };

214

215}

216

217char HexagonEarlyIfConversion::ID = 0;

218

220 "Hexagon early if conversion", false, false)

221

223 if (B->succ_size() != 1)

224 return false;

227 return L && SB == L->getHeader() && MDT->dominates(B, SB);

228}

229

233 << "\n");

234

235

236

237

238 MachineBasicBlock *TB = nullptr, *FB = nullptr;

240 if (T1I == B->end())

241 return false;

242 unsigned Opc = T1I->getOpcode();

243 if (Opc != Hexagon::J2_jumpt && Opc != Hexagon::J2_jumpf)

244 return false;

245 Register PredR = T1I->getOperand(0).getReg();

246

247

249 MachineBasicBlock *NextB = (NextBI != MFN->end()) ? &*NextBI : nullptr;

250

251 MachineBasicBlock *T1B = T1I->getOperand(1).getMBB();

253

254 assert(T2I == B->end() || T2I->getOpcode() == Hexagon::J2_jump);

255 MachineBasicBlock *T2B = (T2I == B->end()) ? NextB

256 : T2I->getOperand(0).getMBB();

257 if (T1B == T2B) {

258

259

260 return false;

261 }

262

263

264

265 if (Opc == Hexagon::J2_jumpt)

266 TB = T1B, FB = T2B;

267 else

268 TB = T2B, FB = T1B;

269

271 return false;

272

273

274

275

276

277 assert(TB && FB && "Failed to find triangle control flow blocks");

278 unsigned TNP = TB->pred_size(), FNP = FB->pred_size();

279 unsigned TNS = TB->succ_size(), FNS = FB->succ_size();

280

281

282

283

284

285

286 bool TOk = (TNP == 1 && TNS == 1 && MLI->getLoopFor(TB) == L);

287 bool FOk = (FNP == 1 && FNS == 1 && MLI->getLoopFor(FB) == L);

288

289

290

292 return false;

293

294

295 if (!TOk && !FOk)

296 return false;

297

298 MachineBasicBlock *TSB = (TNS > 0) ? *TB->succ_begin() : nullptr;

299 MachineBasicBlock *FSB = (FNS > 0) ? *FB->succ_begin() : nullptr;

300 MachineBasicBlock *JB = nullptr;

301

302 if (TOk) {

303 if (FOk) {

304 if (TSB == FSB)

305 JB = TSB;

306

307 } else {

308

309 if (TSB == FB)

310 JB = FB;

311 FB = nullptr;

312 }

313 } else {

314

315 if (FSB == TB)

316 JB = TB;

317 TB = nullptr;

318 }

319

320 if ((TB && isPreheader(TB)) || (FB && isPreheader(FB))) {

321 LLVM_DEBUG(dbgs() << "One of blocks " << PrintMB(TB) << ", " << PrintMB(FB)

322 << " is a loop preheader. Skipping.\n");

323 return false;

324 }

325

326 FP = FlowPattern(B, PredR, TB, FB, JB);

328 return true;

329}

330

331

332

333bool HexagonEarlyIfConversion::hasEHLabel(const MachineBasicBlock *B) const {

334 for (auto &I : *B)

335 if (I.isEHLabel())

336 return true;

337 return false;

338}

339

340

341

342bool HexagonEarlyIfConversion::hasUncondBranch(const MachineBasicBlock *B)

343 const {

345 while (I != E) {

346 if (I->isBarrier())

347 return true;

348 ++I;

349 }

350 return false;

351}

352

353bool HexagonEarlyIfConversion::isValidCandidate(const MachineBasicBlock *B)

354 const {

355 if (B)

356 return true;

357 if (B->isEHPad() || B->hasAddressTaken())

358 return false;

359 if (B->succ_empty())

360 return false;

361

362 for (auto &MI : *B) {

363 if (MI.isDebugInstr())

364 continue;

365 if (MI.isConditionalBranch())

366 return false;

367 unsigned Opc = MI.getOpcode();

368 bool IsJMP = (Opc == Hexagon::J2_jump);

369 if (!isPredicableStore(&MI) && !IsJMP && !isSafeToSpeculate(&MI))

370 return false;

371

372

373

374

375

376

377 for (const MachineOperand &MO : MI.operands()) {

378 if (!MO.isReg() || !MO.isDef())

379 continue;

381 if (R.isVirtual())

382 continue;

383 if (!isPredicate(R))

384 continue;

385 for (const MachineOperand &U : MRI->use_operands(R))

386 if (U.getParent()->isPHI())

387 return false;

388 }

389 }

390 return true;

391}

392

393bool HexagonEarlyIfConversion::usesUndefVReg(const MachineInstr *MI) const {

394 for (const MachineOperand &MO : MI->operands()) {

395 if (!MO.isReg() || !MO.isUse())

396 continue;

398 if (R.isVirtual())

399 continue;

400 const MachineInstr *DefI = MRI->getVRegDef(R);

401

402 assert(DefI && "Expecting a reaching def in MRI");

404 return true;

405 }

406 return false;

407}

408

409bool HexagonEarlyIfConversion::isValid(const FlowPattern &FP) const {

410 if (hasEHLabel(FP.SplitB))

411 return false;

412 if (FP.TrueB && !isValidCandidate(FP.TrueB))

413 return false;

414 if (FP.FalseB && !isValidCandidate(FP.FalseB))

415 return false;

416

417

418

419

420

421

422

423

424

425

426 if (FP.JoinB) {

427 const MachineBasicBlock &B = *FP.JoinB;

428 for (auto &MI : B) {

429 if (MI.isPHI())

430 break;

431 if (usesUndefVReg(&MI))

432 return false;

433 Register DefR = MI.getOperand(0).getReg();

434 if (isPredicate(DefR))

435 return false;

436 }

437 }

438 return true;

439}

440

441unsigned HexagonEarlyIfConversion::computePhiCost(const MachineBasicBlock *B,

442 const FlowPattern &FP) const {

443 if (B->pred_size() < 2)

444 return 0;

445

446 unsigned Cost = 0;

447 for (const MachineInstr &MI : *B) {

448 if (MI.isPHI())

449 break;

450

451

452

453

454 SmallVector<unsigned,2> Inc;

455 for (unsigned i = 1, e = MI.getNumOperands(); i != e; i += 2) {

456 const MachineBasicBlock *BB = MI.getOperand(i+1).getMBB();

457 if (BB == FP.SplitB || BB == FP.TrueB || BB == FP.FalseB)

459 }

461 if (Inc.size() < 2)

462 continue;

463

464 const MachineOperand &RA = MI.getOperand(1);

465 const MachineOperand &RB = MI.getOperand(3);

467

468 if (RA.getSubReg() != 0 || RB.getSubReg() != 0) {

470 continue;

471 }

472 const MachineInstr *Def1 = MRI->getVRegDef(RA.getReg());

473 const MachineInstr *Def3 = MRI->getVRegDef(RB.getReg());

476 }

478}

479

480unsigned HexagonEarlyIfConversion::countPredicateDefs(

481 const MachineBasicBlock *B) const {

482 unsigned PredDefs = 0;

483 for (auto &MI : *B) {

484 for (const MachineOperand &MO : MI.operands()) {

485 if (!MO.isReg() || !MO.isDef())

486 continue;

488 if (R.isVirtual())

489 continue;

490 if (isPredicate(R))

491 PredDefs++;

492 }

493 }

494 return PredDefs;

495}

496

497bool HexagonEarlyIfConversion::isProfitable(const FlowPattern &FP) const {

498 BranchProbability JumpProb(1, 10);

499 BranchProbability Prob(9, 10);

500 if (MBPI && FP.TrueB && FP.FalseB &&

503 return false;

504

505 if (MBPI && FP.TrueB && FP.FalseB &&

508 return false;

509

510 if (FP.TrueB && FP.FalseB) {

511

512 if (MBPI) {

514 return false;

516 return false;

517 }

518

519

520

521 MachineBasicBlock *TSB = *FP.TrueB->succ_begin();

522 MachineBasicBlock *FSB = *FP.FalseB->succ_begin();

523 if (TSB != FSB)

524 return false;

526 return false;

527 }

528

529

530

531

532

533

534 auto TotalCount = [] (const MachineBasicBlock *B, unsigned &Spare) {

535 if (B)

536 return 0u;

537 unsigned T = std::count_if(B->begin(), B->getFirstTerminator(),

538 [](const MachineInstr &MI) {

539 return !MI.isMetaInstruction();

540 });

543 return T;

544 };

545 unsigned Spare = 0;

546 unsigned TotalIn = TotalCount(FP.TrueB, Spare) + TotalCount(FP.FalseB, Spare);

548 dbgs() << "Total number of instructions to be predicated/speculated: "

549 << TotalIn << ", spare room: " << Spare << "\n");

551 return false;

552

553

554

555

556

557

558

559 unsigned TotalPh = 0;

560 unsigned PredDefs = countPredicateDefs(FP.SplitB);

561 if (FP.JoinB) {

562 TotalPh = computePhiCost(FP.JoinB, FP);

563 PredDefs += countPredicateDefs(FP.JoinB);

564 } else {

565 if (FP.TrueB && FP.TrueB->succ_empty()) {

566 MachineBasicBlock *SB = *FP.TrueB->succ_begin();

567 TotalPh += computePhiCost(SB, FP);

568 PredDefs += countPredicateDefs(SB);

569 }

570 if (FP.FalseB && FP.FalseB->succ_empty()) {

571 MachineBasicBlock *SB = *FP.FalseB->succ_begin();

572 TotalPh += computePhiCost(SB, FP);

573 PredDefs += countPredicateDefs(SB);

574 }

575 }

576 LLVM_DEBUG(dbgs() << "Total number of extra muxes from converted phis: "

577 << TotalPh << "\n");

578 if (TotalIn+TotalPh >= SizeLimit+Spare)

579 return false;

580

581 LLVM_DEBUG(dbgs() << "Total number of predicate registers: " << PredDefs

582 << "\n");

583 if (PredDefs > 4)

584 return false;

585

586 return true;

587}

588

589bool HexagonEarlyIfConversion::visitBlock(MachineBasicBlock *B,

590 MachineLoop *L) {

592

593

595

596

597

598

599

600

601

602

605 for (auto &I : Cn) {

606 MachineBasicBlock *SB = I->getBlock();

608 Changed |= visitBlock(SB, L);

609 }

610

611

612

615

616 FlowPattern FP;

617 if (!matchFlowPattern(B, L, FP))

619

623 }

625 LLVM_DEBUG(dbgs() << "Conversion is not profitable\n");

627 }

628

629 convert(FP);

630 simplifyFlowGraph(FP);

631 return true;

632}

633

634bool HexagonEarlyIfConversion::visitLoop(MachineLoop *L) {

635 MachineBasicBlock *HB = L ? L->getHeader() : nullptr;

636 LLVM_DEBUG((L ? dbgs() << "Visiting loop H:" << PrintMB(HB)

637 : dbgs() << "Visiting function")

638 << "\n");

640 if (L) {

641 for (MachineLoop *I : *L)

643 }

644

646 Changed |= visitBlock(L ? HB : EntryB, L);

648}

649

650bool HexagonEarlyIfConversion::isPredicableStore(const MachineInstr *MI)

651 const {

652

653

654

655 unsigned Opc = MI->getOpcode();

656 switch (Opc) {

657 case Hexagon::S2_storerb_io:

658 case Hexagon::S2_storerbnew_io:

659 case Hexagon::S2_storerh_io:

660 case Hexagon::S2_storerhnew_io:

661 case Hexagon::S2_storeri_io:

662 case Hexagon::S2_storerinew_io:

663 case Hexagon::S2_storerd_io:

664 case Hexagon::S4_storeirb_io:

665 case Hexagon::S4_storeirh_io:

666 case Hexagon::S4_storeiri_io:

667 return true;

668 }

669

670

671 return MI->mayStore() && HII->isPredicable(const_cast<MachineInstr&>(*MI));

672}

673

674bool HexagonEarlyIfConversion::isSafeToSpeculate(const MachineInstr *MI)

675 const {

676 if (MI->mayLoadOrStore())

677 return false;

678 if (MI->isCall() || MI->isBarrier() || MI->isBranch())

679 return false;

680 if (MI->hasUnmodeledSideEffects())

681 return false;

682 if (MI->getOpcode() == TargetOpcode::LIFETIME_END)

683 return false;

684

685 return true;

686}

687

688bool HexagonEarlyIfConversion::isPredicate(unsigned R) const {

689 const TargetRegisterClass *RC = MRI->getRegClass(R);

690 return RC == &Hexagon::PredRegsRegClass ||

691 RC == &Hexagon::HvxQRRegClass;

692}

693

694unsigned HexagonEarlyIfConversion::getCondStoreOpcode(unsigned Opc,

695 bool IfTrue) const {

697}

698

699void HexagonEarlyIfConversion::predicateInstr(MachineBasicBlock *ToB,

701 unsigned PredR, bool IfTrue) {

703 if (At != ToB->end())

704 DL = At->getDebugLoc();

705 else if (!ToB->empty())

707

708 unsigned Opc = MI->getOpcode();

709

710 if (isPredicableStore(MI)) {

711 unsigned COpc = getCondStoreOpcode(Opc, IfTrue);

713 MachineInstrBuilder MIB = BuildMI(*ToB, At, DL, HII->get(COpc));

716 MIB.add(*MOI);

717 ++MOI;

718 }

720 for (const MachineOperand &MO : make_range(MOI, MI->operands_end()))

721 MIB.add(MO);

722

723

725

726 MI->eraseFromParent();

727 return;

728 }

729

730 if (Opc == Hexagon::J2_jump) {

731 MachineBasicBlock *TB = MI->getOperand(0).getMBB();

732 const MCInstrDesc &D = HII->get(IfTrue ? Hexagon::J2_jumpt

733 : Hexagon::J2_jumpf);

737 MI->eraseFromParent();

738 return;

739 }

740

741

742

745}

746

747

748

749

750void HexagonEarlyIfConversion::predicateBlockNB(MachineBasicBlock *ToB,

752 unsigned PredR, bool IfTrue) {

753 LLVM_DEBUG(dbgs() << "Predicating block " << PrintMB(FromB) << "\n");

756

757 for (I = FromB->begin(); I != End; I = NextI) {

759 NextI = std::next(I);

760 if (isSafeToSpeculate(&*I))

761 ToB->splice(At, FromB, I);

762 else

763 predicateInstr(ToB, At, &*I, PredR, IfTrue);

764 }

765}

766

767unsigned HexagonEarlyIfConversion::buildMux(MachineBasicBlock *B,

769 unsigned PredR, unsigned TR, unsigned TSR, unsigned FR, unsigned FSR) {

770 unsigned Opc = 0;

771 switch (DRC->getID()) {

772 case Hexagon::IntRegsRegClassID:

773 case Hexagon::IntRegsLow8RegClassID:

774 Opc = Hexagon::C2_mux;

775 break;

776 case Hexagon::DoubleRegsRegClassID:

777 case Hexagon::GeneralDoubleLow8RegsRegClassID:

778 Opc = Hexagon::PS_pselect;

779 break;

780 case Hexagon::HvxVRRegClassID:

781 Opc = Hexagon::PS_vselect;

782 break;

783 case Hexagon::HvxWRRegClassID:

784 Opc = Hexagon::PS_wselect;

785 break;

786 default:

788 }

789 const MCInstrDesc &D = HII->get(Opc);

790

792 Register MuxR = MRI->createVirtualRegister(DRC);

797 return MuxR;

798}

799

800void HexagonEarlyIfConversion::updatePhiNodes(MachineBasicBlock *WhereB,

801 const FlowPattern &FP) {

802

803

805 for (auto I = WhereB->begin(); I != NonPHI; ++I) {

806 MachineInstr *PN = &*I;

807

808 unsigned TR = 0, TSR = 0, FR = 0, FSR = 0, SR = 0, SSR = 0;

809 for (int i = PN->getNumOperands()-2; i > 0; i -= 2) {

811 if (BO.getMBB() == FP.SplitB)

813 else if (BO.getMBB() == FP.TrueB)

815 else if (BO.getMBB() == FP.FalseB)

817 else

818 continue;

821 }

822 if (TR == 0)

823 TR = SR, TSR = SSR;

824 else if (FR == 0)

825 FR = SR, FSR = SSR;

826

828 unsigned MuxR = 0, MuxSR = 0;

829

830 if (TR && FR) {

832 const TargetRegisterClass *RC = MRI->getRegClass(DR);

833 MuxR = buildMux(FP.SplitB, FP.SplitB->getFirstTerminator(), RC,

834 FP.PredR, TR, TSR, FR, FSR);

835 } else if (TR) {

836 MuxR = TR;

837 MuxSR = TSR;

838 } else {

839 MuxR = FR;

840 MuxSR = FSR;

841 }

842

844 false, false, MuxSR));

846 }

847}

848

849void HexagonEarlyIfConversion::convert(const FlowPattern &FP) {

850 MachineBasicBlock *TSB = nullptr, *FSB = nullptr;

852 assert(OldTI != FP.SplitB->end());

854

855 if (FP.TrueB) {

857 predicateBlockNB(FP.SplitB, OldTI, FP.TrueB, FP.PredR, true);

858 }

859 if (FP.FalseB) {

862 predicateBlockNB(FP.SplitB, At, FP.FalseB, FP.PredR, false);

863 }

864

865

866

867

868 MachineBasicBlock *SSB = nullptr;

869 FP.SplitB->erase(OldTI, FP.SplitB->end());

870 while (FP.SplitB->succ_empty()) {

871 MachineBasicBlock *T = *FP.SplitB->succ_begin();

872

873

874

875

876

877

878

879

880

881

882

883

884

885

886 if (T != FP.TrueB && T != FP.FalseB) {

888 SSB = T;

889 }

890 FP.SplitB->removeSuccessor(FP.SplitB->succ_begin());

891 }

892

893

894

895

896

897 if (FP.JoinB) {

898 assert(!SSB || SSB == FP.JoinB);

899 BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jump))

901 FP.SplitB->addSuccessor(FP.JoinB);

902 } else {

903 bool HasBranch = false;

904 if (TSB) {

905 BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jumpt))

908 FP.SplitB->addSuccessor(TSB);

909 HasBranch = true;

910 }

911 if (FSB) {

912 const MCInstrDesc &D = HasBranch ? HII->get(Hexagon::J2_jump)

913 : HII->get(Hexagon::J2_jumpf);

914 MachineInstrBuilder MIB = BuildMI(*FP.SplitB, FP.SplitB->end(), DL, D);

915 if (!HasBranch)

918 FP.SplitB->addSuccessor(FSB);

919 }

920 if (SSB) {

921

922

923

924

925 BuildMI(*FP.SplitB, FP.SplitB->end(), DL, HII->get(Hexagon::J2_jump))

927 FP.SplitB->addSuccessor(SSB);

928 }

929 }

930

931

932

933 if (FP.JoinB) {

935 } else {

936 if (TSB)

938 if (FSB)

940

941 }

942}

943

944void HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) {

945 LLVM_DEBUG(dbgs() << "Removing block " << PrintMB(B) << "\n");

946

947

950 if (IDN) {

951 MachineBasicBlock *IDB = IDN->getBlock();

952

953 using GTN = GraphTraits<MachineDomTreeNode *>;

955

956 DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N));

957 for (auto &I : Cn) {

958 MachineBasicBlock *SB = I->getBlock();

960 }

961 }

962

963 while (B->succ_empty())

964 B->removeSuccessor(B->succ_begin());

965

966 for (MachineBasicBlock *Pred : B->predecessors())

967 Pred->removeSuccessor(B, true);

968

971 MFN->erase(B->getIterator());

972}

973

974void HexagonEarlyIfConversion::eliminatePhis(MachineBasicBlock *B) {

975 LLVM_DEBUG(dbgs() << "Removing phi nodes from block " << PrintMB(B) << "\n");

977 for (I = B->begin(); I != NonPHI; I = NextI) {

978 NextI = std::next(I);

979 MachineInstr *PN = &*I;

981 MachineOperand &UO = PN->getOperand(1);

984 unsigned NewR = UseR;

985 if (UseSR) {

986

987

988

990 const TargetRegisterClass *RC = MRI->getRegClass(DefR);

991 NewR = MRI->createVirtualRegister(RC);

992 NonPHI = BuildMI(*B, NonPHI, DL, HII->get(TargetOpcode::COPY), NewR)

993 .addReg(UseR, 0, UseSR);

994 }

995 MRI->replaceRegWith(DefR, NewR);

996 B->erase(I);

997 }

998}

999

1000void HexagonEarlyIfConversion::mergeBlocks(MachineBasicBlock *PredB,

1001 MachineBasicBlock *SuccB) {

1002 LLVM_DEBUG(dbgs() << "Merging blocks " << PrintMB(PredB) << " and "

1003 << PrintMB(SuccB) << "\n");

1004 bool TermOk = hasUncondBranch(SuccB);

1005 eliminatePhis(SuccB);

1008 PredB->splice(PredB->end(), SuccB, SuccB->begin(), SuccB->end());

1010 MachineBasicBlock *OldLayoutSuccessor = SuccB->getNextNode();

1011 removeBlock(SuccB);

1012 if (!TermOk)

1014}

1015

1016void HexagonEarlyIfConversion::simplifyFlowGraph(const FlowPattern &FP) {

1017 MachineBasicBlock *OldLayoutSuccessor = FP.SplitB->getNextNode();

1018 if (FP.TrueB)

1019 removeBlock(FP.TrueB);

1020 if (FP.FalseB)

1021 removeBlock(FP.FalseB);

1022

1023 FP.SplitB->updateTerminator(OldLayoutSuccessor);

1024 if (FP.SplitB->succ_size() != 1)

1025 return;

1026

1027 MachineBasicBlock *SB = *FP.SplitB->succ_begin();

1029 return;

1030

1031

1032

1033

1034

1035

1036 if (!hasEHLabel(SB) || hasUncondBranch(SB))

1038}

1039

1040bool HexagonEarlyIfConversion::runOnMachineFunction(MachineFunction &MF) {

1042 return false;

1043

1045 HII = ST.getInstrInfo();

1046 TRI = ST.getRegisterInfo();

1047 MFN = &MF;

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

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

1052 ? &getAnalysis().getMBPI()

1053 : nullptr;

1054

1057

1058 for (MachineLoop *L : *MLI)

1059 Changed |= visitLoop(L);

1060 Changed |= visitLoop(nullptr);

1061

1063}

1064

1065

1066

1067

1069 return new HexagonEarlyIfConversion();

1070}

unsigned const MachineRegisterInfo * MRI

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")

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

static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")

This file defines the DenseSet and SmallDenseSet classes.

static cl::opt< bool > EnableHexagonBP("enable-hexagon-br-prob", cl::Hidden, cl::init(true), cl::desc("Enable branch probability info"))

static cl::opt< bool > SkipExitBranches("eif-no-loop-exit", cl::init(false), cl::Hidden, cl::desc("Do not convert branches that may exit the loop"))

static cl::opt< unsigned > SizeLimit("eif-limit", cl::init(6), cl::Hidden, cl::desc("Size limit in Hexagon early if-conversion"))

#define HEXAGON_PACKET_SIZE

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static std::vector< BCECmpChain::ContiguousBlocks > mergeBlocks(std::vector< BCECmpBlock > &&Blocks)

Given a chain of comparison blocks, groups the blocks into contiguous ranges that can be merged toget...

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

static bool isValid(const char C)

Returns true if C is a valid mangled character: <0-9a-zA-Z_>.

SI optimize exec mask operations pre RA

This file defines the SmallVector class.

static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS)

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

Add the specified Pass class to the set of analyses preserved by this pass.

DomTreeNodeBase * getIDom() const

void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)

changeImmediateDominator - This method is used to update the dominator tree information when a node's...

void eraseNode(NodeT *BB)

eraseNode - Removes a node from the dominator tree.

DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const

getNode - return the (Post)DominatorTree node for the specified basic block.

bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const

properlyDominates - Returns true iff A dominates B and A != B.

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

unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override

Remove the branching code at the end of the specific MBB.

int getCondOpcode(int Opc, bool sense) const

bool isPostIncrement(const MachineInstr &MI) const override

Return true for post-incremented instructions.

bool isPredicable(const MachineInstr &MI) const override

Return true if the specified instruction can be predicated.

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

unsigned pred_size() const

LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)

Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...

MachineInstrBundleIterator< const MachineInstr > const_iterator

LLVM_ABI void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor)

Update the terminator instructions in block to account for changes to block layout which may have bee...

succ_iterator succ_begin()

LLVM_ABI iterator getFirstTerminator()

Returns an iterator to the first terminator instruction of this basic block.

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

Remove successor from the successors list of this MachineBasicBlock.

LLVM_ABI iterator getFirstNonPHI()

Returns a pointer to the first instruction in this block that is not a PHINode instruction.

LLVM_ABI DebugLoc findBranchDebugLoc()

Find and return the merged DebugLoc of the branch instructions of the block.

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

BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const

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.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

BasicBlockListType::iterator iterator

void erase(iterator MBBI)

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const

Add a new virtual register operand.

const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const

const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const

bool isImplicitDef() const

unsigned getNumOperands() const

Retuns the total number of operands.

LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

MachineOperand * mop_iterator

iterator/begin/end - Iterate over all operands of a machine instruction.

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

LLVM_ABI void removeOperand(unsigned OpNo)

Erase an operand from an instruction, leaving it with one fewer operand than it started with.

const MachineOperand & getOperand(unsigned i) const

unsigned getSubReg() const

bool isReg() const

isReg - Tests if this is a MO_Register operand.

Register getReg() const

getReg - Returns the register number.

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

static MachineOperand CreateMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0)

void push_back(const T &Elt)

unsigned getID() const

Return the register class ID number.

NodeTy * getNextNode()

Get the next node, or nullptr for the list tail.

This class implements an extremely fast bulk output stream that can only output to a stream.

This provides a very simple, boring adaptor for a begin and end iterator into a range type.

#define llvm_unreachable(msg)

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

@ TB

TB - TwoByte - Set if this instruction has a two byte opcode, which starts with a 0x0F byte before th...

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)

Builder interface. Specify how to create the initial instruction itself.

iterator_range< T > make_range(T x, T y)

Convenience function for iterating over sub-ranges.

FunctionPass * createHexagonEarlyIfConversion()

Definition HexagonEarlyIfConv.cpp:1068

LLVM_ABI raw_ostream & dbgs()

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

class LLVM_GSL_OWNER SmallVector

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

DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode

raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)

LLVM_ABI void updatePhiNodes(BasicBlock *DestBB, BasicBlock *OldPred, BasicBlock *NewPred, PHINode *Until=nullptr)

Replaces all uses of OldPred with the NewPred block in all PHINodes in a block.

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

LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)

Prints virtual and physical registers with or without a TRI instance.

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

static NodeRef getEntryNode(MachineFunction *F)