LLVM: lib/Target/AArch64/AArch64ConditionalCompares.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

38

39using namespace llvm;

40

41#define DEBUG_TYPE "aarch64-ccmp"

42

43

44

47 cl::desc("Maximum number of instructions per speculated block."));

48

49

51 cl::desc("Turn all knobs to 11"));

52

53STATISTIC(NumConsidered, "Number of ccmps considered");

54STATISTIC(NumPhiRejs, "Number of ccmps rejected (PHI)");

55STATISTIC(NumPhysRejs, "Number of ccmps rejected (Physregs)");

56STATISTIC(NumPhi2Rejs, "Number of ccmps rejected (PHI2)");

57STATISTIC(NumHeadBranchRejs, "Number of ccmps rejected (Head branch)");

58STATISTIC(NumCmpBranchRejs, "Number of ccmps rejected (CmpBB branch)");

59STATISTIC(NumCmpTermRejs, "Number of ccmps rejected (CmpBB is cbz...)");

60STATISTIC(NumImmRangeRejs, "Number of ccmps rejected (Imm out of range)");

61STATISTIC(NumLiveDstRejs, "Number of ccmps rejected (Cmp dest live)");

62STATISTIC(NumMultNZCVUses, "Number of ccmps rejected (NZCV used)");

63STATISTIC(NumUnknNZCVDefs, "Number of ccmps rejected (NZCV def unknown)");

64

65STATISTIC(NumSpeculateRejs, "Number of ccmps rejected (Can't speculate)");

66

67STATISTIC(NumConverted, "Number of ccmp instructions created");

68STATISTIC(NumCompBranches, "Number of cbz/cbnz branches converted");

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135namespace {

136class SSACCmpConv {

142

143public:

144

145

147

148

150

151

153

154

156

157private:

158

160

161

163

164

166

167

169

170

171 bool trivialTailPHIs();

172

173

174 void updateTailPHIs();

175

176

177 bool isDeadDef(unsigned DstReg);

178

179

180

182

183

184

186

187public:

188

191 this->MF = &MF;

192 this->MBPI = MBPI;

196 }

197

198

199

200 bool canConvert(MachineBasicBlock *MBB);

201

202

203

204 void convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks);

205

206

207

208 int expectedCodeSizeDelta() const;

209};

210}

211

212

213

214bool SSACCmpConv::trivialTailPHIs() {

215 for (auto &I : *Tail) {

216 if (I.isPHI())

217 break;

218 unsigned HeadReg = 0, CmpBBReg = 0;

219

220 for (unsigned oi = 1, oe = I.getNumOperands(); oi != oe; oi += 2) {

221 MachineBasicBlock *MBB = I.getOperand(oi + 1).getMBB();

223 if (MBB == Head) {

224 assert((!HeadReg || HeadReg == Reg) && "Inconsistent PHI operands");

225 HeadReg = Reg;

226 }

227 if (MBB == CmpBB) {

228 assert((!CmpBBReg || CmpBBReg == Reg) && "Inconsistent PHI operands");

229 CmpBBReg = Reg;

230 }

231 }

232 if (HeadReg != CmpBBReg)

233 return false;

234 }

235 return true;

236}

237

238

239

240void SSACCmpConv::updateTailPHIs() {

241 for (auto &I : *Tail) {

242 if (I.isPHI())

243 break;

244

245 for (unsigned oi = I.getNumOperands(); oi > 2; oi -= 2) {

246

247 if (I.getOperand(oi - 1).getMBB() == CmpBB) {

248 I.removeOperand(oi - 1);

249 I.removeOperand(oi - 2);

250 }

251 }

252 }

253}

254

255

256

257bool SSACCmpConv::isDeadDef(unsigned DstReg) {

258

259 if (DstReg == AArch64::WZR || DstReg == AArch64::XZR)

260 return true;

261 if (!Register::isVirtualRegister(DstReg))

262 return false;

263

264

265 return MRI->use_nodbg_empty(DstReg);

266}

267

268

