LLVM: lib/Target/AArch64/AArch64MIPeepholeOpt.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

77

78using namespace llvm;

79

80#define DEBUG_TYPE "aarch64-mi-peephole-opt"

81

82namespace {

83

85 static char ID;

86

88

93

94 using OpcodePair = std::pair<unsigned, unsigned>;

95 template

96 using SplitAndOpcFunc =

97 std::function<std::optional(T, unsigned, T &, T &)>;

98 using BuildMIFunc =

99 std::function<void(MachineInstr &, OpcodePair, unsigned, unsigned,

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116 template

118 SplitAndOpcFunc SplitAndOpc, BuildMIFunc BuildInstr);

119

122

123 template

124 bool visitADDSUB(unsigned PosOpc, unsigned NegOpc, MachineInstr &MI);

125 template

126 bool visitADDSSUBS(OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI);

127

128

129 enum class SplitStrategy {

130 Intersect,

131 Disjoint,

132 };

133 template

135 SplitStrategy Strategy, unsigned OtherOpc = 0);

145

146 StringRef getPassName() const override {

147 return "AArch64 MI Peephole Optimization pass";

148 }

149

150 void getAnalysisUsage(AnalysisUsage &AU) const override {

154 }

155};

156

157char AArch64MIPeepholeOpt::ID = 0;

158

159}

160

162 "AArch64 MI Peephole Optimization", false, false)

163

164template <typename T>

166 T UImm = static_cast<T>(Imm);

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

168

169

170

171

172

173

176

177

178

181

182

184

185

186

188 return false;

189

192 return true;

193}

194

195template

198 assert(Imm && (Imm != ~static_cast<T>(0)) && "Invalid immediate!");

199

200

201

202

203

205 unsigned LowestGapBitUnset =

207

208

209 assert(LowestGapBitUnset < sizeof(T) * CHAR_BIT && "Undefined behaviour!");

210 T NewImm1 = (static_cast<T>(1) << LowestGapBitUnset) -

212

214

215

217 return false;

218

221 return true;

222}

223

224template

225bool AArch64MIPeepholeOpt::trySplitLogicalImm(unsigned Opc, MachineInstr &MI,

226 SplitStrategy Strategy,

227 unsigned OtherOpc) {

228

229

230

231

232

233

234

235

236

237

238 return splitTwoPartImm(

240 [Opc, Strategy, OtherOpc](T Imm, unsigned RegSize, T &Imm0,

241 T &Imm1) -> std::optional {

242

243

245 return std::nullopt;

246

247

250 if (Insn.size() == 1)

251 return std::nullopt;

252

253 bool SplitSucc = false;

254 switch (Strategy) {

255 case SplitStrategy::Intersect:

256 SplitSucc = splitBitmaskImm(Imm, RegSize, Imm0, Imm1);

257 break;

258 case SplitStrategy::Disjoint:

260 break;

261 }

262 if (SplitSucc)

263 return std::make_pair(Opc, !OtherOpc ? Opc : OtherOpc);

264 return std::nullopt;

265 },

266 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,

270 MachineBasicBlock *MBB = MI.getParent();

277 });

278}

279

280bool AArch64MIPeepholeOpt::visitORR(MachineInstr &MI) {

281

282

283

284

285 if (MI.getOperand(3).getImm() != 0)

286 return false;

287

288 if (MI.getOperand(1).getReg() != AArch64::WZR)

289 return false;

290

291 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());

292 if (!SrcMI)

293 return false;

294

295

296

297

298

299

300

301

302

303

304

305 if (SrcMI->getOpcode() == TargetOpcode::COPY &&

307 const TargetRegisterClass *RC =

309

310

311

312 if (RC != &AArch64::FPR32RegClass &&

313 ((RC != &AArch64::FPR64RegClass && RC != &AArch64::FPR128RegClass &&

314 RC != &AArch64::ZPRRegClass) ||

316 return false;

319 CpySrc = MRI->createVirtualRegister(&AArch64::FPR32RegClass);

321 TII->get(TargetOpcode::COPY), CpySrc)

323 } else {

325 }

330 }

331 else if (SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)

332 return false;

333

334 Register DefReg = MI.getOperand(0).getReg();

335 Register SrcReg = MI.getOperand(2).getReg();

336 MRI->replaceRegWith(DefReg, SrcReg);

337 MRI->clearKillFlags(SrcReg);

339 MI.eraseFromParent();

340

341 return true;

342}

