LLVM: lib/Target/Mips/MipsBranchExpansion.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

61

62

63

64

65

66

67

68

69

70

71

72

73

74

98#include

99#include

100#include

101#include

102#include

103

104using namespace llvm;

105

106#define DEBUG_TYPE "mips-branch-expansion"

107

108STATISTIC(NumInsertedNops, "Number of nops inserted");

109STATISTIC(LongBranches, "Number of long branches.");

110

114

117 cl::desc("MIPS: Expand all branches to long format."),

119

120namespace {

121

124

125struct MBBInfo {

127 bool HasLongBranch = false;

130 MBBInfo() = default;

131};

132

134public:

135 static char ID;

136

137 MipsBranchExpansion()

138 : MachineFunctionPass(ID), ABI(MipsABIInfo::Unknown()) {}

139

140 StringRef getPassName() const override {

141 return "Mips Branch Expansion Pass";

142 }

143

144 bool runOnMachineFunction(MachineFunction &F) override;

145

146 MachineFunctionProperties getRequiredProperties() const override {

147 return MachineFunctionProperties().setNoVRegs();

148 }

149

150private:

152 void initMBBInfo();

153 int64_t computeOffset(const MachineInstr *Br);

154 uint64_t computeOffsetFromTheBeginning(int MBB);

155 void replaceBranch(MachineBasicBlock &MBB, Iter Br, const DebugLoc &DL,

156 MachineBasicBlock *MBBOpnd);

157 bool buildProperJumpMI(MachineBasicBlock *MBB,

159 void expandToLongBranch(MBBInfo &Info);

160 template <typename Pred, typename Safe>

161 bool handleSlot(Pred Predicate, Safe SafeInSlot);

162 bool handleForbiddenSlot();

163 bool handleFPUDelaySlot();

164 bool handleLoadDelaySlot();

165 bool handlePossibleLongBranch();

166 bool handleMFLO();

167 template <typename Pred, typename Safe>

168 bool handleMFLOSlot(Pred Predicate, Safe SafeInSlot);

169

170 const MipsSubtarget *STI;

171 const MipsInstrInfo *TII;

172

173 MachineFunction *MFp;

175 bool IsPIC;

176 MipsABIInfo ABI;

177 bool ForceLongBranchFirstPass = false;

178};

179

180}

181

182char MipsBranchExpansion::ID = 0;

183

185 "Expand out of range branch instructions and fix forbidden"

186 " slot hazards",

187 false, false)

188

189

191 return new MipsBranchExpansion();

192}

193

194

195

197 Iter I = Position, E = Position->getParent()->end();

198 I = std::find_if_not(I, E,

199 [](const Iter &Insn) { return Insn->isTransient(); });

200

201 return I;

202}

203

204

205

208 if (Position == Parent->end()) {

209 do {

211 if (Succ != nullptr && Parent->isSuccessor(Succ)) {

212 Position = Succ->begin();

213 Parent = Succ;

214 } else {

215 return std::make_pair(Position, true);

216 }

217 } while (Parent->empty());

218 }

219

221 if (Instr == Parent->end()) {

223 }

224 return std::make_pair(Instr, false);

225}

226

227

228

232

235 }

236

237 llvm_unreachable("This instruction does not have an MBB operand.");

238}

239

240

241

243 for (; B != E; ++B)

244 if (B->isDebugInstr())

245 return B;

246

247 return E;

248}

249

250

252 ReverseIter End = MBB->rend();

254

255

256 if ((LastBr == End) ||

257 (!LastBr->isConditionalBranch() && !LastBr->isUnconditionalBranch()))

258 return;

259

260 ReverseIter FirstBr = getNonDebugInstr(std::next(LastBr), End);

261

262

263

264 if ((FirstBr == End) ||

265 (!FirstBr->isConditionalBranch() && !FirstBr->isUnconditionalBranch()))

266 return;

267

268 assert(!FirstBr->isIndirectBranch() && "Unexpected indirect branch found.");

269

270

271 MachineBasicBlock *NewMBB =

273

274

275 MachineBasicBlock *Tgt = getTargetMBB(*FirstBr);

282

284}

285

286

287void MipsBranchExpansion::initMBBInfo() {

288

289

290 for (auto &MBB : *MFp)

292

293 MFp->RenumberBlocks();

294 MBBInfos.clear();

295 MBBInfos.resize(MFp->size());

296

297 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) {

298 MachineBasicBlock *MBB = MFp->getBlockNumbered(I);

299

300

302 MBBInfos[I].Size += TII->getInstSizeInBytes(MI);

303 }