269

270

272

274 assert(Cond.size() == 1 && "Unknown Cond array format");

276 return true;

277 }

278

280 default:

281

282

283 return false;

284 case AArch64::CBZW:

285 case AArch64::CBZX:

286 assert(Cond.size() == 3 && "Unknown Cond array format");

288 return true;

289 case AArch64::CBNZW:

290 case AArch64::CBNZX:

291 assert(Cond.size() == 3 && "Unknown Cond array format");

293 return true;

294 }

295}

296

297MachineInstr *SSACCmpConv::findConvertibleCompare(MachineBasicBlock *MBB) {

300 return nullptr;

301

302 if (I->readsRegister(AArch64::NZCV, nullptr)) {

303 switch (I->getOpcode()) {

304 case AArch64::CBZW:

305 case AArch64::CBZX:

306 case AArch64::CBNZW:

307 case AArch64::CBNZX:

308

309 return &*I;

310 }

311 ++NumCmpTermRejs;

312 LLVM_DEBUG(dbgs() << "Flags not used by terminator: " << *I);

313 return nullptr;

314 }

315

316

319 assert(I->isTerminator() && "Spurious terminator");

320 switch (I->getOpcode()) {

321

322 case AArch64::SUBSWri:

323 case AArch64::SUBSXri:

324

325 case AArch64::ADDSWri:

326 case AArch64::ADDSXri:

327

328

329 if (I->getOperand(3).getImm() || isUInt<5>(I->getOperand(2).getImm())) {

330 LLVM_DEBUG(dbgs() << "Immediate out of range for ccmp: " << *I);

331 ++NumImmRangeRejs;

332 return nullptr;

333 }

334 [[fallthrough]];

335 case AArch64::SUBSWrr:

336 case AArch64::SUBSXrr:

337 case AArch64::ADDSWrr:

338 case AArch64::ADDSXrr:

339 if (isDeadDef(I->getOperand(0).getReg()))

340 return &*I;

341 LLVM_DEBUG(dbgs() << "Can't convert compare with live destination: "

342 << *I);

343 ++NumLiveDstRejs;

344 return nullptr;

345 case AArch64::FCMPSrr:

346 case AArch64::FCMPDrr:

347 case AArch64::FCMPESrr:

348 case AArch64::FCMPEDrr:

349 return &*I;

350 }

351

352

354

355 if (PRI.Read) {

356

357

358

359 LLVM_DEBUG(dbgs() << "Can't create ccmp with multiple uses: " << *I);

360 ++NumMultNZCVUses;

361 return nullptr;

362 }

363

366 ++NumUnknNZCVDefs;

367 return nullptr;

368 }

369 }

371 << '\n');

372 return nullptr;

373}

374

375

376

377

378

379

380bool SSACCmpConv::canSpeculateInstrs(MachineBasicBlock *MBB,

381 const MachineInstr *CmpMI) {

382

383

386 return false;

387 }

388

390

391

392

394 if (I.isDebugInstr())

395 continue;

396

400 return false;

401 }

402

403

404 if (I.isPHI()) {

406 return false;

407 }

408

409

410

411

412 if (I.mayLoad()) {

414 return false;

415 }

416

417

418 bool DontMoveAcrossStore = true;

419 if (I.isSafeToMove(DontMoveAcrossStore)) {

421 return false;

422 }

423

424

425 if (&I != CmpMI && I.modifiesRegister(AArch64::NZCV, TRI)) {

427 return false;

428 }

429 }

430 return true;

431}

432

433

434

435

