LLVM: lib/Target/PowerPC/PPCInstrInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

44

45using namespace llvm;

46

47#define DEBUG_TYPE "ppc-instr-info"

48

49#define GET_INSTRMAP_INFO

50#define GET_INSTRINFO_CTOR_DTOR

51#include "PPCGenInstrInfo.inc"

52

54 "Number of spillvsrrc spilled to stack as vec");

56 "Number of spillvsrrc spilled to stack as gpr");

57STATISTIC(NumGPRtoVSRSpill, "Number of gpr spills to spillvsrrc");

59 "Number of ISELs that depend on comparison of constants converted");

60STATISTIC(MissedConvertibleImmediateInstrs,

61 "Number of compare-immediate instructions fed by constants");

63 "Number of record-form rotates converted to record-form andi");

64

67 cl::desc("Disable analysis for CTR loops"));

68

71

73cl::desc("Causes the backend to crash instead of generating a nop VSX copy"),

75

78 cl::desc("Use the old (incorrect) instruction latency calculation"));

79

82 cl::desc("register pressure factor for the transformations."));

83

86 cl::desc("enable register pressure reduce in machine combiner pass."));

87

88

89void PPCInstrInfo::anchor() {}

90

93 -1,

94 STI.isPPC64() ? PPC::BLR8 : PPC::BLR),

95 Subtarget(STI), RI(STI.getTargetMachine()) {}

96

97

98

103 static_cast<const PPCSubtarget *>(STI)->getCPUDirective();

107 static_cast<const PPCSubtarget *>(STI)->getInstrItineraryData();

109 }

110

112}

113

114

115

121

122

125

126

129 assert(DAG->TII && "No InstrInfo?");

130

132 }

133

135}

136

139 unsigned *PredCost) const {

141 return PPCGenInstrInfo::getInstrLatency(ItinData, MI, PredCost);

142

143

144

145

146

147

148

149

151 unsigned DefClass = MI.getDesc().getSchedClass();

152 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {

155 continue;

156

159 continue;

160

162 }

163

165}

166

169 unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const {

170 std::optional Latency = PPCGenInstrInfo::getOperandLatency(

171 ItinData, DefMI, DefIdx, UseMI, UseIdx);

172

173 if (DefMI.getParent())

175

178

179 bool IsRegCR;

180 if (Reg.isVirtual()) {

182 &DefMI.getParent()->getParent()->getRegInfo();

183 IsRegCR = MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRRCRegClass) ||

184 MRI->getRegClass(Reg)->hasSuperClassEq(&PPC::CRBITRCRegClass);

185 } else {

186 IsRegCR = PPC::CRRCRegClass.contains(Reg) ||

187 PPC::CRBITRCRegClass.contains(Reg);

188 }

189

190 if (UseMI.isBranch() && IsRegCR) {

193

194

195

196 unsigned Directive = Subtarget.getCPUDirective();

198 default: break;

210

212 break;

213 }

214 }

215

217}

218

221 MI.setFlags(Flags);

225}

226

227

228

229

230

231

233 bool Invert) const {

234 if (Invert)

235 return false;

237

238

239 case PPC::FADD:

240 case PPC::FADDS:

241

242 case PPC::FMUL:

243 case PPC::FMULS:

244

245 case PPC::VADDFP:

246

247 case PPC::XSADDDP:

248 case PPC::XVADDDP:

249 case PPC::XVADDSP:

250 case PPC::XSADDSP:

251

252 case PPC::XSMULDP:

253 case PPC::XVMULDP:

254 case PPC::XVMULSP:

255 case PPC::XSMULSP:

258

259

260 case PPC::MULHD:

261 case PPC::MULLD:

262 case PPC::MULHW:

263 case PPC::MULLW:

264 return true;

265 default:

266 return false;

267 }

268}

269

270#define InfoArrayIdxFMAInst 0

271#define InfoArrayIdxFAddInst 1

272#define InfoArrayIdxFMULInst 2

273#define InfoArrayIdxAddOpIdx 3

274#define InfoArrayIdxMULOpIdx 4

275#define InfoArrayIdxFSubInst 5

276

277

278

279

280

281

282

283

285

286 {PPC::XSMADDADP, PPC::XSADDDP, PPC::XSMULDP, 1, 2, PPC::XSSUBDP},

287 {PPC::XSMADDASP, PPC::XSADDSP, PPC::XSMULSP, 1, 2, PPC::XSSUBSP},

288 {PPC::XVMADDADP, PPC::XVADDDP, PPC::XVMULDP, 1, 2, PPC::XVSUBDP},

289 {PPC::XVMADDASP, PPC::XVADDSP, PPC::XVMULSP, 1, 2, PPC::XVSUBSP},

290 {PPC::FMADD, PPC::FADD, PPC::FMUL, 3, 1, PPC::FSUB},

291 {PPC::FMADDS, PPC::FADDS, PPC::FMULS, 3, 1, PPC::FSUBS}};

292

293

294

295int16_t PPCInstrInfo::getFMAOpIdxInfo(unsigned Opcode) const {

298 return I;

299 return -1;

300}

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

352 bool DoRegPressureReduce) const {

356

357 auto IsAllOpsVirtualReg = [](const MachineInstr &Instr) {

358 for (const auto &MO : Instr.explicit_operands())

359 if (!(MO.isReg() && MO.getReg().isVirtual()))

360 return false;

361 return true;

362 };

363

364 auto IsReassociableAddOrSub = [&](const MachineInstr &Instr,

365 unsigned OpType) {

366 if (Instr.getOpcode() !=

368 return false;

369

370

371

374 return false;

375

376

377 if (!IsAllOpsVirtualReg(Instr))

378 return false;

379

380

381

383 MRI->hasOneNonDBGUse(Instr.getOperand(0).getReg()))

384 return false;

385

386 return true;

387 };

388

389 auto IsReassociableFMA = [&](const MachineInstr &Instr, int16_t &AddOpIdx,

390 int16_t &MulOpIdx, bool IsLeaf) {

391 int16_t Idx = getFMAOpIdxInfo(Instr.getOpcode());

392 if (Idx < 0)

393 return false;

394

395

396

399 return false;

400

401

402 if (!IsAllOpsVirtualReg(Instr))

403 return false;

404

406 if (IsLeaf)

407 return true;

408

410

411 const MachineOperand &OpAdd = Instr.getOperand(AddOpIdx);

413

415 return false;

416

417

418

419 return IsLeaf ? true : MRI->hasOneNonDBGUse(OpAdd.getReg());

420 };

421

422 int16_t AddOpIdx = -1;

423 int16_t MulOpIdx = -1;

424

425 bool IsUsedOnceL = false;

426 bool IsUsedOnceR = false;

429

430 auto IsRPReductionCandidate = [&]() {

431

432

433 unsigned Opcode = Root.getOpcode();

434 if (Opcode != PPC::XSMADDASP && Opcode != PPC::XSMADDADP)

435 return false;

436

437

438

439 if (IsReassociableFMA(Root, AddOpIdx, MulOpIdx, true)) {

440 assert((MulOpIdx >= 0) && "mul operand index not right!");

441 Register MULRegL = TRI->lookThruSingleUseCopyChain(

443 Register MULRegR = TRI->lookThruSingleUseCopyChain(

445 if (!MULRegL && !MULRegR)

446 return false;

447

448 if (MULRegL && !MULRegR) {

449 MULRegR =

451 IsUsedOnceL = true;

452 } else if (!MULRegL && MULRegR) {

453 MULRegL =

455 IsUsedOnceR = true;

456 } else {

457 IsUsedOnceL = true;

458 IsUsedOnceR = true;

459 }

460

462 return false;

463

464 MULInstrL = MRI->getVRegDef(MULRegL);

465 MULInstrR = MRI->getVRegDef(MULRegR);

466 return true;

467 }

468 return false;

469 };

470

471

472 if (DoRegPressureReduce && IsRPReductionCandidate()) {

473 assert((MULInstrL && MULInstrR) && "wrong register preduction candidate!");

474

477 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BCA\n");

479 return true;

480 }

481

482

485 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_BAC\n");

487 return true;

488 }

489 }

490

491

492

493 AddOpIdx = -1;

494 if (!IsReassociableFMA(Root, AddOpIdx, MulOpIdx, false))

495 return false;

496

497 assert((AddOpIdx >= 0) && "add operand index not right!");

498

501

502

503 AddOpIdx = -1;

504 if (!IsReassociableFMA(*Prev, AddOpIdx, MulOpIdx, false))

505 return false;

506

507 assert((AddOpIdx >= 0) && "add operand index not right!");

508

511 AddOpIdx = -1;

512 if (IsReassociableFMA(*Leaf, AddOpIdx, MulOpIdx, true)) {

514 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XMM_AMM_BMM\n");

515 return true;

516 }

519 LLVM_DEBUG(dbgs() << "add pattern REASSOC_XY_AMM_BMM\n");

520 return true;

521 }

522 return false;

523}

524

528 assert(!InsInstrs.empty() && "Instructions set to be inserted is empty!");

529

534

535 int16_t Idx = getFMAOpIdxInfo(Root.getOpcode());

536 if (Idx < 0)

537 return;

538

540

541

542

546 ConstReg =

548 break;

550 ConstReg =

552 break;

553 default:

554

555 return;

556 }

557

559

562

563

568

569

571

573

574 for (auto *Inst : InsInstrs) {

575 for (MachineOperand &Operand : Inst->explicit_operands()) {

576 assert(Operand.isReg() && "Invalid instruction in InsInstrs!");

577 if (Operand.getReg() == PPC::ZERO8) {

578 Placeholder = &Operand;

579 break;

580 }

581 }

582 }

583

584 assert(Placeholder && "Placeholder does not exist!");

585

586

587

589 generateLoadForNewConst(ConstPoolIdx, &Root, C->getType(), InsInstrs);

590

591

592 Placeholder->setReg(LoadNewConst);

593}

594

597

599 return false;

600

601

602

603

604

605

606

607

608

609

610

611

612

613 if (!(Subtarget.isPPC64() && Subtarget.hasP9Vector() &&

614 Subtarget.getTargetMachine().getCodeModel() == CodeModel::Medium))

615 return false;

616

620

621 auto GetMBBPressure =

625

626

627 RPTracker.init(MBB->getParent(), RegClassInfo, nullptr, MBB, MBB->end(),

628 false, true);

629

631 if (MI.isDebugValue() || MI.isDebugLabel())

632 continue;

636 assert(&*RPTracker.getPos() == &MI && "RPTracker sync error!");

637 RPTracker.recede(RegOpers);

638 }

639

640

642

644 };

645

646

647 unsigned VSSRCLimit =

649

650

651 return GetMBBPressure(MBB)[PPC::RegisterPressureSets::VSSRC] >

653}

654

656

657 if (I->hasOneMemOperand())

658 return false;

659

661 return Op->isLoad() && Op->getPseudoValue() &&

663}

664

665Register PPCInstrInfo::generateLoadForNewConst(

668

669

670

671 assert((Subtarget.isPPC64() && Subtarget.hasP9Vector() &&

673 "Target not supported!\n");

674

677

678

679 Register VReg1 = MRI->createVirtualRegister(&PPC::G8RC_and_G8RC_NOX0RegClass);

681 BuildMI(*MF, MI->getDebugLoc(), get(PPC::ADDIStocHA8), VReg1)

684

685 assert((Ty->isFloatTy() || Ty->isDoubleTy()) &&

686 "Only float and double are supported!");

687

688 unsigned LoadOpcode;

689

690 if (Ty->isFloatTy())

691 LoadOpcode = PPC::DFLOADf32;

692 else

693 LoadOpcode = PPC::DFLOADf64;

694

696 Register VReg2 = MRI->createVirtualRegister(RC);

700

701

703 BuildMI(*MF, MI->getDebugLoc(), get(LoadOpcode), VReg2)

707

709

710

711 InsInstrs.insert(InsInstrs.begin(), Load);

712 InsInstrs.insert(InsInstrs.begin(), TOCOffset);

713 return VReg2;

714}

715

716

717

723 assert(I->mayLoad() && "Should be a load instruction.\n");

724 for (auto MO : I->uses()) {

725 if (!MO.isReg())

726 continue;

728 if (Reg == 0 || !Reg.isVirtual())

729 continue;

730

732 for (auto MO2 : DefMI->uses())

733 if (MO2.isCPI())

734 return (MCP->getConstants())[MO2.getIndex()].Val.ConstVal;

735 }

736 return nullptr;

737}

738

751

754 bool DoRegPressureReduce) const {

755

756

758 return false;

759

760 if (getFMAPatterns(Root, Patterns, DoRegPressureReduce))

761 return true;

762

764 DoRegPressureReduce);

765}

766

777 reassociateFMA(Root, Pattern, InsInstrs, DelInstrs, InstrIdxForVirtReg);

778 break;

779 default:

780

782 DelInstrs, InstrIdxForVirtReg);

783 break;

784 }

785}

786

787void PPCInstrInfo::reassociateFMA(

798 MRI.constrainRegClass(RegC, RC);

799

800 unsigned FmaOp = Root.getOpcode();

801 int16_t Idx = getFMAOpIdxInfo(FmaOp);

802 assert(Idx >= 0 && "Root must be a FMA instruction");

803

804 bool IsILPReassociate =

807

810

814 default:

820 break;

824 Leaf = MRI.getVRegDef(MULReg);

825 break;

826 }

830 Leaf = MRI.getVRegDef(MULReg);

831 break;

832 }

833 }

834

835 uint32_t IntersectedFlags = 0;

836 if (IsILPReassociate)

838 else

840

841 auto GetOperandInfo = [&](const MachineOperand &Operand, Register &Reg,

842 bool &KillFlag) {

844 MRI.constrainRegClass(Reg, RC);

845 KillFlag = Operand.isKill();

846 };

847

848 auto GetFMAInstrInfo = [&](const MachineInstr &Instr, Register &MulOp1,

850 bool &MulOp1KillFlag, bool &MulOp2KillFlag,

851 bool &AddOpKillFlag) {

852 GetOperandInfo(Instr.getOperand(FirstMulOpIdx), MulOp1, MulOp1KillFlag);

853 GetOperandInfo(Instr.getOperand(FirstMulOpIdx + 1), MulOp2, MulOp2KillFlag);

854 GetOperandInfo(Instr.getOperand(AddOpIdx), AddOp, AddOpKillFlag);

855 };

856

857 Register RegM11, RegM12, RegX, RegY, RegM21, RegM22, RegM31, RegM32, RegA11,

858 RegA21, RegB;

859 bool KillX = false, KillY = false, KillM11 = false, KillM12 = false,

860 KillM21 = false, KillM22 = false, KillM31 = false, KillM32 = false,

861 KillA11 = false, KillA21 = false, KillB = false;

862

863 GetFMAInstrInfo(Root, RegM31, RegM32, RegB, KillM31, KillM32, KillB);

864

865 if (IsILPReassociate)

866 GetFMAInstrInfo(*Prev, RegM21, RegM22, RegA21, KillM21, KillM22, KillA21);

867

869 GetFMAInstrInfo(*Leaf, RegM11, RegM12, RegA11, KillM11, KillM12, KillA11);

870 GetOperandInfo(Leaf->getOperand(AddOpIdx), RegX, KillX);

872 GetOperandInfo(Leaf->getOperand(1), RegX, KillX);

873 GetOperandInfo(Leaf->getOperand(2), RegY, KillY);

874 } else {

875

876 GetOperandInfo(Leaf->getOperand(1), RegX, KillX);

877 GetOperandInfo(Leaf->getOperand(2), RegY, KillY);

878 }

879

880

881

882

883

884

885

886 Register NewVRA = MRI.createVirtualRegister(RC);

887 InstrIdxForVirtReg.insert(std::make_pair(NewVRA, 0));

888

890 if (IsILPReassociate) {

891 NewVRB = MRI.createVirtualRegister(RC);

892 InstrIdxForVirtReg.insert(std::make_pair(NewVRB, 1));

893 }

894

897 NewVRD = MRI.createVirtualRegister(RC);

898 InstrIdxForVirtReg.insert(std::make_pair(NewVRD, 2));

899 }

900

901 auto AdjustOperandOrder = [&](MachineInstr *MI, Register RegAdd, bool KillAdd,

902 Register RegMul1, bool KillRegMul1,

903 Register RegMul2, bool KillRegMul2) {

904 MI->getOperand(AddOpIdx).setReg(RegAdd);

905 MI->getOperand(AddOpIdx).setIsKill(KillAdd);

906 MI->getOperand(FirstMulOpIdx).setReg(RegMul1);

907 MI->getOperand(FirstMulOpIdx).setIsKill(KillRegMul1);

908 MI->getOperand(FirstMulOpIdx + 1).setReg(RegMul2);

909 MI->getOperand(FirstMulOpIdx + 1).setIsKill(KillRegMul2);

910 };

911

912 MachineInstrBuilder NewARegPressure, NewCRegPressure;

913 switch (Pattern) {

914 default:

917

918 MachineInstrBuilder MINewB =

923 MachineInstrBuilder MINewA =

928

929 if (AddOpIdx != 1) {

930 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);

931 AdjustOperandOrder(MINewA, RegY, KillY, RegM31, KillM31, RegM32, KillM32);

932 }

933

934 MachineInstrBuilder MINewC =

939

940

944

945

949 break;

950 }

952 assert(NewVRD && "new FMA register not created!");

953

954 MachineInstrBuilder MINewA =

959 MachineInstrBuilder MINewB =

964 MachineInstrBuilder MINewD =

969

970 if (AddOpIdx != 1) {

971 AdjustOperandOrder(MINewB, RegX, KillX, RegM21, KillM21, RegM22, KillM22);

972 AdjustOperandOrder(MINewD, NewVRA, true, RegM31, KillM31, RegM32,

973 KillM32);

974 }

975

976 MachineInstrBuilder MINewC =

981

982

987

988

993 break;

994 }

998 bool KillVarReg = false;

1000 VarReg = RegM31;

1001 KillVarReg = KillM31;

1002 } else {

1003 VarReg = RegM32;

1004 KillVarReg = KillM32;

1005 }

1006

1007

1008

1009

1010

1011

1015 .addReg(PPC::ZERO8);

1020

1021

1022

1023

1024 break;

1025 }

1026 }

1027

1028 if (!IsILPReassociate) {

1031

1032 InsInstrs.push_back(NewARegPressure);

1033 InsInstrs.push_back(NewCRegPressure);

1034 }

1035

1037 "Insertion instructions set should not be empty!");

1038

1039

1041 if (IsILPReassociate)

1044}

1045

1046

1049 unsigned &SubIdx) const {

1050 switch (MI.getOpcode()) {

1051 default: return false;

1052 case PPC::EXTSW:

1053 case PPC::EXTSW_32:

1054 case PPC::EXTSW_32_64:

1055 SrcReg = MI.getOperand(1).getReg();

1056 DstReg = MI.getOperand(0).getReg();

1057 SubIdx = PPC::sub_32;

1058 return true;

1059 }

1060}

1061

1063 int &FrameIndex) const {

1065

1066

1067 if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() &&

1068 MI.getOperand(2).isFI()) {

1069 FrameIndex = MI.getOperand(2).getIndex();

1070 return MI.getOperand(0).getReg();

1071 }

1072 }

1073 return 0;

1074}

1075

1076

1077

1080 switch (MI.getOpcode()) {

1081 default:

1082

1083 break;

1084 case PPC::LI:

1085 case PPC::LI8:

1086 case PPC::PLI:

1087 case PPC::PLI8:

1088 case PPC::LIS:

1089 case PPC::LIS8:

1090 case PPC::ADDIStocHA:

1091 case PPC::ADDIStocHA8:

1092 case PPC::ADDItocL:

1093 case PPC::ADDItocL8:

1094 case PPC::LOAD_STACK_GUARD:

1095 case PPC::PPCLdFixedAddr:

1096 case PPC::XXLXORz:

1097 case PPC::XXLXORspz:

1098 case PPC::XXLXORdpz:

1099 case PPC::XXLEQVOnes:

1100 case PPC::XXSPLTI32DX:

1101 case PPC::XXSPLTIW:

1102 case PPC::XXSPLTIDP:

1103 case PPC::V_SET0B:

1104 case PPC::V_SET0H:

1105 case PPC::V_SET0:

1106 case PPC::V_SETALLONESB:

1107 case PPC::V_SETALLONESH:

1108 case PPC::V_SETALLONES:

1109 case PPC::CRSET:

1110 case PPC::CRUNSET:

1111 case PPC::XXSETACCZ:

1112 case PPC::DMXXSETACCZ:

1113 return true;

1114 }

1116}

1117

1119 int &FrameIndex) const {

1121 if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() &&

1122 MI.getOperand(2).isFI()) {

1123 FrameIndex = MI.getOperand(2).getIndex();

1124 return MI.getOperand(0).getReg();

1125 }

1126 }

1127 return 0;

1128}

1129

1131 unsigned OpIdx1,

