LLVM: lib/Target/ARM/MVETPAndVPTOptimisationsPass.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

31#include

32

33using namespace llvm;

34

35#define DEBUG_TYPE "arm-mve-vpt-opts"

36

39 cl::desc("Enable merging Loop End and Dec instructions."),

41

44 cl::desc("Enable setting lr as a predicate in tail predication regions."),

46

47namespace {

49public:

50 static char ID;

53

55

57

64 }

65

67 return "ARM MVE TailPred and VPT Optimisation Pass";

68 }

69

70private:

85};

86

87char MVETPAndVPTOptimisations::ID = 0;

88

89}

90

92 "ARM MVE TailPred and VPT Optimisations pass", false,

93 false)

98

101 while (MI && MI->getOpcode() == TargetOpcode::COPY &&

102 MI->getOperand(1).getReg().isVirtual())

103 MI = MRI->getVRegDef(MI->getOperand(1).getReg());

104 return MI;

105}

106

107

108

109

115 if (!Header || !Latch) {

117 return false;

118 }

119

120

121 LoopEnd = nullptr;

123 if (T.getOpcode() == ARM::t2LoopEnd && T.getOperand(1).getMBB() == Header) {

124 LoopEnd = &T;

125 break;

126 }

127 if (T.getOpcode() == ARM::t2LoopEndDec &&

128 T.getOperand(2).getMBB() == Header) {

129 LoopEnd = &T;

130 break;

131 }

132 }

133 if (!LoopEnd) {

135 return false;

136 }

137 LLVM_DEBUG(dbgs() << " found loop end: " << *LoopEnd);

138

139

140

141

142

143

144

145

146

147

148 if (LoopEnd->getOpcode() == ARM::t2LoopEndDec)

149 LoopDec = LoopEnd;

150 else {

151 LoopDec =

153 if (!LoopDec || LoopDec->getOpcode() != ARM::t2LoopDec) {

154 LLVM_DEBUG(dbgs() << " didn't find LoopDec where we expected!\n");

155 return false;

156 }

157 }

158 LLVM_DEBUG(dbgs() << " found loop dec: " << *LoopDec);

159

160 LoopPhi =

162 if (!LoopPhi || LoopPhi->getOpcode() != TargetOpcode::PHI ||

166 LLVM_DEBUG(dbgs() << " didn't find PHI where we expected!\n");

167 return false;

168 }

169 LLVM_DEBUG(dbgs() << " found loop phi: " << *LoopPhi);

170

175 if (!LoopStart || (LoopStart->getOpcode() != ARM::t2DoLoopStart &&

176 LoopStart->getOpcode() != ARM::t2WhileLoopSetup &&

177 LoopStart->getOpcode() != ARM::t2WhileLoopStartLR)) {

178 LLVM_DEBUG(dbgs() << " didn't find Start where we expected!\n");

179 return false;

180 }

181 LLVM_DEBUG(dbgs() << " found loop start: " << *LoopStart);

182

183 return true;

184}

185

188 assert(MI->getOpcode() == ARM::t2WhileLoopSetup &&

189 "Only expected a t2WhileLoopSetup in RevertWhileLoopStart!");

190

191

194 MIB.add(MI->getOperand(0));

195 MIB.add(MI->getOperand(1));

198 MIB.addReg(ARM::NoRegister);

200

201

203 if (I.getOpcode() == ARM::t2WhileLoopStart) {

205 BuildMI(*MBB, &I, I.getDebugLoc(), TII->get(ARM::t2Bcc));

206 MIB.add(MI->getOperand(1));

208 MIB.addReg(ARM::CPSR);

209 I.eraseFromParent();

210 break;

211 }

212 }

213

214 MI->eraseFromParent();

215}

216

217

218

219

220

221

222

223

224

225

226

227bool MVETPAndVPTOptimisations::LowerWhileLoopStart(MachineLoop *ML) {

229 << ML->getHeader()->getName() << "\n");

230

231 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;

233 return false;

234

235 if (LoopStart->getOpcode() != ARM::t2WhileLoopSetup)

236 return false;

237

239 auto WLSIt = find_if(MRI->use_nodbg_instructions(LR), [](auto &MI) {

240 return MI.getOpcode() == ARM::t2WhileLoopStart;

241 });

242 if (MergeEndDec || WLSIt == MRI->use_instr_nodbg_end()) {

246 return true;

247 }