304}

305

306

307int64_t MipsBranchExpansion::computeOffset(const MachineInstr *Br) {

311

312

313 if (ThisMBB < TargetMBB) {

314 for (int N = ThisMBB + 1; N < TargetMBB; ++N)

316

318 }

319

320

321 for (int N = ThisMBB; N >= TargetMBB; --N)

323

325}

326

327

328uint64_t MipsBranchExpansion::computeOffsetFromTheBeginning(int MBB) {

330 for (int N = 0; N < MBB; ++N)

333}

334

335

336

337void MipsBranchExpansion::replaceBranch(MachineBasicBlock &MBB, Iter Br,

339 MachineBasicBlock *MBBOpnd) {

340 unsigned NewOpc = TII->getOppositeBranchOpc(Br->getOpcode());

341 const MCInstrDesc &NewDesc = TII->get(NewOpc);

342

343 MachineInstrBuilder MIB = BuildMI(MBB, Br, DL, NewDesc);

344

345 for (unsigned I = 0, E = Br->getDesc().getNumOperands(); I < E; ++I) {

346 MachineOperand &MO = Br->getOperand(I);

347

351 break;

353

354

355 if (TII->isBranchWithImm(Br->getOpcode()))

356 llvm_unreachable("Unexpected immediate in branch instruction");

358 break;

361 break;

362 default:

363 llvm_unreachable("Unexpected operand type in branch instruction");

364 }

365 }

366

367 if (Br->hasDelaySlot()) {

368

369

370 assert(Br->isBundledWithSucc());

372 MIBundleBuilder(&*MIB).append((++II)->removeFromBundle());

373 }

374 Br->eraseFromParent();

375}

376

377bool MipsBranchExpansion::buildProperJumpMI(MachineBasicBlock *MBB,

382

383 unsigned JR = ABI.IsN64() ? Mips::JR64 : Mips::JR;

384 unsigned JIC = ABI.IsN64() ? Mips::JIC64 : Mips::JIC;

385 unsigned JR_HB = ABI.IsN64() ? Mips::JR_HB64 : Mips::JR_HB;

386 unsigned JR_HB_R6 = ABI.IsN64() ? Mips::JR_HB64_R6 : Mips::JR_HB_R6;

387

388 unsigned JumpOp;

390 JumpOp = HasR6 ? JR_HB_R6 : JR_HB;

391 else

392 JumpOp = HasR6 ? JIC : JR;

393

395 JumpOp = Mips::JIC_MMR6;

396

397 unsigned ATReg = ABI.IsN64() ? Mips::AT_64 : Mips::AT;

398 MachineInstrBuilder Instr =

400 if (AddImm)

402

403 return !AddImm;

404}

405

406

407

408

409

410

411void MipsBranchExpansion::expandToLongBranch(MBBInfo &I) {

417 MachineBasicBlock *LongBrMBB = MFp->CreateMachineBasicBlock(BB);

418

419 MFp->insert(FallThroughMBB, LongBrMBB);

421

422 if (IsPIC) {

423 MachineBasicBlock *BalTgtMBB = MFp->CreateMachineBasicBlock(BB);

424 MFp->insert(FallThroughMBB, BalTgtMBB);

427

428

429

430

431 const unsigned BalOp =

434 : STI->inMicroMipsMode() ? Mips::BAL_BR_MM : Mips::BAL_BR;

435

436 if (!ABI.IsN64()) {

437

438

439

440

441

442

443

444

445

446

447

448

449

450

451

452

453

454

455

456

457

458

459

460

461

462

463

464

465

466 Pos = LongBrMBB->begin();

467

468 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)

471 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SW))

475

476

477

478

479

480

481

482

483

484

485

486

487

488

489

490

491

492 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi), Mips::AT)

495

496 MachineInstrBuilder BalInstr =

498 MachineInstrBuilder ADDiuInstr =

499 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_ADDiu), Mips::AT)

504 LongBrMBB->insert(Pos, ADDiuInstr);

505 LongBrMBB->insert(Pos, BalInstr);

506 } else {

507 LongBrMBB->insert(Pos, BalInstr);

508 LongBrMBB->insert(Pos, ADDiuInstr);

509 LongBrMBB->rbegin()->bundleWithPred();

510 }

511

512 Pos = BalTgtMBB->begin();

513

514 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDu), Mips::AT)

517 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LW), Mips::RA)

520

521

522 bool hasDelaySlot = buildProperJumpMI(BalTgtMBB, Pos, DL);

523