1132 unsigned OpIdx2) const {

1134

1135

1136 if (MI.getOpcode() != PPC::RLWIMI && MI.getOpcode() != PPC::RLWIMI_rec)

1138

1139

1140

1141

1142

1143

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

1145 return nullptr;

1146

1147

1148

1149

1150

1151

1152

1153

1154

1155 assert(((OpIdx1 == 1 && OpIdx2 == 2) || (OpIdx1 == 2 && OpIdx2 == 1)) &&

1156 "Only the operands 1 and 2 can be swapped in RLSIMI/RLWIMI_rec.");

1157 Register Reg0 = MI.getOperand(0).getReg();

1158 Register Reg1 = MI.getOperand(1).getReg();

1159 Register Reg2 = MI.getOperand(2).getReg();

1160 unsigned SubReg1 = MI.getOperand(1).getSubReg();

1161 unsigned SubReg2 = MI.getOperand(2).getSubReg();

1162 bool Reg1IsKill = MI.getOperand(1).isKill();

1163 bool Reg2IsKill = MI.getOperand(2).isKill();

1164 bool ChangeReg0 = false;

1165

1166

1167 if (Reg0 == Reg1) {

1168

1170 "Expecting a two-address instruction!");

1171 assert(MI.getOperand(0).getSubReg() == SubReg1 && "Tied subreg mismatch");

1172 Reg2IsKill = false;

1173 ChangeReg0 = true;

1174 }

1175

1176

1177 unsigned MB = MI.getOperand(4).getImm();

1178 unsigned ME = MI.getOperand(5).getImm();

1179

1180

1181

1182 if (MB == 0 && ME == 31)

1183 return nullptr;

1184

1185 if (NewMI) {

1186

1187 Register Reg0 = ChangeReg0 ? Reg2 : MI.getOperand(0).getReg();

1188 bool Reg0IsDead = MI.getOperand(0).isDead();

1189 return BuildMI(MF, MI.getDebugLoc(), MI.getDesc())

1193 .addImm((ME + 1) & 31)

1194 .addImm((MB - 1) & 31);

1195 }

1196

1197 if (ChangeReg0) {

1198 MI.getOperand(0).setReg(Reg2);

1199 MI.getOperand(0).setSubReg(SubReg2);

1200 }

1201 MI.getOperand(2).setReg(Reg1);

1202 MI.getOperand(1).setReg(Reg2);

1203 MI.getOperand(2).setSubReg(SubReg1);

1204 MI.getOperand(1).setSubReg(SubReg2);

1205 MI.getOperand(2).setIsKill(Reg1IsKill);

1206 MI.getOperand(1).setIsKill(Reg2IsKill);

1207

1208

1209 MI.getOperand(4).setImm((ME + 1) & 31);

1210 MI.getOperand(5).setImm((MB - 1) & 31);

1211 return &MI;

1212}

1213

1215 unsigned &SrcOpIdx1,

1216 unsigned &SrcOpIdx2) const {

1217

1218

1219

1220

1222 if (AltOpc == -1)

1224

1225

1226

1227 return fixCommutedOpIndices(SrcOpIdx1, SrcOpIdx2, 2, 3);

1228}

1229

1232

1233

1234 unsigned Directive = Subtarget.getCPUDirective();

1235 unsigned Opcode;

1237 default: Opcode = PPC::NOP; break;

1238 case PPC::DIR_PWR6: Opcode = PPC::NOP_GT_PWR6; break;

1239 case PPC::DIR_PWR7: Opcode = PPC::NOP_GT_PWR7; break;

1240 case PPC::DIR_PWR8: Opcode = PPC::NOP_GT_PWR7; break;

1241

1242 case PPC::DIR_PWR9: Opcode = PPC::NOP_GT_PWR7; break;

1243 }

1244

1247}

1248

1249

1255

1256

1257

1258

1263 bool AllowModify) const {

1264 bool isPPC64 = Subtarget.isPPC64();

1265

1266

1268 if (I == MBB.end())

1269 return false;

1270

1271 if (!isUnpredicatedTerminator(*I))

1272 return false;

1273

1274 if (AllowModify) {

1275

1276

1277 if (I->getOpcode() == PPC::B &&

1278 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {

1279 I->eraseFromParent();

1280

1281

1282 I = MBB.getLastNonDebugInstr();

1283 if (I == MBB.end() || !isUnpredicatedTerminator(*I))

1284 return false;

1285 }

1286 }

1287

1288

1290

1291

1292 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {

1293 if (LastInst.getOpcode() == PPC::B) {

1295 return true;

1297 return false;

1298 } else if (LastInst.getOpcode() == PPC::BCC) {

1300 return true;

1301

1305 return false;

1306 } else if (LastInst.getOpcode() == PPC::BC) {

1308 return true;

1309

1313 return false;

1314 } else if (LastInst.getOpcode() == PPC::BCn) {

1316 return true;

1317

1321 return false;

1322 } else if (LastInst.getOpcode() == PPC::BDNZ8 ||

1323 LastInst.getOpcode() == PPC::BDNZ) {

1325 return true;

1327 return true;

1331 true));

1332 return false;

1333 } else if (LastInst.getOpcode() == PPC::BDZ8 ||

1334 LastInst.getOpcode() == PPC::BDZ) {

1336 return true;

1338 return true;

1342 true));

1343 return false;

1344 }

1345

1346

1347 return true;

1348 }

1349

1350

1352

1353

1354 if (I != MBB.begin() && isUnpredicatedTerminator(*--I))

1355 return true;

1356

1357

1358 if (SecondLastInst.getOpcode() == PPC::BCC &&

1359 LastInst.getOpcode() == PPC::B) {

1362 return true;

1367 return false;

1368 } else if (SecondLastInst.getOpcode() == PPC::BC &&

1369 LastInst.getOpcode() == PPC::B) {

1372 return true;

1377 return false;

1378 } else if (SecondLastInst.getOpcode() == PPC::BCn &&

1379 LastInst.getOpcode() == PPC::B) {

1382 return true;

1387 return false;

1388 } else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||

1389 SecondLastInst.getOpcode() == PPC::BDNZ) &&

1390 LastInst.getOpcode() == PPC::B) {

1393 return true;

1395 return true;

1399 true));

1401 return false;

1402 } else if ((SecondLastInst.getOpcode() == PPC::BDZ8 ||

1403 SecondLastInst.getOpcode() == PPC::BDZ) &&

1404 LastInst.getOpcode() == PPC::B) {

1407 return true;

1409 return true;

1413 true));

1415 return false;

1416 }

1417

1418

1419

1420 if (SecondLastInst.getOpcode() == PPC::B && LastInst.getOpcode() == PPC::B) {

1422 return true;

1424 I = LastInst;

1425 if (AllowModify)

1426 I->eraseFromParent();

1427 return false;

1428 }

1429

1430

1431 return true;

1432}

1433

1435 int *BytesRemoved) const {

1436 assert(!BytesRemoved && "code size not handled");

1437

1439 if (I == MBB.end())

1440 return 0;

1441

1442 if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC &&

1443 I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&

1444 I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&

1445 I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ)

1446 return 0;

1447

1448

1449 I->eraseFromParent();

1450

1451 I = MBB.end();

1452

1453 if (I == MBB.begin()) return 1;

1454 --I;

1455 if (I->getOpcode() != PPC::BCC &&

1456 I->getOpcode() != PPC::BC && I->getOpcode() != PPC::BCn &&

1457 I->getOpcode() != PPC::BDNZ8 && I->getOpcode() != PPC::BDNZ &&

1458 I->getOpcode() != PPC::BDZ8 && I->getOpcode() != PPC::BDZ)

1459 return 1;

1460

1461

1462 I->eraseFromParent();

1463 return 2;

1464}

1465

1471 int *BytesAdded) const {

1472

1473 assert(TBB && "insertBranch must not be told to insert a fallthrough");

1475 "PPC branch conditions have two components!");

1476 assert(!BytesAdded && "code size not handled");

1477

1478 bool isPPC64 = Subtarget.isPPC64();

1479

1480

1481 if (!FBB) {

1482 if (Cond.empty())

1486 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :

1487 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB);

1492 else

1497 return 1;

1498 }

1499

1500

1503 (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ) :

1504 (isPPC64 ? PPC::BDZ8 : PPC::BDZ))).addMBB(TBB);

1509 else

1515 return 2;

1516}

1517

1518

1522 Register FalseReg, int &CondCycles,

1523 int &TrueCycles, int &FalseCycles) const {

1524 if (!Subtarget.hasISEL())

1525 return false;

1526

1527 if (Cond.size() != 2)

1528 return false;

1529

1530

1531

1533 return false;

1534

1535

1536

1538 return false;

1539

1540

1543 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));

1544 if (!RC)

1545 return false;

1546

1547

1548 if (!PPC::GPRCRegClass.hasSubClassEq(RC) &&

1549 !PPC::GPRC_NOR0RegClass.hasSubClassEq(RC) &&

1550 !PPC::G8RCRegClass.hasSubClassEq(RC) &&

1551 !PPC::G8RC_NOX0RegClass.hasSubClassEq(RC))

1552 return false;

1553

1554

1555

1556

1557

1558 CondCycles = 1;

1559 TrueCycles = 1;

1560 FalseCycles = 1;

1561

1562 return true;

1563}

1564

1571 "PPC branch conditions have two components!");

1572

1573

1576 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg));

1577 assert(RC && "TrueReg and FalseReg must have overlapping register classes");

1578

1579 bool Is64Bit = PPC::G8RCRegClass.hasSubClassEq(RC) ||

1580 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC);

1582 PPC::GPRCRegClass.hasSubClassEq(RC) ||

1583 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) &&

1584 "isel is for regular integer GPRs only");

1585

1586 unsigned OpCode = Is64Bit ? PPC::ISEL8 : PPC::ISEL;

1588

1589 unsigned SubIdx = 0;

1590 bool SwapOps = false;

1591 switch (SelectPred) {

1595 SubIdx = PPC::sub_eq; SwapOps = false; break;

1599 SubIdx = PPC::sub_eq; SwapOps = true; break;

1603 SubIdx = PPC::sub_lt; SwapOps = false; break;

1607 SubIdx = PPC::sub_lt; SwapOps = true; break;

1611 SubIdx = PPC::sub_gt; SwapOps = false; break;

1615 SubIdx = PPC::sub_gt; SwapOps = true; break;

1619 SubIdx = PPC::sub_un; SwapOps = false; break;

1623 SubIdx = PPC::sub_un; SwapOps = true; break;

1626 }

1627

1628 Register FirstReg = SwapOps ? FalseReg : TrueReg,

1629 SecondReg = SwapOps ? TrueReg : FalseReg;

1630

1631

1632

1633

1634 if (MRI.getRegClass(FirstReg)->contains(PPC::R0) ||

1635 MRI.getRegClass(FirstReg)->contains(PPC::X0)) {

1637 MRI.getRegClass(FirstReg)->contains(PPC::X0) ?

1638 &PPC::G8RC_NOX0RegClass : &PPC::GPRC_NOR0RegClass;

1639 Register OldFirstReg = FirstReg;

1640 FirstReg = MRI.createVirtualRegister(FirstRC);

1642 .addReg(OldFirstReg);

1643 }

1644

1648}

1649

1651 unsigned Ret = 4;

1652 if (CRBit == PPC::CR0LT || CRBit == PPC::CR1LT ||

1653 CRBit == PPC::CR2LT || CRBit == PPC::CR3LT ||

1654 CRBit == PPC::CR4LT || CRBit == PPC::CR5LT ||

1655 CRBit == PPC::CR6LT || CRBit == PPC::CR7LT)

1656 Ret = 3;

1657 if (CRBit == PPC::CR0GT || CRBit == PPC::CR1GT ||

1658 CRBit == PPC::CR2GT || CRBit == PPC::CR3GT ||

1659 CRBit == PPC::CR4GT || CRBit == PPC::CR5GT ||

1660 CRBit == PPC::CR6GT || CRBit == PPC::CR7GT)

1661 Ret = 2;

1662 if (CRBit == PPC::CR0EQ || CRBit == PPC::CR1EQ ||

1663 CRBit == PPC::CR2EQ || CRBit == PPC::CR3EQ ||

1664 CRBit == PPC::CR4EQ || CRBit == PPC::CR5EQ ||

1665 CRBit == PPC::CR6EQ || CRBit == PPC::CR7EQ)

1666 Ret = 1;

1667 if (CRBit == PPC::CR0UN || CRBit == PPC::CR1UN ||

1668 CRBit == PPC::CR2UN || CRBit == PPC::CR3UN ||

1669 CRBit == PPC::CR4UN || CRBit == PPC::CR5UN ||

1670 CRBit == PPC::CR6UN || CRBit == PPC::CR7UN)

1671 Ret = 0;

1672

1673 assert(Ret != 4 && "Invalid CR bit register");

1674 return Ret;

1675}

1676

1680 Register SrcReg, bool KillSrc,

1681 bool RenamableDest, bool RenamableSrc) const {

1682

1683

1685 if (PPC::F8RCRegClass.contains(DestReg) &&

1686 PPC::VSRCRegClass.contains(SrcReg)) {

1688 TRI->getMatchingSuperReg(DestReg, PPC::sub_64, &PPC::VSRCRegClass);

1689

1692

1693 DestReg = SuperReg;

1694 } else if (PPC::F8RCRegClass.contains(SrcReg) &&

1695 PPC::VSRCRegClass.contains(DestReg)) {

1697 TRI->getMatchingSuperReg(SrcReg, PPC::sub_64, &PPC::VSRCRegClass);

1698

1701

1702 SrcReg = SuperReg;

1703 }

1704

1705

1706 if (PPC::CRBITRCRegClass.contains(SrcReg) &&

1707 PPC::GPRCRegClass.contains(DestReg)) {

1711

1712

1718 return;

1719 } else if (PPC::CRRCRegClass.contains(SrcReg) &&

1720 (PPC::G8RCRegClass.contains(DestReg) ||

1721 PPC::GPRCRegClass.contains(DestReg))) {

1722 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);

1723 unsigned MvCode = Is64Bit ? PPC::MFOCRF8 : PPC::MFOCRF;

1724 unsigned ShCode = Is64Bit ? PPC::RLWINM8 : PPC::RLWINM;

1725 unsigned CRNum = TRI->getEncodingValue(SrcReg);

1728 if (CRNum == 7)

1729 return;

1730

1733 .addImm(CRNum * 4 + 4)

1736 return;

1737 } else if (PPC::G8RCRegClass.contains(SrcReg) &&

1738 PPC::VSFRCRegClass.contains(DestReg)) {

1739 assert(Subtarget.hasDirectMove() &&

1740 "Subtarget doesn't support directmove, don't know how to copy.");

1742 NumGPRtoVSRSpill++;

1744 return;

1745 } else if (PPC::VSFRCRegClass.contains(SrcReg) &&

1746 PPC::G8RCRegClass.contains(DestReg)) {

1747 assert(Subtarget.hasDirectMove() &&

1748 "Subtarget doesn't support directmove, don't know how to copy.");

1751 return;

1752 } else if (PPC::SPERCRegClass.contains(SrcReg) &&

1753 PPC::GPRCRegClass.contains(DestReg)) {

1756 return;

1757 } else if (PPC::GPRCRegClass.contains(SrcReg) &&

1758 PPC::SPERCRegClass.contains(DestReg)) {

1761 return;

1762 } else if ((PPC::G8RCRegClass.contains(DestReg) ||

1763 PPC::GPRCRegClass.contains(DestReg)) &&

1764 SrcReg == PPC::CARRY) {

1765 bool Is64Bit = PPC::G8RCRegClass.contains(DestReg);

1766 BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MFSPR8 : PPC::MFSPR), DestReg)

1769 return;

1770 } else if ((PPC::G8RCRegClass.contains(SrcReg) ||

1771 PPC::GPRCRegClass.contains(SrcReg)) &&

1772 DestReg == PPC::CARRY) {

1773 bool Is64Bit = PPC::G8RCRegClass.contains(SrcReg);

1774 BuildMI(MBB, I, DL, get(Is64Bit ? PPC::MTSPR8 : PPC::MTSPR))

1778 return;

1779 }

1780

1781 unsigned Opc;

1782 if (PPC::GPRCRegClass.contains(DestReg, SrcReg))

1783 Opc = PPC::OR;

1784 else if (PPC::G8RCRegClass.contains(DestReg, SrcReg))

1785 Opc = PPC::OR8;

1786 else if (PPC::F4RCRegClass.contains(DestReg, SrcReg))

1787 Opc = PPC::FMR;

1788 else if (PPC::CRRCRegClass.contains(DestReg, SrcReg))

1789 Opc = PPC::MCRF;

1790 else if (PPC::VRRCRegClass.contains(DestReg, SrcReg))

1791 Opc = PPC::VOR;

1792 else if (PPC::VSRCRegClass.contains(DestReg, SrcReg))

1793

1794

1795

1796

1797

1798

1799

1800

1801 Opc = PPC::XXLOR;

1802 else if (PPC::VSFRCRegClass.contains(DestReg, SrcReg) ||

1803 PPC::VSSRCRegClass.contains(DestReg, SrcReg))

1804 Opc = (Subtarget.hasP9Vector()) ? PPC::XSCPSGNDP : PPC::XXLORf;

1805 else if (Subtarget.pairedVectorMemops() &&

1806 PPC::VSRpRCRegClass.contains(DestReg, SrcReg)) {

1807 if (SrcReg > PPC::VSRp15)

1808 SrcReg = PPC::V0 + (SrcReg - PPC::VSRp16) * 2;

1809 else

1810 SrcReg = PPC::VSL0 + (SrcReg - PPC::VSRp0) * 2;

1811 if (DestReg > PPC::VSRp15)

1812 DestReg = PPC::V0 + (DestReg - PPC::VSRp16) * 2;

1813 else

1814 DestReg = PPC::VSL0 + (DestReg - PPC::VSRp0) * 2;

1819 return;

1820 }

1821 else if (PPC::CRBITRCRegClass.contains(DestReg, SrcReg))

1822 Opc = PPC::CROR;

1823 else if (PPC::SPERCRegClass.contains(DestReg, SrcReg))

1824 Opc = PPC::EVOR;

1825 else if ((PPC::ACCRCRegClass.contains(DestReg) ||

1826 PPC::UACCRCRegClass.contains(DestReg)) &&

1827 (PPC::ACCRCRegClass.contains(SrcReg) ||

1828 PPC::UACCRCRegClass.contains(SrcReg))) {

1829

1830

1831

1832

1834 bool DestPrimed = PPC::ACCRCRegClass.contains(DestReg);

1835 bool SrcPrimed = PPC::ACCRCRegClass.contains(SrcReg);

1837 PPC::VSL0 + (SrcReg - (SrcPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;

1839 PPC::VSL0 + (DestReg - (DestPrimed ? PPC::ACC0 : PPC::UACC0)) * 4;

1840 if (SrcPrimed)

1842 for (unsigned Idx = 0; Idx < 4; Idx++)

1844 .addReg(VSLSrcReg + Idx)

1846 if (DestPrimed)

1848 if (SrcPrimed && !KillSrc)

1850 return;

1851 } else if (PPC::G8pRCRegClass.contains(DestReg) &&

1852 PPC::G8pRCRegClass.contains(SrcReg)) {

1853

1854 unsigned DestRegIdx = DestReg - PPC::G8p0;

1855 MCRegister DestRegSub0 = PPC::X0 + 2 * DestRegIdx;

1856 MCRegister DestRegSub1 = PPC::X0 + 2 * DestRegIdx + 1;

1857 unsigned SrcRegIdx = SrcReg - PPC::G8p0;

1858 MCRegister SrcRegSub0 = PPC::X0 + 2 * SrcRegIdx;

1859 MCRegister SrcRegSub1 = PPC::X0 + 2 * SrcRegIdx + 1;

1866 return;

1867 } else if ((PPC::WACCRCRegClass.contains(DestReg) ||

1868 PPC::WACC_HIRCRegClass.contains(DestReg)) &&

1869 (PPC::WACCRCRegClass.contains(SrcReg) ||

1870 PPC::WACC_HIRCRegClass.contains(SrcReg))) {

1871

1872 Opc = PPC::WACCRCRegClass.contains(SrcReg) ? PPC::DMXXEXTFDMR512

1873 : PPC::DMXXEXTFDMR512_HI;

1874

1876 RS.enterBasicBlockEnd(MBB);

1877 RS.backward(std::next(I));

1878

1879 Register TmpReg1 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass, I,

1880 false, 0,

1881 false);

1882

1883 RS.setRegUsed(TmpReg1);

1884 Register TmpReg2 = RS.scavengeRegisterBackwards(PPC::VSRpRCRegClass, I,

1885 false, 0,

1886 false);

1887

1892

1893 Opc = PPC::WACCRCRegClass.contains(DestReg) ? PPC::DMXXINSTDMR512

1894 : PPC::DMXXINSTDMR512_HI;

1895

1899

1900 return;

1901 } else if (PPC::DMRRCRegClass.contains(DestReg) &&

1902 PPC::DMRRCRegClass.contains(SrcReg)) {

1903

1906

1907 return;

1908

1909 } else

1911

1913 if (MCID.getNumOperands() == 3)

1916 else

1918}

1919