436bool SSACCmpConv::canConvert(MachineBasicBlock *MBB) {

437 Head = MBB;

438 Tail = CmpBB = nullptr;

439

441 return false;

442 MachineBasicBlock *Succ0 = Head->succ_begin()[0];

443 MachineBasicBlock *Succ1 = Head->succ_begin()[1];

444

445

448

449

451 return false;

452

453 CmpBB = Succ0;

454 Tail = Succ1;

455

457 return false;

458

459

463 ++NumConsidered;

464

465

466

467

468

469

470

471 if (!trivialTailPHIs()) {

472 LLVM_DEBUG(dbgs() << "Can't handle phis in Tail.\n");

473 ++NumPhiRejs;

474 return false;

475 }

476

477 if (Tail->livein_empty()) {

478 LLVM_DEBUG(dbgs() << "Can't handle live-in physregs in Tail.\n");

479 ++NumPhysRejs;

480 return false;

481 }

482

483

484

486 LLVM_DEBUG(dbgs() << "Can't handle phis in CmpBB.\n");

487 ++NumPhi2Rejs;

488 return false;

489 }

490

492 LLVM_DEBUG(dbgs() << "Can't handle live-in physregs in CmpBB.\n");

493 ++NumPhysRejs;

494 return false;

495 }

496

497

498 HeadCond.clear();

499 MachineBasicBlock *TBB = nullptr, *FBB = nullptr;

501 LLVM_DEBUG(dbgs() << "Head branch not analyzable.\n");

502 ++NumHeadBranchRejs;

503 return false;

504 }

505

506

507

508 if (TBB || HeadCond.empty()) {

510 dbgs() << "analyzeBranch didn't find conditional branch in Head.\n");

511 ++NumHeadBranchRejs;

512 return false;

513 }

514

515 if (parseCond(HeadCond, HeadCmpBBCC)) {

516 LLVM_DEBUG(dbgs() << "Unsupported branch type on Head\n");

517 ++NumHeadBranchRejs;

518 return false;

519 }

520

521

522 if (TBB != CmpBB) {

525 }

526

527 CmpBBCond.clear();

528 TBB = FBB = nullptr;

530 LLVM_DEBUG(dbgs() << "CmpBB branch not analyzable.\n");

531 ++NumCmpBranchRejs;

532 return false;

533 }

534

535 if (TBB || CmpBBCond.empty()) {

537 dbgs() << "analyzeBranch didn't find conditional branch in CmpBB.\n");

538 ++NumCmpBranchRejs;

539 return false;

540 }

541

542 if (parseCond(CmpBBCond, CmpBBTailCC)) {

543 LLVM_DEBUG(dbgs() << "Unsupported branch type on CmpBB\n");

544 ++NumCmpBranchRejs;

545 return false;

546 }

547

550

553 << ", CmpBB->Tail on "

555

556 CmpMI = findConvertibleCompare(CmpBB);

557 if (!CmpMI)

558 return false;

559

560 if (!canSpeculateInstrs(CmpBB, CmpMI)) {

561 ++NumSpeculateRejs;

562 return false;

563 }

564 return true;

565}

566

567void SSACCmpConv::convert(SmallVectorImpl<MachineBasicBlock *> &RemovedBlocks) {

570 << *CmpBB);

571

572

573

574 updateTailPHIs();

575

576

577

578 BranchProbability Head2CmpBB = MBPI->getEdgeProbability(Head, CmpBB);

580

583

584

585

587

588

589

590

591

592

596 Head2Tail + Head2CmpBB * CmpBB2Tail);

597

598

599

600

601

602

606 }

607 }

608

612

613

614

615 if (HeadCond[0].getImm() == -1) {

616 ++NumCompBranches;

617 unsigned Opc = 0;

618 switch (HeadCond[1].getImm()) {

619 case AArch64::CBZW:

620 case AArch64::CBNZW:

621 Opc = AArch64::SUBSWri;

622 break;

623 case AArch64::CBZX:

624 case AArch64::CBNZX:

625 Opc = AArch64::SUBSXri;

626 break;

627 default:

629 }

630 const MCInstrDesc &MCID = TII->get(Opc);

631

632 Register DestReg = MRI->createVirtualRegister(TII->getRegClass(MCID, 0));

633

634 BuildMI(*Head, Head->end(), TermDL, MCID)

636 .add(HeadCond[2])

639

640 MRI->constrainRegClass(HeadCond[2].getReg(), TII->getRegClass(MCID, 1));

641 }