343

344bool AArch64MIPeepholeOpt::visitCSEL(MachineInstr &MI) {

345

346 if (MI.getOperand(1).getReg() != MI.getOperand(2).getReg())

347 return false;

348

349 auto ZeroReg =

350 MI.getOpcode() == AArch64::CSELXr ? AArch64::XZR : AArch64::WZR;

351 auto OrOpcode =

352 MI.getOpcode() == AArch64::CSELXr ? AArch64::ORRXrs : AArch64::ORRWrs;

353

357 .addReg(MI.getOperand(1).getReg())

359

360 MI.eraseFromParent();

361 return true;

362}

363

364bool AArch64MIPeepholeOpt::visitINSERT(MachineInstr &MI) {

365

366

367

368

369

370

371

372 if (MI.isRegTiedToDefOperand(1))

373 return false;

374

375 Register DstReg = MI.getOperand(0).getReg();

376 const TargetRegisterClass *RC = MRI->getRegClass(DstReg);

377 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());

378 if (!SrcMI)

379 return false;

380

381

382

383

384

385

386

387

388

389

390

391 if ((SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END) ||

392 !AArch64::GPR64allRegClass.hasSubClassEq(RC))

393 return false;

394

395

396 MachineInstr *SubregMI =

398 TII->get(TargetOpcode::SUBREG_TO_REG), DstReg)

400 .add(MI.getOperand(2))

401 .add(MI.getOperand(3));

402 LLVM_DEBUG(dbgs() << MI << " replace by:\n: " << *SubregMI << "\n");

403 (void)SubregMI;

404 MI.eraseFromParent();

405

406 return true;

407}

408

409template

411

412

413 if ((Imm & 0xfff000) == 0 || (Imm & 0xfff) == 0 ||

414 (Imm & ~static_cast<T>(0xffffff)) != 0)

415 return false;

416

417

420 if (Insn.size() == 1)

421 return false;

422

423

424 Imm0 = (Imm >> 12) & 0xfff;

425 Imm1 = Imm & 0xfff;

426 return true;

427}

428

429template

430bool AArch64MIPeepholeOpt::visitADDSUB(

431 unsigned PosOpc, unsigned NegOpc, MachineInstr &MI) {

432

433

434

435

436

437

438

439

440

441

442

443

444

445

446

447

448 if (MI.getOperand(1).getReg() == AArch64::XZR ||

449 MI.getOperand(1).getReg() == AArch64::WZR)

450 return false;

451

452 return splitTwoPartImm(

454 [PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,

455 T &Imm1) -> std::optional {

457 return std::make_pair(PosOpc, PosOpc);

459 return std::make_pair(NegOpc, NegOpc);

460 return std::nullopt;

461 },

462 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,

466 MachineBasicBlock *MBB = MI.getParent();

475 });

476}

477

478template

479bool AArch64MIPeepholeOpt::visitADDSSUBS(

480 OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI) {

481

482

483

484 if (MI.getOperand(1).getReg() == AArch64::XZR ||

485 MI.getOperand(1).getReg() == AArch64::WZR)

486 return false;

487

488 return splitTwoPartImm(

490 [PosOpcs, NegOpcs, &MI, &TRI = TRI,

492 T &Imm1) -> std::optional {

493 OpcodePair OP;

495 OP = PosOpcs;

497 OP = NegOpcs;

498 else

499 return std::nullopt;

500

501

502 MachineInstr &SrcMI = *MRI->getUniqueVRegDef(MI.getOperand(1).getReg());

504 if (!NZCVUsed || NZCVUsed->C || NZCVUsed->V)

505 return std::nullopt;

506 return OP;

507 },

508 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,

512 MachineBasicBlock *MBB = MI.getParent();

521 });

522}

523

524

525

526bool AArch64MIPeepholeOpt::checkMovImmInstr(MachineInstr &MI,

527 MachineInstr *&MovMI,

528 MachineInstr *&SubregToRegMI) {

529

530 MachineBasicBlock *MBB = MI.getParent();

532 if (L && L->isLoopInvariant(MI))

533 return false;

534

535

536 MovMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());

537 if (!MovMI)

538 return false;

539

540

541 SubregToRegMI = nullptr;

542 if (MovMI->getOpcode() == TargetOpcode::SUBREG_TO_REG) {

543 SubregToRegMI = MovMI;

545 if (!MovMI)

546 return false;

547 }

548