1920unsigned PPCInstrInfo::getSpillIndex(const TargetRegisterClass *RC) const {

1922

1923 if (PPC::GPRCRegClass.hasSubClassEq(RC) ||

1924 PPC::GPRC_NOR0RegClass.hasSubClassEq(RC)) {

1926 } else if (PPC::G8RCRegClass.hasSubClassEq(RC) ||

1927 PPC::G8RC_NOX0RegClass.hasSubClassEq(RC)) {

1929 } else if (PPC::F8RCRegClass.hasSubClassEq(RC)) {

1931 } else if (PPC::F4RCRegClass.hasSubClassEq(RC)) {

1933 } else if (PPC::SPERCRegClass.hasSubClassEq(RC)) {

1935 } else if (PPC::CRRCRegClass.hasSubClassEq(RC)) {

1937 } else if (PPC::CRBITRCRegClass.hasSubClassEq(RC)) {

1939 } else if (PPC::VRRCRegClass.hasSubClassEq(RC)) {

1941 } else if (PPC::VSRCRegClass.hasSubClassEq(RC)) {

1943 } else if (PPC::VSFRCRegClass.hasSubClassEq(RC)) {

1945 } else if (PPC::VSSRCRegClass.hasSubClassEq(RC)) {

1947 } else if (PPC::SPILLTOVSRRCRegClass.hasSubClassEq(RC)) {

1949 } else if (PPC::ACCRCRegClass.hasSubClassEq(RC)) {

1950 assert(Subtarget.pairedVectorMemops() &&

1951 "Register unexpected when paired memops are disabled.");

1953 } else if (PPC::UACCRCRegClass.hasSubClassEq(RC)) {

1954 assert(Subtarget.pairedVectorMemops() &&

1955 "Register unexpected when paired memops are disabled.");

1957 } else if (PPC::WACCRCRegClass.hasSubClassEq(RC)) {

1958 assert(Subtarget.pairedVectorMemops() &&

1959 "Register unexpected when paired memops are disabled.");

1961 } else if (PPC::VSRpRCRegClass.hasSubClassEq(RC)) {

1962 assert(Subtarget.pairedVectorMemops() &&

1963 "Register unexpected when paired memops are disabled.");

1965 } else if (PPC::G8pRCRegClass.hasSubClassEq(RC)) {

1967 } else if (PPC::DMRROWRCRegClass.hasSubClassEq(RC)) {

1969 } else if (PPC::DMRROWpRCRegClass.hasSubClassEq(RC)) {

1970 llvm_unreachable("TODO: Implement spill DMRROWp regclass!");

1971 } else if (PPC::DMRpRCRegClass.hasSubClassEq(RC)) {

1973 } else if (PPC::DMRRCRegClass.hasSubClassEq(RC)) {

1975 } else {

1977 }

1979}

1980

1981unsigned

1983 ArrayRef OpcodesForSpill = getStoreOpcodesForSpillArray();

1984 return OpcodesForSpill[getSpillIndex(RC)];

1985}

1986

1987unsigned

1990 return OpcodesForSpill[getSpillIndex(RC)];

1991}

1992

1993void PPCInstrInfo::StoreRegToStackSlot(

1994 MachineFunction &MF, unsigned SrcReg, bool isKill, int FrameIdx,

1999

2002

2005 FrameIdx));

2006

2007 if (PPC::CRRCRegClass.hasSubClassEq(RC) ||

2008 PPC::CRBITRCRegClass.hasSubClassEq(RC))

2010

2013}

2014

2020

2021 StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs);

2022

2024 MBB.insert(MI, NewMI);

2025

2031 NewMIs.back()->addMemOperand(MF, MMO);

2032}

2033

2038

2039

2040

2041

2042

2043

2044

2047}

2048

2050 unsigned DestReg, int FrameIdx,

2053 const {

2056 FrameIdx));

2057}

2058

2065 if (MI != MBB.end()) DL = MI->getDebugLoc();

2066

2067 LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs);

2068

2070 MBB.insert(MI, NewMI);

2071

2077 NewMIs.back()->addMemOperand(MF, MMO);

2078}

2079

2082 Register DestReg, int FrameIdx,

2086

2087

2088

2089

2090

2091

2092

2094

2096}

2097

2100 assert(Cond.size() == 2 && "Invalid PPC branch opcode!");

2103 else

2104

2106 return false;

2107}

2108

2109

2110

2111

2114

2115 unsigned DefOpc = DefMI.getOpcode();

2116 if (DefOpc != PPC::LI && DefOpc != PPC::LI8)

2117 return false;

2118 if (DefMI.getOperand(1).isImm())

2119 return false;

2120 if (DefMI.getOperand(1).getImm() != 0)

2121 return false;

2122

2123

2124

2125

2126

2128

2129

2131 return false;

2132

2133

2134

2135 unsigned UseIdx;

2136 for (UseIdx = 0; UseIdx < UseMI.getNumOperands(); ++UseIdx)

2137 if (UseMI.getOperand(UseIdx).isReg() &&

2138 UseMI.getOperand(UseIdx).getReg() == Reg)

2139 break;

2140

2141 assert(UseIdx < UseMI.getNumOperands() && "Cannot find Reg in UseMI");

2142 assert(UseIdx < UseMCID.getNumOperands() && "No operand description for Reg");

2143

2144

2145

2146

2148 int16_t RegClass = getOpRegClassID(UseInfo);

2149 if (UseInfo.RegClass != PPC::GPRC_NOR0RegClassID &&

2150 UseInfo.RegClass != PPC::G8RC_NOX0RegClassID)

2151 return false;

2152

2153

2154

2155

2156 if (UseInfo.Constraints != 0)

2157 return false;

2158

2160 RegClass == PPC::G8RC_NOX0RegClassID ? PPC::ZERO8 : PPC::ZERO;

2161

2162 LLVM_DEBUG(dbgs() << "Folded immediate zero for: ");

2164 UseMI.getOperand(UseIdx).setReg(ZeroReg);

2167 return true;

2168}

2169

2170

2171

2172

2176 if (MRI->use_nodbg_empty(Reg))

2177 DefMI.eraseFromParent();

2179}

2180

2183 if (MI.definesRegister(PPC::CTR, nullptr) ||

2184 MI.definesRegister(PPC::CTR8, nullptr))

2185 return true;

2186 return false;

2187}

2188

2189

2190

2191

2192

2193

2194

2196 unsigned NumT, unsigned ExtraT,

2198 unsigned NumF, unsigned ExtraF,

2201}

2202

2203

2205

2206

2207

2208

2209

2210

2211

2212 return false;

2213}

2214

2218 switch (MI.getOpcode()) {

2219 default:

2220 break;

2221

2222

2223

2224 case PPC::MFFS:

2225 case PPC::MTFSF:

2226 case PPC::FENCE:

2227 return true;

2228 }

2230}

2231

2234 unsigned OpC = MI.getOpcode();

2235 if (OpC == PPC::BLR || OpC == PPC::BLR8) {

2236 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {

2237 bool isPPC64 = Subtarget.isPPC64();

2238 MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZLR8 : PPC::BDNZLR)

2239 : (isPPC64 ? PPC::BDZLR8 : PPC::BDZLR)));

2240

2245 MI.setDesc(get(PPC::BCLR));

2248 MI.setDesc(get(PPC::BCLRn));

2250 } else {

2251 MI.setDesc(get(PPC::BCCLR));

2254 .add(Pred[1]);

2255 }

2256

2257 return true;

2258 } else if (OpC == PPC::B) {

2259 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR) {

2260 bool isPPC64 = Subtarget.isPPC64();

2261 MI.setDesc(get(Pred[0].getImm() ? (isPPC64 ? PPC::BDNZ8 : PPC::BDNZ)

2262 : (isPPC64 ? PPC::BDZ8 : PPC::BDZ)));

2263

2269 MI.removeOperand(0);

2270

2271 MI.setDesc(get(PPC::BC));

2273 .add(Pred[1])

2277 MI.removeOperand(0);

2278

2279 MI.setDesc(get(PPC::BCn));

2281 .add(Pred[1])

2283 } else {

2285 MI.removeOperand(0);

2286

2287 MI.setDesc(get(PPC::BCC));

2290 .add(Pred[1])

2292 }

2293

2294 return true;

2295 } else if (OpC == PPC::BCTR || OpC == PPC::BCTR8 || OpC == PPC::BCTRL ||

2296 OpC == PPC::BCTRL8 || OpC == PPC::BCTRL_RM ||

2297 OpC == PPC::BCTRL8_RM) {

2298 if (Pred[1].getReg() == PPC::CTR8 || Pred[1].getReg() == PPC::CTR)

2299 llvm_unreachable("Cannot predicate bctr[l] on the ctr register");

2300

2301 bool setLR = OpC == PPC::BCTRL || OpC == PPC::BCTRL8 ||

2302 OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM;

2303 bool isPPC64 = Subtarget.isPPC64();

2304

2306 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8 : PPC::BCCTR8)

2307 : (setLR ? PPC::BCCTRL : PPC::BCCTR)));

2310 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCTRL8n : PPC::BCCTR8n)

2311 : (setLR ? PPC::BCCTRLn : PPC::BCCTRn)));

2313 } else {

2314 MI.setDesc(get(isPPC64 ? (setLR ? PPC::BCCCTRL8 : PPC::BCCCTR8)

2315 : (setLR ? PPC::BCCCTRL : PPC::BCCCTR)));

2318 .add(Pred[1]);

2319 }

2320

2321

2322 if (setLR)

2326 if (OpC == PPC::BCTRL_RM || OpC == PPC::BCTRL8_RM)

2329

2330 return true;

2331 }

2332

2333 return false;

2334}

2335

2338 assert(Pred1.size() == 2 && "Invalid PPC first predicate");

2339 assert(Pred2.size() == 2 && "Invalid PPC second predicate");

2340

2341 if (Pred1[1].getReg() == PPC::CTR8 || Pred1[1].getReg() == PPC::CTR)

2342 return false;

2343 if (Pred2[1].getReg() == PPC::CTR8 || Pred2[1].getReg() == PPC::CTR)

2344 return false;

2345

2346

2348 return false;

2349

2352

2353 if (P1 == P2)

2354 return true;

2355

2356

2359 return true;

2362 return true;

2363

2364 return false;

2365}

2366

2368 std::vector &Pred,

2369 bool SkipDead) const {

2370

2371

2372

2373

2374

2375

2377 { &PPC::CRRCRegClass, &PPC::CRBITRCRegClass,

2378 &PPC::CTRRCRegClass, &PPC::CTRRC8RegClass };

2379

2380 bool Found = false;

2382 for (unsigned c = 0; c < std::size(RCs) && !Found; ++c) {

2384 if (MO.isReg()) {

2385 if (MO.isDef() && RC->contains(MO.getReg())) {

2386 Pred.push_back(MO);

2387 Found = true;

2388 }

2389 } else if (MO.isRegMask()) {

2391 if (MO.clobbersPhysReg(R)) {

2392 Pred.push_back(MO);

2393 Found = true;

2394 }

2395 }

2396 }

2397 }

2398

2399 return Found;

2400}

2401

2403 Register &SrcReg2, int64_t &Mask,

2404 int64_t &Value) const {

2405 unsigned Opc = MI.getOpcode();

2406

2407 switch (Opc) {

2408 default: return false;

2409 case PPC::CMPWI:

2410 case PPC::CMPLWI:

2411 case PPC::CMPDI:

2412 case PPC::CMPLDI:

2413 SrcReg = MI.getOperand(1).getReg();

2414 SrcReg2 = 0;

2415 Value = MI.getOperand(2).getImm();

2416 Mask = 0xFFFF;

2417 return true;

2418 case PPC::CMPW:

2419 case PPC::CMPLW:

2420 case PPC::CMPD:

2421 case PPC::CMPLD:

2422 case PPC::FCMPUS:

2423 case PPC::FCMPUD:

2424 SrcReg = MI.getOperand(1).getReg();

2425 SrcReg2 = MI.getOperand(2).getReg();

2427 Mask = 0;

2428 return true;

2429 }

2430}

2431

2433 Register SrcReg2, int64_t Mask,

2437 return false;

2438

2441

2442

2443

2444 if (OpC == PPC::FCMPUS || OpC == PPC::FCMPUD)

2445 return false;

2446

2448

2449

2450

2451

2452

2453

2454

2455

2456 bool isPPC64 = Subtarget.isPPC64();

2457 bool is32BitSignedCompare = OpC == PPC::CMPWI || OpC == PPC::CMPW;

2458 bool is32BitUnsignedCompare = OpC == PPC::CMPLWI || OpC == PPC::CMPLW;

2459 bool is64BitUnsignedCompare = OpC == PPC::CMPLDI || OpC == PPC::CMPLD;

2460

2461

2462 Register ActualSrc = TRI->lookThruCopyLike(SrcReg, MRI);

2464 SrcReg = ActualSrc;

2465

2466

2468 if (MI) return false;

2469

2470 bool equalityOnly = false;

2471 bool noSub = false;

2472 if (isPPC64) {

2473 if (is32BitSignedCompare) {

2474

2476 noSub = true;

2477 else

2478 return false;

2479 } else if (is32BitUnsignedCompare) {

2480

2481

2483 noSub = true;

2484 equalityOnly = true;

2485 } else

2486 return false;

2487 } else

2488 equalityOnly = is64BitUnsignedCompare;

2489 } else

2490 equalityOnly = is32BitUnsignedCompare;

2491

2492 if (equalityOnly) {

2493

2494

2496 I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();

2497 I != IE; ++I) {

2499 if (UseMI->getOpcode() == PPC::BCC) {

2502

2504 return false;

2505 } else if (UseMI->getOpcode() == PPC::ISEL ||

2506 UseMI->getOpcode() == PPC::ISEL8) {

2507 unsigned SubIdx = UseMI->getOperand(3).getSubReg();

2508 if (SubIdx != PPC::sub_eq)

2509 return false;

2510 } else

2511 return false;

2512 }

2513 }

2514

2516

2517

2519 ++I) {

2520 bool FoundUse = false;

2522 J = MRI->use_instr_begin(CRReg), JE = MRI->use_instr_end();

2523 J != JE; ++J)

2524 if (&*J == &*I) {

2525 FoundUse = true;

2526 break;

2527 }

2528

2529 if (FoundUse)

2530 break;

2531 }

2532

2535

2536

2537

2538

2540 if (SrcReg2 != 0)

2541

2542 MI = nullptr;

2543

2544

2545

2546

2547 else if (MI->getParent() != CmpInstr.getParent())

2548 return false;

2549 else if (Value != 0) {

2550

2551

2552

2553

2554

2555

2556

2557

2558 if (equalityOnly || MRI->hasOneUse(CRReg))

2559 return false;

2560

2562 if (UseMI->getOpcode() != PPC::BCC)

2563 return false;

2564

2568 int16_t Immed = (int16_t)Value;

2569

2570

2571

2572 if (Immed == -1 && PredCond == PPC::PRED_GT)

2573

2574

2576 else if (Immed == -1 && PredCond == PPC::PRED_LE)

2577

2579 else if (Immed == 1 && PredCond == PPC::PRED_LT)

2580

2582 else if (Immed == 1 && PredCond == PPC::PRED_GE)

2583

2585 else

2586 return false;

2587

2588

2589

2590

2591

2592 UseMI->getOperand(0).setImm(Pred);

2594 }

2595

2596

2597 --I;

2598

2599

2601

2602 for (; I != E && !noSub; --I) {

2604 unsigned IOpC = Instr.getOpcode();

2605

2606 if (&*I != &CmpInstr && (Instr.modifiesRegister(PPC::CR0, TRI) ||

2607 Instr.readsRegister(PPC::CR0, TRI)))

2608

2609

2610

2611

2612

2613 return false;

2614

2615

2616 if ((OpC == PPC::CMPW || OpC == PPC::CMPLW ||

2617 OpC == PPC::CMPD || OpC == PPC::CMPLD) &&

2618 (IOpC == PPC::SUBF || IOpC == PPC::SUBF8) &&

2619 ((Instr.getOperand(1).getReg() == SrcReg &&

2620 Instr.getOperand(2).getReg() == SrcReg2) ||

2621 (Instr.getOperand(1).getReg() == SrcReg2 &&

2622 Instr.getOperand(2).getReg() == SrcReg))) {

2624 break;

2625 }

2626

2627 if (I == B)

2628

2629 return false;

2630 }

2631

2632

2633 if (MI && Sub)

2634 return false;

2635

2636

2638

2639 int NewOpC = -1;

2640 int MIOpC = MI->getOpcode();

2641 if (MIOpC == PPC::ANDI_rec || MIOpC == PPC::ANDI8_rec ||

2642 MIOpC == PPC::ANDIS_rec || MIOpC == PPC::ANDIS8_rec)

2643 NewOpC = MIOpC;

2644 else {

2645 NewOpC = PPC::getRecordFormOpcode(MIOpC);

2647 NewOpC = MIOpC;

2648 }

2649

2650

2651

2652

2653

2654

2655

2656 if (NewOpC == -1)

2657 return false;

2658

2659

2660

2661

2662

2663 if (!equalityOnly && (NewOpC == PPC::SUBF_rec || NewOpC == PPC::SUBF8_rec) &&

2665 return false;

2666

2667

2668

2669

2670

2671

2672

2673 bool ShouldSwap = false;

2675 ShouldSwap = SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&

2676 Sub->getOperand(2).getReg() == SrcReg;

2677

2678

2679

2680 ShouldSwap = !ShouldSwap;

2681 }

2682

2683 if (ShouldSwap)

2685 I = MRI->use_instr_begin(CRReg), IE = MRI->use_instr_end();

2686 I != IE; ++I) {

2688 if (UseMI->getOpcode() == PPC::BCC) {

2691 assert((!equalityOnly ||

2693 "Invalid predicate for equality-only optimization");

2694 (void)PredCond;

2695 PredsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(0)),

2697 } else if (UseMI->getOpcode() == PPC::ISEL ||

2698 UseMI->getOpcode() == PPC::ISEL8) {

2699 unsigned NewSubReg = UseMI->getOperand(3).getSubReg();

2700 assert((!equalityOnly || NewSubReg == PPC::sub_eq) &&

2701 "Invalid CR bit for equality-only optimization");

2702

2703 if (NewSubReg == PPC::sub_lt)

2704 NewSubReg = PPC::sub_gt;

2705 else if (NewSubReg == PPC::sub_gt)

2706 NewSubReg = PPC::sub_lt;

2707

2708 SubRegsToUpdate.push_back(std::make_pair(&(UseMI->getOperand(3)),

2709 NewSubReg));

2710 } else

2711 return false;

2712 }

2714 "Non-zero immediate support and ShouldSwap"

2715 "may conflict in updating predicate");

2716

2717

2718

2719

2721

2723 BuildMI(*MI->getParent(), std::next(MII), MI->getDebugLoc(),

2724 get(TargetOpcode::COPY), CRReg)

2726

2727

2728

2729 MI->clearRegisterDeads(PPC::CR0);

2730

2731 if (MIOpC != NewOpC) {

2732

2733

2734

2735

2736

2737

2738

2739

2740

2741 if (MIOpC == PPC::RLWINM || MIOpC == PPC::RLWINM8) {

2742 Register GPRRes = MI->getOperand(0).getReg();

2743 int64_t SH = MI->getOperand(2).getImm();

2744 int64_t MB = MI->getOperand(3).getImm();

2745 int64_t ME = MI->getOperand(4).getImm();

2746

2747

2748 bool MBInLoHWord = MB >= 16;

2749 bool MEInLoHWord = ME >= 16;

2751

2752 if (MB <= ME && MBInLoHWord == MEInLoHWord && SH == 0) {

2753 Mask = ((1LLU << (32 - MB)) - 1) & ~((1LLU << (31 - ME)) - 1);

2754

2755 Mask >>= MBInLoHWord ? 0 : 16;

2756 NewOpC = MIOpC == PPC::RLWINM

2757 ? (MBInLoHWord ? PPC::ANDI_rec : PPC::ANDIS_rec)

2758 : (MBInLoHWord ? PPC::ANDI8_rec : PPC::ANDIS8_rec);

2759 } else if (MRI->use_empty(GPRRes) && (ME == 31) &&

2760 (ME - MB + 1 == SH) && (MB >= 16)) {

2761

2762

2763

2764 Mask = ((1LLU << 32) - 1) & ~((1LLU << (32 - SH)) - 1);

2765 Mask >>= 16;

2766 NewOpC = MIOpC == PPC::RLWINM ? PPC::ANDIS_rec : PPC::ANDIS8_rec;

2767 }

2768

2769 if (Mask != ~0LLU) {

2770 MI->removeOperand(4);

2771 MI->removeOperand(3);

2772 MI->getOperand(2).setImm(Mask);

2773 NumRcRotatesConvertedToRcAnd++;

2774 }

2775 } else if (MIOpC == PPC::RLDICL && MI->getOperand(2).getImm() == 0) {

2776 int64_t MB = MI->getOperand(3).getImm();

2777 if (MB >= 48) {

2778 uint64_t Mask = (1LLU << (63 - MB + 1)) - 1;

2779 NewOpC = PPC::ANDI8_rec;

2780 MI->removeOperand(3);

2781 MI->getOperand(2).setImm(Mask);

2782 NumRcRotatesConvertedToRcAnd++;

2783 }

2784 }

2785

2787 MI->setDesc(NewDesc);

2788

2790 if (MI->definesRegister(ImpDef, nullptr)) {

2791 MI->addOperand(*MI->getParent()->getParent(),

2793 }

2794 }

2796 if (MI->readsRegister(ImpUse, nullptr)) {

2797 MI->addOperand(*MI->getParent()->getParent(),

2799 }

2800 }

2801 }

2802 assert(MI->definesRegister(PPC::CR0, nullptr) &&

2803 "Record-form instruction does not define cr0?");

2804

2805

2806

2807

2808 for (unsigned i = 0, e = PredsToUpdate.size(); i < e; i++)

2809 PredsToUpdate[i].first->setImm(PredsToUpdate[i].second);

2810

2811 for (unsigned i = 0, e = SubRegsToUpdate.size(); i < e; i++)

2812 SubRegsToUpdate[i].first->setSubReg(SubRegsToUpdate[i].second);

2813

2814 return true;

2815}

2816