642

644

645

646

647 unsigned Opc = 0;

648 unsigned FirstOp = 1;

649 bool isZBranch = false;

651 default:

653 case AArch64::SUBSWri: Opc = AArch64::CCMPWi; break;

654 case AArch64::SUBSWrr: Opc = AArch64::CCMPWr; break;

655 case AArch64::SUBSXri: Opc = AArch64::CCMPXi; break;

656 case AArch64::SUBSXrr: Opc = AArch64::CCMPXr; break;

657 case AArch64::ADDSWri: Opc = AArch64::CCMNWi; break;

658 case AArch64::ADDSWrr: Opc = AArch64::CCMNWr; break;

659 case AArch64::ADDSXri: Opc = AArch64::CCMNXi; break;

660 case AArch64::ADDSXrr: Opc = AArch64::CCMNXr; break;

661 case AArch64::FCMPSrr: Opc = AArch64::FCCMPSrr; FirstOp = 0; break;

662 case AArch64::FCMPDrr: Opc = AArch64::FCCMPDrr; FirstOp = 0; break;

663 case AArch64::FCMPESrr: Opc = AArch64::FCCMPESrr; FirstOp = 0; break;

664 case AArch64::FCMPEDrr: Opc = AArch64::FCCMPEDrr; FirstOp = 0; break;

665 case AArch64::CBZW:

666 case AArch64::CBNZW:

667 Opc = AArch64::CCMPWi;

668 FirstOp = 0;

669 isZBranch = true;

670 break;

671 case AArch64::CBZX:

672 case AArch64::CBNZX:

673 Opc = AArch64::CCMPXi;

674 FirstOp = 0;

675 isZBranch = true;

676 break;

677 }

678

679

680

681

682

683

685 const MCInstrDesc &MCID = TII->get(Opc);

687 TII->getRegClass(MCID, 0));

690 TII->getRegClass(MCID, 1));

691 MachineInstrBuilder MIB = BuildMI(*Head, CmpMI, CmpMI->getDebugLoc(), MCID)

693 if (isZBranch)

694 MIB.addImm(0);

695 else

696 MIB.add(CmpMI->getOperand(FirstOp + 1));

698

699

700

701 if (isZBranch) {

702 bool isNZ = CmpMI->getOpcode() == AArch64::CBNZW ||

703 CmpMI->getOpcode() == AArch64::CBNZX;

707 }

710

713 ++NumConverted;

714}

715

716int SSACCmpConv::expectedCodeSizeDelta() const {

717 int delta = 0;

718

719

720

721 if (HeadCond[0].getImm() == -1) {

722 switch (HeadCond[1].getImm()) {

723 case AArch64::CBZW:

724 case AArch64::CBNZW:

725 case AArch64::CBZX:

726 case AArch64::CBNZX:

727

728 delta = 1;

729 break;

730 default:

732 }

733 }

734

735

736

737

739 default:

740 --delta;

741 break;

742 case AArch64::CBZW:

743 case AArch64::CBNZW:

744 case AArch64::CBZX:

745 case AArch64::CBNZX:

746 break;

747 }

748 return delta;

749}

750

751

752

753

754

755namespace {

756class AArch64ConditionalCompares : public MachineFunctionPass {

757 const MachineBranchProbabilityInfo *MBPI;

758 const TargetInstrInfo *TII;

759 const TargetRegisterInfo *TRI;

760 MCSchedModel SchedModel;

761

762 bool MinSize;

763 MachineRegisterInfo *MRI;

764 MachineDominatorTree *DomTree;

765 MachineLoopInfo *Loops;

766 MachineTraceMetrics *Traces;

768 SSACCmpConv CmpConv;

769

770public:

771 static char ID;

772 AArch64ConditionalCompares() : MachineFunctionPass(ID) {}

773 void getAnalysisUsage(AnalysisUsage &AU) const override;

774 bool runOnMachineFunction(MachineFunction &MF) override;

775 StringRef getPassName() const override {

776 return "AArch64 Conditional Compares";

777 }

778

779private:

780 bool tryConvert(MachineBasicBlock *);

783 void invalidateTraces();

785};

786}

