LLVM: lib/Target/Mips/MipsDelaySlotFiller.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

43#include

44#include

45#include

46#include

47

48using namespace llvm;

49

50#define DEBUG_TYPE "mips-delay-slot-filler"

51

52STATISTIC(FilledSlots, "Number of delay slots filled");

53STATISTIC(UsefulSlots, "Number of delay slots filled with instructions that"

54 " are not NOP.");

55

57 "disable-mips-delay-filler",

59 cl::desc("Fill all delay slots with NOPs."),

61

63 "disable-mips-df-forward-search",

65 cl::desc("Disallow MIPS delay filler to search forward."),

67

69 "disable-mips-df-succbb-search",

71 cl::desc("Disallow MIPS delay filler to search successor basic blocks."),

73

75 "disable-mips-df-backward-search",

77 cl::desc("Disallow MIPS delay filler to search backward."),

79

89

92 cl::desc("MIPS Specific: Compact branch policy."),

94 "Do not use compact branches if possible."),

96 "Use compact branches where appropriate (default)."),

98 "Always use compact branches if possible.")));

99

100namespace {

101

105

106 class RegDefsUses {

107 public:

109

111

112

114

115

117

118

119

122

123 bool update(const MachineInstr &MI, unsigned Begin, unsigned End);

124

125 private:

127 bool IsDef) const;

128

129

130 bool isRegInSet(const BitVector &RegSet, unsigned Reg) const;

131

134 };

135

136

137 class InspectMemInstr {

138 public:

139 InspectMemInstr(bool ForbidMemInstr_) : ForbidMemInstr(ForbidMemInstr_) {}

140 virtual ~InspectMemInstr() = default;

141

142

144

145 protected:

146

147 bool OrigSeenLoad = false;

148 bool OrigSeenStore = false;

149 bool SeenLoad = false;

150 bool SeenStore = false;

151

152

153

154 bool ForbidMemInstr;

155

156 private:

157 virtual bool hasHazard_(const MachineInstr &MI) = 0;

158 };

159

160

161 class NoMemInstr : public InspectMemInstr {

162 public:

163 NoMemInstr() : InspectMemInstr(true) {}

164

165 private:

166 bool hasHazard_(const MachineInstr &MI) override { return true; }

167 };

168

169

170 class LoadFromStackOrConst : public InspectMemInstr {

171 public:

172 LoadFromStackOrConst() : InspectMemInstr(false) {}

173

174 private:

175 bool hasHazard_(const MachineInstr &MI) override;

176 };

177

178

179

180 class MemDefsUses : public InspectMemInstr {

181 public:

182 explicit MemDefsUses(const MachineFrameInfo *MFI);

183

184 private:

185 using ValueType = PointerUnion<const Value *, const PseudoSourceValue *>;

186

187 bool hasHazard_(const MachineInstr &MI) override;

188

189

190

191

192 bool updateDefsUses(ValueType V, bool MayStore);

193

194

196 SmallVectorImpl &Objects) const;

197

198 const MachineFrameInfo *MFI;

199 SmallPtrSet<ValueType, 4> Uses, Defs;

200

201

202

203 bool SeenNoObjLoad = false;

204 bool SeenNoObjStore = false;

205 };

206

208 public:

209 MipsDelaySlotFiller() : MachineFunctionPass(ID) {}

210

211 StringRef getPassName() const override { return "Mips Delay Slot Filler"; }

212

213 bool runOnMachineFunction(MachineFunction &F) override {

214 TM = &F.getTarget();

216 for (MachineBasicBlock &MBB : F)

217 Changed |= runOnMachineBasicBlock(MBB);

218

219

220

221

223 F.getRegInfo().invalidateLiveness();

224

226 }

227

228 MachineFunctionProperties getRequiredProperties() const override {

229 return MachineFunctionProperties().setNoVRegs();

230 }

231

232 void getAnalysisUsage(AnalysisUsage &AU) const override {

233 AU.addRequired();

235 }

236

237 static char ID;

238

239 private:

240 bool runOnMachineBasicBlock(MachineBasicBlock &MBB);