2819 if (MRI->isSSA())

2820 return false;

2821

2823 int64_t CmpMask, CmpValue;

2824 if (analyzeCompare(CmpMI, SrcReg, SrcReg2, CmpMask, CmpValue))

2825 return false;

2826

2827

2828 if (CmpValue || !CmpMask || SrcReg2)

2829 return false;

2830

2831

2832

2833

2834

2836 if (Opc == PPC::CMPLWI || Opc == PPC::CMPLDI)

2837 return false;

2838

2839

2840

2841

2842

2843 if (Subtarget.isPPC64() && Opc == PPC::CMPWI)

2844 return false;

2845

2846

2848 return false;

2849

2850 bool SrcRegHasOtherUse = false;

2852 if (!SrcMI || !SrcMI->definesRegister(SrcReg, nullptr))

2853 return false;

2854

2857 if (CRReg != PPC::CR0)

2858 return false;

2859

2860

2861 bool SeenUseOfCRReg = false;

2862 bool IsCRRegKilled = false;

2863 if (!isRegElgibleForForwarding(RegMO, *SrcMI, CmpMI, false, IsCRRegKilled,

2864 SeenUseOfCRReg) ||

2865 SrcMI->definesRegister(CRReg, nullptr) || SeenUseOfCRReg)

2866 return false;

2867

2868 int SrcMIOpc = SrcMI->getOpcode();

2869 int NewOpC = PPC::getRecordFormOpcode(SrcMIOpc);

2870 if (NewOpC == -1)

2871 return false;

2872

2875

2877 SrcMI->setDesc(NewDesc);

2881

2883 "Record-form instruction does not define cr0?");

2884

2889 return true;

2890}

2891

2897 OffsetIsScalable = false;

2899 return false;

2901 return true;

2902}

2903

2906

2908 return false;

2909

2911 return true;

2912

2914

2915

2917 return false;

2918

2919 return true;

2920}

2921

2922

2923

2926 switch (FirstOpc) {

2927 default:

2928 return false;

2929 case PPC::STD:

2930 case PPC::STFD:

2931 case PPC::STXSD:

2932 case PPC::DFSTOREf64:

2933 return FirstOpc == SecondOpc;

2934

2935

2936

2937 case PPC::STW:

2938 case PPC::STW8:

2939 return SecondOpc == PPC::STW || SecondOpc == PPC::STW8;

2940 }

2941}

2942

2946 int64_t OpOffset2, bool OffsetIsScalable2, unsigned ClusterSize,

2947 unsigned NumBytes) const {

2948

2949 assert(BaseOps1.size() == 1 && BaseOps2.size() == 1);

2953 "Only base registers and frame indices are supported.");

2954

2955

2956

2957

2958 if (ClusterSize > 2)

2959 return false;

2960

2961

2962

2963 if ((BaseOp1.isReg() != BaseOp2.isReg()) ||

2966 return false;

2967

2968

2969

2972 unsigned FirstOpc = FirstLdSt.getOpcode();

2973 unsigned SecondOpc = SecondLdSt.getOpcode();

2975

2976

2978 return false;

2979

2980

2983 return false;

2984

2985 int64_t Offset1 = 0, Offset2 = 0;

2988 const MachineOperand *Base1 = nullptr, *Base2 = nullptr;

2991 Width1 != Width2)

2992 return false;

2993

2994 assert(Base1 == &BaseOp1 && Base2 == &BaseOp2 &&

2995 "getMemOperandWithOffsetWidth return incorrect base op");

2996

2997 assert(Offset1 <= Offset2 && "Caller should have ordered offsets.");

2998 return Offset1 + (int64_t)Width1.getValue() == Offset2;

2999}

3000

3001

3002

3003

3005 unsigned Opcode = MI.getOpcode();

3006

3007 if (Opcode == PPC::INLINEASM || Opcode == PPC::INLINEASM_BR) {

3009 const char *AsmStr = MI.getOperand(0).getSymbolName();

3011 } else if (Opcode == TargetOpcode::STACKMAP) {

3014 } else if (Opcode == TargetOpcode::PATCHPOINT) {

3017 } else {

3018 return get(Opcode).getSize();

3019 }

3020}

3021

3022std::pair<unsigned, unsigned>

3024

3025 return std::make_pair(TF, 0u);

3026}

3027

3030 using namespace PPCII;

3031 static const std::pair<unsigned, const char *> TargetFlags[] = {

3032 {MO_PLT, "ppc-plt"},

3033 {MO_PIC_FLAG, "ppc-pic"},

3034 {MO_PCREL_FLAG, "ppc-pcrel"},

3035 {MO_GOT_FLAG, "ppc-got"},

3036 {MO_PCREL_OPT_FLAG, "ppc-opt-pcrel"},

3037 {MO_TLSGD_FLAG, "ppc-tlsgd"},

3038 {MO_TPREL_FLAG, "ppc-tprel"},

3039 {MO_TLSLDM_FLAG, "ppc-tlsldm"},

3040 {MO_TLSLD_FLAG, "ppc-tlsld"},

3041 {MO_TLSGDM_FLAG, "ppc-tlsgdm"},

3042 {MO_GOT_TLSGD_PCREL_FLAG, "ppc-got-tlsgd-pcrel"},

3043 {MO_GOT_TLSLD_PCREL_FLAG, "ppc-got-tlsld-pcrel"},

3044 {MO_GOT_TPREL_PCREL_FLAG, "ppc-got-tprel-pcrel"},

3045 {MO_LO, "ppc-lo"},

3046 {MO_HA, "ppc-ha"},

3047 {MO_TPREL_LO, "ppc-tprel-lo"},

3048 {MO_TPREL_HA, "ppc-tprel-ha"},

3049 {MO_DTPREL_LO, "ppc-dtprel-lo"},

3050 {MO_TLSLD_LO, "ppc-tlsld-lo"},

3051 {MO_TOC_LO, "ppc-toc-lo"},

3052 {MO_TLS, "ppc-tls"},

3053 {MO_PIC_HA_FLAG, "ppc-ha-pic"},

3054 {MO_PIC_LO_FLAG, "ppc-lo-pic"},

3055 {MO_TPREL_PCREL_FLAG, "ppc-tprel-pcrel"},

3056 {MO_TLS_PCREL_FLAG, "ppc-tls-pcrel"},

3057 {MO_GOT_PCREL_FLAG, "ppc-got-pcrel"},

3058 };

3059 return ArrayRef(TargetFlags);

3060}

3061

3062

3063

3064

3065

3066

3067

3069 unsigned UpperOpcode, LowerOpcode;

3070 switch (MI.getOpcode()) {

3071 case PPC::DFLOADf32:

3072 UpperOpcode = PPC::LXSSP;

3073 LowerOpcode = PPC::LFS;

3074 break;

3075 case PPC::DFLOADf64:

3076 UpperOpcode = PPC::LXSD;

3077 LowerOpcode = PPC::LFD;

3078 break;

3079 case PPC::DFSTOREf32:

3080 UpperOpcode = PPC::STXSSP;

3081 LowerOpcode = PPC::STFS;

3082 break;

3083 case PPC::DFSTOREf64:

3084 UpperOpcode = PPC::STXSD;

3085 LowerOpcode = PPC::STFD;

3086 break;

3087 case PPC::XFLOADf32:

3088 UpperOpcode = PPC::LXSSPX;

3089 LowerOpcode = PPC::LFSX;

3090 break;

3091 case PPC::XFLOADf64:

3092 UpperOpcode = PPC::LXSDX;

3093 LowerOpcode = PPC::LFDX;

3094 break;

3095 case PPC::XFSTOREf32:

3096 UpperOpcode = PPC::STXSSPX;

3097 LowerOpcode = PPC::STFSX;

3098 break;

3099 case PPC::XFSTOREf64:

3100 UpperOpcode = PPC::STXSDX;

3101 LowerOpcode = PPC::STFDX;

3102 break;

3103 case PPC::LIWAX:

3104 UpperOpcode = PPC::LXSIWAX;

3105 LowerOpcode = PPC::LFIWAX;

3106 break;

3107 case PPC::LIWZX:

3108 UpperOpcode = PPC::LXSIWZX;

3109 LowerOpcode = PPC::LFIWZX;

3110 break;

3111 case PPC::STIWX:

3112 UpperOpcode = PPC::STXSIWX;

3113 LowerOpcode = PPC::STFIWX;

3114 break;

3115 default:

3117 }

3118

3119 Register TargetReg = MI.getOperand(0).getReg();

3120 unsigned Opcode;

3121 if ((TargetReg >= PPC::F0 && TargetReg <= PPC::F31) ||

3122 (TargetReg >= PPC::VSL0 && TargetReg <= PPC::VSL31))

3123 Opcode = LowerOpcode;

3124 else

3125 Opcode = UpperOpcode;

3126 MI.setDesc(get(Opcode));

3127 return true;

3128}

3129

3133

3135 auto &MBB = *MI.getParent();

3136 auto DL = MI.getDebugLoc();

3137

3138 switch (MI.getOpcode()) {

3139 case PPC::BUILD_UACC: {

3141 MCRegister UACC = MI.getOperand(1).getReg();

3142 if (ACC - PPC::ACC0 != UACC - PPC::UACC0) {

3143 MCRegister SrcVSR = PPC::VSL0 + (UACC - PPC::UACC0) * 4;

3144 MCRegister DstVSR = PPC::VSL0 + (ACC - PPC::ACC0) * 4;

3145

3146

3147

3148 for (int VecNo = 0; VecNo < 4; VecNo++)

3150 .addReg(SrcVSR + VecNo)

3151 .addReg(SrcVSR + VecNo);

3152 }

3153

3154

3155

3156 [[fallthrough]];

3157 }

3158 case PPC::KILL_PAIR: {

3159 MI.setDesc(get(PPC::UNENCODED_NOP));

3160 MI.removeOperand(1);

3161 MI.removeOperand(0);

3162 return true;

3163 }

3164 case TargetOpcode::LOAD_STACK_GUARD: {

3165 auto M = MBB.getParent()->getFunction().getParent();

3167 (Subtarget.isTargetLinux() || M->getStackProtectorGuard() == "tls") &&

3168 "Only Linux target or tls mode are expected to contain "

3169 "LOAD_STACK_GUARD");

3171 if (M->getStackProtectorGuard() == "tls")

3172 Offset = M->getStackProtectorGuardOffset();

3173 else

3174 Offset = Subtarget.isPPC64() ? -0x7010 : -0x7008;

3175 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;

3176 MI.setDesc(get(Subtarget.isPPC64() ? PPC::LD : PPC::LWZ));

3180 return true;

3181 }

3182 case PPC::PPCLdFixedAddr: {

3183 assert((Subtarget.getTargetTriple().isOSGlibc() ||

3184 Subtarget.getTargetTriple().isMusl()) &&

3185 "Only targets with Glibc expected to contain PPCLdFixedAddr");

3187 const unsigned Reg = Subtarget.isPPC64() ? PPC::X13 : PPC::R2;

3188 MI.setDesc(get(PPC::LWZ));

3189 uint64_t FAType = MI.getOperand(1).getImm();

3190#undef PPC_LNX_FEATURE

3191#undef PPC_CPU

3192#define PPC_LNX_DEFINE_OFFSETS

3193#include "llvm/TargetParser/PPCTargetParser.def"

3194 bool IsLE = Subtarget.isLittleEndian();

3195 bool Is64 = Subtarget.isPPC64();

3196 if (FAType == PPC_FAWORD_HWCAP) {

3197 if (IsLE)

3198 Offset = Is64 ? PPC_HWCAP_OFFSET_LE64 : PPC_HWCAP_OFFSET_LE32;

3199 else

3200 Offset = Is64 ? PPC_HWCAP_OFFSET_BE64 : PPC_HWCAP_OFFSET_BE32;

3201 } else if (FAType == PPC_FAWORD_HWCAP2) {

3202 if (IsLE)

3203 Offset = Is64 ? PPC_HWCAP2_OFFSET_LE64 : PPC_HWCAP2_OFFSET_LE32;

3204 else

3205 Offset = Is64 ? PPC_HWCAP2_OFFSET_BE64 : PPC_HWCAP2_OFFSET_BE32;

3206 } else if (FAType == PPC_FAWORD_CPUID) {

3207 if (IsLE)

3208 Offset = Is64 ? PPC_CPUID_OFFSET_LE64 : PPC_CPUID_OFFSET_LE32;

3209 else

3210 Offset = Is64 ? PPC_CPUID_OFFSET_BE64 : PPC_CPUID_OFFSET_BE32;

3211 }

3212 assert(Offset && "Do not know the offset for this fixed addr load");

3213 MI.removeOperand(1);

3214 Subtarget.getTargetMachine().setGlibcHWCAPAccess();

3218 return true;

3219#define PPC_TGT_PARSER_UNDEF_MACROS

3220#include "llvm/TargetParser/PPCTargetParser.def"

3221#undef PPC_TGT_PARSER_UNDEF_MACROS

3222 }

3223 case PPC::DFLOADf32:

3224 case PPC::DFLOADf64:

3225 case PPC::DFSTOREf32:

3226 case PPC::DFSTOREf64: {

3227 assert(Subtarget.hasP9Vector() &&

3228 "Invalid D-Form Pseudo-ops on Pre-P9 target.");

3229 assert(MI.getOperand(2).isReg() &&

3231 "D-form op must have register and immediate operands");

3233 }

3234 case PPC::XFLOADf32:

3235 case PPC::XFSTOREf32:

3236 case PPC::LIWAX:

3237 case PPC::LIWZX:

3238 case PPC::STIWX: {

3239 assert(Subtarget.hasP8Vector() &&

3240 "Invalid X-Form Pseudo-ops on Pre-P8 target.");

3241 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&

3242 "X-form op must have register and register operands");

3244 }

3245 case PPC::XFLOADf64:

3246 case PPC::XFSTOREf64: {

3247 assert(Subtarget.hasVSX() &&

3248 "Invalid X-Form Pseudo-ops on target that has no VSX.");

3249 assert(MI.getOperand(2).isReg() && MI.getOperand(1).isReg() &&

3250 "X-form op must have register and register operands");

3252 }

3253 case PPC::SPILLTOVSR_LD: {

3254 Register TargetReg = MI.getOperand(0).getReg();

3255 if (PPC::VSFRCRegClass.contains(TargetReg)) {

3256 MI.setDesc(get(PPC::DFLOADf64));

3258 }

3259 else

3260 MI.setDesc(get(PPC::LD));

3261 return true;

3262 }

3263 case PPC::SPILLTOVSR_ST: {

3264 Register SrcReg = MI.getOperand(0).getReg();

3265 if (PPC::VSFRCRegClass.contains(SrcReg)) {

3266 NumStoreSPILLVSRRCAsVec++;

3267 MI.setDesc(get(PPC::DFSTOREf64));

3269 } else {

3270 NumStoreSPILLVSRRCAsGpr++;

3271 MI.setDesc(get(PPC::STD));

3272 }

3273 return true;

3274 }

3275 case PPC::SPILLTOVSR_LDX: {

3276 Register TargetReg = MI.getOperand(0).getReg();

3277 if (PPC::VSFRCRegClass.contains(TargetReg))

3278 MI.setDesc(get(PPC::LXSDX));

3279 else

3280 MI.setDesc(get(PPC::LDX));

3281 return true;

3282 }

3283 case PPC::SPILLTOVSR_STX: {

3284 Register SrcReg = MI.getOperand(0).getReg();

3285 if (PPC::VSFRCRegClass.contains(SrcReg)) {

3286 NumStoreSPILLVSRRCAsVec++;

3287 MI.setDesc(get(PPC::STXSDX));

3288 } else {

3289 NumStoreSPILLVSRRCAsGpr++;

3290 MI.setDesc(get(PPC::STDX));

3291 }

3292 return true;

3293 }

3294

3295

3296 case PPC::CFENCE:

3297 case PPC::CFENCE8: {

3298 auto Val = MI.getOperand(0).getReg();

3299 unsigned CmpOp = Subtarget.isPPC64() ? PPC::CMPD : PPC::CMPW;

3305 MI.setDesc(get(PPC::ISYNC));

3306 MI.removeOperand(0);

3307 return true;

3308 }

3309 }

3310 return false;

3311}

3312

3313

3314

3315

3316

3317static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc,

3318 unsigned TrueReg, unsigned FalseReg,

3319 unsigned CRSubReg) {

3320

3321 if (CompareOpc == PPC::CMPWI || CompareOpc == PPC::CMPDI) {

3322 switch (CRSubReg) {

3323 default: llvm_unreachable("Unknown integer comparison type.");

3324 case PPC::sub_lt:

3325 return Imm1 < Imm2 ? TrueReg : FalseReg;

3326 case PPC::sub_gt:

3327 return Imm1 > Imm2 ? TrueReg : FalseReg;

3328 case PPC::sub_eq:

3329 return Imm1 == Imm2 ? TrueReg : FalseReg;

3330 }

3331 }

3332

3333 else if (CompareOpc == PPC::CMPLWI || CompareOpc == PPC::CMPLDI) {

3334 switch (CRSubReg) {

3335 default: llvm_unreachable("Unknown integer comparison type.");

3336 case PPC::sub_lt:

3337 return (uint64_t)Imm1 < (uint64_t)Imm2 ? TrueReg : FalseReg;

3338 case PPC::sub_gt:

3339 return (uint64_t)Imm1 > (uint64_t)Imm2 ? TrueReg : FalseReg;

3340 case PPC::sub_eq:

3341 return Imm1 == Imm2 ? TrueReg : FalseReg;

3342 }

3343 }

3344 return PPC::NoRegister;

3345}

3346

3348 unsigned OpNo,

3349 int64_t Imm) const {

3350 assert(MI.getOperand(OpNo).isReg() && "Operand must be a REG");

3351

3352 Register InUseReg = MI.getOperand(OpNo).getReg();

3353 MI.getOperand(OpNo).ChangeToImmediate(Imm);

3354

3355

3356

3357

3358

3359

3361 int UseOpIdx = MI.findRegisterUseOperandIdx(InUseReg, TRI, false);

3362 if (UseOpIdx >= 0) {

3365

3366

3367

3368

3369

3370

3371

3372 MI.removeOperand(UseOpIdx);

3373 }

3374}

3375

3376

3377

3380

3381 int OperandToKeep = LII.SetCR ? 1 : 0;

3382 for (int i = MI.getNumOperands() - 1; i > OperandToKeep; i--)

3383 MI.removeOperand(i);

3384

3385

3386 if (LII.SetCR) {

3387 MI.setDesc(get(LII.Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));

3388

3391 return;

3392 }

3393 else

3394 MI.setDesc(get(LII.Is64Bit ? PPC::LI8 : PPC::LI));

3395

3396

3399}

3400

3402 bool &SeenIntermediateUse) const {

3403 assert(MI.getParent()->getParent()->getRegInfo().isSSA() &&

3404 "Should be called after register allocation.");

3407 It++;

3408 SeenIntermediateUse = false;

3409 for (; It != E; ++It) {

3410 if (It->modifiesRegister(Reg, TRI))

3411 return &*It;

3412 if (It->readsRegister(Reg, TRI))

3413 SeenIntermediateUse = true;

3414 }

3415 return nullptr;

3416}

3417

3421 int64_t Imm) const {

3422 assert(MBB.getParent()->getRegInfo().isSSA() &&

3423 "Register should be in non-SSA form after RA");

3424 bool isPPC64 = Subtarget.isPPC64();

3425

3426

3427

3433 if (Imm & 0xFFFF)

3436 .addImm(Imm & 0xFFFF);

3437 } else {

3438 assert(isPPC64 && "Materializing 64-bit immediate to single register is "

3439 "only supported in PPC64");

3441 if ((Imm >> 32) & 0xFFFF)

3444 .addImm((Imm >> 32) & 0xFFFF);

3451 .addImm((Imm >> 16) & 0xFFFF);

3452 if (Imm & 0xFFFF)

3455 .addImm(Imm & 0xFFFF);

3456 }

3457}

3458

3459MachineInstr *PPCInstrInfo::getForwardingDefMI(

3461 unsigned &OpNoForForwarding,

3462 bool &SeenIntermediateUse) const {

3463 OpNoForForwarding = ~0U;

3467

3468

3469

3470 if (MRI->isSSA()) {

3471 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {

3472 if (MI.getOperand(i).isReg())

3473 continue;

3474 Register Reg = MI.getOperand(i).getReg();

3475 if (!Reg.isVirtual())

3476 continue;

3479 MachineInstr *DefMIForTrueReg = MRI->getVRegDef(TrueReg);

3480 if (DefMIForTrueReg->getOpcode() == PPC::LI ||

3481 DefMIForTrueReg->getOpcode() == PPC::LI8 ||

3482 DefMIForTrueReg->getOpcode() == PPC::ADDI ||

3483 DefMIForTrueReg->getOpcode() == PPC::ADDI8) {

3484 OpNoForForwarding = i;

3485 DefMI = DefMIForTrueReg;

3486

3487

3488

3489

3490 if (DefMI->getOpcode() == PPC::LI || DefMI->getOpcode() == PPC::LI8)

3491 break;

3492 }

3493 }

3494 }

3495 } else {

3496

3497

3498

3499 ImmInstrInfo III;

3500 unsigned Opc = MI.getOpcode();

3501 bool ConvertibleImmForm =

3502 Opc == PPC::CMPWI || Opc == PPC::CMPLWI || Opc == PPC::CMPDI ||

3503 Opc == PPC::CMPLDI || Opc == PPC::ADDI || Opc == PPC::ADDI8 ||

3504 Opc == PPC::ORI || Opc == PPC::ORI8 || Opc == PPC::XORI ||

3505 Opc == PPC::XORI8 || Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec ||

3506 Opc == PPC::RLDICL_32 || Opc == PPC::RLDICL_32_64 ||

3507 Opc == PPC::RLWINM || Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8 ||

3508 Opc == PPC::RLWINM8_rec;

3509 bool IsVFReg = (MI.getNumOperands() && MI.getOperand(0).isReg())

3512 if (!ConvertibleImmForm && instrHasImmForm(Opc, IsVFReg, III, true))

3513 return nullptr;

3514

3515

3516 if ((Opc == PPC::OR || Opc == PPC::OR8) &&

3517 MI.getOperand(1).getReg() == MI.getOperand(2).getReg())

3518 return nullptr;

3519 for (int i = 1, e = MI.getNumOperands(); i < e; i++) {

3520 MachineOperand &MO = MI.getOperand(i);

3521 SeenIntermediateUse = false;

3524

3525

3528

3529

3531 default:

3532 break;

3533 case PPC::LI:

3534 case PPC::LI8:

3535 case PPC::ADDItocL8:

3536 case PPC::ADDI:

3537 case PPC::ADDI8:

3538 OpNoForForwarding = i;

3540 }

3541 }