524 if (!hasDelaySlot) {

525 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::ADDiu), Mips::SP)

528 }

529 if (hasDelaySlot) {

530 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::ADDiu), Mips::SP)

533 BalTgtMBB->rbegin()->bundleWithPred();

534 }

535 } else {

536

537

538

539

540

541

542

543

544

545

546

547

548

549

550

551

552

553

554

555

556

557

558

559

560

561

562

563

564

565

566

567

568

569

570

571

572

573

574

575

576

577

578

579

580

581 Pos = LongBrMBB->begin();

582

583 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)

586 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::SD))

590 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu),

591 Mips::AT_64)

592 .addReg(Mips::ZERO_64)

595 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)

598

599 MachineInstrBuilder BalInstr =

601 MachineInstrBuilder DADDiuInstr =

602 BuildMI(*MFp, DL, TII->get(Mips::LONG_BRANCH_DADDiu), Mips::AT_64)

607 LongBrMBB->insert(Pos, DADDiuInstr);

608 LongBrMBB->insert(Pos, BalInstr);

609 } else {

610 LongBrMBB->insert(Pos, BalInstr);

611 LongBrMBB->insert(Pos, DADDiuInstr);

612 LongBrMBB->rbegin()->bundleWithPred();

613 }

614

615 Pos = BalTgtMBB->begin();

616

617 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDu), Mips::AT_64)

619 .addReg(Mips::AT_64);

620 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::LD), Mips::RA_64)

623

624 bool hasDelaySlot = buildProperJumpMI(BalTgtMBB, Pos, DL);

625

626 if (!hasDelaySlot) {

627 BuildMI(*BalTgtMBB, std::prev(Pos), DL, TII->get(Mips::DADDiu),

628 Mips::SP_64)

631 } else {

632 BuildMI(*BalTgtMBB, Pos, DL, TII->get(Mips::DADDiu), Mips::SP_64)

635 BalTgtMBB->rbegin()->bundleWithPred();

636 }

637 }

638 } else {

639 Pos = LongBrMBB->begin();

641

642

643

644 uint64_t JOffset = computeOffsetFromTheBeginning(MBB->getNumber()) +

646 uint64_t TgtMBBOffset = computeOffsetFromTheBeginning(TgtMBB->getNumber());

647

648

649 if (JOffset < TgtMBBOffset)

650 TgtMBBOffset += 2 * 4;

651

652 bool SameSegmentJump = JOffset >> 28 == TgtMBBOffset >> 28;

653

654 if (STI->hasMips32r6() && TII->isBranchOffsetInRange(Mips::BC, I.Offset)) {

655

656

657

658

659

663 } else if (SameSegmentJump) {

664

665

666

667

668

669

671 TII->insertNop(*LongBrMBB, Pos, DL)->bundleWithPred();

672 } else {

673

674

675

676

677

678 if (ABI.IsN64()) {

679 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op_64),

680 Mips::AT_64)

682 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),

683 Mips::AT_64)

686 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)

689 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),

690 Mips::AT_64)

693 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::DSLL), Mips::AT_64)

696 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_DADDiu2Op),

697 Mips::AT_64)

700 } else {

701 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_LUi2Op),

702 Mips::AT)

704 BuildMI(*LongBrMBB, Pos, DL, TII->get(Mips::LONG_BRANCH_ADDiu2Op),

705 Mips::AT)

708 }

709 buildProperJumpMI(LongBrMBB, Pos, DL);

710 }

711 }

712

713 if (I.Br->isUnconditionalBranch()) {

714

715 assert(I.Br->getDesc().getNumOperands() == 1);

716 I.Br->removeOperand(0);

718 } else

719

720 replaceBranch(*MBB, I.Br, DL, &*FallThroughMBB);

721}

722

732 MBB.removeLiveIn(Mips::V0);

733}

734

735template <typename Pred, typename Safe>

736bool MipsBranchExpansion::handleMFLOSlot(Pred Predicate, Safe SafeInSlot) {

738 bool hasPendingMFLO = false;

739

741 for (Iter I = FI->begin(); I != FI->end(); ++I) {

742

743 if (Predicate(*I) && !hasPendingMFLO) {

744 continue;

745 }

746

747 Iter IInSlot;

748 bool LastInstInFunction =

749 std::next(I) == FI->end() && std::next(FI) == MFp->end();

750

751

752

753

754

755 if (!LastInstInFunction) {

757 LastInstInFunction |= Res.second;

758 IInSlot = Res.first;

759 if (LastInstInFunction)

760 continue;

761 if (!SafeInSlot(*IInSlot, *I)) {

763 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())

764 ->bundleWithPred();

765 NumInsertedNops++;

767 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())

768 ->bundleWithPred();

769 NumInsertedNops++;

770 }

771 if (hasPendingMFLO)

772 hasPendingMFLO = false;

773 } else if (hasPendingMFLO)