248

250 BuildMI(*WLSIt->getParent(), *WLSIt, WLSIt->getDebugLoc(),

251 TII->get(ARM::t2WhileLoopStartLR), LR)

253 .add(WLSIt->getOperand(1));

254 (void)MI;

255 LLVM_DEBUG(dbgs() << "Lowered WhileLoopStart into: " << *MI.getInstr());

256

257 WLSIt->eraseFromParent();

259 return true;

260}

261

262

263

266}

267

268

269

270

271

272MachineInstr *MVETPAndVPTOptimisations::CheckForLRUseInPredecessors(

278

279 while (!Worklist.empty()) {

282 continue;

283

286 continue;

287

288 LLVM_DEBUG(dbgs() << "Found LR use in predecessors, reverting: " << MI);

289

290

293 LoopStart->getDebugLoc(), TII->get(ARM::t2DoLoopStart));

296

297

299

300

302 return MIB;

303 }

304

308 }

309 return LoopStart;

310}

311

312

313

314

315

316

317

318

319bool MVETPAndVPTOptimisations::MergeLoopEnd(MachineLoop *ML) {

321 return false;

322

323 LLVM_DEBUG(dbgs() << "MergeLoopEnd on loop " << ML->getHeader()->getName()

324 << "\n");

325

326 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;

328 return false;

329

330

331

332

333 auto *PreHeader = ML->getLoopPreheader();

334 if (LoopStart->getOpcode() == ARM::t2WhileLoopStartLR && PreHeader)

335 LoopStart = CheckForLRUseInPredecessors(PreHeader, LoopStart);

336

340 LLVM_DEBUG(dbgs() << "Found LR use in loop, reverting: " << MI);

341 if (LoopStart->getOpcode() == ARM::t2DoLoopStart)

343 else

347 return true;

348 }

349 }

350 }

351

352

353

354

358

365 while (!Worklist.empty()) {

369 continue;

370 if (MI.getOpcode() != TargetOpcode::COPY ||

371 MI.getOperand(0).getReg().isVirtual()) {

372 LLVM_DEBUG(dbgs() << "Extra users of register found: " << MI);

373 return false;

374 }

375 Worklist.push_back(MI.getOperand(0).getReg());

377 }

378 }

379 return true;

380 };

381 if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||

382 !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||

383 !CheckUsers(StartReg, {LoopPhi}, MRI)) {

384

385 if (LoopStart->getOpcode() == ARM::t2WhileLoopStartLR) {

389 return true;

390 }

391 return false;

392 }

393

394 MRI->constrainRegClass(StartReg, &ARM::GPRlrRegClass);

395 MRI->constrainRegClass(PhiReg, &ARM::GPRlrRegClass);

396 MRI->constrainRegClass(DecReg, &ARM::GPRlrRegClass);

397

401 } else {

404 }

405

409

410

415 }

416

417

420 TII->get(ARM::t2LoopEndDec), DecReg)

423 (void)MI;

424 LLVM_DEBUG(dbgs() << "Merged LoopDec and End into: " << *MI.getInstr());

425

429 MI->eraseFromParent();

430 return true;

431}

432

433

434

435

436

437bool MVETPAndVPTOptimisations::ConvertTailPredLoop(MachineLoop *ML,

440 << ML->getHeader()->getName() << "\n");

441

442

443

444 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;

446 return false;

447 if (LoopDec != LoopEnd || (LoopStart->getOpcode() != ARM::t2DoLoopStart &&

448 LoopStart->getOpcode() != ARM::t2WhileLoopStartLR))

449 return false;

450

459 }

460

461 if (VCTPs.empty()) {

463 return false;

464 }

465

466

470 if (VCTP->getOpcode() != FirstVCTP->getOpcode() ||

471 VCTP->getOperand(0).getReg() != FirstVCTP->getOperand(0).getReg()) {

473 return false;

474 }

475 }

476

477

478

479

480

481

482

483

484

485

486

489 LLVM_DEBUG(dbgs() << " cannot determine VCTP PHI\n");

490 return false;

491 }

493 if (!Phi || Phi->getOpcode() != TargetOpcode::PHI ||

494 Phi->getNumOperands() != 5 ||

495 (Phi->getOperand(2).getMBB() != ML->getLoopLatch() &&

496 Phi->getOperand(4).getMBB() != ML->getLoopLatch())) {

497 LLVM_DEBUG(dbgs() << " cannot determine VCTP Count\n");

498 return false;

499 }