3542 }

3543 }

3544 }

3545 return OpNoForForwarding == ~0U ? nullptr : DefMI;

3546}

3547

3548unsigned PPCInstrInfo::getSpillTarget() const {

3549

3550

3551 bool IsP10Variant = Subtarget.isISA3_1() || Subtarget.pairedVectorMemops();

3552

3553 return Subtarget.isISAFuture() ? 3 : IsP10Variant ?

3554 2 : Subtarget.hasP9Vector() ?

3555 1 : 0;

3556}

3557

3558ArrayRef PPCInstrInfo::getStoreOpcodesForSpillArray() const {

3560}

3561

3562ArrayRef PPCInstrInfo::getLoadOpcodesForSpillArray() const {

3564}

3565

3566

3567

3568

3569

3570

3571

3572

3573

3574

3575

3576

3577

3578

3579

3580

3581

3582

3583

3584

3585

3586

3587

3588

3589

3593 bool PostRA = MRI->isSSA();

3594

3595

3596

3597 if (!PostRA)

3598 return false;

3599 unsigned ToBeDeletedReg = 0;

3600 int64_t OffsetImm = 0;

3601 unsigned XFormOpcode = 0;

3603

3604

3606 III))

3607 return false;

3608

3609 bool OtherIntermediateUse = false;

3611

3612

3613 if (OtherIntermediateUse || !ADDMI)

3614 return false;

3615

3616

3618 return false;

3619

3620 unsigned ScaleRegIdx = 0;

3621 int64_t OffsetAddi = 0;

3623

3624

3625

3626

3627

3629 ScaleRegIdx = 2;

3631 ScaleRegIdx = 1;

3632 else

3633 return false;

3634

3635 assert(ADDIMI && "There should be ADDIMI for valid ToBeChangedReg.");

3640 for (auto It = ++Start; It != End; It++)

3642 return true;

3643 return false;

3644 };

3645

3646

3647

3649 (ScaleReg == PPC::R0 || ScaleReg == PPC::X0))

3650 return false;

3651

3652

3653

3654 if (NewDefFor(ToBeChangedReg, *ADDMI, MI) || NewDefFor(ScaleReg, *ADDMI, MI))

3655 return false;

3656

3657

3659 << "\n");

3664 << "\n");

3665

3666

3668

3669

3670 MI.setDesc(get(XFormOpcode));

3672 .ChangeToRegister(ScaleReg, false, false,

3674

3676 .ChangeToRegister(ToBeChangedReg, false, false, true);

3677

3678

3680

3683

3684 return true;

3685}

3686

3688 int64_t &Imm) const {

3690

3691

3692 if (Opc != PPC::ADDI && Opc != PPC::ADDI8)

3693 return false;

3694

3695

3697 return false;

3698

3700

3701 return true;

3702}

3703

3706

3707

3708 return Opc == PPC::ADD4 || Opc == PPC::ADD8;

3709}

3710

3712 unsigned &ToBeDeletedReg,

3713 unsigned &XFormOpcode,

3714 int64_t &OffsetImm,

3716

3717 if (MI.mayLoadOrStore())

3718 return false;

3719

3720 unsigned Opc = MI.getOpcode();

3721

3722 XFormOpcode = RI.getMappedIdxOpcForImmOpc(Opc);

3723

3724

3725 if (XFormOpcode == PPC::INSTRUCTION_LIST_END)

3726 return false;

3727

3728

3731 return false;

3732

3734 return false;

3735

3738

3739 if (!ImmOperand.isImm())

3740 return false;

3741

3742 assert(RegOperand.isReg() && "Instruction format is not right");

3743

3744

3745 if (!RegOperand.isKill())

3746 return false;

3747

3748 ToBeDeletedReg = RegOperand.getReg();

3749 OffsetImm = ImmOperand.getImm();

3750

3751 return true;

3752}

3753

3756 int64_t &OffsetAddi,

3757 int64_t OffsetImm) const {

3758 assert((Index == 1 || Index == 2) && "Invalid operand index for add.");

3760

3762 return false;

3763

3764 bool OtherIntermediateUse = false;

3765

3767

3768

3769

3770

3771

3772

3773

3774

3775

3776

3777

3778

3779

3780

3781

3782

3783

3784

3785 if (OtherIntermediateUse || !ADDIMI)

3786 return false;

3787

3789 return false;

3790

3791 if (isInt<16>(OffsetAddi + OffsetImm))

3792 return true;

3793 return false;

3794}

3795

3796

3797

3798

3804 bool PostRA = MRI->isSSA();

3805 bool SeenIntermediateUse = true;

3806 unsigned ForwardingOperand = ~0U;

3808 SeenIntermediateUse);

3810 return false;

3811 assert(ForwardingOperand < MI.getNumOperands() &&

3812 "The forwarding operand needs to be valid at this point");

3813 bool IsForwardingOperandKilled = MI.getOperand(ForwardingOperand).isKill();

3814 bool KillFwdDefMI = !SeenIntermediateUse && IsForwardingOperandKilled;

3815 if (KilledDef && KillFwdDefMI)

3816 *KilledDef = DefMI;

3817

3818

3819

3826

3827

3828

3829 if (RI.getMappedIdxOpcForImmOpc(MI.getOpcode()) !=

3830 PPC::INSTRUCTION_LIST_END &&

3831 transformToNewImmFormFedByAdd(MI, *DefMI, ForwardingOperand))

3832 return true;

3833

3835 bool IsVFReg = MI.getOperand(0).isReg()

3837 : false;

3838 bool HasImmForm = instrHasImmForm(MI.getOpcode(), IsVFReg, III, PostRA);

3839

3840

3841

3842 if (HasImmForm &&

3843 transformToImmFormFedByAdd(MI, III, ForwardingOperand, *DefMI,

3844 KillFwdDefMI))

3845 return true;

3846

3847

3848

3849 if (HasImmForm &&

3850 transformToImmFormFedByLI(MI, III, ForwardingOperand, *DefMI))

3851 return true;

3852

3853

3854

3855 if (!HasImmForm && simplifyToLI(MI, *DefMI, ForwardingOperand, KilledDef))

3856 return true;

3857

3858 return false;

3859}

3860

3864 Register FoldingReg = MI.getOperand(1).getReg();

3866 return false;

3868 if (SrcMI->getOpcode() != PPC::RLWINM &&

3869 SrcMI->getOpcode() != PPC::RLWINM_rec &&

3870 SrcMI->getOpcode() != PPC::RLWINM8 &&

3871 SrcMI->getOpcode() != PPC::RLWINM8_rec)

3872 return false;

3873 assert((MI.getOperand(2).isImm() && MI.getOperand(3).isImm() &&

3876 "Invalid PPC::RLWINM Instruction!");

3878 uint64_t SHMI = MI.getOperand(2).getImm();

3880 uint64_t MBMI = MI.getOperand(3).getImm();

3882 uint64_t MEMI = MI.getOperand(4).getImm();

3883

3884 assert((MEMI < 32 && MESrc < 32 && MBMI < 32 && MBSrc < 32) &&

3885 "Invalid PPC::RLWINM Instruction!");

3886

3887

3888

3889

3890

3891

3892

3893

3894

3895

3896

3897

3898

3899

3900

3901

3902

3903

3904

3905

3906

3907 bool SrcMaskFull = (MBSrc - MESrc == 1) || (MBSrc == 0 && MESrc == 31);

3908

3909

3910 if ((MBMI > MEMI) && !SrcMaskFull)

3911 return false;

3912

3913

3915

3916

3917

3919

3920 APInt RotatedSrcMask = MaskSrc.rotl(SHMI);

3921 APInt FinalMask = RotatedSrcMask & MaskMI;

3923 bool Simplified = false;

3924

3925

3926 if (FinalMask.isZero()) {

3927 bool Is64Bit =

3928 (MI.getOpcode() == PPC::RLWINM8 || MI.getOpcode() == PPC::RLWINM8_rec);

3929 Simplified = true;

3932

3933 if (MI.getOpcode() == PPC::RLWINM || MI.getOpcode() == PPC::RLWINM8) {

3934

3935 MI.removeOperand(4);

3936 MI.removeOperand(3);

3937 MI.removeOperand(2);

3938 MI.getOperand(1).ChangeToImmediate(0);

3939 MI.setDesc(get(Is64Bit ? PPC::LI8 : PPC::LI));

3940 } else {

3941

3942 MI.removeOperand(4);

3943 MI.removeOperand(3);

3944 MI.getOperand(2).setImm(0);

3945 MI.setDesc(get(Is64Bit ? PPC::ANDI8_rec : PPC::ANDI_rec));

3948 MI.getOperand(1).setIsKill(true);

3950 } else

3951

3952 MI.getOperand(1).setIsKill(false);

3953 }

3954

3957

3959 NewMB <= NewME) ||

3960 SrcMaskFull) {

3961

3962

3963

3964 Simplified = true;

3967

3968 uint16_t NewSH = (SHSrc + SHMI) % 32;

3969 MI.getOperand(2).setImm(NewSH);

3970

3971 if (!SrcMaskFull) {

3972 MI.getOperand(3).setImm(NewMB);

3973 MI.getOperand(4).setImm(NewME);

3974 }

3977 MI.getOperand(1).setIsKill(true);

3979 } else

3980

3981 MI.getOperand(1).setIsKill(false);

3982

3985 }

3986 if (Simplified & MRI->use_nodbg_empty(FoldingReg) &&

3988

3989

3990

3991 *ToErase = SrcMI;

3994 }

3995 return Simplified;

3996}

3997

4000

4001

4002

4003

4010 switch (Opc) {

4011 default: return false;

4012 case PPC::ADD4:

4013 case PPC::ADD8:

4019 III.ImmOpcode = Opc == PPC::ADD4 ? PPC::ADDI : PPC::ADDI8;

4020 break;

4021 case PPC::ADDC:

4022 case PPC::ADDC8:

4028 III.ImmOpcode = Opc == PPC::ADDC ? PPC::ADDIC : PPC::ADDIC8;

4029 break;

4030 case PPC::ADDC_rec:

4037 break;

4038 case PPC::SUBFC:

4039 case PPC::SUBFC8:

4044 III.ImmOpcode = Opc == PPC::SUBFC ? PPC::SUBFIC : PPC::SUBFIC8;

4045 break;

4046 case PPC::CMPW:

4047 case PPC::CMPD:

4052 III.ImmOpcode = Opc == PPC::CMPW ? PPC::CMPWI : PPC::CMPDI;

4053 break;

4054 case PPC::CMPLW:

4055 case PPC::CMPLD:

4060 III.ImmOpcode = Opc == PPC::CMPLW ? PPC::CMPLWI : PPC::CMPLDI;

4061 break;

4062 case PPC::AND_rec:

4063 case PPC::AND8_rec:

4064 case PPC::OR:

4065 case PPC::OR8:

4066 case PPC::XOR:

4067 case PPC::XOR8:

4072 switch(Opc) {

4074 case PPC::AND_rec:

4076 break;

4077 case PPC::AND8_rec:

4079 break;

4080 case PPC::OR: III.ImmOpcode = PPC::ORI; break;

4081 case PPC::OR8: III.ImmOpcode = PPC::ORI8; break;

4082 case PPC::XOR: III.ImmOpcode = PPC::XORI; break;

4083 case PPC::XOR8: III.ImmOpcode = PPC::XORI8; break;

4084 }

4085 break;

4086 case PPC::RLWNM:

4087 case PPC::RLWNM8:

4088 case PPC::RLWNM_rec:

4089 case PPC::RLWNM8_rec:

4090 case PPC::SLW:

4091 case PPC::SLW8:

4092 case PPC::SLW_rec:

4093 case PPC::SLW8_rec:

4094 case PPC::SRW:

4095 case PPC::SRW8:

4096 case PPC::SRW_rec:

4097 case PPC::SRW8_rec:

4098 case PPC::SRAW:

4099 case PPC::SRAW_rec:

4104

4105

4106

4107

4109 if (Opc == PPC::RLWNM || Opc == PPC::RLWNM8 || Opc == PPC::RLWNM_rec ||

4110 Opc == PPC::RLWNM8_rec)

4112 else

4114 switch(Opc) {

4116 case PPC::RLWNM: III.ImmOpcode = PPC::RLWINM; break;

4117 case PPC::RLWNM8: III.ImmOpcode = PPC::RLWINM8; break;

4118 case PPC::RLWNM_rec:

4119 III.ImmOpcode = PPC::RLWINM_rec;

4120 break;

4121 case PPC::RLWNM8_rec:

4122 III.ImmOpcode = PPC::RLWINM8_rec;

4123 break;

4124 case PPC::SLW: III.ImmOpcode = PPC::RLWINM; break;

4125 case PPC::SLW8: III.ImmOpcode = PPC::RLWINM8; break;

4126 case PPC::SLW_rec:

4127 III.ImmOpcode = PPC::RLWINM_rec;

4128 break;

4129 case PPC::SLW8_rec:

4130 III.ImmOpcode = PPC::RLWINM8_rec;

4131 break;

4132 case PPC::SRW: III.ImmOpcode = PPC::RLWINM; break;

4133 case PPC::SRW8: III.ImmOpcode = PPC::RLWINM8; break;

4134 case PPC::SRW_rec:

4135 III.ImmOpcode = PPC::RLWINM_rec;

4136 break;

4137 case PPC::SRW8_rec:

4138 III.ImmOpcode = PPC::RLWINM8_rec;

4139 break;

4140 case PPC::SRAW:

4144 break;

4145 case PPC::SRAW_rec:

4149 break;

4150 }

4151 break;

4152 case PPC::RLDCL:

4153 case PPC::RLDCL_rec:

4154 case PPC::RLDCR:

4155 case PPC::RLDCR_rec:

4156 case PPC::SLD:

4157 case PPC::SLD_rec:

4158 case PPC::SRD:

4159 case PPC::SRD_rec:

4160 case PPC::SRAD:

4161 case PPC::SRAD_rec:

4166

4167

4168

4169

4171 if (Opc == PPC::RLDCL || Opc == PPC::RLDCL_rec || Opc == PPC::RLDCR ||

4172 Opc == PPC::RLDCR_rec)

4174 else

4176 switch(Opc) {

4178 case PPC::RLDCL: III.ImmOpcode = PPC::RLDICL; break;

4179 case PPC::RLDCL_rec:

4180 III.ImmOpcode = PPC::RLDICL_rec;

4181 break;

4182 case PPC::RLDCR: III.ImmOpcode = PPC::RLDICR; break;

4183 case PPC::RLDCR_rec:

4184 III.ImmOpcode = PPC::RLDICR_rec;

4185 break;

4186 case PPC::SLD: III.ImmOpcode = PPC::RLDICR; break;

4187 case PPC::SLD_rec:

4188 III.ImmOpcode = PPC::RLDICR_rec;

4189 break;

4190 case PPC::SRD: III.ImmOpcode = PPC::RLDICL; break;

4191 case PPC::SRD_rec:

4192 III.ImmOpcode = PPC::RLDICL_rec;

4193 break;

4194 case PPC::SRAD:

4198 break;

4199 case PPC::SRAD_rec:

4203 break;

4204 }

4205 break;

4206

4207 case PPC::LBZX:

4208 case PPC::LBZX8:

4209 case PPC::LHZX:

4210 case PPC::LHZX8:

4211 case PPC::LHAX:

4212 case PPC::LHAX8:

4213 case PPC::LWZX:

4214 case PPC::LWZX8:

4215 case PPC::LWAX:

4216 case PPC::LDX:

4217 case PPC::LFSX:

4218 case PPC::LFDX:

4219 case PPC::STBX:

4220 case PPC::STBX8:

4221 case PPC::STHX:

4222 case PPC::STHX8:

4223 case PPC::STWX:

4224 case PPC::STWX8:

4225 case PPC::STDX:

4226 case PPC::STFSX:

4227 case PPC::STFDX:

4235 switch(Opc) {

4237 case PPC::LBZX: III.ImmOpcode = PPC::LBZ; break;

4238 case PPC::LBZX8: III.ImmOpcode = PPC::LBZ8; break;

4239 case PPC::LHZX: III.ImmOpcode = PPC::LHZ; break;

4240 case PPC::LHZX8: III.ImmOpcode = PPC::LHZ8; break;

4241 case PPC::LHAX: III.ImmOpcode = PPC::LHA; break;

4242 case PPC::LHAX8: III.ImmOpcode = PPC::LHA8; break;

4243 case PPC::LWZX: III.ImmOpcode = PPC::LWZ; break;

4244 case PPC::LWZX8: III.ImmOpcode = PPC::LWZ8; break;

4245 case PPC::LWAX:

4248 break;

4250 case PPC::LFSX: III.ImmOpcode = PPC::LFS; break;

4251 case PPC::LFDX: III.ImmOpcode = PPC::LFD; break;

4252 case PPC::STBX: III.ImmOpcode = PPC::STB; break;

4253 case PPC::STBX8: III.ImmOpcode = PPC::STB8; break;

4254 case PPC::STHX: III.ImmOpcode = PPC::STH; break;

4255 case PPC::STHX8: III.ImmOpcode = PPC::STH8; break;

4256 case PPC::STWX: III.ImmOpcode = PPC::STW; break;

4257 case PPC::STWX8: III.ImmOpcode = PPC::STW8; break;

4258 case PPC::STDX:

4261 break;

4262 case PPC::STFSX: III.ImmOpcode = PPC::STFS; break;

4263 case PPC::STFDX: III.ImmOpcode = PPC::STFD; break;

4264 }

4265 break;

4266 case PPC::LBZUX:

4267 case PPC::LBZUX8:

4268 case PPC::LHZUX:

4269 case PPC::LHZUX8:

4270 case PPC::LHAUX:

4271 case PPC::LHAUX8:

4272 case PPC::LWZUX:

4273 case PPC::LWZUX8:

4274 case PPC::LDUX:

4275 case PPC::LFSUX:

4276 case PPC::LFDUX:

4277 case PPC::STBUX:

4278 case PPC::STBUX8:

4279 case PPC::STHUX:

4280 case PPC::STHUX8:

4281 case PPC::STWUX:

4282 case PPC::STWUX8:

4283 case PPC::STDUX:

4284 case PPC::STFSUX:

4285 case PPC::STFDUX:

4293 switch(Opc) {

4295 case PPC::LBZUX: III.ImmOpcode = PPC::LBZU; break;

4296 case PPC::LBZUX8: III.ImmOpcode = PPC::LBZU8; break;

4297 case PPC::LHZUX: III.ImmOpcode = PPC::LHZU; break;

4298 case PPC::LHZUX8: III.ImmOpcode = PPC::LHZU8; break;

4299 case PPC::LHAUX: III.ImmOpcode = PPC::LHAU; break;

4300 case PPC::LHAUX8: III.ImmOpcode = PPC::LHAU8; break;

4301 case PPC::LWZUX: III.ImmOpcode = PPC::LWZU; break;

4302 case PPC::LWZUX8: III.ImmOpcode = PPC::LWZU8; break;

4303 case PPC::LDUX:

4306 break;

4307 case PPC::LFSUX: III.ImmOpcode = PPC::LFSU; break;

4308 case PPC::LFDUX: III.ImmOpcode = PPC::LFDU; break;

4309 case PPC::STBUX: III.ImmOpcode = PPC::STBU; break;

4310 case PPC::STBUX8: III.ImmOpcode = PPC::STBU8; break;

4311 case PPC::STHUX: III.ImmOpcode = PPC::STHU; break;

4312 case PPC::STHUX8: III.ImmOpcode = PPC::STHU8; break;

4313 case PPC::STWUX: III.ImmOpcode = PPC::STWU; break;

4314 case PPC::STWUX8: III.ImmOpcode = PPC::STWU8; break;

4315 case PPC::STDUX:

4318 break;

4319 case PPC::STFSUX: III.ImmOpcode = PPC::STFSU; break;

4320 case PPC::STFDUX: III.ImmOpcode = PPC::STFDU; break;

4321 }

4322 break;

4323

4324

4325

4326

4327 case PPC::LXVX:

4328 case PPC::LXSSPX:

4329 case PPC::LXSDX:

4330 case PPC::STXVX:

4331 case PPC::STXSSPX:

4332 case PPC::STXSDX:

4333 case PPC::XFLOADf32:

4334 case PPC::XFLOADf64:

4335 case PPC::XFSTOREf32:

4336 case PPC::XFSTOREf64:

4337 if (!Subtarget.hasP9Vector())

4338 return false;

4347 switch(Opc) {

4349 case PPC::LXVX:

4352 break;

4353 case PPC::LXSSPX:

4354 if (PostRA) {

4355 if (IsVFReg)

4357 else {

4360 }

4361 break;

4362 }

4363 [[fallthrough]];

4364 case PPC::XFLOADf32:

4366 break;

4367 case PPC::LXSDX:

4368 if (PostRA) {

4369 if (IsVFReg)

4371 else {

4374 }

4375 break;

4376 }

4377 [[fallthrough]];

4378 case PPC::XFLOADf64:

4380 break;

4381 case PPC::STXVX:

4384 break;

4385 case PPC::STXSSPX:

4386 if (PostRA) {

4387 if (IsVFReg)

4389 else {

4392 }

4393 break;

4394 }

4395 [[fallthrough]];

4396 case PPC::XFSTOREf32:

4397 III.ImmOpcode = PPC::DFSTOREf32;

4398 break;

4399 case PPC::STXSDX:

4400 if (PostRA) {

4401 if (IsVFReg)

4403 else {

4406 }

4407 break;

4408 }

4409 [[fallthrough]];

4410 case PPC::XFSTOREf64:

4411 III.ImmOpcode = PPC::DFSTOREf64;

4412 break;

4413 }

4414 break;

4415 }