774 hasPendingMFLO = false;

776 hasPendingMFLO = true;

777 }

778 }

779 }

780

782}

783

784template <typename Pred, typename Safe>

785bool MipsBranchExpansion::handleSlot(Pred Predicate, Safe SafeInSlot) {

787

789 for (Iter I = FI->begin(); I != FI->end(); ++I) {

790

791

793 continue;

794

795 Iter IInSlot;

796 bool LastInstInFunction =

797 std::next(I) == FI->end() && std::next(FI) == MFp->end();

798 if (!LastInstInFunction) {

800 LastInstInFunction |= Res.second;

801 IInSlot = Res.first;

802 }

803

804 if (LastInstInFunction || !SafeInSlot(*IInSlot, *I)) {

806 if (std::next(Iit) == FI->end() ||

807 std::next(Iit)->getOpcode() != Mips::NOP) {

809 TII->insertNop(*(I->getParent()), std::next(I), I->getDebugLoc())

810 ->bundleWithPred();

811 NumInsertedNops++;

812 }

813 }

814 }

815 }

816

818}

819

820bool MipsBranchExpansion::handleMFLO() {

821

822

824 return false;

825

826 return handleMFLOSlot(

827 [this](auto &I) -> bool { return TII->IsMfloOrMfhi(I); },

828 [this](auto &IInSlot, auto &I) -> bool {

829 return TII->SafeAfterMflo(IInSlot);

830 });

831}

832

833bool MipsBranchExpansion::handleForbiddenSlot() {

834

836 return false;

837

838 return handleSlot(

839 [this](auto &I) -> bool { return TII->HasForbiddenSlot(I); },

840 [this](auto &IInSlot, auto &I) -> bool {

841 return TII->SafeInForbiddenSlot(IInSlot);

842 });

843}

844

845bool MipsBranchExpansion::handleFPUDelaySlot() {

846

848 return false;

849

850 return handleSlot([this](auto &I) -> bool { return TII->HasFPUDelaySlot(I); },

851 [this](auto &IInSlot, auto &I) -> bool {

852 return TII->SafeInFPUDelaySlot(IInSlot, I);

853 });

854}

855

856bool MipsBranchExpansion::handleLoadDelaySlot() {

857

859 return false;

860

861 return handleSlot(

862 [this](auto &I) -> bool { return TII->HasLoadDelaySlot(I); },

863 [this](auto &IInSlot, auto &I) -> bool {

864 return TII->SafeInLoadDelaySlot(IInSlot, I);

865 });

866}

867

868bool MipsBranchExpansion::handlePossibleLongBranch() {

870 return false;

871

873 return false;

874

875 bool EverMadeChange = false, MadeChange = true;

876

877 while (MadeChange) {

878 MadeChange = false;

879

880 initMBBInfo();

881

882 for (unsigned I = 0, E = MBBInfos.size(); I < E; ++I) {

883 MachineBasicBlock *MBB = MFp->getBlockNumbered(I);

884

885 ReverseIter End = MBB->rend();

887

888 if ((Br != End) && Br->isBranch() && !Br->isIndirectBranch() &&

889 (Br->isConditionalBranch() ||

890 (Br->isUnconditionalBranch() && IsPIC))) {

891 int64_t Offset = computeOffset(&*Br);

892

893 if (ForceLongBranchFirstPass ||

894 TII->isBranchOffsetInRange(Br->getOpcode(), Offset)) {

895 MBBInfos[I].Offset = Offset;

896 MBBInfos[I].Br = &*Br;

897 }

898 }

899 }

900

901 ForceLongBranchFirstPass = false;

902

904

905 for (I = MBBInfos.begin(); I != E; ++I) {

906

907

908 if (I->Br)

909 continue;

910

911 expandToLongBranch(*I);

912 ++LongBranches;

913 EverMadeChange = MadeChange = true;

914 }

915

916 MFp->RenumberBlocks();

917 }

918

919 return EverMadeChange;

920}

921