500 CountReg = Phi->getOperand(2).getMBB() == ML->getLoopLatch()

501 ? Phi->getOperand(3).getReg()

502 : Phi->getOperand(1).getReg();

503

504

505

506

513 LLVM_DEBUG(dbgs() << " InsertPt could not be a terminator!\n");

514 return false;

515 }

516

517 unsigned NewOpc = LoopStart->getOpcode() == ARM::t2DoLoopStart

518 ? ARM::t2DoLoopStartTP

519 : ARM::t2WhileLoopStartTP;

525 if (NewOpc == ARM::t2WhileLoopStartTP)

527 LLVM_DEBUG(dbgs() << "Replacing " << *LoopStart << " with "

528 << *MI.getInstr());

529 MRI->constrainRegClass(CountReg, &ARM::rGPRRegClass);

531

533

534

538 MI->getOperand(Idx + 2).setReg(LR);

539 }

540 }

541

542 return true;

543}

544

545

547

548

549

550

552 switch (Opcode) {

553 default:

554 return true;

555 case ARM::MVE_VCMPf32:

556 case ARM::MVE_VCMPf16:

557 case ARM::MVE_VCMPf32r:

558 case ARM::MVE_VCMPf16r:

559 case ARM::MVE_VCMPi8r:

560 case ARM::MVE_VCMPi16r:

561 case ARM::MVE_VCMPi32r:

562 case ARM::MVE_VCMPu8r:

563 case ARM::MVE_VCMPu16r:

564 case ARM::MVE_VCMPu32r:

565 case ARM::MVE_VCMPs8r:

566 case ARM::MVE_VCMPs16r:

567 case ARM::MVE_VCMPs32r:

568 return false;

569 }

570}

571

572

574 assert(IsVCMP(Instr.getOpcode()) && "Inst must be a VCMP");

576}

577

578

579

582

583

585 return false;

586

589

590

591

595 if (CondOP1.isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))

596 return true;

597

599 return false;

602 CondOP2.isIdenticalTo(PrevOP1);

603}

604

605

607 if (Instr.getNumOperands() == 0)

608 return false;

610 if (!Dst.isReg())

611 return false;

612 Register DstReg = Dst.getReg();

614 return false;

617 return RegClass && (RegClass->getID() == ARM::VCCRRegClassID);

618}

619

620

621

622

623

624

625

626

627

628MachineInstr &MVETPAndVPTOptimisations::ReplaceRegisterUseWithVPNOT(

632

638

639

640 User.setReg(NewResult);

641 User.setIsKill(false);

642

643 LLVM_DEBUG(dbgs() << " Inserting VPNOT (for spill prevention): ";

645

646 return *MIBuilder.getInstr();

647}

648

649

650

651

655 assert(Iter->getOpcode() == ARM::MVE_VPNOT && "Not a VPNOT!");

657 "The VPNOT cannot be predicated");

658

662

663

664

665 bool MustMove = false, HasUser = false;

667 for (; Iter != MBB.end(); ++Iter) {

669 Iter->findRegisterUseOperand(VPNOTOperand, nullptr,

670 true)) {

671

672 VPNOTOperandKiller = MO;

673 }

674

675 if (Iter->findRegisterUseOperandIdx(Reg, nullptr) != -1) {

676 MustMove = true;

677 continue;

678 }

679

680 if (Iter->findRegisterUseOperandIdx(VPNOTResult, nullptr) == -1)

681 continue;

682

683 HasUser = true;

684 if (!MustMove)

685 break;

686

687

689 Iter->dump());

691

692

693 if (VPNOTOperandKiller)

694 VPNOTOperandKiller->setIsKill(false);

695

696 break;

697 }

698 return HasUser;

699}

700

701

702

703

704

705

706

707

708

709

710

711

712

713