4416 return true;

4417}

4418

4419

4421 assert(Op1 != Op2 && "Cannot swap operand with itself.");

4422

4423 unsigned MaxOp = std::max(Op1, Op2);

4424 unsigned MinOp = std::min(Op1, Op2);

4427 MI.removeOperand(std::max(Op1, Op2));

4428 MI.removeOperand(std::min(Op1, Op2));

4429

4430

4431

4432 if (MaxOp - MinOp == 1 && MI.getNumOperands() == MinOp) {

4433 MI.addOperand(MOp2);

4434 MI.addOperand(MOp1);

4435 } else {

4436

4437

4439 unsigned TotalOps = MI.getNumOperands() + 2;

4440 for (unsigned i = MI.getNumOperands() - 1; i >= MinOp; i--) {

4442 MI.removeOperand(i);

4443 }

4444

4445 MI.addOperand(MOp2);

4446

4447 for (unsigned i = MI.getNumOperands(); i < TotalOps; i++) {

4448 if (i == MaxOp)

4449 MI.addOperand(MOp1);

4450 else {

4451 MI.addOperand(MOps.back());

4453 }

4454 }

4455 }

4456}

4457

4458

4459

4460bool PPCInstrInfo::isUseMIElgibleForForwarding(MachineInstr &MI,

4462 unsigned OpNoForForwarding

4463 ) const {

4464

4465

4466 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();

4467 if (MRI.isSSA())

4468 return false;

4469

4470

4472 return false;

4473

4474

4476 return false;

4477

4478

4479

4481 return false;

4482

4483

4484

4487 return false;

4488

4489

4490

4491

4492

4493 return true;

4494}

4495

4496

4497

4498bool PPCInstrInfo::isDefMIElgibleForForwarding(MachineInstr &DefMI,

4502 unsigned Opc = DefMI.getOpcode();

4503 if (Opc != PPC::ADDItocL8 && Opc != PPC::ADDI && Opc != PPC::ADDI8)

4504 return false;

4505

4506

4507

4508

4509 if (Opc == PPC::ADDItocL8 && Subtarget.isAIX())

4510 return false;

4511

4513 "Add inst must have at least three operands");

4514 RegMO = &DefMI.getOperand(1);

4515 ImmMO = &DefMI.getOperand(2);

4516

4517

4518 if (!RegMO->isReg())

4519 return false;

4520

4521

4522

4523

4525}

4526

4527bool PPCInstrInfo::isRegElgibleForForwarding(

4530 bool &IsFwdFeederRegKilled, bool &SeenIntermediateUse) const {

4531

4532

4533

4534

4535

4536

4537 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();

4538 if (MRI.isSSA())

4539 return false;

4540

4542

4543

4546 It++;

4547 for (; It != E; ++It) {

4549 return false;

4551 IsFwdFeederRegKilled = true;

4553 SeenIntermediateUse = true;

4554

4555 if ((&*It) == &DefMI)

4556 break;

4557 }

4558 assert((&*It) == &DefMI && "DefMI is missing");

4559

4560

4561

4563 return KillDefMI;

4564

4565 return true;

4566}

4567

4568bool PPCInstrInfo::isImmElgibleForForwarding(const MachineOperand &ImmMO,

4571 int64_t &Imm,

4572 int64_t BaseImm) const {

4574 if (DefMI.getOpcode() == PPC::ADDItocL8) {

4575

4576

4577

4580 return false;

4581

4582

4583

4584

4585

4589 return false;

4590 }

4591

4592 return true;

4593 }

4594

4595 if (ImmMO.isImm()) {

4596

4597

4598

4599

4600 APInt ActualValue(64, ImmMO.getImm() + BaseImm, true);

4602 return false;

4604 return false;

4606

4608 return false;

4611 }

4612 else

4613 return false;

4614

4615

4616

4617 return true;

4618}

4619

4621 unsigned OpNoForForwarding,

4623 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||

4624 DefMI.getOperand(1).isImm())

4625 return false;

4626

4627 MachineFunction *MF = MI.getParent()->getParent();

4630

4631 int64_t Immediate = DefMI.getOperand(1).getImm();

4632

4634

4635 bool ReplaceWithLI = false;

4636 bool Is64BitLI = false;

4637 int64_t NewImm = 0;

4638 bool SetCR = false;

4639 unsigned Opc = MI.getOpcode();

4640 switch (Opc) {

4641 default:

4642 return false;

4643

4644

4645

4646

4647

4648 case PPC::CMPWI:

4649 case PPC::CMPLWI:

4650 case PPC::CMPDI:

4651 case PPC::CMPLDI: {

4652

4653

4654

4655

4656 if (PostRA)

4657 return false;

4658

4659

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

4662 int64_t Comparand = MI.getOperand(2).getImm();

4663 int64_t SExtComparand = ((uint64_t)Comparand & ~0x7FFFuLL) != 0

4664 ? (Comparand | 0xFFFFFFFFFFFF0000)

4665 : Comparand;

4666

4667 for (auto &CompareUseMI : MRI->use_instructions(DefReg)) {

4668 unsigned UseOpc = CompareUseMI.getOpcode();

4669 if (UseOpc != PPC::ISEL && UseOpc != PPC::ISEL8)

4670 continue;

4671 unsigned CRSubReg = CompareUseMI.getOperand(3).getSubReg();

4672 Register TrueReg = CompareUseMI.getOperand(1).getReg();

4673 Register FalseReg = CompareUseMI.getOperand(2).getReg();

4674 unsigned RegToCopy =

4675 selectReg(SExtImm, SExtComparand, Opc, TrueReg, FalseReg, CRSubReg);

4676 if (RegToCopy == PPC::NoRegister)

4677 continue;

4678

4679 if (RegToCopy == PPC::ZERO || RegToCopy == PPC::ZERO8) {

4680 CompareUseMI.setDesc(get(UseOpc == PPC::ISEL8 ? PPC::LI8 : PPC::LI));

4682 CompareUseMI.removeOperand(3);

4683 CompareUseMI.removeOperand(2);

4684 continue;

4685 }

4687 dbgs() << "Found LI -> CMPI -> ISEL, replacing with a copy.\n");

4690

4691 CompareUseMI.setDesc(get(PPC::COPY));

4692 CompareUseMI.removeOperand(3);

4693 CompareUseMI.removeOperand(RegToCopy == TrueReg ? 2 : 1);

4694 CmpIselsConverted++;

4697 }

4699 return true;

4700

4701

4702

4703 MissedConvertibleImmediateInstrs++;

4704 return false;

4705 }

4706

4707

4708 case PPC::ADDI:

4709 case PPC::ADDI8: {

4710

4711 int64_t Addend = MI.getOperand(2).getImm();

4712 if (isInt<16>(Addend + SExtImm)) {

4713 ReplaceWithLI = true;

4714 Is64BitLI = Opc == PPC::ADDI8;

4715 NewImm = Addend + SExtImm;

4716 break;

4717 }

4718 return false;

4719 }

4720 case PPC::SUBFIC:

4721 case PPC::SUBFIC8: {

4722

4723 if (MI.getNumOperands() > 3 && MI.getOperand(3).isDead())

4724 return false;

4725 int64_t Minuend = MI.getOperand(2).getImm();

4726 if (isInt<16>(Minuend - SExtImm)) {

4727 ReplaceWithLI = true;

4728 Is64BitLI = Opc == PPC::SUBFIC8;

4729 NewImm = Minuend - SExtImm;

4730 break;

4731 }

4732 return false;

4733 }

4734 case PPC::RLDICL:

4735 case PPC::RLDICL_rec:

4736 case PPC::RLDICL_32:

4737 case PPC::RLDICL_32_64: {

4738

4739 int64_t SH = MI.getOperand(2).getImm();

4740 int64_t MB = MI.getOperand(3).getImm();

4741 APInt InVal((Opc == PPC::RLDICL || Opc == PPC::RLDICL_rec) ? 64 : 32,

4742 SExtImm, true);

4743 InVal = InVal.rotl(SH);

4744 uint64_t Mask = MB == 0 ? -1LLU : (1LLU << (63 - MB + 1)) - 1;

4745 InVal &= Mask;

4746

4747

4748

4749 if (isUInt<15>(InVal.getSExtValue()) ||

4750 (Opc == PPC::RLDICL_rec && isUInt<16>(InVal.getSExtValue()))) {

4751 ReplaceWithLI = true;

4752 Is64BitLI = Opc != PPC::RLDICL_32;

4753 NewImm = InVal.getSExtValue();

4754 SetCR = Opc == PPC::RLDICL_rec;

4755 break;

4756 }

4757 return false;

4758 }

4759 case PPC::RLWINM:

4760 case PPC::RLWINM8:

4761 case PPC::RLWINM_rec:

4762 case PPC::RLWINM8_rec: {

4763 int64_t SH = MI.getOperand(2).getImm();

4764 int64_t MB = MI.getOperand(3).getImm();

4765 int64_t ME = MI.getOperand(4).getImm();

4766 APInt InVal(32, SExtImm, true);

4767 InVal = InVal.rotl(SH);

4769 InVal &= Mask;

4770

4771

4772

4773 bool ValueFits = isUInt<15>(InVal.getSExtValue());

4774 ValueFits |= ((Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec) &&

4776 if (ValueFits) {

4777 ReplaceWithLI = true;

4778 Is64BitLI = Opc == PPC::RLWINM8 || Opc == PPC::RLWINM8_rec;

4779 NewImm = InVal.getSExtValue();

4780 SetCR = Opc == PPC::RLWINM_rec || Opc == PPC::RLWINM8_rec;

4781 break;

4782 }

4783 return false;

4784 }

4785 case PPC::ORI:

4786 case PPC::ORI8:

4787 case PPC::XORI:

4788 case PPC::XORI8: {

4789 int64_t LogicalImm = MI.getOperand(2).getImm();

4791 if (Opc == PPC::ORI || Opc == PPC::ORI8)

4792 Result = LogicalImm | SExtImm;

4793 else

4794 Result = LogicalImm ^ SExtImm;

4796 ReplaceWithLI = true;

4797 Is64BitLI = Opc == PPC::ORI8 || Opc == PPC::XORI8;

4799 break;

4800 }

4801 return false;

4802 }

4803 }

4804

4805 if (ReplaceWithLI) {

4806

4807 if (SetCR) {

4808

4809

4810 bool ImmChanged = (SExtImm & NewImm) != NewImm;

4811 if (PostRA && ImmChanged)

4812 return false;

4813

4814 if (!PostRA) {

4815

4816

4818 DefMI.getOperand(1).setImm(NewImm);

4819

4820

4821

4822 else if (MRI->use_empty(MI.getOperand(0).getReg())) {

4823 if (NewImm) {

4824 assert(Immediate && "Transformation converted zero to non-zero?");

4825 NewImm = Immediate;

4826 }

4827 } else if (ImmChanged)

4828 return false;

4829 }

4830 }

4831

4832 LLVM_DEBUG(dbgs() << "Replacing constant instruction:\n");

4836 LoadImmediateInfo LII;

4837 LII.Imm = NewImm;

4838 LII.Is64Bit = Is64BitLI;

4839 LII.SetCR = SetCR;

4840

4841

4842 if (KilledDef && SetCR)

4843 *KilledDef = nullptr;

4845

4846 if (PostRA)

4848

4851 return true;

4852 }

4853 return false;

4854}

4855

4856bool PPCInstrInfo::transformToNewImmFormFedByAdd(

4858 MachineRegisterInfo *MRI = &MI.getParent()->getParent()->getRegInfo();

4860

4861

4862 if (PostRA)

4863 return false;

4864

4865

4866 if (MI.mayLoadOrStore())

4867 return false;

4868

4869 unsigned XFormOpcode = RI.getMappedIdxOpcForImmOpc(MI.getOpcode());

4870

4871 assert((XFormOpcode != PPC::INSTRUCTION_LIST_END) &&

4872 "MI must have x-form opcode");

4873

4874

4875 ImmInstrInfo III;

4876 bool IsVFReg = MI.getOperand(0).isReg()

4879

4880 if (instrHasImmForm(XFormOpcode, IsVFReg, III, PostRA))

4881 return false;

4882

4884 return false;

4885

4887 return false;

4888

4889 MachineOperand ImmOperandMI = MI.getOperand(III.ImmOpNo);

4890 if (!ImmOperandMI.isImm())

4891 return false;

4892

4893

4894 MachineOperand *ImmMO = nullptr;

4895 MachineOperand *RegMO = nullptr;

4896 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))

4897 return false;

4898 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");

4899

4900

4901

4902

4903 int64_t ImmBase = ImmOperandMI.getImm();

4904 int64_t Imm = 0;

4905 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm, ImmBase))

4906 return false;

4907

4908

4909 LLVM_DEBUG(dbgs() << "Replacing existing reg+imm instruction:\n");

4913

4915 MI.getOperand(III.ImmOpNo).setImm(Imm);

4916

4919 return true;

4920}

4921

4922

4923

4924

4925

4926bool PPCInstrInfo::transformToImmFormFedByAdd(

4929

4930

4931

4932

4933

4934

4935

4936 if (!isUseMIElgibleForForwarding(MI, III, OpNoForForwarding))

4937 return false;

4938

4939

4940

4941 MachineOperand *ImmMO = nullptr;

4942 MachineOperand *RegMO = nullptr;

4943 if (!isDefMIElgibleForForwarding(DefMI, III, ImmMO, RegMO))

4944 return false;

4945 assert(ImmMO && RegMO && "Imm and Reg operand must have been set");

4946

4947

4948

4949 int64_t Imm = 0;

4950 if (!isImmElgibleForForwarding(*ImmMO, DefMI, III, Imm))

4951 return false;

4952

4953 bool IsFwdFeederRegKilled = false;

4954 bool SeenIntermediateUse = false;

4955

4956 if (!isRegElgibleForForwarding(*RegMO, DefMI, MI, KillDefMI,

4957 IsFwdFeederRegKilled, SeenIntermediateUse))

4958 return false;

4959

4960 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();

4962

4963

4964

4965

4966 LLVM_DEBUG(dbgs() << "Replacing indexed instruction:\n");

4970

4971

4973 false, false,

4975

4976

4977 if (ImmMO->isImm()) {

4978

4979

4981 }

4982 else {

4983

4984

4985

4986

4987

4988 if (DefMI.getOpcode() == PPC::ADDItocL8)

4990

4991

4992

4993

4994

4996 for (unsigned i = MI.getNumOperands() - 1; i >= III.ZeroIsSpecialOrig; i--) {

4998 MI.removeOperand(i);

4999 }

5000

5001

5003

5004 MI.addOperand(*ImmMO);

5005

5006 for (auto &MO : MOps)

5007 MI.addOperand(MO);

5008 }

5009

5010

5012

5013 if (PostRA)

5017

5018 return true;

5019}

5020

5021bool PPCInstrInfo::transformToImmFormFedByLI(MachineInstr &MI,

5023 unsigned ConstantOpNo,

5025

5026 if ((DefMI.getOpcode() != PPC::LI && DefMI.getOpcode() != PPC::LI8) ||

5027 DefMI.getOperand(1).isImm())

5028 return false;

5029

5030

5032

5033 MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();

5035

5037 return false;

5039 return false;

5043 APInt ActualValue(64, Imm, true);

5044 if (!ActualValue.isSignedIntN(III.ImmWidth))

5045 return false;

5046 } else {

5047 uint64_t UnsignedMax = (1 << III.ImmWidth) - 1;

5048 if ((uint64_t)Imm > UnsignedMax)

5049 return false;

5050 }

5051

5052

5053

5054

5058 Register OrigZeroReg = MI.getOperand(PosForOrigZero).getReg();

5060

5061

5062 if ((NewZeroReg == PPC::R0 || NewZeroReg == PPC::X0) &&

5064 return false;

5065 if ((OrigZeroReg == PPC::R0 || OrigZeroReg == PPC::X0) &&

5066 ConstantOpNo != PosForOrigZero)

5067 return false;

5068 }

5069

5070 unsigned Opc = MI.getOpcode();

5071 bool SpecialShift32 = Opc == PPC::SLW || Opc == PPC::SLW_rec ||

5072 Opc == PPC::SRW || Opc == PPC::SRW_rec ||

5073 Opc == PPC::SLW8 || Opc == PPC::SLW8_rec ||

5074 Opc == PPC::SRW8 || Opc == PPC::SRW8_rec;

5075 bool SpecialShift64 = Opc == PPC::SLD || Opc == PPC::SLD_rec ||

5076 Opc == PPC::SRD || Opc == PPC::SRD_rec;

5077 bool SetCR = Opc == PPC::SLW_rec || Opc == PPC::SRW_rec ||

5078 Opc == PPC::SLD_rec || Opc == PPC::SRD_rec;

5079 bool RightShift = Opc == PPC::SRW || Opc == PPC::SRW_rec || Opc == PPC::SRD ||

5080 Opc == PPC::SRD_rec;

5081

5082 LLVM_DEBUG(dbgs() << "Replacing reg+reg instruction: ");

5088

5089

5090

5091

5092

5093

5094 if (SpecialShift32 || SpecialShift64) {

5095 LoadImmediateInfo LII;

5096 LII.Imm = 0;

5097 LII.SetCR = SetCR;

5098 LII.Is64Bit = SpecialShift64;

5099 uint64_t ShAmt = Imm & (SpecialShift32 ? 0x1F : 0x3F);

5100 if (Imm & (SpecialShift32 ? 0x20 : 0x40))

5102

5103

5104

5105 else if (!SetCR && ShAmt == 0 && !PostRA) {

5106 MI.removeOperand(2);

5107 MI.setDesc(get(PPC::COPY));

5108 } else {

5109

5110 if (SpecialShift32) {

5111

5112

5113

5114 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 32 - ShAmt : ShAmt;

5115 uint64_t MB = RightShift ? ShAmt : 0;

5116 uint64_t ME = RightShift ? 31 : 31 - ShAmt;

5118 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(MB)

5119 .addImm(ME);

5120 } else {

5121

5122

5123

5124 uint64_t SH = ShAmt == 0 ? 0 : RightShift ? 64 - ShAmt : ShAmt;

5125 uint64_t ME = RightShift ? ShAmt : 63 - ShAmt;

5127 MachineInstrBuilder(*MI.getParent()->getParent(), MI).addImm(ME);

5128 }

5129 }

5130 } else

5132 }

5133

5134

5138 } else

5140

5141

5142

5145

5146

5147

5148

5151

5152

5155 const TargetRegisterClass *NewRC =

5156 MRI.getRegClass(RegToModify)->hasSuperClassEq(&PPC::GPRCRegClass) ?

5157 &PPC::GPRC_and_GPRC_NOR0RegClass : &PPC::G8RC_and_G8RC_NOX0RegClass;

5158 MRI.setRegClass(RegToModify, NewRC);

5159 }

5160 }

5161 }

5162

5163 if (PostRA)

5165

5169 return true;

5170}

5171

5174 if (Subtarget.hasVSX() && RC == &PPC::VRRCRegClass)

5175 return &PPC::VSRCRegClass;

5176 return RC;

5177}

5178

5180 return PPC::getRecordFormOpcode(Opcode);

5181}

5182

5184 return (Opcode == PPC::LBZU || Opcode == PPC::LBZUX || Opcode == PPC::LBZU8 ||

5185 Opcode == PPC::LBZUX8 || Opcode == PPC::LHZU ||

5186 Opcode == PPC::LHZUX || Opcode == PPC::LHZU8 ||

5187 Opcode == PPC::LHZUX8);

5188}

5189

5190

5194 return false;

5195

5197 if (MI)

5198 return false;

5199

5200 int Opcode = MI->getOpcode();

5202 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();

5203 if (TII->isSExt32To64(Opcode))

5204 return true;

5205

5206

5208 return true;

5209

5210

5211

5212 if (Opcode == PPC::RLDICL && MI->getOperand(3).getImm() >= 33)

5213 return true;

5214

5215

5216

5217

5218 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||

5219 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec) &&