787

788char AArch64ConditionalCompares::ID = 0;

789

791 "AArch64 CCMP Pass", false, false)

797

799 return new AArch64ConditionalCompares();

800}

801

802void AArch64ConditionalCompares::getAnalysisUsage(AnalysisUsage &AU) const {

811}

812

813

814void AArch64ConditionalCompares::updateDomTree(

816

817

819 for (MachineBasicBlock *RemovedMBB : Removed) {

821 assert(Node != HeadNode && "Cannot erase the head node");

822 assert(Node->getIDom() == HeadNode && "CmpBB should be dominated by Head");

823 while (Node->getNumChildren())

826 }

827}

828

829

830void

833 return;

834 for (MachineBasicBlock *RemovedMBB : Removed)

835 Loops->removeBlock(RemovedMBB);

836}

837

838

839void AArch64ConditionalCompares::invalidateTraces() {

842}

843

844

845

846

847bool AArch64ConditionalCompares::shouldConvert() {

848

850 return true;

851 if (!MinInstr)

852 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);

853

854

856

857

858 if (MinSize) {

859 int CodeSizeDelta = CmpConv.expectedCodeSizeDelta();

860 LLVM_DEBUG(dbgs() << "Code size delta: " << CodeSizeDelta << '\n');

861

862

863 if (CodeSizeDelta < 0)

864 return true;

865 if (CodeSizeDelta > 0) {

866 LLVM_DEBUG(dbgs() << "Code size is increasing, give up on this one.\n");

867 return false;

868 }

869

870 }

871

872

873

874

875

876

877

879

880

881 unsigned HeadDepth =

883 unsigned CmpBBDepth =

886 << "\nCmpBB depth: " << CmpBBDepth << '\n');

887 if (CmpBBDepth > HeadDepth + DelayLimit) {

888 LLVM_DEBUG(dbgs() << "Branch delay would be larger than " << DelayLimit

889 << " cycles.\n");

890 return false;

891 }

892

893

894

896 LLVM_DEBUG(dbgs() << "Resources: " << ResDepth << '\n');

897

898

899

900

901 if (ResDepth > HeadDepth) {

902 LLVM_DEBUG(dbgs() << "Too many instructions to speculate.\n");

903 return false;

904 }

905 return true;

906}

907

908bool AArch64ConditionalCompares::tryConvert(MachineBasicBlock *MBB) {

911 invalidateTraces();

912 SmallVector<MachineBasicBlock *, 4> RemovedBlocks;

913 CmpConv.convert(RemovedBlocks);

915 updateDomTree(RemovedBlocks);

916 for (MachineBasicBlock *MBB : RemovedBlocks)

918 updateLoops(RemovedBlocks);

919 }

921}

922

923bool AArch64ConditionalCompares::runOnMachineFunction(MachineFunction &MF) {

924 LLVM_DEBUG(dbgs() << "********** AArch64 Conditional Compares **********\n"

925 << "********** Function: " << MF.getName() << '\n');

927 return false;

928

933 DomTree = &getAnalysis().getDomTree();

934 Loops = &getAnalysis().getLI();

935 MBPI = &getAnalysis().getMBPI();

936 Traces = &getAnalysis().getMTM();

937 MinInstr = nullptr;

939

941 CmpConv.runOnMachineFunction(MF, MBPI);

942

943

944

945

946

947

949 if (tryConvert(I->getBlock()))

951

953}

unsigned const MachineRegisterInfo * MRI

static cl::opt< bool > Stress("aarch64-stress-ccmp", cl::Hidden, cl::desc("Turn all knobs to 11"))