241

242 Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch,

244

245

246

247

248 bool delayHasHazard(const MachineInstr &Candidate, RegDefsUses &RegDU,

249 InspectMemInstr &IM) const;

250

251

252

253 template

254 bool searchRange(MachineBasicBlock &MBB, IterTy Begin, IterTy End,

255 RegDefsUses &RegDU, InspectMemInstr &IM, Iter Slot,

256 IterTy &Filler) const;

257

258

259

260 bool searchBackward(MachineBasicBlock &MBB, MachineInstr &Slot) const;

261

262

263

264 bool searchForward(MachineBasicBlock &MBB, Iter Slot) const;

265

266

267

268

269 bool searchSuccBBs(MachineBasicBlock &MBB, Iter Slot) const;

270

271

272

273 MachineBasicBlock *selectSuccBB(MachineBasicBlock &B) const;

274

275

276

277 std::pair<MipsInstrInfo::BranchType, MachineInstr *>

278 getBranch(MachineBasicBlock &MBB, const MachineBasicBlock &Dst) const;

279

280

281

282 bool examinePred(MachineBasicBlock &Pred, const MachineBasicBlock &Succ,

283 RegDefsUses &RegDU, bool &HasMultipleSuccs,

284 BB2BrMap &BrMap) const;

285

286 bool terminateSearch(const MachineInstr &Candidate) const;

287

288 const TargetMachine *TM = nullptr;

289 };

290

291}

292

293char MipsDelaySlotFiller::ID = 0;

294

296 return MI->hasDelaySlot() && MI->isBundledWithSucc();

297}

298

300 "Fill delay slot for MIPS", false, false)

301

302

303static void insertDelayFiller(Iter Filler, const BB2BrMap &BrMap) {

305

307 if (I.second) {

309 ++UsefulSlots;

310 } else {

311 I.first->push_back(MF->CloneMachineInstr(&*Filler));

312 }

313 }

314}

315

316

318 for (const MachineOperand &MO : Filler->operands()) {

319 unsigned R;

320

321 if (!MO.isReg() || !MO.isDef() || !(R = MO.getReg()))

322 continue;

323

324#ifndef NDEBUG

327 "Shouldn't move an instruction with unallocatable registers across "

328 "basic block boundaries.");

329#endif

330

331 if (MBB.isLiveIn(R))

332 MBB.addLiveIn(R);

333 }

334}

335

338

340

341 update(MI, 0, MI.getDesc().getNumOperands());

342

343

344

345 if (MI.isCall())

346 Defs.set(Mips::RA);

347

348

349

350 if (MI.isBranch()) {

351 update(MI, MI.getDesc().getNumOperands(), MI.getNumOperands());

352 Defs.reset(Mips::AT);

353 }

354}

355

356void RegDefsUses::setCallerSaved(const MachineInstr &MI) {

358

359

360

361

362 if (MI.definesRegister(Mips::RA, nullptr) ||

363 MI.definesRegister(Mips::RA_64, nullptr)) {

364 Defs.set(Mips::RA);

365 Defs.set(Mips::RA_64);

366 }

367

368

369 BitVector CallerSavedRegs(TRI.getNumRegs(), true);

370

371 CallerSavedRegs.reset(Mips::ZERO);

372 CallerSavedRegs.reset(Mips::ZERO_64);

373

374 for (const MCPhysReg *R = TRI.getCalleeSavedRegs(MI.getParent()->getParent());

375 *R; ++R)

376 for (MCRegAliasIterator AI(*R, &TRI, true); AI.isValid(); ++AI)

377 CallerSavedRegs.reset(*AI);

378

379 Defs |= CallerSavedRegs;

380}

381

382void RegDefsUses::setUnallocatableRegs(const MachineFunction &MF) {

383 BitVector AllocSet = TRI.getAllocatableSet(MF);

384

385 for (unsigned R : AllocSet.set_bits())

386 for (MCRegAliasIterator AI(R, &TRI, false); AI.isValid(); ++AI)

387 AllocSet.set(*AI);

388

389 AllocSet.set(Mips::ZERO);

390 AllocSet.set(Mips::ZERO_64);

391

392 Defs |= AllocSet.flip();

393}