5220 MI->getOperand(3).getImm() > 0 &&

5221 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())

5222 return true;

5223

5224

5225

5226 if (Opcode == PPC::ANDIS_rec || Opcode == PPC::ANDIS8_rec) {

5227 uint16_t Imm = MI->getOperand(2).getImm();

5228 if ((Imm & 0x8000) == 0)

5229 return true;

5230 }

5231

5232 return false;

5233}

5234

5235

5236

5237

5241 return false;

5242

5244 if (MI)

5245 return false;

5246

5247 int Opcode = MI->getOpcode();

5249 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();

5250 if (TII->isZExt32To64(Opcode))

5251 return true;

5252

5253

5255 Opcode == PPC::LWZUX || Opcode == PPC::LWZU8 || Opcode == PPC::LWZUX8) &&

5256 MI->getOperand(0).getReg() == Reg)

5257 return true;

5258

5259

5260

5261 if (Opcode == PPC::LI || Opcode == PPC::LI8 ||

5262 Opcode == PPC::LIS || Opcode == PPC::LIS8) {

5263 int64_t Imm = MI->getOperand(1).getImm();

5264 if (((uint64_t)Imm & ~0x7FFFuLL) == 0)

5265 return true;

5266 }

5267

5268

5269

5270 if ((Opcode == PPC::RLDICL || Opcode == PPC::RLDICL_rec ||

5271 Opcode == PPC::RLDCL || Opcode == PPC::RLDCL_rec ||

5272 Opcode == PPC::RLDICL_32_64) &&

5273 MI->getOperand(3).getImm() >= 32)

5274 return true;

5275

5276 if ((Opcode == PPC::RLDIC || Opcode == PPC::RLDIC_rec) &&

5277 MI->getOperand(3).getImm() >= 32 &&

5278 MI->getOperand(3).getImm() <= 63 - MI->getOperand(2).getImm())

5279 return true;

5280

5281 if ((Opcode == PPC::RLWINM || Opcode == PPC::RLWINM_rec ||

5282 Opcode == PPC::RLWNM || Opcode == PPC::RLWNM_rec ||

5283 Opcode == PPC::RLWINM8 || Opcode == PPC::RLWNM8) &&

5284 MI->getOperand(3).getImm() <= MI->getOperand(4).getImm())

5285 return true;

5286

5287 return false;

5288}

5289

5290

5291

5293 if (MI.getOperand(1).isImm() || MI.getOperand(2).isReg())

5294 return false;

5295 unsigned TOCSaveOffset = Subtarget.getFrameLowering()->getTOCSaveOffset();

5296 unsigned StackOffset = MI.getOperand(1).getImm();

5297 Register StackReg = MI.getOperand(2).getReg();

5298 Register SPReg = Subtarget.isPPC64() ? PPC::X1 : PPC::R1;

5300 return true;

5301

5302 return false;

5303}

5304

5305

5306

5308

5309

5310

5311

5312

5313

5314

5315

5316

5317

5320 unsigned BinOpDepth,

5322 if (!Reg.isVirtual())

5323 return;

5324

5326 if (MI)

5327 return;

5328

5329 unsigned Opcode = MI->getOpcode();

5330

5331 switch (Opcode) {

5332 case PPC::OR:

5333 case PPC::ISEL:

5334 case PPC::OR8:

5335 case PPC::PHI: {

5337 break;

5338 unsigned OperandEnd = 3, OperandStride = 1;

5339 if (Opcode == PPC::PHI) {

5340 OperandEnd = MI->getNumOperands();

5341 OperandStride = 2;

5342 }

5343

5344 for (unsigned I = 1; I < OperandEnd; I += OperandStride) {

5345 assert(MI->getOperand(I).isReg() && "Operand must be register");

5347 BinOpDepth + 1, LV);

5348 }

5349

5350 break;

5351 }

5352 case PPC::COPY: {

5353

5354

5355

5356 Register SrcReg = MI->getOperand(1).getReg();

5357

5358

5361

5362

5364 return;

5365 }

5366

5367

5368

5369

5370 if (SrcReg != PPC::X3)

5371

5372

5374 return;

5375 }

5376 case PPC::ORI:

5377 case PPC::XORI:

5378 case PPC::ORIS:

5379 case PPC::XORIS:

5380 case PPC::ORI8:

5381 case PPC::XORI8:

5382 case PPC::ORIS8:

5383 case PPC::XORIS8:

5385 LV);

5386 break;

5387 case PPC::AND:

5388 case PPC::AND8:

5390 break;

5391

5393 BinOpDepth + 1, LV);

5395 BinOpDepth + 1, LV);

5396 break;

5397 }

5398

5400 if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)

5401 return;

5402

5404 MI->getMF()->getSubtarget<PPCSubtarget>().getInstrInfo();

5405

5406

5407

5408

5409 std::unordered_map<unsigned, unsigned> OpcodeMap = {

5410 {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},

5411 {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},

5412 {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},

5413 {PPC::AND, PPC::AND8}};

5414

5415 int NewOpcode = -1;

5416 auto It = OpcodeMap.find(Opcode);

5417 if (It != OpcodeMap.end()) {

5418

5419 NewOpcode = It->second;

5420 } else {

5421 if (TII->isSExt32To64(Opcode))

5422 return;

5423

5424

5425

5426

5427 NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr(Opcode);

5428 }

5429

5430 assert(NewOpcode != -1 &&

5431 "Must have a 64-bit opcode to map the 32-bit opcode!");

5432

5436 TRI->getRegClass(MCID.operands()[0].RegClass);

5437

5438 Register SrcReg = MI->getOperand(0).getReg();

5440

5441

5442

5443

5444 if (NewRC == SrcRC)

5445 return;

5446

5448 auto MBB = MI->getParent();

5449

5450

5451

5452

5453

5454

5456 for (unsigned i = 1; i < MI->getNumOperands(); i++) {

5458 if (!Operand.isReg())

5459 continue;

5460

5463 continue;

5464

5466 TRI->getRegClass(MCID.operands()[i].RegClass);

5468 if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||

5469 OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {

5470

5471 Register TmpReg = MRI->createVirtualRegister(NewUsedRegRC);

5472 Register DstTmpReg = MRI->createVirtualRegister(NewUsedRegRC);

5477 .addImm(PPC::sub_32);

5478 PromoteRegs[i] = DstTmpReg;

5479 }

5480 }

5481

5482 Register NewDefinedReg = MRI->createVirtualRegister(NewRC);

5483

5486 --Iter;

5488 for (unsigned i = 1; i < MI->getNumOperands(); i++) {

5489 if (auto It = PromoteRegs.find(i); It != PromoteRegs.end())

5491 else

5493 }

5494

5495 for (unsigned i = 1; i < Iter->getNumOperands(); i++) {

5497 if (!Operand.isReg())

5498 continue;

5501 continue;

5503 }

5504

5505 MI->eraseFromParent();

5506

5507

5508

5509

5510

5514}

5515

5516

5517

5518

5519

5520

5521std::pair<bool, bool>

5523 const unsigned BinOpDepth,

5526 return std::pair<bool, bool>(false, false);

5527

5529 if (MI)

5530 return std::pair<bool, bool>(false, false);

5531

5534

5535

5536

5537 if (IsSExt && IsZExt)

5538 return std::pair<bool, bool>(IsSExt, IsZExt);

5539

5540 switch (MI->getOpcode()) {

5541 case PPC::COPY: {

5542 Register SrcReg = MI->getOperand(1).getReg();

5543

5544

5545

5547

5549

5551 return std::pair<bool, bool>(SrcExt.first || IsSExt,

5552 SrcExt.second || IsZExt);

5553 }

5554

5555

5557

5558 if (MI->getParent()->getBasicBlock() ==

5560 Register VReg = MI->getOperand(0).getReg();

5564 return std::pair<bool, bool>(IsSExt, IsZExt);

5565 }

5566 }

5567

5568 if (SrcReg != PPC::X3) {

5569

5571 return std::pair<bool, bool>(SrcExt.first || IsSExt,

5572 SrcExt.second || IsZExt);

5573 }

5574

5575

5576

5577

5578

5579

5580

5582 std::pair<bool, bool> IsExtendPair = std::pair<bool, bool>(IsSExt, IsZExt);

5585 if (II == MBB->instr_begin() || (--II)->getOpcode() != PPC::ADJCALLSTACKUP)

5586 return IsExtendPair;

5587

5590 return IsExtendPair;

5591

5594 if (!CalleeFn)

5595 return IsExtendPair;

5597 if (IntTy && IntTy->getBitWidth() <= 32) {

5599 IsSExt |= Attrs.hasAttribute(Attribute::SExt);

5600 IsZExt |= Attrs.hasAttribute(Attribute::ZExt);

5601 return std::pair<bool, bool>(IsSExt, IsZExt);

5602 }

5603

5604 return IsExtendPair;

5605 }

5606

5607

5608

5609 case PPC::ORI:

5610 case PPC::XORI:

5611 case PPC::ORI8:

5612 case PPC::XORI8: {

5613 Register SrcReg = MI->getOperand(1).getReg();

5615 return std::pair<bool, bool>(SrcExt.first || IsSExt,

5616 SrcExt.second || IsZExt);

5617 }

5618

5619

5620

5621

5622

5623 case PPC::ORIS:

5624 case PPC::XORIS:

5625 case PPC::ORIS8:

5626 case PPC::XORIS8: {

5627 Register SrcReg = MI->getOperand(1).getReg();

5629 uint16_t Imm = MI->getOperand(2).getImm();

5630 if (Imm & 0x8000)

5631 return std::pair<bool, bool>(false, SrcExt.second || IsZExt);

5632 else

5633 return std::pair<bool, bool>(SrcExt.first || IsSExt,

5634 SrcExt.second || IsZExt);

5635 }

5636

5637

5638

5639 case PPC::OR:

5640 case PPC::OR8:

5641 case PPC::ISEL:

5642 case PPC::PHI: {

5644 return std::pair<bool, bool>(false, false);

5645

5646

5647

5648 unsigned OperandEnd = 3, OperandStride = 1;

5649 if (MI->getOpcode() == PPC::PHI) {

5650 OperandEnd = MI->getNumOperands();

5651 OperandStride = 2;

5652 }

5653

5654 IsSExt = true;

5655 IsZExt = true;

5656 for (unsigned I = 1; I != OperandEnd; I += OperandStride) {

5657 if (MI->getOperand(I).isReg())

5658 return std::pair<bool, bool>(false, false);

5659

5660 Register SrcReg = MI->getOperand(I).getReg();

5662 IsSExt &= SrcExt.first;

5663 IsZExt &= SrcExt.second;

5664 }

5665 return std::pair<bool, bool>(IsSExt, IsZExt);

5666 }

5667

5668

5669

5670

5671 case PPC::AND:

5672 case PPC::AND8: {

5674 return std::pair<bool, bool>(false, false);

5675

5676 Register SrcReg1 = MI->getOperand(1).getReg();

5677 Register SrcReg2 = MI->getOperand(2).getReg();

5680 return std::pair<bool, bool>(Src1Ext.first && Src2Ext.first,

5681 Src1Ext.second || Src2Ext.second);

5682 }

5683

5684 default:

5685 break;

5686 }

5687 return std::pair<bool, bool>(IsSExt, IsZExt);

5688}

5689

5691 return (Opcode == (Subtarget.isPPC64() ? PPC::BDNZ8 : PPC::BDNZ));

5692}

5693

5694namespace {

5699 int64_t TripCount;

5700

5701public:

5704 : Loop(Loop), EndLoop(EndLoop), LoopCount(LoopCount),

5706 TII(MF->getSubtarget().getInstrInfo()) {

5707

5708

5709 if (LoopCount->getOpcode() == PPC::LI8 || LoopCount->getOpcode() == PPC::LI)

5711 else

5712 TripCount = -1;

5713 }

5714

5715 bool shouldIgnoreForPipelining(const MachineInstr *MI) const override {

5716

5717 return MI == EndLoop;

5718 }

5719

5720 std::optional createTripCountGreaterCondition(

5721 int TC, MachineBasicBlock &MBB,

5722 SmallVectorImpl &Cond) override {

5723 if (TripCount == -1) {

5724

5725

5728 MF->getSubtarget().isPPC64() ? PPC::CTR8 : PPC::CTR,

5729 true));

5730 return {};

5731 }

5732

5733 return TripCount > TC;

5734 }

5735

5736 void setPreheader(MachineBasicBlock *NewPreheader) override {

5737

5738

5739 }

5740

5741 void adjustTripCount(int TripCountAdjust) override {

5742

5743

5744 if (LoopCount->getOpcode() == PPC::LI8 ||

5745 LoopCount->getOpcode() == PPC::LI) {

5746 int64_t TripCount = LoopCount->getOperand(1).getImm() + TripCountAdjust;

5748 return;

5749 }

5750

5751

5752

5753 }

5754

5755 void disposed(LiveIntervals *LIS) override {

5756 if (LIS) {

5759 }

5761

5763 }

5764};

5765}

5766

5767std::unique_ptrTargetInstrInfo::PipelinerLoopInfo

5769

5772 if (Preheader == LoopBB)

5773 Preheader = *std::next(LoopBB->pred_begin());

5775

5776 if (I != LoopBB->end() && isBDNZ(I->getOpcode())) {

5779 Register LoopCountReg = LoopInst->getOperand(0).getReg();

5781 MachineInstr *LoopCount = MRI.getUniqueVRegDef(LoopCountReg);

5782 return std::make_unique(LoopInst, &*I, LoopCount);

5783 }

5784 }

5785 return nullptr;

5786}

5787

5791

5792 unsigned LOOPi = (Subtarget.isPPC64() ? PPC::MTCTR8loop : PPC::MTCTRloop);

5793

5794

5795 for (auto &I : PreHeader.instrs())

5796 if (I.getOpcode() == LOOPi)

5797 return &I;

5798 return nullptr;

5799}

5800

5801

5802

5807 return false;

5808

5809

5812 return false;

5815 return false;

5816

5818 return false;

5819

5823 return true;

5824}

5825

5830

5833 return false;

5834

5835

5836

5837

5838

5839

5841 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr;

5842 int64_t OffsetA = 0, OffsetB = 0;

5848 int LowOffset = std::min(OffsetA, OffsetB);

5849 int HighOffset = std::max(OffsetA, OffsetB);

5850 LocationSize LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;

5852 LowOffset + (int)LowWidth.getValue() <= HighOffset)

5853 return true;

5854 }

5855 }

5856 return false;

5857}

unsigned const MachineRegisterInfo * MRI

MachineInstrBuilder & UseMI

MachineInstrBuilder MachineInstrBuilder & DefMI

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

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

Function Alias Analysis false

static const Function * getParent(const Value *V)

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

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

const HexagonInstrInfo * TII

Module.h This file contains the declarations for the Module class.

This file implements the LivePhysRegs utility for tracking liveness of physical registers.

This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...

Register const TargetRegisterInfo * TRI

Promote Memory to Register

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

uint64_t IntrinsicInst * II

static bool isOpZeroOfSubwordPreincLoad(int Opcode)

Definition PPCInstrInfo.cpp:5183

static bool MBBDefinesCTR(MachineBasicBlock &MBB)

Definition PPCInstrInfo.cpp:2181

static bool definedByZeroExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)

Definition PPCInstrInfo.cpp:5238

static cl::opt< float > FMARPFactor("ppc-fma-rp-factor", cl::Hidden, cl::init(1.5), cl::desc("register pressure factor for the transformations."))

#define InfoArrayIdxMULOpIdx

Definition PPCInstrInfo.cpp:274

static unsigned selectReg(int64_t Imm1, int64_t Imm2, unsigned CompareOpc, unsigned TrueReg, unsigned FalseReg, unsigned CRSubReg)

Definition PPCInstrInfo.cpp:3317

static unsigned getCRBitValue(unsigned CRBit)

Definition PPCInstrInfo.cpp:1650

static bool isAnImmediateOperand(const MachineOperand &MO)

Definition PPCInstrInfo.cpp:3130

static const uint16_t FMAOpIdxInfo[][6]

Definition PPCInstrInfo.cpp:284

static cl::opt< bool > DisableCTRLoopAnal("disable-ppc-ctrloop-analysis", cl::Hidden, cl::desc("Disable analysis for CTR loops"))

#define InfoArrayIdxAddOpIdx

Definition PPCInstrInfo.cpp:273

static cl::opt< bool > UseOldLatencyCalc("ppc-old-latency-calc", cl::Hidden, cl::desc("Use the old (incorrect) instruction latency calculation"))

#define InfoArrayIdxFMAInst

Definition PPCInstrInfo.cpp:270

static bool isClusterableLdStOpcPair(unsigned FirstOpc, unsigned SecondOpc, const PPCSubtarget &Subtarget)

Definition PPCInstrInfo.cpp:2924

static cl::opt< bool > EnableFMARegPressureReduction("ppc-fma-rp-reduction", cl::Hidden, cl::init(true), cl::desc("enable register pressure reduce in machine combiner pass."))

static bool isLdStSafeToCluster(const MachineInstr &LdSt, const TargetRegisterInfo *TRI)

Definition PPCInstrInfo.cpp:2904

const unsigned MAX_BINOP_DEPTH

Definition PPCInstrInfo.cpp:5307

static cl::opt< bool > DisableCmpOpt("disable-ppc-cmp-opt", cl::desc("Disable compare instruction optimization"), cl::Hidden)

#define InfoArrayIdxFSubInst

Definition PPCInstrInfo.cpp:275

#define InfoArrayIdxFAddInst

Definition PPCInstrInfo.cpp:271

#define InfoArrayIdxFMULInst

Definition PPCInstrInfo.cpp:272

static bool definedBySignExtendingOp(const unsigned Reg, const MachineRegisterInfo *MRI)

Definition PPCInstrInfo.cpp:5191

static cl::opt< bool > VSXSelfCopyCrash("crash-on-ppc-vsx-self-copy", cl::desc("Causes the backend to crash instead of generating a nop VSX copy"), cl::Hidden)

static void swapMIOperands(MachineInstr &MI, unsigned Op1, unsigned Op2)

Definition PPCInstrInfo.cpp:4420

static constexpr MCPhysReg SPReg

const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB

const SmallVectorImpl< MachineOperand > & Cond

static bool isPhysical(const MachineOperand &MO)

This file declares the machine register scavenger class.

static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)

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

#define STATISTIC(VARNAME, DESC)

Class for arbitrary precision integers.

uint64_t getZExtValue() const

Get zero extended value.

bool isZero() const

Determine if this value is zero, i.e. all bits are clear.

LLVM_ABI APInt rotl(unsigned rotateAmt) const

Rotate left by rotateAmt.

static APInt getBitsSetWithWrap(unsigned numBits, unsigned loBit, unsigned hiBit)

Wrap version of getBitsSet.

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

const T & front() const

front - Get the first element.

size_t size() const

size - Get the array size.

This class holds the attributes for a particular argument, parameter, function, or return value.

This is an important base class in LLVM.

LLVM_ABI Align getPrefTypeAlign(Type *Ty) const

Returns the preferred stack/global alignment for the specified type.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)

const BasicBlock & getEntryBlock() const

AttributeList getAttributes() const

Return the attribute list for this Function.

Type * getReturnType() const

Returns the type of the ret val.

LLVM_ABI const DataLayout & getDataLayout() const

Get the data layout of the module this global belongs to.

Itinerary data supplied by a subtarget to be used by a target.

std::optional< unsigned > getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const

Return the cycle for the given class and operand.

Class to represent integer types.

void RemoveMachineInstrFromMaps(MachineInstr &MI)

LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)

Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...

static LocationSize precise(uint64_t Value)

TypeSize getValue() const

Represents a single loop in the control flow graph.

Instances of this class represent a single low-level machine instruction.

void setOpcode(unsigned Op)

Describe properties that are true of each instruction in the target description file.

unsigned getNumOperands() const

Return the number of declared MachineOperands for this MachineInstruction.

ArrayRef< MCOperandInfo > operands() const

ArrayRef< MCPhysReg > implicit_defs() const

Return a list of registers that are potentially written by any instance of this machine instruction.

ArrayRef< MCPhysReg > implicit_uses() const

Return a list of registers that are potentially read by any instance of this machine instruction.

bool isPseudo() const

Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.

This holds information about one operand of a machine instruction, indicating the register class for ...

Wrapper class representing physical registers. Should be passed by value.

LLVM_ABI iterator getFirstTerminator()

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

Instructions::iterator instr_iterator

pred_iterator pred_begin()

MachineInstrBundleIterator< MachineInstr, true > reverse_iterator

Instructions::const_iterator const_instr_iterator

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

MachineInstrBundleIterator< MachineInstr > iterator

MachineInstrBundleIterator< const MachineInstr, true > const_reverse_iterator

The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...

const std::vector< MachineConstantPoolEntry > & getConstants() const

unsigned getConstantPoolIndex(const Constant *C, Align Alignment)

getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

Align getObjectAlign(int ObjectIdx) const

Return the alignment of the specified stack object.

int64_t getObjectSize(int ObjectIdx) const

Return the size of the specified object.

const TargetSubtargetInfo & getSubtarget() const

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

MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)

getMachineMemOperand - Allocate a new MachineMemOperand.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

const DataLayout & getDataLayout() const

Return the DataLayout attached to the Module associated to this MF.

Function & getFunction()

Return the LLVM function that this machine code represents.

Ty * getInfo()

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

MachineConstantPool * getConstantPool()

getConstantPool - Return the constant pool object for the current function.