549 if (MovMI->getOpcode() != AArch64::MOVi32imm &&

550 MovMI->getOpcode() != AArch64::MOVi64imm)

551 return false;

552

553

554

556 return false;

557 if (SubregToRegMI && MRI->hasOneUse(SubregToRegMI->getOperand(0).getReg()))

558 return false;

559

560

561 return true;

562}

563

564template

565bool AArch64MIPeepholeOpt::splitTwoPartImm(

566 MachineInstr &MI,

567 SplitAndOpcFunc SplitAndOpc, BuildMIFunc BuildInstr) {

568 unsigned RegSize = sizeof(T) * 8;

570 "Invalid RegSize for legal immediate peephole optimization");

571

572

573 MachineInstr *MovMI, *SubregToRegMI;

574 if (!checkMovImmInstr(MI, MovMI, SubregToRegMI))

575 return false;

576

577

579

580

581

582

583 if (SubregToRegMI)

584 Imm &= 0xFFFFFFFF;

585 OpcodePair Opcode;

586 if (auto R = SplitAndOpc(Imm, RegSize, Imm0, Imm1))

587 Opcode = *R;

588 else

589 return false;

590

591

592

593

594

595

596

597 const TargetRegisterClass *FirstInstrDstRC =

599 const TargetRegisterClass *FirstInstrOperandRC =

601 const TargetRegisterClass *SecondInstrDstRC =

602 (Opcode.first == Opcode.second)

603 ? FirstInstrDstRC

605 const TargetRegisterClass *SecondInstrOperandRC =

606 (Opcode.first == Opcode.second)

607 ? FirstInstrOperandRC

609

610

611 Register DstReg = MI.getOperand(0).getReg();

612 Register SrcReg = MI.getOperand(1).getReg();

613 Register NewTmpReg = MRI->createVirtualRegister(FirstInstrDstRC);

614

615

617 ? MRI->createVirtualRegister(SecondInstrDstRC)

618 : DstReg;

619

620

621 MRI->constrainRegClass(SrcReg, FirstInstrOperandRC);

622 MRI->constrainRegClass(NewTmpReg, SecondInstrOperandRC);

623 if (DstReg != NewDstReg)

624 MRI->constrainRegClass(NewDstReg, MRI->getRegClass(DstReg));

625

626

627 BuildInstr(MI, Opcode, Imm0, Imm1, SrcReg, NewTmpReg, NewDstReg);

628

629

630

631 if (DstReg != NewDstReg) {

632 MRI->replaceRegWith(DstReg, NewDstReg);

633 MI.getOperand(0).setReg(DstReg);

634 }

635

636

637 MI.eraseFromParent();

638 if (SubregToRegMI)

641

642 return true;

643}

644

645bool AArch64MIPeepholeOpt::visitINSviGPR(MachineInstr &MI, unsigned Opc) {

646

647

648

649

650

651

652

653

654

655

656

657 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(3).getReg());

658

659

660

661 while (true) {

662 if (!SrcMI || SrcMI->getOpcode() != TargetOpcode::COPY)

663 return false;

664

666 return false;

667

669 &AArch64::FPR128RegClass) {

670 break;

671 }

673 }

674

675 Register DstReg = MI.getOperand(0).getReg();

677 MachineInstr *INSvilaneMI =

679 .add(MI.getOperand(1))

680 .add(MI.getOperand(2))

683

684 LLVM_DEBUG(dbgs() << MI << " replace by:\n: " << *INSvilaneMI << "\n");

685 (void)INSvilaneMI;

686 MI.eraseFromParent();

687 return true;

688}

689

690

691

694 if (MI->getOperand(0).isReg() || MI->getOperand(0).isDef())

695 return false;

697 if (RC != &AArch64::FPR64RegClass)

698 return false;

699 return MI->getOpcode() > TargetOpcode::GENERIC_OP_END;

700}

701