394

395void RegDefsUses::addLiveOut(const MachineBasicBlock &MBB,

396 const MachineBasicBlock &SuccBB) {

397 for (const MachineBasicBlock *S : MBB.successors())

398 if (S != &SuccBB)

399 for (const auto &LI : S->liveins())

400 Uses.set(LI.PhysReg.id());

401}

402

403bool RegDefsUses::update(const MachineInstr &MI, unsigned Begin, unsigned End) {

404 BitVector NewDefs(TRI.getNumRegs()), NewUses(TRI.getNumRegs());

405 bool HasHazard = false;

406

407 for (unsigned I = Begin; I != End; ++I) {

408 const MachineOperand &MO = MI.getOperand(I);

409

411 if (checkRegDefsUses(NewDefs, NewUses, MO.getReg(), MO.isDef())) {

413 << I << ": ";

415 HasHazard = true;

416 }

417 }

418 }

419

420 Defs |= NewDefs;

421 Uses |= NewUses;

422

423 return HasHazard;

424}

425

426bool RegDefsUses::checkRegDefsUses(BitVector &NewDefs, BitVector &NewUses,

427 unsigned Reg, bool IsDef) const {

428 if (IsDef) {

430

431 return (isRegInSet(Defs, Reg) || isRegInSet(Uses, Reg));

432 }

433

435

436 return isRegInSet(Defs, Reg);

437}

438

439bool RegDefsUses::isRegInSet(const BitVector &RegSet, unsigned Reg) const {

440

441 for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI)

442 if (RegSet.test(*AI))

443 return true;

444 return false;

445}

446

447bool InspectMemInstr::hasHazard(const MachineInstr &MI) {

448 if (MI.mayStore() && MI.mayLoad())

449 return false;

450

451 if (ForbidMemInstr)

452 return true;

453

454 OrigSeenLoad = SeenLoad;

455 OrigSeenStore = SeenStore;

456 SeenLoad |= MI.mayLoad();

457 SeenStore |= MI.mayStore();

458

459

460

461 if (MI.hasOrderedMemoryRef() && (OrigSeenLoad || OrigSeenStore)) {

462 ForbidMemInstr = true;

463 return true;

464 }

465

466 return hasHazard_(MI);

467}

468

469bool LoadFromStackOrConst::hasHazard_(const MachineInstr &MI) {

470 if (MI.mayStore())

471 return true;

472

473 if (MI.hasOneMemOperand() || !(*MI.memoperands_begin())->getPseudoValue())

474 return true;

475

476 if (const PseudoSourceValue *PSV =

477 (*MI.memoperands_begin())->getPseudoValue()) {

479 return false;

480 return !PSV->isConstant(nullptr) && !PSV->isStack();

481 }

482

483 return true;

484}

485

486MemDefsUses::MemDefsUses(const MachineFrameInfo *MFI_)

487 : InspectMemInstr(false), MFI(MFI_) {}

488

489bool MemDefsUses::hasHazard_(const MachineInstr &MI) {

490 bool HasHazard = false;

491

492

496 HasHazard |= updateDefsUses(VT, MI.mayStore());

497 return HasHazard;

498 }

499

500

501 HasHazard = MI.mayStore() && (OrigSeenLoad || OrigSeenStore);

502 HasHazard |= MI.mayLoad() || OrigSeenStore;

503

504 SeenNoObjLoad |= MI.mayLoad();

505 SeenNoObjStore |= MI.mayStore();

506

507 return HasHazard;

508}

509

510bool MemDefsUses::updateDefsUses(ValueType V, bool MayStore) {

511 if (MayStore)

512 return !Defs.insert(V).second || Uses.count(V) || SeenNoObjStore ||

513 SeenNoObjLoad;

514

515 Uses.insert(V);

516 return Defs.count(V) || SeenNoObjStore;

517}

518

519bool MemDefsUses::