714bool MVETPAndVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &MBB) {

718

719 while (Iter != End) {

720 Register VCCRValue, OppositeVCCRValue;

721

722

723

724 for (; Iter != End; ++Iter) {

725

728 continue;

729 Register Dst = Iter->getOperand(0).getReg();

730

731

732

733 if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&

734 Iter->findRegisterUseOperandIdx(VCCRValue, nullptr) != -1) {

735

736

738 continue;

739

740 OppositeVCCRValue = Dst;

741 ++Iter;

742 break;

743 }

744

745

746 VCCRValue = Dst;

747 }

748

749

750 if (Iter == End)

751 break;

752

753 assert(VCCRValue && OppositeVCCRValue &&

754 "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "

755 "stopped before the end of the block!");

756 assert(VCCRValue != OppositeVCCRValue &&

757 "VCCRValue should not be equal to OppositeVCCRValue!");

758

759

760 Register LastVPNOTResult = OppositeVCCRValue;

761

762

763 for (; Iter != End; ++Iter) {

764 bool IsInteresting = false;

765

767 Iter->findRegisterUseOperand(VCCRValue, nullptr)) {

768 IsInteresting = true;

769

770

771

772

773 if (Iter->getOpcode() == ARM::MVE_VPNOT) {

775

776 MRI->replaceRegWith(Result, LastVPNOTResult);

777 DeadInstructions.push_back(&*Iter);

779

781 << "Replacing all uses of '" << printReg(Result)

782 << "' with '" << printReg(LastVPNOTResult) << "'\n");

783 } else {

785 ReplaceRegisterUseWithVPNOT(MBB, *Iter, *MO, LastVPNOTResult);

787

789 std::swap(VCCRValue, OppositeVCCRValue);

790

792 << "' with '" << printReg(LastVPNOTResult)

793 << "' in instr: " << *Iter);

794 }

795 } else {

796

797

798 if (MachineOperand *MO = Iter->findRegisterUseOperand(

799 OppositeVCCRValue, nullptr)) {

800 IsInteresting = true;

801

802

803 if (LastVPNOTResult != OppositeVCCRValue) {

805 << printReg(OppositeVCCRValue) << "' with '"

806 << printReg(LastVPNOTResult) << " for instr: ";

807 Iter->dump());

808 MO->setReg(LastVPNOTResult);

810 }

811

812 MO->setIsKill(false);

813 }

814

815

816

817 if (Iter->getOpcode() == ARM::MVE_VPNOT &&

819 Register VPNOTOperand = Iter->getOperand(1).getReg();

820 if (VPNOTOperand == LastVPNOTResult ||

821 VPNOTOperand == OppositeVCCRValue) {

822 IsInteresting = true;

823

824 std::swap(VCCRValue, OppositeVCCRValue);

825 LastVPNOTResult = Iter->getOperand(0).getReg();

826 }

827 }

828 }

829

830

832 break;

833 }

834 }

835

836 for (MachineInstr *DeadInstruction : DeadInstructions)

837 DeadInstruction->eraseFromParent();

838

840}

841

842

845

846

847

848

849

850

852

853

854

856

858 if (PrevVCMP) {

861 nullptr, true)) {

862

863

864 PrevVCMPResultKiller = MO;

865 }

866 }

867

868

870 continue;

871

872

874

876 PrevVCMP = nullptr;

877 continue;

878 }

879

881 PrevVCMP = &Instr;

882 continue;

883 }

884

885

886

888

889

893 .addReg(PrevVCMPResultReg);

895 LLVM_DEBUG(dbgs() << "Inserting VPNOT (to replace VCMP): ";

898

899

900

901 if (PrevVCMPResultKiller)

902 PrevVCMPResultKiller->setIsKill(false);

903

904

905

906 DeadInstructions.push_back(&Instr);

907 PrevVCMP = nullptr;

908 PrevVCMPResultKiller = nullptr;

909 }

910

911 for (MachineInstr *DeadInstruction : DeadInstructions)

912 DeadInstruction->eraseFromParent();

913

914 return !DeadInstructions.empty();

915}

916

919

920

921

922

923

924 unsigned LastVPTImm = 0;

927

929

931 if (PIdx == -1)

932 continue;

933 Register VPR = Instr.getOperand(PIdx + 1).getReg();

935 continue;

936

937