702bool AArch64MIPeepholeOpt::visitINSvi64lane(MachineInstr &MI) {

703

704

705

706

707

708

709

710 MachineInstr *Low64MI = MRI->getUniqueVRegDef(MI.getOperand(1).getReg());

711 if (Low64MI->getOpcode() != AArch64::INSERT_SUBREG)

712 return false;

715 return false;

716

717

718

719

720

721

722

723

724

725

726

727

728

729

730 MachineInstr *High64MI = MRI->getUniqueVRegDef(MI.getOperand(3).getReg());

731 if (!High64MI || High64MI->getOpcode() != AArch64::INSERT_SUBREG)

732 return false;

734 if (High64MI && High64MI->getOpcode() == TargetOpcode::COPY)

736 if (!High64MI || (High64MI->getOpcode() != AArch64::MOVID &&

737 High64MI->getOpcode() != AArch64::MOVIv2d_ns))

738 return false;

740 return false;

741

742

743 Register OldDef = MI.getOperand(0).getReg();

744 Register NewDef = MI.getOperand(1).getReg();

745 MRI->constrainRegClass(NewDef, MRI->getRegClass(OldDef));

746 MRI->replaceRegWith(OldDef, NewDef);

747 MI.eraseFromParent();

748

749 return true;

750}

751

752bool AArch64MIPeepholeOpt::visitFMOVDr(MachineInstr &MI) {

753

754 MachineInstr *Low64MI = MRI->getUniqueVRegDef(MI.getOperand(1).getReg());

756 return false;

757

758

759 Register OldDef = MI.getOperand(0).getReg();

760 Register NewDef = MI.getOperand(1).getReg();

762 MRI->clearKillFlags(OldDef);

763 MRI->clearKillFlags(NewDef);

764 MRI->constrainRegClass(NewDef, MRI->getRegClass(OldDef));

765 MRI->replaceRegWith(OldDef, NewDef);

766 MI.eraseFromParent();

767

768 return true;

769}

770

771bool AArch64MIPeepholeOpt::visitUBFMXri(MachineInstr &MI) {

772

773

774 int64_t Immr = MI.getOperand(2).getImm();

775 int64_t Imms = MI.getOperand(3).getImm();

776

777 bool IsLSR = Imms == 31 && Immr <= Imms;

778 bool IsLSL = Immr == Imms + 33;

779 if (!IsLSR && !IsLSL)

780 return false;

781

782 if (IsLSL) {

783 Immr -= 32;

784 }

785

786 const TargetRegisterClass *DstRC64 =

788 const TargetRegisterClass *DstRC32 =

789 TRI->getSubRegisterClass(DstRC64, AArch64::sub_32);

790 assert(DstRC32 && "Destination register class of UBFMXri doesn't have a "

791 "sub_32 subregister class");

792

793 const TargetRegisterClass *SrcRC64 =

795 const TargetRegisterClass *SrcRC32 =

796 TRI->getSubRegisterClass(SrcRC64, AArch64::sub_32);

797 assert(SrcRC32 && "Source register class of UBFMXri doesn't have a sub_32 "

798 "subregister class");

799

800 Register DstReg64 = MI.getOperand(0).getReg();

801 Register DstReg32 = MRI->createVirtualRegister(DstRC32);

802 Register SrcReg64 = MI.getOperand(1).getReg();

803 Register SrcReg32 = MRI->createVirtualRegister(SrcRC32);

804

806 SrcReg32)

807 .addReg(SrcReg64, 0, AArch64::sub_32);

808 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(AArch64::UBFMWri),

809 DstReg32)

814 TII->get(AArch64::SUBREG_TO_REG), DstReg64)

817 .addImm(AArch64::sub_32);

818 MI.eraseFromParent();

819 return true;

820}

821

822

823

824