static cl::opt< unsigned > BlockInstrLimit("aarch64-ccmp-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))

static bool parseCond(ArrayRef< MachineOperand > Cond, AArch64CC::CondCode &CC)

Definition AArch64ConditionalCompares.cpp:271

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

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

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

static unsigned InstrCount

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

static cl::opt< bool > Stress("stress-early-ifcvt", cl::Hidden, cl::desc("Turn all knobs to 11"))

static cl::opt< unsigned > BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))

const HexagonInstrInfo * TII

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)

#define INITIALIZE_PASS_DEPENDENCY(depName)

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

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

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

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

#define STATISTIC(VARNAME, DESC)

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

AnalysisUsage & addPreserved()

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

ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...

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.

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

bool hasMinSize() const

Optimize this function for minimum size (-Oz).

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

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

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

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

const MCSchedModel & getSchedModel() const

Get the machine model for this subtarget's CPU.

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

LLVM_ABI void updateTerminator(MachineBasicBlock *PreviousLayoutSuccessor)

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

LLVM_ABI void setSuccProbability(succ_iterator I, BranchProbability Prob)

Set successor probability of a given iterator.

succ_iterator succ_begin()

bool livein_empty() const

LLVM_ABI iterator getFirstTerminator()

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

unsigned succ_size() const

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

Remove successor from the successors list of this MachineBasicBlock.

bool hasSuccessorProbabilities() const

Return true if any of the successors have probabilities attached to them.

LLVM_ABI void eraseFromParent()

This method unlinks 'this' from the containing function and deletes it.

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

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

Analysis pass which computes a MachineDominatorTree.

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.

StringRef getName() const

getName - Return the name of the corresponding LLVM function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

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 isReg() const

isReg - Tests if this is a MO_Register operand.

Register getReg() const

getReg - Returns the register number.

MachineRegisterInfo - Keep track of information for virtual and physical registers,...

Trace getTrace(const MachineBasicBlock *MBB)

Get the trace that passes through MBB.

InstrCycles getInstrCycles(const MachineInstr &MI) const

Return the depth and height of MI.

unsigned getResourceDepth(bool Bottom) const

Return the resource depth of the top/bottom of the trace center block.

Ensemble * getEnsemble(MachineTraceStrategy)

Get the trace ensemble representing the given trace selection strategy.

void invalidate(const MachineBasicBlock *MBB)

Invalidate cached information about MBB.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

TargetInstrInfo - Interface to description of machine instruction set.

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

virtual const TargetInstrInfo * getInstrInfo() const

virtual const TargetRegisterInfo * getRegisterInfo() const =0

Return the target's register information.

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.

static const char * getCondCodeName(CondCode Code)

static CondCode getInvertedCondCode(CondCode Code)

static unsigned getNZCVToSatisfyCondCode(CondCode Code)

Given a condition code, return NZCV flags that would satisfy that condition.

unsigned ID

LLVM IR allows to use arbitrary numbers as calling convention identifiers.

@ Tail

Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...

@ Define

Register definition.

initializer< Ty > init(const Ty &Val)

NodeAddr< NodeBase * > Node

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.

LLVM_ABI PhysRegInfo AnalyzePhysRegInBundle(const MachineInstr &MI, Register Reg, const TargetRegisterInfo *TRI)

AnalyzePhysRegInBundle - Analyze how the current instruction or bundle uses a physical register.

FunctionPass * createAArch64ConditionalCompares()

Definition AArch64ConditionalCompares.cpp:798

MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)

LLVM_ABI raw_ostream & dbgs()

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

constexpr bool isUInt(uint64_t x)

Checks if an unsigned integer fits into the given bit width.

DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode

ArrayRef(const T &OneElt) -> ArrayRef< T >

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

IterT prev_nodbg(IterT It, IterT Begin, bool SkipPseudoOp=true)

Decrement It, then continue decrementing it while it points to a debug instruction.

LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)

Prints a machine basic block reference.

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

Implement std::swap in terms of BitVector swap.

unsigned MispredictPenalty

unsigned Depth

Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...

bool Read

Reg or one of its aliases is read.

bool Defined

Reg or one of its aliases is defined.

bool Clobbered

There is a regmask operand indicating Reg is clobbered.