939 if (!Copy || Copy->getOpcode() != TargetOpcode::COPY ||

940 Copy->getOperand(1).getReg().isVirtual() ||

941 MRI->getRegClass(Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {

942 LastVPTReg = 0;

943 continue;

944 }

946

947

948 auto getImm = [&](Register GPR) -> unsigned {

950 if (Def && (Def->getOpcode() == ARM::t2MOVi ||

951 Def->getOpcode() == ARM::t2MOVi16))

952 return Def->getOperand(1).getImm();

953 return -1U;

954 };

955 unsigned Imm = getImm(GPR);

956 if (Imm == -1U) {

957 LastVPTReg = 0;

958 continue;

959 }

960

961 unsigned NotImm = ~Imm & 0xffff;

962 if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {

963 MRI->clearKillFlags(LastVPTReg);

964 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);

965 if (MRI->use_empty(VPR)) {

966 DeadInstructions.insert(Copy);

967 if (MRI->hasOneUse(GPR))

968 DeadInstructions.insert(MRI->getVRegDef(GPR));

969 }

970 LLVM_DEBUG(dbgs() << "Reusing predicate: in " << Instr);

971 VPR = LastVPTReg;

972 } else if (LastVPTReg != 0 && LastVPTImm == NotImm) {

973

974

975 Register NewVPR = MRI->createVirtualRegister(&ARM::VCCRRegClass);

977 TII->get(ARM::MVE_VPNOT), NewVPR)

980

981

982 Instr.getOperand(PIdx + 1).setReg(NewVPR);

983 if (MRI->use_empty(VPR)) {

984 DeadInstructions.insert(Copy);

985 if (MRI->hasOneUse(GPR))

986 DeadInstructions.insert(MRI->getVRegDef(GPR));

987 }

988 LLVM_DEBUG(dbgs() << "Adding VPNot: " << *VPNot << " to replace use at "

989 << Instr);

990 VPR = NewVPR;

991 }

992

993 LastVPTImm = Imm;

994 LastVPTReg = VPR;

995 }

996

998 DI->eraseFromParent();

999

1000 return !DeadInstructions.empty();

1001}

1002

1003

1004

1005

1006

1007

1009 bool HasVCTP = false;

1011

1014 HasVCTP = true;

1015 continue;

1016 }

1017

1018 if (!HasVCTP || MI.getOpcode() != ARM::MVE_VPSEL)

1019 continue;

1020

1023 .add(MI.getOperand(0))

1024 .add(MI.getOperand(1))

1025 .add(MI.getOperand(1))

1027 .add(MI.getOperand(4))

1028 .add(MI.getOperand(5))

1029 .add(MI.getOperand(2));

1030

1031 (void)MIBuilder;

1035 }

1036

1037 for (MachineInstr *DeadInstruction : DeadInstructions)

1038 DeadInstruction->eraseFromParent();

1039

1040 return !DeadInstructions.empty();

1041}

1042

1043

1044

1046 bool Changed = false;

1048 if (MI.getOpcode() != ARM::t2DoLoopStart)

1049 continue;

1053 Changed = true;

1054 }

1055 return Changed;

1056}

1057

1058bool MVETPAndVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {

1060

1061 if (!STI.isThumb2() || !STI.hasLOB())

1062 return false;

1063

1066 MachineLoopInfo *MLI = &getAnalysis().getLI();

1068 &getAnalysis().getDomTree();

1069

1070 LLVM_DEBUG(dbgs() << "********** ARM MVE VPT Optimisations **********\n"

1071 << "********** Function: " << Fn.getName() << '\n');

1072

1075 Modified |= LowerWhileLoopStart(ML);

1077 Modified |= ConvertTailPredLoop(ML, DT);

1078 }

1079

1082 Modified |= ReplaceConstByVPNOTs(MBB, DT);

1084 Modified |= ReduceOldVCCRValueUses(MBB);

1086 }

1087

1088 LLVM_DEBUG(dbgs() << "**************************************\n");

1090}

1091

1092

1094 return new MVETPAndVPTOptimisations();

1095}

unsigned const MachineRegisterInfo * MRI

MachineBasicBlock MachineBasicBlock::iterator MBBI

Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx

const HexagonInstrInfo * TII

ARM MVE TailPred and VPT Optimisations static false MachineInstr * LookThroughCOPY(MachineInstr *MI, MachineRegisterInfo *MRI)

static void RevertWhileLoopSetup(MachineInstr *MI, const TargetInstrInfo *TII)

static cl::opt< bool > SetLRPredicate("arm-set-lr-predicate", cl::Hidden, cl::desc("Enable setting lr as a predicate in tail predication regions."), cl::init(true))