520getUnderlyingObjects(const MachineInstr &MI,

521 SmallVectorImpl &Objects) const {

522 if (MI.hasOneMemOperand())

523 return false;

524

525 auto & MMO = **MI.memoperands_begin();

526

527 if (const PseudoSourceValue *PSV = MMO.getPseudoValue()) {

528 if (!PSV->isAliased(MFI))

529 return false;

531 return true;

532 }

533

534 if (const Value *V = MMO.getValue()) {

537

538 for (const Value *UValue : Objs) {

540 return false;

541

543 }

544 return true;

545 }

546

547 return false;

548}

549

550

551Iter MipsDelaySlotFiller::replaceWithCompactBranch(MachineBasicBlock &MBB,

552 Iter Branch,

556

557 unsigned NewOpcode = TII->getEquivalentCompactForm(Branch);

558 Branch = TII->genInstrWithNewOpc(NewOpcode, Branch);

559

561

562 if (ToErase->shouldUpdateAdditionalCallInfo())

563 ToErase->getMF()->moveAdditionalCallInfo(ToErase,

565 ToErase->eraseFromParent();

567}

568

569

570

571

572

573

575 switch (Opcode) {

576 case Mips::BGEZAL:

577 return Mips::BGEZALS_MM;

578 case Mips::BLTZAL:

579 return Mips::BLTZALS_MM;

580 case Mips::JAL:

581 case Mips::JAL_MM:

582 return Mips::JALS_MM;

583 case Mips::JALR:

584 return Mips::JALRS_MM;

585 case Mips::JALR16_MM:

586 return Mips::JALRS16_MM;

587 case Mips::TAILCALL_MM:

588 llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!");

589 case Mips::TAILCALLREG:

590 return Mips::JR16_MM;

591 default:

592 llvm_unreachable("Unexpected call instruction for microMIPS.");

593 }

594}

595

596

597

598bool MipsDelaySlotFiller::runOnMachineBasicBlock(MachineBasicBlock &MBB) {

603

606 continue;

607

608

610 (TM->getOptLevel() != CodeGenOptLevel::None) &&

611 !(InMicroMipsMode && STI.hasMips32r6())) {

612

613 bool Filled = false;

614

616 TII->getEquivalentCompactForm(I)) {

617 if (searchBackward(MBB, *I)) {

619 " in backwards search.\n");

620 Filled = true;

621 } else if (I->isTerminator()) {

622 if (searchSuccBBs(MBB, I)) {

623 Filled = true;

625 " in successor BB search.\n");

626 }

627 } else if (searchForward(MBB, I)) {

629 " in forwards search.\n");

630 Filled = true;

631 }

632 }

633

634 if (Filled) {

635

637

639 DSI->isCall()) {

640

641

642

643

644

645

646

647

649 }

650 ++FilledSlots;

652 continue;

653 }

654 }

655

656

657

658

659

660

661

662

663

664

665 if ((InMicroMipsMode ||

667 TII->getEquivalentCompactForm(I)) {

668 I = replaceWithCompactBranch(MBB, I, I->getDebugLoc());

670 continue;

671 }

672

673

675 I->dump());

676 TII->insertNop(MBB, std::next(I), I->getDebugLoc());

677 MIBundleBuilder(MBB, I, std::next(I, 2));

678 ++FilledSlots;

680 }

681

683}

684

685template

686bool MipsDelaySlotFiller::searchRange(MachineBasicBlock &MBB, IterTy Begin,

687 IterTy End, RegDefsUses &RegDU,

688 InspectMemInstr &IM, Iter Slot,

689 IterTy &Filler) const {

690 for (IterTy I = Begin; I != End;) {

691 IterTy CurrI = I;

692 ++I;

694

695

696

697 if (CurrI->isDebugInstr() || CurrI->isJumpTableDebugInfo()) {

699 CurrI->dump());

700 continue;

701 }

702

703 if (CurrI->isBundle()) {

705 CurrI->dump());

706

707 RegDU.update(*CurrI, 0, CurrI->getNumOperands());

708 continue;

709 }

710

711 if (terminateSearch(*CurrI)) {

713 CurrI->dump());