922bool MipsBranchExpansion::runOnMachineFunction(MachineFunction &MF) {

923 const TargetMachine &TM = MF.getTarget();

925 ABI = static_cast<const MipsTargetMachine &>(TM).getABI();

928

929 if (IsPIC && ABI.IsO32() &&

930 MF.getInfo()->globalBaseRegSet())

932

933 MFp = &MF;

934

936

937 bool longBranchChanged = handlePossibleLongBranch();

938 bool forbiddenSlotChanged = handleForbiddenSlot();

939 bool fpuDelaySlotChanged = handleFPUDelaySlot();

940 bool loadDelaySlotChanged = handleLoadDelaySlot();

941 bool MfloChanged = handleMFLO();

942

943 bool Changed = longBranchChanged || forbiddenSlotChanged ||

944 fpuDelaySlotChanged || loadDelaySlotChanged || MfloChanged;

945

946

947 while (forbiddenSlotChanged) {

948 longBranchChanged = handlePossibleLongBranch();

949 fpuDelaySlotChanged = handleFPUDelaySlot();

950 loadDelaySlotChanged = handleLoadDelaySlot();

951 MfloChanged = handleMFLO();

952 if (!longBranchChanged && !fpuDelaySlotChanged && !loadDelaySlotChanged &&

953 !MfloChanged)

954 break;

955 forbiddenSlotChanged = handleForbiddenSlot();

956 }

957

959}

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

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

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

Analysis containing CSE Info

const HexagonInstrInfo * TII

static std::pair< Iter, bool > getNextMachineInstr(Iter Position, MachineBasicBlock *Parent)

Definition MipsBranchExpansion.cpp:206

static cl::opt< bool > ForceLongBranch("force-mips-long-branch", cl::init(false), cl::desc("MIPS: Expand all branches to long format."), cl::Hidden)

static cl::opt< bool > SkipLongBranch("skip-mips-long-branch", cl::init(false), cl::desc("MIPS: Skip branch expansion pass."), cl::Hidden)

static MachineBasicBlock * getTargetMBB(const MachineInstr &Br)

Iterate over list of Br's operands and search for a MachineBasicBlock operand.

Definition MipsBranchExpansion.cpp:229

static void emitGPDisp(MachineFunction &F, const MipsInstrInfo *TII)

Definition MipsBranchExpansion.cpp:723

static ReverseIter getNonDebugInstr(ReverseIter B, const ReverseIter &E)

Definition MipsBranchExpansion.cpp:242

static Iter getNextMachineInstrInBB(Iter Position)

Definition MipsBranchExpansion.cpp:196

#define IsMFLOMFHI(instr)

uint64_t IntrinsicInst * II

static bool splitMBB(BlockSplitInfo &BSI)

Splits a MachineBasicBlock to branch before SplitBefore.

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

This file defines the SmallVector class.

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

#define STATISTIC(VARNAME, DESC)

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

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

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

Replace successor OLD with NEW and update probability info.

LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)

Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...

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...

const BasicBlock * getBasicBlock() const

Return the LLVM basic block that this instance corresponded to originally.

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

Add Succ as a successor of this MachineBasicBlock.

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

Remove successor from the successors list of this MachineBasicBlock.

Instructions::iterator instr_iterator

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

reverse_iterator rbegin()

LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const

Return true if the specified MBB is a successor of this 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

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

const TargetSubtargetInfo & getSubtarget() const

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

BasicBlockListType::iterator iterator

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

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

CreateMachineInstr - Allocate a new MachineInstr.

void insert(iterator MBBI, MachineBasicBlock *MBB)

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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

Representation of each machine instruction.

const MachineBasicBlock * getParent() const

const MCInstrDesc & getDesc() const

Returns the target instruction descriptor of this MachineInstr.

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

MachineBasicBlock * getMBB() const

MachineOperandType getType() const

getType - Returns the MachineOperandType for this operand.

Register getReg() const

getReg - Returns the register number.

@ MO_Immediate

Immediate operand.

@ MO_MachineBasicBlock

MachineBasicBlock reference.

@ MO_Register

Register operand.

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

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

bool inMicroMipsMode() const

const MipsInstrInfo * getInstrInfo() const override

bool useIndirectJumpsHazard() const

bool inMips16Mode() const

bool enableLongBranchPass() const

typename SuperClass::iterator iterator

bool isPositionIndependent() const

NodeTy * getNextNode()

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

#define llvm_unreachable(msg)

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

@ BasicBlock

Various leaf nodes.

Predicate

Predicate - These are "(BI << 5) | BO" for various predicates.

initializer< Ty > init(const Ty &Val)

NodeAddr< InstrNode * > Instr

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.

class LLVM_GSL_OWNER SmallVector

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

FunctionPass * createMipsBranchExpansion()