825bool AArch64MIPeepholeOpt::visitCopy(MachineInstr &MI) {

826 Register InputReg = MI.getOperand(1).getReg();

827 if (MI.getOperand(1).getSubReg() != AArch64::sub_32 ||

828 MRI->hasOneNonDBGUse(InputReg))

829 return false;

830

831 MachineInstr *SrcMI = MRI->getUniqueVRegDef(InputReg);

832 SmallPtrSet<MachineInstr *, 4> DeadInstrs;

833 DeadInstrs.insert(SrcMI);

834 while (SrcMI && SrcMI->isFullCopy() &&

837 DeadInstrs.insert(SrcMI);

838 }

839

840 if (!SrcMI)

841 return false;

842

843

844 auto getSXTWSrcReg = [](MachineInstr *SrcMI) -> Register {

845 if (SrcMI->getOpcode() != AArch64::SBFMXri ||

848 return AArch64::NoRegister;

850 };

851

852 auto getUXTWSrcReg = [&](MachineInstr *SrcMI) -> Register {

853 if (SrcMI->getOpcode() != AArch64::SUBREG_TO_REG ||

856 return AArch64::NoRegister;

857 MachineInstr *Orr = MRI->getUniqueVRegDef(SrcMI->getOperand(2).getReg());

858 if (!Orr || Orr->getOpcode() != AArch64::ORRWrr ||

861 return AArch64::NoRegister;

863 if (!Cpy || Cpy->getOpcode() != AArch64::COPY ||

865 return AArch64::NoRegister;

866 DeadInstrs.insert(Orr);

868 };

869

870 Register SrcReg = getSXTWSrcReg(SrcMI);

871 if (!SrcReg)

872 SrcReg = getUXTWSrcReg(SrcMI);

873 if (!SrcReg)

874 return false;

875

876 MRI->constrainRegClass(SrcReg, MRI->getRegClass(InputReg));

878 MI.getOperand(1).setReg(SrcReg);

880 for (auto *DeadMI : DeadInstrs) {

882 DeadMI->eraseFromParent();

883 }

884 return true;

885}

886

887bool AArch64MIPeepholeOpt::runOnMachineFunction(MachineFunction &MF) {

889 return false;

890

891 TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());

892 TRI = static_cast<const AArch64RegisterInfo *>(

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

896

897 assert(MRI->isSSA() && "Expected to be run on SSA form!");

898

900

901 for (MachineBasicBlock &MBB : MF) {

903 switch (MI.getOpcode()) {

904 default:

905 break;

906 case AArch64::INSERT_SUBREG:

908 break;

909 case AArch64::ANDWrr:

910 Changed |= trySplitLogicalImm<uint32_t>(AArch64::ANDWri, MI,

911 SplitStrategy::Intersect);

912 break;

913 case AArch64::ANDXrr:

914 Changed |= trySplitLogicalImm<uint64_t>(AArch64::ANDXri, MI,

915 SplitStrategy::Intersect);

916 break;

917 case AArch64::ANDSWrr:

918 Changed |= trySplitLogicalImm<uint32_t>(

919 AArch64::ANDWri, MI, SplitStrategy::Intersect, AArch64::ANDSWri);

920 break;

921 case AArch64::ANDSXrr:

922 Changed |= trySplitLogicalImm<uint64_t>(

923 AArch64::ANDXri, MI, SplitStrategy::Intersect, AArch64::ANDSXri);

924 break;

925 case AArch64::EORWrr:

926 Changed |= trySplitLogicalImm<uint32_t>(AArch64::EORWri, MI,

927 SplitStrategy::Disjoint);

928 break;

929 case AArch64::EORXrr:

930 Changed |= trySplitLogicalImm<uint64_t>(AArch64::EORXri, MI,

931 SplitStrategy::Disjoint);

932 break;

933 case AArch64::ORRWrr:

934 Changed |= trySplitLogicalImm<uint32_t>(AArch64::ORRWri, MI,

935 SplitStrategy::Disjoint);

936 break;

937 case AArch64::ORRXrr:

938 Changed |= trySplitLogicalImm<uint64_t>(AArch64::ORRXri, MI,

939 SplitStrategy::Disjoint);

940 break;

941 case AArch64::ORRWrs:

943 break;

944 case AArch64::ADDWrr:

945 Changed |= visitADDSUB<uint32_t>(AArch64::ADDWri, AArch64::SUBWri, MI);

946 break;

947 case AArch64::SUBWrr:

948 Changed |= visitADDSUB<uint32_t>(AArch64::SUBWri, AArch64::ADDWri, MI);

949 break;

950 case AArch64::ADDXrr:

951 Changed |= visitADDSUB<uint64_t>(AArch64::ADDXri, AArch64::SUBXri, MI);

952 break;

953 case AArch64::SUBXrr:

954 Changed |= visitADDSUB<uint64_t>(AArch64::SUBXri, AArch64::ADDXri, MI);

955 break;

956 case AArch64::ADDSWrr:

958 visitADDSSUBS<uint32_t>({AArch64::ADDWri, AArch64::ADDSWri},

959 {AArch64::SUBWri, AArch64::SUBSWri}, MI);

960 break;

961 case AArch64::SUBSWrr:

963 visitADDSSUBS<uint32_t>({AArch64::SUBWri, AArch64::SUBSWri},

964 {AArch64::ADDWri, AArch64::ADDSWri}, MI);

965 break;

966 case AArch64::ADDSXrr:

968 visitADDSSUBS<uint64_t>({AArch64::ADDXri, AArch64::ADDSXri},

969 {AArch64::SUBXri, AArch64::SUBSXri}, MI);

970 break;

971 case AArch64::SUBSXrr:

973 visitADDSSUBS<uint64_t>({AArch64::SUBXri, AArch64::SUBSXri},

974 {AArch64::ADDXri, AArch64::ADDSXri}, MI);

975 break;

976 case AArch64::CSELWr:

977 case AArch64::CSELXr:

979 break;

980 case AArch64::INSvi64gpr:

981 Changed |= visitINSviGPR(MI, AArch64::INSvi64lane);

982 break;

983 case AArch64::INSvi32gpr:

984 Changed |= visitINSviGPR(MI, AArch64::INSvi32lane);

985 break;

986 case AArch64::INSvi16gpr:

987 Changed |= visitINSviGPR(MI, AArch64::INSvi16lane);

988 break;

989 case AArch64::INSvi8gpr:

990 Changed |= visitINSviGPR(MI, AArch64::INSvi8lane);

991 break;

992 case AArch64::INSvi64lane:

994 break;

995 case AArch64::FMOVDr:

997 break;

998 case AArch64::UBFMXri:

1000 break;

1001 case AArch64::COPY:

1003 break;

1004 }

1005 }

1006 }

1007

1009}

1010

1012 return new AArch64MIPeepholeOpt();

1013}

unsigned const MachineRegisterInfo * MRI

static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)

static bool splitDisjointBitmaskImm(T Imm, unsigned RegSize, T &Imm1Enc, T &Imm2Enc)

Definition AArch64MIPeepholeOpt.cpp:196

unsigned HighestBitSet

Definition AArch64MIPeepholeOpt.cpp:175

T NewImm1

Definition AArch64MIPeepholeOpt.cpp:179

unsigned T T & Imm2Enc

Definition AArch64MIPeepholeOpt.cpp:165

unsigned T & Imm1Enc

Definition AArch64MIPeepholeOpt.cpp:165

T NewImm2

Definition AArch64MIPeepholeOpt.cpp:183

unsigned RegSize

Definition AArch64MIPeepholeOpt.cpp:165

static bool is64bitDefwithZeroHigh64bit(MachineInstr *MI, MachineRegisterInfo *MRI)

Definition AArch64MIPeepholeOpt.cpp:692

static bool splitAddSubImm(T Imm, unsigned RegSize, T &Imm0, T &Imm1)

Definition AArch64MIPeepholeOpt.cpp:410

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

unsigned LowestBitSet

Definition AArch64MIPeepholeOpt.cpp:174

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

Register const TargetRegisterInfo * TRI

Promote Memory to Register

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

Represent the analysis usage information of a pass.

AnalysisUsage & addRequired()

LLVM_ABI void setPreservesCFG()

This function should be called by the pass, iff they do not:

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

LoopT * getLoopFor(const BlockT *BB) const

Return the inner most loop that BB lives in.

const MCInstrDesc & get(unsigned Opcode) const

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

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

void getAnalysisUsage(AnalysisUsage &AU) const override

getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.

const TargetSubtargetInfo & getSubtarget() const

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

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

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 & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const

Add a virtual register use operand.

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

const MachineBasicBlock * getParent() const

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

unsigned getSubReg() const

Register getReg() const

getReg - Returns the register number.

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

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

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

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

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

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.

virtual const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum) const

Given a machine instruction descriptor, returns the register class constraint for OpNum,...

static bool isLogicalImmediate(uint64_t imm, unsigned regSize)

isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...

static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)

encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...

void expandMOVImm(uint64_t Imm, unsigned BitSize, SmallVectorImpl< ImmInsnModel > &Insn)

Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more real move-immediate instructions to...

unsigned ID

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

@ Define

Register definition.

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.

FunctionPass * createAArch64MIPeepholeOptPass()

Definition AArch64MIPeepholeOpt.cpp:1011

int countr_one(T Value)

Count the number of ones from the least significant bit to the first zero bit.

iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)

Make a range that does early increment to allow mutation of the underlying range without disrupting i...

unsigned Log2_64(uint64_t Value)

Return the floor log base 2 of the specified value, -1 if the value is zero.

int countr_zero(T Val)

Count number of 0's from the least significant bit to the most stopping at the first 1.

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

decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)

LLVM_ABI raw_ostream & dbgs()

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

std::optional< UsedNZCV > examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl< MachineInstr * > *CCUseInstrs=nullptr)

class LLVM_GSL_OWNER SmallVector

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

unsigned getRegState(const MachineOperand &RegOp)

Get all register state flags from machine operand RegOp.