714 break;

715 }

716

717 assert((!CurrI->isCall() && !CurrI->isReturn() && !CurrI->isBranch()) &&

718 "Cannot put calls, returns or branches in delay slot.");

719

720 if (CurrI->isKill()) {

721 CurrI->eraseFromParent();

722 continue;

723 }

724

725 if (delayHasHazard(*CurrI, RegDU, IM))

726 continue;

727

731 unsigned Opcode = (*Slot).getOpcode();

732

733

734 if ((IsMFLOMFHI(CurrI->getOpcode())) &&

736 continue;

737

738

739

740

741

742

744 (Opcode == Mips::JR || Opcode == Mips::PseudoIndirectBranch ||

745 Opcode == Mips::PseudoIndirectBranch_MM ||

746 Opcode == Mips::PseudoReturn || Opcode == Mips::TAILCALL))

747 continue;

748

749

750 if (InMicroMipsMode && (Opcode == Mips::LWP_MM || Opcode == Mips::SWP_MM ||

751 Opcode == Mips::MOVEP_MM))

752 continue;

753

754 Filler = CurrI;

756 CurrI->dump());

757

758 return true;

759 }

760

761 return false;

762}

763

764bool MipsDelaySlotFiller::searchBackward(MachineBasicBlock &MBB,

765 MachineInstr &Slot) const {

767 return false;

768

770 RegDefsUses RegDU(*Fn->getSubtarget().getRegisterInfo());

771 MemDefsUses MemDU(&Fn->getFrameInfo());

772 ReverseIter Filler;

773

774 RegDU.init(Slot);

775

778 Filler)) {

780 "slot using backwards search.\n");

781 return false;

782 }

783

784 MBB.splice(std::next(SlotI), &MBB, Filler.getReverse());

785 MIBundleBuilder(MBB, SlotI, std::next(SlotI, 2));

786 ++UsefulSlots;

787 return true;

788}

789

790bool MipsDelaySlotFiller::searchForward(MachineBasicBlock &MBB,

791 Iter Slot) const {

792

794 return false;

795

797 NoMemInstr NM;

798 Iter Filler;

799

800 RegDU.setCallerSaved(*Slot);

801

802 if (!searchRange(MBB, std::next(Slot), MBB.end(), RegDU, NM, Slot, Filler)) {

804 "slot using forwards search.\n");

805 return false;

806 }

807

809 MIBundleBuilder(MBB, Slot, std::next(Slot, 2));

810 ++UsefulSlots;

811 return true;

812}

813

814bool MipsDelaySlotFiller::searchSuccBBs(MachineBasicBlock &MBB,

815 Iter Slot) const {

817 return false;

818

819 MachineBasicBlock *SuccBB = selectSuccBB(MBB);

820

821 if (!SuccBB)

822 return false;

823

825 bool HasMultipleSuccs = false;

827 std::unique_ptr IM;

828 Iter Filler;

830

831

832 for (MachineBasicBlock *Pred : SuccBB->predecessors())

833 if (!examinePred(*Pred, *SuccBB, RegDU, HasMultipleSuccs, BrMap))

834 return false;

835

836

837

838 RegDU.setUnallocatableRegs(*Fn);

839

840

841

842 if (HasMultipleSuccs) {

843 IM.reset(new LoadFromStackOrConst());

844 } else {

845 const MachineFrameInfo &MFI = Fn->getFrameInfo();

846 IM.reset(new MemDefsUses(&MFI));

847 }

848

849 if (!searchRange(MBB, SuccBB->begin(), SuccBB->end(), RegDU, *IM, Slot,

850 Filler))

851 return false;

852

853 insertDelayFiller(Filler, BrMap);

855 Filler->eraseFromParent();

856

857 return true;

858}

859

860MachineBasicBlock *