static bool findLoopComponents(MachineLoop *ML, MachineRegisterInfo *MRI, MachineInstr *&LoopStart, MachineInstr *&LoopPhi, MachineInstr *&LoopDec, MachineInstr *&LoopEnd)

static bool MoveVPNOTBeforeFirstUser(MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, Register Reg)

static cl::opt< bool > MergeEndDec("arm-enable-merge-loopenddec", cl::Hidden, cl::desc("Enable merging Loop End and Dec instructions."), cl::init(true))

static ARMCC::CondCodes GetCondCode(MachineInstr &Instr)

static bool IsVPNOTEquivalent(MachineInstr &Cond, MachineInstr &Prev)

static bool IsInvalidTPInstruction(MachineInstr &MI)

static bool IsVCMP(unsigned Opcode)

ARM MVE TailPred and VPT Optimisations pass

static bool IsWritingToVCCR(MachineInstr &Instr)

static bool CanHaveSwappedOperands(unsigned Opcode)

#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

assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())

This file defines the SmallVector class.

const ARMBaseInstrInfo * getInstrInfo() const override

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

bool dominates(const BasicBlock *BB, const Use &U) const

Return true if the (end of the) basic block BB dominates the use U.

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

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

SmallVector< LoopT *, 4 > getLoopsInPreorder() const

Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...

iterator getFirstTerminator()

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

iterator_range< iterator > terminators()

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

Analysis pass which computes a MachineDominatorTree.

DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...

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.

virtual bool runOnMachineFunction(MachineFunction &MF)=0

runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...

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.

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.

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

MachineInstr * getInstr() const

If conversion operators fail, use this method to get the MachineInstr explicitly.

const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register definition operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

unsigned getNumOperands() const

Retuns the total number of operands.

const DebugLoc & getDebugLoc() const

Returns the debug location id of this MachineInstr.

void eraseFromParent()

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

const MachineOperand & getOperand(unsigned i) const

MachineOperand class - Representation of each machine instruction operand.

MachineBasicBlock * getMBB() const

void setReg(Register Reg)

Change the register this operand corresponds to.

void setIsKill(bool Val=true)

Register getReg() const

getReg - Returns the register number.

bool isIdenticalTo(const MachineOperand &Other) const

Returns true if this operand is identical to the specified operand except for liveness related flags ...

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

void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)

setRegAllocationHint - Specify a register allocation hint for the specified virtual register.

virtual StringRef getPassName() const

getPassName - Return a nice clean name for a pass.

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

Return true if the specified register number is in the virtual register namespace.

size_type count(ConstPtrType Ptr) const

count - Return 1 if the specified pointer is in the set, 0 otherwise.

std::pair< iterator, bool > insert(PtrType Ptr)

Inserts Ptr if and only if there is no element in the container equal to Ptr.

SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

std::pair< const_iterator, bool > insert(const T &V)

insert - Insert an element into the set if it isn't already there.

void push_back(const T &Elt)

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

StringRef - Represent a constant reference to a string, i.e.

TargetInstrInfo - Interface to description of machine instruction set.

unsigned getID() const

Return the register class ID number.

Target - Wrapper for Target specific information.

A Use represents the edge between a Value definition and its users.

self_iterator getIterator()

static CondCodes getOppositeCondition(CondCodes CC)

static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)

getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...

unsigned ID

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

@ Define

Register definition.

Reg

All possible values of the reg field in the ModR/M byte.

initializer< Ty > init(const Ty &Val)

NodeAddr< InstrNode * > Instr

NodeAddr< PhiNode * > Phi

NodeAddr< DefNode * > Def

This is an optimization pass for GlobalISel generic memory operations.

void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)

int findFirstVPTPredOperandIdx(const MachineInstr &MI)

FunctionPass * createMVETPAndVPTOptimisationsPass()

createMVETPAndVPTOptimisationsPass

ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)

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

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

static bool isVCTP(const MachineInstr *MI)

static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)

Get the operands corresponding to the given Pred value.

raw_ostream & dbgs()

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

static bool isLoopStart(const MachineInstr &MI)

void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)

void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)

void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)

auto find_if(R &&Range, UnaryPredicate P)

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

bool is_contained(R &&Range, const E &Element)

Returns true if Element is found in Range.

static unsigned VCMPOpcodeToVPT(unsigned Opcode)

void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)

void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB)

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.

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

Implement std::swap in terms of BitVector swap.