const TargetMachine & getTarget() const

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

Register getReg(unsigned Idx) const

Get the register for the operand index.

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

const MachineInstrBuilder & add(const MachineOperand &MO) const

const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) 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

const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const

Representation of each machine instruction.

unsigned getOpcode() const

Returns the opcode of this MachineInstr.

bool mayLoadOrStore(QueryType Type=AnyInBundle) const

Return true if this instruction could possibly read or modify memory.

const MachineBasicBlock * getParent() const

bool isCall(QueryType Type=AnyInBundle) const

bool getFlag(MIFlag Flag) const

Return whether an MI flag is set.

LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)

Add the specified operand to the instruction.

LLVM_ABI unsigned getNumExplicitOperands() const

Returns the number of non-implicit operands.

bool hasImplicitDef() const

Returns true if the instruction has implicit definition.

bool modifiesRegister(Register Reg, const TargetRegisterInfo *TRI) const

Return true if the MachineInstr modifies (fully define or partially define) the specified register.

LLVM_ABI bool hasUnmodeledSideEffects() const

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

bool definesRegister(Register Reg, const TargetRegisterInfo *TRI) const

Return true if the MachineInstr fully defines the specified register.

LLVM_ABI void setDesc(const MCInstrDesc &TID)

Replace the instruction descriptor (thus opcode) of the current instruction with a new one.

bool hasOneMemOperand() const

Return true if this instruction has exactly one MachineMemOperand.

mmo_iterator memoperands_begin() const

Access to memory operands of the instruction.

LLVM_ABI bool hasOrderedMemoryRef() const

Return true if this instruction may have an ordered or volatile memory reference, or if the informati...

LLVM_ABI const MachineFunction * getMF() const

Return the function that contains the basic block that this instruction belongs to.

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.

LLVM_ABI void dump() const

LLVM_ABI void clearRegisterDeads(Register Reg)

Clear all dead flags on operands defining register Reg.

const MachineOperand & getOperand(unsigned i) const

uint32_t getFlags() const

Return the MI flags bitvector.

A description of a memory reference used in the backend.

@ MOLoad

The memory access reads data.

@ MOStore

The memory access writes data.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

void setImm(int64_t immVal)

bool isReg() const

isReg - Tests if this is a MO_Register operand.

MachineBasicBlock * getMBB() const

bool isCPI() const

isCPI - Tests if this is a MO_ConstantPoolIndex operand.

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

void setIsKill(bool Val=true)

MachineInstr * getParent()

getParent - Return the instruction that this operand belongs to.

static MachineOperand CreateImm(int64_t Val)

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

Register getReg() const

getReg - Returns the register number.

void setTargetFlags(unsigned F)

bool isFI() const

isFI - Tests if this is a MO_FrameIndex operand.

LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const

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

static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)

bool isMBB() const

isMBB - Tests if this is a MO_MachineBasicBlock operand.

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

defusechain_instr_iterator< true, false, false, true > use_instr_iterator

use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...

LLVM_ABI bool isLiveIn(Register Reg) const

PPCDispatchGroupSBHazardRecognizer - This class implements a scoreboard-based hazard recognizer for P...

PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...

bool isLiveInSExt(Register VReg) const

This function returns true if the specified vreg is a live-in register and sign-extended.

bool isLiveInZExt(Register VReg) const

This function returns true if the specified vreg is a live-in register and zero-extended.

PPCHazardRecognizer970 - This class defines a finite state automata that models the dispatch logic on...

Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition PPCInstrInfo.cpp:1062

Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override

Definition PPCInstrInfo.cpp:1118

bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const override

Definition PPCInstrInfo.cpp:2215

bool getFMAPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const

Return true when there is potentially a faster code sequence for a fma chain ending in Root.

Definition PPCInstrInfo.cpp:350

bool combineRLWINM(MachineInstr &MI, MachineInstr **ToErase=nullptr) const

Definition PPCInstrInfo.cpp:3861

bool isReMaterializableImpl(const MachineInstr &MI) const override

Definition PPCInstrInfo.cpp:1078

PPCInstrInfo(const PPCSubtarget &STI)

Definition PPCInstrInfo.cpp:91

const TargetRegisterClass * updatedRC(const TargetRegisterClass *RC) const

Definition PPCInstrInfo.cpp:5173

bool isPredicated(const MachineInstr &MI) const override

Definition PPCInstrInfo.cpp:2204

bool expandVSXMemPseudo(MachineInstr &MI) const

Definition PPCInstrInfo.cpp:3068

bool onlyFoldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg) const

Definition PPCInstrInfo.cpp:2112

void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override

Definition PPCInstrInfo.cpp:1677

void finalizeInsInstrs(MachineInstr &Root, unsigned &Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs) const override

Fixup the placeholders we put in genAlternativeCodeSequence() for MachineCombiner.

Definition PPCInstrInfo.cpp:525

MCInst getNop() const override

Return the noop instruction to use for a noop.

Definition PPCInstrInfo.cpp:1250

void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition PPCInstrInfo.cpp:2034

static int getRecordFormOpcode(unsigned Opcode)

Definition PPCInstrInfo.cpp:5179

MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const override

Commutes the operands in the given instruction.

Definition PPCInstrInfo.cpp:1130

bool isXFormMemOp(unsigned Opcode) const

const PPCRegisterInfo & getRegisterInfo() const

getRegisterInfo - TargetInstrInfo is a superset of MRegister info.

CombinerObjective getCombinerObjective(unsigned Pattern) const override

Definition PPCInstrInfo.cpp:739

unsigned getStoreOpcodeForSpill(const TargetRegisterClass *RC) const

Definition PPCInstrInfo.cpp:1982

unsigned getLoadOpcodeForSpill(const TargetRegisterClass *RC) const

Definition PPCInstrInfo.cpp:1988

void promoteInstr32To64ForElimEXTSW(const Register &Reg, MachineRegisterInfo *MRI, unsigned BinOpDepth, LiveVariables *LV) const

Definition PPCInstrInfo.cpp:5318

bool isTOCSaveMI(const MachineInstr &MI) const

Definition PPCInstrInfo.cpp:5292

ScheduleHazardRecognizer * CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II, const ScheduleDAG *DAG) const override

CreateTargetPostRAHazardRecognizer - Return the postRA hazard recognizer to use for this target when ...

Definition PPCInstrInfo.cpp:117

bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const override

Definition PPCInstrInfo.cpp:2173

bool isBDNZ(unsigned Opcode) const

Check Opcode is BDNZ (Decrement CTR and branch if it is still nonzero).

Definition PPCInstrInfo.cpp:5690

bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override

Definition PPCInstrInfo.cpp:2099

bool isZeroExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const

std::pair< unsigned, unsigned > decomposeMachineOperandsTargetFlags(unsigned TF) const override

Definition PPCInstrInfo.cpp:3023

std::pair< bool, bool > isSignOrZeroExtended(const unsigned Reg, const unsigned BinOpDepth, const MachineRegisterInfo *MRI) const

Definition PPCInstrInfo.cpp:5522

bool expandPostRAPseudo(MachineInstr &MI) const override

Definition PPCInstrInfo.cpp:3134

bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override

void insertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override

Definition PPCInstrInfo.cpp:1230

bool isValidToBeChangedReg(MachineInstr *ADDMI, unsigned Index, MachineInstr *&ADDIMI, int64_t &OffsetAddi, int64_t OffsetImm) const

Definition PPCInstrInfo.cpp:3754

bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const override

Definition PPCInstrInfo.cpp:2432

ArrayRef< std::pair< unsigned, const char * > > getSerializableDirectMachineOperandTargetFlags() const override

Definition PPCInstrInfo.cpp:3029

std::optional< unsigned > getOperandLatency(const InstrItineraryData *ItinData, const MachineInstr &DefMI, unsigned DefIdx, const MachineInstr &UseMI, unsigned UseIdx) const override

Definition PPCInstrInfo.cpp:167

void materializeImmPostRA(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, Register Reg, int64_t Imm) const

Definition PPCInstrInfo.cpp:3418

bool isADDInstrEligibleForFolding(MachineInstr &ADDMI) const

Definition PPCInstrInfo.cpp:3704

bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override

Return true if two MIs access different memory addresses and false otherwise.

Definition PPCInstrInfo.cpp:5826

bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override

Definition PPCInstrInfo.cpp:2336

ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const override

CreateTargetHazardRecognizer - Return the hazard recognizer to use for this target when scheduling th...

Definition PPCInstrInfo.cpp:100

bool canInsertSelect(const MachineBasicBlock &, ArrayRef< MachineOperand > Cond, Register, Register, Register, int &, int &, int &) const override

Definition PPCInstrInfo.cpp:1519

bool getMemOperandsWithOffsetWidth(const MachineInstr &LdSt, SmallVectorImpl< const MachineOperand * > &BaseOps, int64_t &Offset, bool &OffsetIsScalable, LocationSize &Width, const TargetRegisterInfo *TRI) const override

Get the base operand and byte offset of an instruction that reads/writes memory.

Definition PPCInstrInfo.cpp:2892

void setSpecialOperandAttr(MachineInstr &MI, uint32_t Flags) const

Definition PPCInstrInfo.cpp:219

bool isADDIInstrEligibleForFolding(MachineInstr &ADDIMI, int64_t &Imm) const

Definition PPCInstrInfo.cpp:3687

void loadRegFromStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC) const

Definition PPCInstrInfo.cpp:2059

void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override

Definition PPCInstrInfo.cpp:2080

bool foldFrameOffset(MachineInstr &MI) const

Definition PPCInstrInfo.cpp:3590

bool isLoadFromConstantPool(MachineInstr *I) const

Definition PPCInstrInfo.cpp:655

MachineInstr * findLoopInstr(MachineBasicBlock &PreHeader, SmallPtrSet< MachineBasicBlock *, 8 > &Visited) const

Find the hardware loop instruction used to set-up the specified loop.

Definition PPCInstrInfo.cpp:5788

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

Definition PPCInstrInfo.cpp:1434

unsigned getInstrLatency(const InstrItineraryData *ItinData, const MachineInstr &MI, unsigned *PredCost=nullptr) const override

Definition PPCInstrInfo.cpp:137

void storeRegToStackSlotNoUpd(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC) const

Definition PPCInstrInfo.cpp:2015

bool isCoalescableExtInstr(const MachineInstr &MI, Register &SrcReg, Register &DstReg, unsigned &SubIdx) const override

Definition PPCInstrInfo.cpp:1047

bool convertToImmediateForm(MachineInstr &MI, SmallSet< Register, 4 > &RegsToUpdate, MachineInstr **KilledDef=nullptr) const

Definition PPCInstrInfo.cpp:3799

bool isAssociativeAndCommutative(const MachineInstr &Inst, bool Invert) const override

Definition PPCInstrInfo.cpp:232

bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const override

Definition PPCInstrInfo.cpp:2402

bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, LocationSize &Width, const TargetRegisterInfo *TRI) const

Return true if get the base operand, byte offset of an instruction and the memory width.

Definition PPCInstrInfo.cpp:5803

unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override

Definition PPCInstrInfo.cpp:1466

bool shouldReduceRegisterPressure(const MachineBasicBlock *MBB, const RegisterClassInfo *RegClassInfo) const override

On PowerPC, we leverage machine combiner pass to reduce register pressure when the register pressure ...

Definition PPCInstrInfo.cpp:595

void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstrIdxForVirtReg) const override

When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...

Definition PPCInstrInfo.cpp:767

bool isSignExtended(const unsigned Reg, const MachineRegisterInfo *MRI) const

void replaceInstrOperandWithImm(MachineInstr &MI, unsigned OpNo, int64_t Imm) const

Definition PPCInstrInfo.cpp:3347

unsigned getInstSizeInBytes(const MachineInstr &MI) const override

GetInstSize - Return the number of bytes of code the specified instruction may be.

Definition PPCInstrInfo.cpp:3004

std::unique_ptr< TargetInstrInfo::PipelinerLoopInfo > analyzeLoopForPipelining(MachineBasicBlock *LoopBB) const override

Analyze loop L, which must be a single-basic-block loop, and if the conditions can be understood enou...

Definition PPCInstrInfo.cpp:5768

bool shouldClusterMemOps(ArrayRef< const MachineOperand * > BaseOps1, int64_t Offset1, bool OffsetIsScalable1, ArrayRef< const MachineOperand * > BaseOps2, int64_t Offset2, bool OffsetIsScalable2, unsigned ClusterSize, unsigned NumBytes) const override

Returns true if the two given memory operations should be scheduled adjacent.

Definition PPCInstrInfo.cpp:2943

void replaceInstrWithLI(MachineInstr &MI, const LoadImmediateInfo &LII) const

Definition PPCInstrInfo.cpp:3378

bool isImmInstrEligibleForFolding(MachineInstr &MI, unsigned &BaseReg, unsigned &XFormOpcode, int64_t &OffsetOfImmInstr, ImmInstrInfo &III) const

Definition PPCInstrInfo.cpp:3711

bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Pred) const override

Definition PPCInstrInfo.cpp:2232

bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const override

Return true when there is potentially a faster code sequence for an instruction chain ending in <Root...

Definition PPCInstrInfo.cpp:752

bool optimizeCmpPostRA(MachineInstr &MI) const

Definition PPCInstrInfo.cpp:2817

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

Definition PPCInstrInfo.cpp:1259

const Constant * getConstantFromConstantPool(MachineInstr *I) const

Definition PPCInstrInfo.cpp:719

bool ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override

Definition PPCInstrInfo.cpp:2367

void insertSelect(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const DebugLoc &DL, Register DstReg, ArrayRef< MachineOperand > Cond, Register TrueReg, Register FalseReg) const override

Definition PPCInstrInfo.cpp:1565

bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override

Definition PPCInstrInfo.cpp:1214

bool instrHasImmForm(unsigned Opc, bool IsVFReg, ImmInstrInfo &III, bool PostRA) const

Definition PPCInstrInfo.cpp:3998

MachineInstr * getDefMIPostRA(unsigned Reg, MachineInstr &MI, bool &SeenIntermediateUse) const

Definition PPCInstrInfo.cpp:3401

static void emitAccCopyInfo(MachineBasicBlock &MBB, MCRegister DestReg, MCRegister SrcReg)

const PPCTargetMachine & getTargetMachine() const

MI-level patchpoint operands.

uint32_t getNumPatchBytes() const

Return the number of patchable bytes the given patchpoint should emit.

Track the current register pressure at some position in the instruction stream, and remember the high...

LLVM_ABI void closeRegion()

Finalize the region boundaries and recored live ins and live outs.

LLVM_ABI void recede(SmallVectorImpl< VRegMaskOrUnit > *LiveUses=nullptr)

Recede across the previous instruction.

RegisterPressure & getPressure()

Get the resulting register pressure over the traversed region.

LLVM_ABI void recedeSkipDebugValues()

Recede until we find an instruction which is not a DebugValue.

LLVM_ABI void init(const MachineFunction *mf, const RegisterClassInfo *rci, const LiveIntervals *lis, const MachineBasicBlock *mbb, MachineBasicBlock::const_iterator pos, bool TrackLaneMasks, bool TrackUntiedDefs)

Setup the RegPressureTracker.

MachineBasicBlock::const_iterator getPos() const

Get the MI position corresponding to this register pressure.

unsigned getRegPressureSetLimit(unsigned Idx) const

Get the register unit limit for the given pressure set index.

List of registers defined and used by a machine instruction.

LLVM_ABI void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)

Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...

Wrapper class representing virtual and physical registers.

constexpr bool isVirtual() const

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

static constexpr bool isVirtualRegister(unsigned Reg)

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

const TargetInstrInfo * TII

Target instruction information.

MachineFunction & MF

Machine function.

HazardRecognizer - This determines whether or not an instruction can be issued this cycle,...

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.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

iterator insert(iterator I, T &&Elt)

void push_back(const T &Elt)

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

MI-level stackmap operands.

uint32_t getNumPatchBytes() const

Return the number of patchable bytes the given stackmap should emit.

StackOffset holds a fixed and a scalable offset in bytes.

Object returned by analyzeLoopForPipelining.

TargetInstrInfo - Interface to description of machine instruction set.

virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const

Returns true iff the routine could find two commutable operands in the given machine instruction.

virtual void genAlternativeCodeSequence(MachineInstr &Root, unsigned Pattern, SmallVectorImpl< MachineInstr * > &InsInstrs, SmallVectorImpl< MachineInstr * > &DelInstrs, DenseMap< Register, unsigned > &InstIdxForVirtReg) const

When getMachineCombinerPatterns() finds patterns, this function generates the instructions that could...

virtual ScheduleHazardRecognizer * CreateTargetHazardRecognizer(const TargetSubtargetInfo *STI, const ScheduleDAG *DAG) const

Allocate and return a hazard recognizer to use for this target when scheduling the machine instructio...

virtual bool getMachineCombinerPatterns(MachineInstr &Root, SmallVectorImpl< unsigned > &Patterns, bool DoRegPressureReduce) const

Return true when there is potentially a faster code sequence for an instruction chain ending in Root.

virtual bool isReMaterializableImpl(const MachineInstr &MI) const

For instructions with opcodes for which the M_REMATERIALIZABLE flag is set, this hook lets the target...

virtual bool isSchedulingBoundary(const MachineInstr &MI, const MachineBasicBlock *MBB, const MachineFunction &MF) const

Test if the given instruction should be considered a scheduling boundary.

virtual CombinerObjective getCombinerObjective(unsigned Pattern) const

Return the objective of a combiner pattern.

virtual MachineInstr * commuteInstructionImpl(MachineInstr &MI, bool NewMI, unsigned OpIdx1, unsigned OpIdx2) const

This method commutes the operands of the given machine instruction MI.

CodeModel::Model getCodeModel() const

Returns the code model.

const MCAsmInfo * getMCAsmInfo() const

Return target specific asm information.

bool contains(Register Reg) const

Return true if the specified register is included in this register class.

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

TargetSubtargetInfo - Generic base class for all target subtargets.

The instances of the Type class are immutable: once they are created, they are never changed.

LLVM Value Representation.

LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const

Returns an alignment of the pointer value.

#define llvm_unreachable(msg)

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

constexpr std::underlying_type_t< E > Mask()

Get a bitmask with 1s in all places up to the high-order bit of E's largest value.

@ C

The default llvm calling convention, compatible with C.

PPCII - This namespace holds all of the PowerPC target-specific per-instruction flags.

Define some predicates that are used for node matching.

Predicate getSwappedPredicate(Predicate Opcode)

Assume the condition register is set by MI(a,b), return the predicate if we modify the instructions s...

Predicate

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

int getAltVSXFMAOpcode(uint16_t Opcode)

int getNonRecordFormOpcode(uint16_t)

unsigned getPredicateCondition(Predicate Opcode)

Return the condition without hint bits.

Predicate getPredicate(unsigned Condition, unsigned Hint)

Return predicate consisting of specified condition and hint bits.

unsigned getPredicateHint(Predicate Opcode)

Return the hint bits of the predicate.

Predicate InvertPredicate(Predicate Opcode)

Invert the specified predicate. != -> ==, < -> >=.

static bool isVFRegister(MCRegister Reg)

@ Implicit

Not emitted register (e.g. carry, or temporary result).

@ Define

Register definition.

@ Kill

The last use of a register.

template class LLVM_TEMPLATE_ABI opt< bool >

initializer< Ty > init(const Ty &Val)

NodeAddr< InstrNode * > Instr

This is an optimization pass for GlobalISel generic memory operations.

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

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

constexpr bool isInt(int64_t x)

Checks if an integer fits into the given bit width.

decltype(auto) dyn_cast(const From &Val)

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

auto dyn_cast_if_present(const Y &Val)

dyn_cast_if_present - Functionally identical to dyn_cast, except that a null (or none in the case ...

unsigned getDeadRegState(bool B)

static const MachineInstrBuilder & addFrameReference(const MachineInstrBuilder &MIB, int FI, int Offset=0, bool mem=true)

addFrameReference - This function is used to add a reference to the base of an abstract object on the...

static unsigned getCRFromCRBit(unsigned SrcReg)

auto reverse(ContainerTy &&C)

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.

CombinerObjective

The combiner's goal may differ based on which pattern it is attempting to optimize.

@ MustReduceRegisterPressure

constexpr bool isUInt(uint64_t x)

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

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

void recomputeLivenessFlags(MachineBasicBlock &MBB)

Recomputes dead and kill flags in MBB.

@ Sub

Subtraction of integers.

unsigned getKillRegState(bool B)

uint16_t MCPhysReg

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

DWARFExpression::Operation Op

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

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

Returns true if Element is found in Range.

constexpr int64_t SignExtend64(uint64_t x)

Sign-extend the number in the bottom B bits of X to a 64-bit integer.

static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME)

Returns true iff Val consists of one contiguous run of 1s with any number of 0s on either side.

This struct is a compact representation of a valid (non-zero power of two) alignment.

uint64_t IsSummingOperands

uint64_t OpNoForForwarding

uint64_t ImmMustBeMultipleOf

uint64_t ZeroIsSpecialNew

uint64_t ZeroIsSpecialOrig

static LLVM_ABI MachinePointerInfo getConstantPool(MachineFunction &MF)

Return a MachinePointerInfo record that refers to the constant pool.

static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)

Return a MachinePointerInfo record that refers to the specified FrameIndex.

RegisterPressure computed within a region of instructions delimited by TopPos and BottomPos.

std::vector< unsigned > MaxSetPressure

Map of max reg pressure indexed by pressure set ID, not class ID.