861MipsDelaySlotFiller::selectSuccBB(MachineBasicBlock &B) const {

862 if (B.succ_empty())

863 return nullptr;

864

865

866 auto &Prob = getAnalysis().getMBPI();

867 MachineBasicBlock *S =

868 *llvm::max_element(B.successors(), [&](const MachineBasicBlock *Dst0,

869 const MachineBasicBlock *Dst1) {

870 return Prob.getEdgeProbability(&B, Dst0) <

871 Prob.getEdgeProbability(&B, Dst1);

872 });

873 return S->isEHPad() ? nullptr : S;

874}

875

876std::pair<MipsInstrInfo::BranchType, MachineInstr *>

877MipsDelaySlotFiller::getBranch(MachineBasicBlock &MBB,

878 const MachineBasicBlock &Dst) const {

879 const MipsInstrInfo *TII =

881 MachineBasicBlock *TrueBB = nullptr, *FalseBB = nullptr;

882 SmallVector<MachineInstr*, 2> BranchInstrs;

884

887

889 return std::make_pair(R, nullptr);

890

894

896

897 return std::make_pair(R, BranchInstrs[0]);

898 }

899

900 assert((TrueBB == &Dst) || (FalseBB == &Dst));

901

902

905

906

909

911}

912

913bool MipsDelaySlotFiller::examinePred(MachineBasicBlock &Pred,

914 const MachineBasicBlock &Succ,

915 RegDefsUses &RegDU,

916 bool &HasMultipleSuccs,

917 BB2BrMap &BrMap) const {

918 std::pair<MipsInstrInfo::BranchType, MachineInstr *> P =

919 getBranch(Pred, Succ);

920

921

922

924 return false;

925

928 HasMultipleSuccs = true;

929 RegDU.addLiveOut(Pred, Succ);

930 }

931

932 BrMap[&Pred] = P.second;

933 return true;

934}

935

936bool MipsDelaySlotFiller::delayHasHazard(const MachineInstr &Candidate,

937 RegDefsUses &RegDU,

938 InspectMemInstr &IM) const {

940 "KILL instructions should have been eliminated at this point.");

941

943

944 HasHazard |= IM.hasHazard(Candidate);

945 HasHazard |= RegDU.update(Candidate, 0, Candidate.getNumOperands());

946

947 return HasHazard;

948}

949

950bool MipsDelaySlotFiller::terminateSearch(const MachineInstr &Candidate) const {

954}

955

956

957

959 return new MipsDelaySlotFiller();

960}

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

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Function Alias Analysis false

static const Function * getParent(const Value *V)

This file implements the BitVector class.

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

#define clEnumValN(ENUMVAL, FLAGNAME, DESC)

This file defines the DenseMap class.

static bool hasHazard(StateT InitialState, function_ref< HazardFnResult(StateT &, const MachineInstr &)> IsHazard, function_ref< void(StateT &, const MachineInstr &)> UpdateState, const MachineBasicBlock *InitialMBB, MachineBasicBlock::const_reverse_instr_iterator InitialI)

Register const TargetRegisterInfo * TRI

static bool hasUnoccupiedSlot(const MachineInstr *MI)

Definition MipsDelaySlotFiller.cpp:295

static cl::opt< bool > DisableDelaySlotFiller("disable-mips-delay-filler", cl::init(false), cl::desc("Fill all delay slots with NOPs."), cl::Hidden)

static cl::opt< bool > DisableBackwardSearch("disable-mips-df-backward-search", cl::init(false), cl::desc("Disallow MIPS delay filler to search backward."), cl::Hidden)

static void addLiveInRegs(Iter Filler, MachineBasicBlock &MBB)

This function adds registers Filler defines to MBB's live-in register list.

Definition MipsDelaySlotFiller.cpp:317

static cl::opt< bool > DisableSuccBBSearch("disable-mips-df-succbb-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search successor basic blocks."), cl::Hidden)

const BB2BrMap & BrMap

Definition MipsDelaySlotFiller.cpp:303

static cl::opt< bool > DisableForwardSearch("disable-mips-df-forward-search", cl::init(true), cl::desc("Disallow MIPS delay filler to search forward."), cl::Hidden)

static cl::opt< CompactBranchPolicy > MipsCompactBranchPolicy("mips-compact-branches", cl::Optional, cl::init(CB_Optimal), cl::desc("MIPS Specific: Compact branch policy."), cl::values(clEnumValN(CB_Never, "never", "Do not use compact branches if possible."), clEnumValN(CB_Optimal, "optimal", "Use compact branches where appropriate (default)."), clEnumValN(CB_Always, "always", "Always use compact branches if possible.")))

CompactBranchPolicy

Definition MipsDelaySlotFiller.cpp:80

@ CB_Never

The policy 'never' may in some circumstances or for some ISAs not be absolutely adhered to.

Definition MipsDelaySlotFiller.cpp:81

@ CB_Optimal

Optimal is the default and will produce compact branches when delay slots cannot be filled.

Definition MipsDelaySlotFiller.cpp:83

@ CB_Always

'always' may in some circumstances may not be absolutely adhered to there may not be a corresponding ...

Definition MipsDelaySlotFiller.cpp:85

static int getEquivalentCallShort(int Opcode)

Definition MipsDelaySlotFiller.cpp:574

#define IsMFLOMFHI(instr)

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

This file defines the PointerUnion class, which is a discriminated union of pointer types.

const SmallVectorImpl< MachineOperand > & Cond

Remove Loads Into Fake Uses

This file defines the SmallPtrSet class.

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)

AnalysisUsage & addRequired()

bool test(unsigned Idx) const

iterator_range< const_set_bits_iterator > set_bits() const

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

const MCInstrDesc & get(unsigned Opcode) const

Return the machine instruction descriptor that corresponds to the specified instruction opcode.

Helper class for constructing bundles of MachineInstrs.

MIBundleBuilder & append(MachineInstr *MI)

Insert MI into MBB by appending it to the instructions in the bundle.

bool isEHPad() const

Returns true if the block is a landing pad.

Instructions::iterator instr_iterator

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

iterator_range< succ_iterator > successors()

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

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.

reverse_iterator getReverse() const

Get a reverse iterator to the same node.

Representation of each machine instruction.

bool isTerminator(QueryType Type=AnyInBundle) const

Returns true if this instruction part of the terminator for a basic block.

bool isImplicitDef() const

bool isCall(QueryType Type=AnyInBundle) const

unsigned getNumOperands() const

Retuns the total number of operands.

LLVM_ABI bool hasUnmodeledSideEffects() const

Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...

MachineOperand class - Representation of each machine instruction operand.

bool isReg() const

isReg - Tests if this is a MO_Register operand.

LLVM_ABI void dump() const

Register getReg() const

getReg - Returns the register number.

bool inMicroMipsMode() const

const MipsInstrInfo * getInstrInfo() const override

void push_back(const T &Elt)

virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const

Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....

virtual unsigned getInstSizeInBytes(const MachineInstr &MI) const

Returns the size in bytes of the specified MachineInstr, or ~0U when this function is not implemented...

CodeGenOptLevel getOptLevel() const

Returns the optimization level: None, Less, Default, or Aggressive.

TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...

BitVector getAllocatableSet(const MachineFunction &MF, const TargetRegisterClass *RC=nullptr) const

Returns a bitset indexed by register number indicating if a register is allocatable or not.

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

#define llvm_unreachable(msg)

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

ValuesClass values(OptsTy... Options)

Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...

initializer< Ty > init(const Ty &Val)

This is an optimization pass for GlobalISel generic memory operations.

FunctionAddr VTableAddr Value

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

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

uint16_t MCPhysReg

An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...

auto max_element(R &&Range)

Provide wrappers to std::max_element which take ranges instead of having to pass begin/end explicitly...

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

PointerUnion< const Value *, const PseudoSourceValue * > ValueType

FunctionPass * createMipsDelaySlotFillerPass()

createMipsDelaySlotFillerPass - Returns a pass that fills in delay slots in Mips MachineFunctions

Definition MipsDelaySlotFiller.cpp:958

LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)

This method is similar to getUnderlyingObject except that it can look through phi and select instruct...

LLVM_ABI bool isIdentifiedObject(const Value *V)

Return true if this pointer refers to a distinct and identifiable object.