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

1

2

3

4

5

6

7

8

9

10

11

12

30

31using namespace llvm;

32

33#define DEBUG_TYPE "framelowering"

34STATISTIC(NumPESpillVSR, "Number of spills to vector in prologue");

35STATISTIC(NumPEReloadVSR, "Number of reloads from vector in epilogue");

36STATISTIC(NumPrologProbed, "Number of prologues probed");

37

40 cl::desc("Enable spills in prologue to vector registers."),

42

45 return STI.isPPC64() ? 16 : 8;

46

47 return STI.isPPC64() ? 16 : 4;

48}

49

52 return STI.isPPC64() ? 40 : 20;

54}

55

57

58 return STI.isPPC64() ? -8U : -4U;

59}

60

62 if (STI.isAIXABI() || STI.isPPC64())

63 return (STI.isELFv2ABI() ? 4 : 6) * (STI.isPPC64() ? 8 : 4);

64

65

66 return 8;

67}

68

70

72 return -12U;

73

74

75 return STI.isPPC64() ? -16U : -8U;

76}

77

79 return (STI.isAIXABI() && !STI.isPPC64()) ? 4 : 8;

80}

81

84 STI.getPlatformStackAlignment(), 0),

91

92

94 unsigned &NumEntries) const {

95

96

97#define CALLEE_SAVED_FPRS \

98 {PPC::F31, -8}, \

99 {PPC::F30, -16}, \

100 {PPC::F29, -24}, \

101 {PPC::F28, -32}, \

102 {PPC::F27, -40}, \

103 {PPC::F26, -48}, \

104 {PPC::F25, -56}, \

105 {PPC::F24, -64}, \

106 {PPC::F23, -72}, \

107 {PPC::F22, -80}, \

108 {PPC::F21, -88}, \

109 {PPC::F20, -96}, \

110 {PPC::F19, -104}, \

111 {PPC::F18, -112}, \

112 {PPC::F17, -120}, \

113 {PPC::F16, -128}, \

114 {PPC::F15, -136}, \

115 {PPC::F14, -144}

116

117

118

119#define CALLEE_SAVED_GPRS32 \

120 {PPC::R31, -4}, \

121 {PPC::R30, -8}, \

122 {PPC::R29, -12}, \

123 {PPC::R28, -16}, \

124 {PPC::R27, -20}, \

125 {PPC::R26, -24}, \

126 {PPC::R25, -28}, \

127 {PPC::R24, -32}, \

128 {PPC::R23, -36}, \

129 {PPC::R22, -40}, \

130 {PPC::R21, -44}, \

131 {PPC::R20, -48}, \

132 {PPC::R19, -52}, \

133 {PPC::R18, -56}, \

134 {PPC::R17, -60}, \

135 {PPC::R16, -64}, \

136 {PPC::R15, -68}, \

137 {PPC::R14, -72}

138

139

140#define CALLEE_SAVED_GPRS64 \

141 {PPC::X31, -8}, \

142 {PPC::X30, -16}, \

143 {PPC::X29, -24}, \

144 {PPC::X28, -32}, \

145 {PPC::X27, -40}, \

146 {PPC::X26, -48}, \

147 {PPC::X25, -56}, \

148 {PPC::X24, -64}, \

149 {PPC::X23, -72}, \

150 {PPC::X22, -80}, \

151 {PPC::X21, -88}, \

152 {PPC::X20, -96}, \

153 {PPC::X19, -104}, \

154 {PPC::X18, -112}, \

155 {PPC::X17, -120}, \

156 {PPC::X16, -128}, \

157 {PPC::X15, -136}, \

158 {PPC::X14, -144}

159

160

161#define CALLEE_SAVED_VRS \

162 {PPC::V31, -16}, \

163 {PPC::V30, -32}, \

164 {PPC::V29, -48}, \

165 {PPC::V28, -64}, \

166 {PPC::V27, -80}, \

167 {PPC::V26, -96}, \

168 {PPC::V25, -112}, \

169 {PPC::V24, -128}, \

170 {PPC::V23, -144}, \

171 {PPC::V22, -160}, \

172 {PPC::V21, -176}, \

173 {PPC::V20, -192}

174

175

176

177

178 static const SpillSlot ELFOffsets32[] = {

181

182

183

184

185

186 {PPC::CR2, -4},

187

188

189 {PPC::VRSAVE, -4},

190

192

193

194 {PPC::S31, -8},

195 {PPC::S30, -16},

196 {PPC::S29, -24},

197 {PPC::S28, -32},

198 {PPC::S27, -40},

199 {PPC::S26, -48},

200 {PPC::S25, -56},

201 {PPC::S24, -64},

202 {PPC::S23, -72},

203 {PPC::S22, -80},

204 {PPC::S21, -88},

205 {PPC::S20, -96},

206 {PPC::S19, -104},

207 {PPC::S18, -112},

208 {PPC::S17, -120},

209 {PPC::S16, -128},

210 {PPC::S15, -136},

211 {PPC::S14, -144}};

212

213 static const SpillSlot ELFOffsets64[] = {

216

217

218 {PPC::VRSAVE, -4},

220 };

221

224

225 {PPC::R13, -76},

227

228 static const SpillSlot AIXOffsets64[] = {

230

231 if (Subtarget.is64BitELFABI()) {

232 NumEntries = std::size(ELFOffsets64);

233 return ELFOffsets64;

234 }

235

236 if (Subtarget.is32BitELFABI()) {

237 NumEntries = std::size(ELFOffsets32);

238 return ELFOffsets32;

239 }

240

241 assert(Subtarget.isAIXABI() && "Unexpected ABI.");

242

243 if (Subtarget.isPPC64()) {

244 NumEntries = std::size(AIXOffsets64);

245 return AIXOffsets64;

246 }

247

248 NumEntries = std::size(AIXOffsets32);

249 return AIXOffsets32;

250}

251

256

261

266

267

268

269

280

281

282

283uint64_t

285 bool UseEstimate) const {

286 unsigned NewMaxCallFrameSize = 0;

288 &NewMaxCallFrameSize);

291 return FrameSize;

292}

293

294

295

298 bool UseEstimate,

299 unsigned *NewMaxCallFrameSize) const {

302

303

306

307

308 Align TargetAlign = getStackAlign();

309 Align MaxAlign = MFI.getMaxAlign();

310 Align Alignment = std::max(TargetAlign, MaxAlign);

311

312 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

313

314 MCRegister LR = RegInfo->getRARegister();

316 bool CanUseRedZone = !MFI.hasVarSizedObjects() &&

318 MustSaveLR(MF, LR) &&

319 !FI->mustSaveTOC() &&

320 !RegInfo->hasBasePointer(MF) &&

322

323

324

325 bool FitsInRedZone = FrameSize <= Subtarget.getRedZoneSize();

326

327

328 if (!DisableRedZone && CanUseRedZone && FitsInRedZone) {

329

330 return 0;

331 }

332

333

335

336

338 maxCallFrameSize = std::max(maxCallFrameSize, minCallFrameSize);

339

340

341

343 maxCallFrameSize = alignTo(maxCallFrameSize, Alignment);

344

345

346 if (NewMaxCallFrameSize)

347 *NewMaxCallFrameSize = maxCallFrameSize;

348

349

350 FrameSize += maxCallFrameSize;

351

352

353 FrameSize = alignTo(FrameSize, Alignment);

354

355 return FrameSize;

356}

357

358

359

367

368

369

370

373

374

375

377 return false;

378

384}

385

387

388

389

391 unsigned FPReg = is31 ? PPC::R31 : PPC::R1;

392 unsigned FP8Reg = is31 ? PPC::X31 : PPC::X1;

393

394 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

396 unsigned BPReg = HasBP ? (unsigned) RegInfo->getBaseRegister(MF) : FPReg;

397 unsigned BP8Reg = HasBP ? (unsigned) PPC::X30 : FP8Reg;

398

403 if (!MO.isReg())

404 continue;

405

406 switch (MO.getReg()) {

407 case PPC::FP:

408 MO.setReg(FPReg);

409 break;

410 case PPC::FP8:

411 MO.setReg(FP8Reg);

412 break;

413 case PPC::BP:

414 MO.setReg(BPReg);

415 break;

416 case PPC::BP8:

417 MO.setReg(BP8Reg);

418 break;

419

420 }

421 }

422 }

423}

424

425

426

427

428

429

430

431

432

433

434

435

436

437

438

439

440

441bool

443 bool UseAtEnd,

444 bool TwoUniqueRegsRequired,

448 Register R0 = Subtarget.isPPC64() ? PPC::X0 : PPC::R0;

449 Register R12 = Subtarget.isPPC64() ? PPC::X12 : PPC::R12;

450

451

452 if (SR1)

453 *SR1 = R0;

454

455 if (SR2) {

456 assert (SR1 && "Asking for the second scratch register but not the first?");

457 *SR2 = R12;

458 }

459

460

461 if ((UseAtEnd && MBB->isReturnBlock()) ||

462 (!UseAtEnd && (&MBB->getParent()->front() == MBB)))

463 return true;

464

465 if (UseAtEnd) {

466

467

469 if (MBBI == MBB->begin()) {

470 RS.enterBasicBlock(*MBB);

471 } else {

472 RS.enterBasicBlockEnd(*MBB);

474 }

475 } else {

476

477 RS.enterBasicBlock(*MBB);

478 }

479

480

481

482

483

484 if (RS.isRegUsed(R0) && RS.isRegUsed(R12))

485 return true;

486

487

488 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

490

491

492 BitVector BV = RS.getRegsAvailable(Subtarget.isPPC64() ? &PPC::G8RCRegClass :

493 &PPC::GPRCRegClass);

494

495

496

497

498

499 for (int i = 0; CSRegs[i]; ++i)

500 BV.reset(CSRegs[i]);

501

502

503 if (SR1) {

504 int FirstScratchReg = BV.find_first();

505 *SR1 = FirstScratchReg == -1 ? (unsigned)PPC::NoRegister : FirstScratchReg;

506 }

507

508

509

510

511 if (SR2) {

512 int SecondScratchReg = BV.find_next(*SR1);

513 if (SecondScratchReg != -1)

514 *SR2 = SecondScratchReg;

515 else

516 *SR2 = TwoUniqueRegsRequired ? Register() : *SR1;

517 }

518

519

520

521 if (BV.count() < (TwoUniqueRegsRequired ? 2U : 1U))

522 return false;

523

524 return true;

525}

526

527

528

529

530

531

532

533

534bool

535PPCFrameLowering::twoUniqueScratchRegsRequired(MachineBasicBlock *MBB) const {

536 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

540 int NegFrameSize = -FrameSize;

541 bool IsLargeFrame = isInt<16>(NegFrameSize);

544 bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();

545 const PPCTargetLowering &TLI = *Subtarget.getTargetLowering();

546

547 return ((IsLargeFrame || !HasRedZone) && HasBP && MaxAlign > 1) ||

549}

550

553

554 return findScratchRegister(TmpMBB, false,

555 twoUniqueScratchRegsRequired(TmpMBB));

556}

557

560

561 return findScratchRegister(TmpMBB, true);

562}

563

564bool PPCFrameLowering::stackUpdateCanBeMoved(MachineFunction &MF) const {

567

568

569 if (!RegInfo || !FI)

570 return false;

571

572

573 if (!Subtarget.isELFv2ABI() || !Subtarget.isPPC64())

574 return false;

575

576

577

578

579

580

581

582

585 if (!FrameSize || FrameSize > Subtarget.getRedZoneSize())

586 return false;

587

588

589

590

591

593 return false;

594

595

596

597

598

600 return false;

601

602

603

604

605 return !RegInfo->requiresFrameIndexScavenging(MF);

606}

607

613 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

615

618

619 const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();

620

621 const bool HasFastMFLR = Subtarget.hasFastMFLR();

622

623

624 bool isPPC64 = Subtarget.isPPC64();

625

626 bool isSVR4ABI = Subtarget.isSVR4ABI();

627 bool isELFv2ABI = Subtarget.isELFv2ABI();

628 assert((isSVR4ABI || Subtarget.isAIXABI()) && "Unsupported PPC ABI.");

629

630

632 int64_t NegFrameSize = -FrameSize;

635

638

639

644 bool MustSaveCR = !MustSaveCRs.empty();

645

646 bool HasFP = hasFP(MF);

647 bool HasBP = RegInfo->hasBasePointer(MF);

648 bool HasRedZone = isPPC64 || !isSVR4ABI;

649 const bool HasROPProtect = Subtarget.hasROPProtect();

650 bool HasPrivileged = Subtarget.hasPrivileged();

651

653 Register BPReg = RegInfo->getBaseRegister(MF);

655 Register LRReg = isPPC64 ? PPC::LR8 : PPC::LR;

656 Register TOCReg = isPPC64 ? PPC::X2 : PPC::R2;

658 Register TempReg = isPPC64 ? PPC::X12 : PPC::R12;

659

660 const MCInstrDesc& MFLRInst = TII.get(isPPC64 ? PPC::MFLR8

661 : PPC::MFLR );

663 : PPC::STW );

664 const MCInstrDesc& StoreUpdtInst = TII.get(isPPC64 ? PPC::STDU

665 : PPC::STWU );

666 const MCInstrDesc& StoreUpdtIdxInst = TII.get(isPPC64 ? PPC::STDUX

667 : PPC::STWUX);

668 const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8

669 : PPC::OR );

670 const MCInstrDesc& SubtractCarryingInst = TII.get(isPPC64 ? PPC::SUBFC8

671 : PPC::SUBFC);

672 const MCInstrDesc& SubtractImmCarryingInst = TII.get(isPPC64 ? PPC::SUBFIC8

673 : PPC::SUBFIC);

674 const MCInstrDesc &MoveFromCondRegInst = TII.get(isPPC64 ? PPC::MFCR8

675 : PPC::MFCR);

676 const MCInstrDesc &StoreWordInst = TII.get(isPPC64 ? PPC::STW8 : PPC::STW);

678 TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHSTP8 : PPC::HASHST8)

679 : (HasPrivileged ? PPC::HASHSTP : PPC::HASHST));

680

681

682

683

684

685 assert((isPPC64 || !isSVR4ABI || !(!FrameSize && (MustSaveLR || HasFP))) &&

686 "FrameSize must be >0 to save/restore the FP or LR for 32-bit SVR4.");

687

688

689 bool SingleScratchReg = findScratchRegister(

690 &MBB, false, twoUniqueScratchRegsRequired(&MBB), &ScratchReg, &TempReg);

691 assert(SingleScratchReg &&

692 "Required number of registers not available in this block");

693

694 SingleScratchReg = ScratchReg == TempReg;

695

697

698 int64_t FPOffset = 0;

699 if (HasFP) {

702 assert(FPIndex && "No Frame Pointer Save Slot!");

704 }

705

706 int64_t BPOffset = 0;

707 if (HasBP) {

710 assert(BPIndex && "No Base Pointer Save Slot!");

712 }

713

714 int64_t PBPOffset = 0;

718 assert(PBPIndex && "No PIC Base Pointer Save Slot!");

720 }

721

722

724 if (HasBP && MaxAlign > 1)

725 assert(Log2(MaxAlign) < 16 && "Invalid alignment!");

726

727

728

729 bool isLargeFrame = isInt<16>(NegFrameSize);

730

731

732

733

735 bool MovingStackUpdateDown = false;

736

737

738 if (stackUpdateCanBeMoved(MF)) {

741

742

743

744

745

746

747

748

749

750

751 if (CSI.isSpilledToReg()) {

752 StackUpdateLoc = MBBI;

753 MovingStackUpdateDown = false;

754 break;

755 }

756

757 int FrIdx = CSI.getFrameIdx();

758

759

760

761 if (FrIdx >= 0)

762 continue;

763

765 StackUpdateLoc++;

766 MovingStackUpdateDown = true;

767 } else {

768

769

770 StackUpdateLoc = MBBI;

771 MovingStackUpdateDown = false;

772 break;

773 }

774 }

775

776

777 if (MovingStackUpdateDown) {

779 int FrIdx = CSI.getFrameIdx();

780 if (FrIdx < 0)

782 }

783 }

784 }

785

786

787

788

789 auto BuildMoveFromCR = [&]() {

790 if (isELFv2ABI && MustSaveCRs.size() == 1) {

791

792

793

794

795 assert(isPPC64 && "V2 ABI is 64-bit only.");

799 } else {

801 BuildMI(MBB, MBBI, dl, MoveFromCondRegInst, TempReg);

802 for (unsigned CRfield : MustSaveCRs)

804 }

805 };

806

807

808

809 if (MustSaveCR && SingleScratchReg && MustSaveLR) {

810 BuildMoveFromCR();

813 .addImm(CRSaveOffset)

815 }

816

819

820 if (MustSaveCR && !(SingleScratchReg && MustSaveLR))

821 BuildMoveFromCR();

822

823 if (HasRedZone) {

824 if (HasFP)

834 if (HasBP)

839 }

840

841

842

843

844 auto SaveLR = [&](int64_t Offset) {

850

851

852

853

854

855

856

857 if (HasROPProtect) {

859 const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);

860 assert((ImmOffset <= -8 && ImmOffset >= -512) &&

861 "ROP hash save offset out of range.");

862 assert(((ImmOffset & 0x7) == 0) &&

863 "ROP hash save offset must be 8 byte aligned.");

864 BuildMI(MBB, StackUpdateLoc, dl, HashST)

868 }

869 };

870

872 SaveLR(LROffset);

873

874 if (MustSaveCR &&

876 assert(HasRedZone && "A red zone is always available on PPC64");

879 .addImm(CRSaveOffset)

881 }

882

883

884 if (!FrameSize) {

886 SaveLR(LROffset);

887 return;

888 }

889

890

891

892

893 if (HasBP && HasRedZone) {

894

898 }

899

900

901

902 bool HasSTUX =

904 (HasBP && MaxAlign > 1) || isLargeFrame;

905

906

907

908

909

910

911

912

914 (HasSTUX || isInt<16>(FrameSize + LROffset) || HasROPProtect))

915 SaveLR(LROffset);

916

917

918

919

921

922

924 TII.get(isPPC64 ? PPC::PROBED_STACKALLOC_64

925 : PPC::PROBED_STACKALLOC_32))

927 .addDef(ScratchReg)

928 .addImm(NegFrameSize);

929

930

931

932 if (!HasRedZone) {

936 }

937 } else {

938

939 if (HasBP && MaxAlign > 1) {

940 if (isPPC64)

945 else

951 if (!isLargeFrame) {

952 BuildMI(MBB, MBBI, dl, SubtractImmCarryingInst, ScratchReg)

954 .addImm(NegFrameSize);

955 } else {

956 assert(!SingleScratchReg && "Only a single scratch reg available");

957 TII.materializeImmPostRA(MBB, MBBI, dl, TempReg, NegFrameSize);

958 BuildMI(MBB, MBBI, dl, SubtractCarryingInst, ScratchReg)

961 }

962

967 } else if (!isLargeFrame) {

970 .addImm(NegFrameSize)

972 } else {

973 TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, NegFrameSize);

978 }

979 }

980

981

982

983 if (MustSaveTOC) {

984 assert(isELFv2ABI && "TOC saves in the prologue only supported on ELFv2");

985 BuildMI(MBB, StackUpdateLoc, dl, TII.get(PPC::STD))

987 .addImm(TOCSaveOffset)

989 }

990

991 if (!HasRedZone) {

992 assert(!isPPC64 && "A red zone is always available on PPC64");

993 if (HasSTUX) {

994

995

996

997

998

999

1000

1001

1002

1003

1007

1008 if (ScratchReg == PPC::R0) {

1009

1010

1011 int LastOffset = 0;

1012 if (HasFP) {

1013

1014

1017 .addImm(FPOffset-LastOffset);

1018 LastOffset = FPOffset;

1019

1023 .addReg(ScratchReg);

1024 }

1026

1029 .addImm(PBPOffset-LastOffset);

1030 LastOffset = PBPOffset;

1034 .addReg(ScratchReg);

1035 }

1036 if (HasBP) {

1037

1040 .addImm(BPOffset-LastOffset);

1041 LastOffset = BPOffset;

1045 .addReg(ScratchReg);

1046

1049 .addImm(-LastOffset);

1050 }

1051 } else {

1052

1053

1054

1055

1056

1057 if (HasFP)

1061 .addReg(ScratchReg);

1066 .addReg(ScratchReg);

1067 if (HasBP) {

1071 .addReg(ScratchReg);

1074 .addReg(ScratchReg);

1075 }

1076 }

1077 } else {

1078

1079

1080

1081

1082 if (HasFP)

1085 .addImm(FrameSize + FPOffset)

1090 .addImm(FrameSize + PBPOffset)

1092 if (HasBP) {

1095 .addImm(FrameSize + BPOffset)

1100 }

1101 }

1102 }

1103

1104

1105 if (!HasSTUX && MustSaveLR && !HasFastMFLR &&

1106 isInt<16>(FrameSize + LROffset) && !HasROPProtect)

1107 SaveLR(LROffset + FrameSize);

1108

1109

1110 if (needsCFI) {

1111 unsigned CFIIndex;

1112

1113 if (HasBP) {

1114

1115

1116

1117 unsigned Reg = MRI->getDwarfRegNum(BPReg, true);

1120 } else {

1121

1122 assert(NegFrameSize);

1125 }

1128

1129 if (HasFP) {

1130

1131 unsigned Reg = MRI->getDwarfRegNum(FPReg, true);

1136 }

1137

1139

1140 unsigned Reg = MRI->getDwarfRegNum(PPC::R30, true);

1145 }

1146

1147 if (HasBP) {

1148

1149 unsigned Reg = MRI->getDwarfRegNum(BPReg, true);

1154 }

1155

1157

1158 unsigned Reg = MRI->getDwarfRegNum(LRReg, true);

1163 }

1164 }

1165

1166

1167 if (HasFP) {

1171

1172 if (!HasBP && needsCFI) {

1173

1174

1175 unsigned Reg = MRI->getDwarfRegNum(FPReg, true);

1178

1181 }

1182 }

1183

1184 if (needsCFI) {

1185

1186

1190 if (Reg == PPC::LR || Reg == PPC::LR8 || Reg == PPC::RM) continue;

1191

1192

1193

1194 if (PPC::CRBITRCRegClass.contains(Reg))

1195 continue;

1196

1197 if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)

1198 continue;

1199

1200

1201

1202 if (isSVR4ABI && isPPC64 && (PPC::CR2 <= Reg && Reg <= PPC::CR4)) {

1203

1204

1205

1206 Register CRReg = isELFv2ABI? Reg : PPC::CR2;

1208 nullptr, MRI->getDwarfRegNum(CRReg, true), CRSaveOffset));

1211 continue;

1212 }

1213

1214 if (I.isSpilledToReg()) {

1215 unsigned SpilledReg = I.getDstReg();

1217 nullptr, MRI->getDwarfRegNum(Reg, true),

1218 MRI->getDwarfRegNum(SpilledReg, true)));

1221 } else {

1223

1224

1225

1226 if (MovingStackUpdateDown)

1227 Offset -= NegFrameSize;

1228

1230 nullptr, MRI->getDwarfRegNum(Reg, true), Offset));

1233 }

1234 }

1235 }

1236}

1237

1240 bool isPPC64 = Subtarget.isPPC64();

1245

1246 const bool needsCFI = MF.needsFrameMoves() && !Subtarget.isAIXABI();

1248 int Opc = MI.getOpcode();

1249 return Opc == PPC::PROBED_STACKALLOC_64 || Opc == PPC::PROBED_STACKALLOC_32;

1250 });

1251 if (StackAllocMIPos == PrologMBB.end())

1252 return;

1257 int64_t NegFrameSize = MI.getOperand(2).getImm();

1259 int64_t NegProbeSize = -(int64_t)ProbeSize;

1260 assert(isInt<32>(NegProbeSize) && "Unhandled probe size");

1261 int64_t NumBlocks = NegFrameSize / NegProbeSize;

1262 int64_t NegResidualSize = NegFrameSize % NegProbeSize;

1264 Register ScratchReg = MI.getOperand(0).getReg();

1266 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

1267 bool HasBP = RegInfo->hasBasePointer(MF);

1268 Register BPReg = RegInfo->getBaseRegister(MF);

1270 bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();

1271 const MCInstrDesc &CopyInst = TII.get(isPPC64 ? PPC::OR8 : PPC::OR);

1272

1275 unsigned RegNum = MRI->getDwarfRegNum(Reg, true);

1280 };

1284 unsigned RegNum = MRI->getDwarfRegNum(Reg, true);

1285 unsigned CFIIndex = MBB.getParent()->addFrameInst(

1289 };

1290

1291 auto CanUseDForm = [](int64_t Imm) { return isInt<16>(Imm) && Imm % 4 == 0; };

1292

1300 else {

1301 BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::LIS8 : PPC::LIS), TempReg)

1303 BuildMI(MBB, MBBI, DL, TII.get(isPPC64 ? PPC::ORI8 : PPC::ORI), TempReg)

1305 .addImm(Imm & 0xFFFF);

1306 }

1307 };

1308

1311 Register NegSizeReg, bool UseDForm,

1313 if (UseDForm)

1318 else

1322 .addReg(NegSizeReg);

1323 };

1324

1325

1326

1327

1328

1329

1330

1331

1332

1333

1334

1335

1336

1337

1338

1339

1340

1341

1342

1343

1344

1345

1346

1347

1348

1349

1353 assert(HasBP && "The function is supposed to have base pointer when its "

1354 "stack is realigned.");

1356

1357

1358

1359

1360

1361 assert(ProbeSize >= Subtarget.getRedZoneSize() &&

1362 "Probe size should be larger or equal to the size of red-zone so "

1363 "that red-zone is not clobbered by probing.");

1364

1365 Register &FinalStackPtr = TempReg;

1366

1367

1368

1369 NegProbeSize = std::max(NegProbeSize, -((int64_t)1 << 15));

1371 "NegProbeSize should be materializable by DForm");

1373

1374

1375

1376

1377

1378

1379

1380

1381

1382

1383

1384

1385

1388 MF.insert(MBBInsertPoint, ProbeLoopBodyMBB);

1390 MF.insert(MBBInsertPoint, ProbeExitMBB);

1391

1392 {

1393 Register BackChainPointer = HasRedZone ? BPReg : TempReg;

1394 allocateAndProbe(*ProbeExitMBB, ProbeExitMBB->end(), 0, ScratchReg, false,

1395 BackChainPointer);

1396 if (HasRedZone)

1397

1398

1399 BuildMI(*ProbeExitMBB, ProbeExitMBB->end(), DL, CopyInst, TempReg)

1404 }

1405

1406 {

1407 BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF), ScratchReg)

1409 .addReg(FinalStackPtr);

1410 if (!HasRedZone)

1412 BuildMI(&MBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI), CRReg)

1414 .addImm(NegProbeSize);

1418 .addMBB(ProbeExitMBB);

1419 MBB.addSuccessor(ProbeLoopBodyMBB);

1420 MBB.addSuccessor(ProbeExitMBB);

1421 }

1422

1423 {

1424 Register BackChainPointer = HasRedZone ? BPReg : TempReg;

1425 allocateAndProbe(*ProbeLoopBodyMBB, ProbeLoopBodyMBB->end(), NegProbeSize,

1426 0, true , BackChainPointer);

1427 BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::ADDI8 : PPC::ADDI),

1428 ScratchReg)

1430 .addImm(-NegProbeSize);

1431 BuildMI(ProbeLoopBodyMBB, DL, TII.get(isPPC64 ? PPC::CMPDI : PPC::CMPWI),

1432 CRReg)

1434 .addImm(NegProbeSize);

1435 BuildMI(ProbeLoopBodyMBB, DL, TII.get(PPC::BCC))

1438 .addMBB(ProbeLoopBodyMBB);

1439 ProbeLoopBodyMBB->addSuccessor(ProbeExitMBB);

1440 ProbeLoopBodyMBB->addSuccessor(ProbeLoopBodyMBB);

1441 }

1442

1444 return ProbeExitMBB;

1445 };

1446

1447

1448

1449 if (HasBP && MaxAlign > 1) {

1450

1451 if (isPPC64)

1452 BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLDICL), ScratchReg)

1456 else

1457 BuildMI(*CurrentMBB, {MI}, DL, TII.get(PPC::RLWINM), ScratchReg)

1462 BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::SUBF8 : PPC::SUBF),

1466 MaterializeImm(*CurrentMBB, {MI}, NegFrameSize, ScratchReg);

1467 BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::ADD8 : PPC::ADD4),

1471 CurrentMBB = probeRealignedStack(*CurrentMBB, {MI}, ScratchReg, FPReg);

1472 if (needsCFI)

1474 } else {

1475

1477

1478 if (needsCFI)

1479 buildDefCFA(*CurrentMBB, {MI}, FPReg, 0);

1480

1481 if (NegResidualSize) {

1482 bool ResidualUseDForm = CanUseDForm(NegResidualSize);

1483 if (!ResidualUseDForm)

1484 MaterializeImm(*CurrentMBB, {MI}, NegResidualSize, ScratchReg);

1485 allocateAndProbe(*CurrentMBB, {MI}, NegResidualSize, ScratchReg,

1486 ResidualUseDForm, FPReg);

1487 }

1488 bool UseDForm = CanUseDForm(NegProbeSize);

1489

1490 if (NumBlocks < 3) {

1491 if (!UseDForm)

1492 MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);

1493 for (int i = 0; i < NumBlocks; ++i)

1494 allocateAndProbe(*CurrentMBB, {MI}, NegProbeSize, ScratchReg, UseDForm,

1496 if (needsCFI) {

1497

1499 }

1500 } else {

1501

1502

1503

1504

1505 MaterializeImm(*CurrentMBB, {MI}, NumBlocks, ScratchReg);

1506 BuildMI(*CurrentMBB, {MI}, DL, TII.get(isPPC64 ? PPC::MTCTR8 : PPC::MTCTR))

1508 if (!UseDForm)

1509 MaterializeImm(*CurrentMBB, {MI}, NegProbeSize, ScratchReg);

1510

1514 MF.insert(MBBInsertPoint, LoopMBB);

1516 MF.insert(MBBInsertPoint, ExitMBB);

1517

1518 allocateAndProbe(*LoopMBB, LoopMBB->end(), NegProbeSize, ScratchReg,

1519 UseDForm, FPReg);

1520 BuildMI(LoopMBB, DL, TII.get(isPPC64 ? PPC::BDNZ8 : PPC::BDNZ))

1524

1525 ExitMBB->splice(ExitMBB->end(), CurrentMBB,

1527 CurrentMBB->end());

1530 if (needsCFI) {

1531

1533 }

1534

1536 }

1537 }

1538 ++NumPrologProbed;

1539 MI.eraseFromParent();

1540}

1541

1546

1548 dl = MBBI->getDebugLoc();

1549

1551 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

1552

1553

1555

1556

1558

1559

1560 bool isPPC64 = Subtarget.isPPC64();

1561

1562

1566 bool MustSaveCR = !MustSaveCRs.empty();

1567

1568 bool HasFP = hasFP(MF);

1569 bool HasBP = RegInfo->hasBasePointer(MF);

1570 bool HasRedZone = Subtarget.isPPC64() || !Subtarget.isSVR4ABI();

1571 bool HasROPProtect = Subtarget.hasROPProtect();

1572 bool HasPrivileged = Subtarget.hasPrivileged();

1573

1575 Register BPReg = RegInfo->getBaseRegister(MF);

1578 Register TempReg = isPPC64 ? PPC::X12 : PPC::R12;

1579 const MCInstrDesc& MTLRInst = TII.get( isPPC64 ? PPC::MTLR8

1580 : PPC::MTLR );

1582 : PPC::LWZ );

1583 const MCInstrDesc& LoadImmShiftedInst = TII.get( isPPC64 ? PPC::LIS8

1584 : PPC::LIS );

1585 const MCInstrDesc& OrInst = TII.get(isPPC64 ? PPC::OR8

1586 : PPC::OR );

1587 const MCInstrDesc& OrImmInst = TII.get( isPPC64 ? PPC::ORI8

1588 : PPC::ORI );

1589 const MCInstrDesc& AddImmInst = TII.get( isPPC64 ? PPC::ADDI8

1590 : PPC::ADDI );

1591 const MCInstrDesc& AddInst = TII.get( isPPC64 ? PPC::ADD8

1592 : PPC::ADD4 );

1593 const MCInstrDesc& LoadWordInst = TII.get( isPPC64 ? PPC::LWZ8

1594 : PPC::LWZ);

1595 const MCInstrDesc& MoveToCRInst = TII.get( isPPC64 ? PPC::MTOCRF8

1596 : PPC::MTOCRF);

1598 TII.get(isPPC64 ? (HasPrivileged ? PPC::HASHCHKP8 : PPC::HASHCHK8)

1599 : (HasPrivileged ? PPC::HASHCHKP : PPC::HASHCHK));

1601

1602 int64_t FPOffset = 0;

1603

1604

1605 bool SingleScratchReg = findScratchRegister(&MBB, true, false, &ScratchReg,

1606 &TempReg);

1607 assert(SingleScratchReg &&

1608 "Could not find an available scratch register");

1609

1610 SingleScratchReg = ScratchReg == TempReg;

1611

1612 if (HasFP) {

1614 assert(FPIndex && "No Frame Pointer Save Slot!");

1616 }

1617

1618 int64_t BPOffset = 0;

1619 if (HasBP) {

1621 assert(BPIndex && "No Base Pointer Save Slot!");

1623 }

1624

1625 int64_t PBPOffset = 0;

1628 assert(PBPIndex && "No PIC Base Pointer Save Slot!");

1630 }

1631

1632 bool IsReturnBlock = (MBBI != MBB.end() && MBBI->isReturn());

1633

1634 if (IsReturnBlock) {

1635 unsigned RetOpcode = MBBI->getOpcode();

1636 bool UsesTCRet = RetOpcode == PPC::TCRETURNri ||

1637 RetOpcode == PPC::TCRETURNdi ||

1638 RetOpcode == PPC::TCRETURNai ||

1639 RetOpcode == PPC::TCRETURNri8 ||

1640 RetOpcode == PPC::TCRETURNdi8 ||

1641 RetOpcode == PPC::TCRETURNai8;

1642

1643 if (UsesTCRet) {

1646 assert(StackAdjust.isImm() && "Expecting immediate value.");

1647

1648 int StackAdj = StackAdjust.getImm();

1649 int Delta = StackAdj - MaxTCRetDelta;

1650 assert((Delta >= 0) && "Delta must be positive");

1651 if (MaxTCRetDelta>0)

1652 FrameSize += (StackAdj +Delta);

1653 else

1654 FrameSize += StackAdj;

1655 }

1656 }

1657

1658

1659

1660 bool isLargeFrame = isInt<16>(FrameSize);

1661

1662

1663

1664

1665

1666

1667

1668

1669

1670

1671

1672

1673

1674 unsigned RBReg = SPReg;

1676

1677

1678

1679

1680

1682 if (stackUpdateCanBeMoved(MF)) {

1683 const std::vector & Info = MFI.getCalleeSavedInfo();

1685

1686

1687 if (CSI.isSpilledToReg()) {

1688 StackUpdateLoc = MBBI;

1689 break;

1690 }

1691 int FrIdx = CSI.getFrameIdx();

1692

1693

1694

1695

1696 if (FrIdx >= 0)

1697 continue;

1698

1700 StackUpdateLoc--;

1701 else {

1702

1703 StackUpdateLoc = MBBI;

1704 break;

1705 }

1706 }

1707 }

1708

1709 if (FrameSize) {

1710

1711

1712

1713

1714

1715

1716 if (HasRedZone && HasBP) {

1718 addReg(BPReg).

1719 addReg(BPReg);

1720 }

1721

1722

1723

1724

1726 assert(HasFP && "Expecting a valid frame pointer.");

1727 if (!HasRedZone)

1729 if (!isLargeFrame) {

1732 } else {

1733 TII.materializeImmPostRA(MBB, MBBI, dl, ScratchReg, FrameSize);

1737 .addReg(ScratchReg);

1738 }

1740 if (HasRedZone) {

1744 } else {

1745

1746

1747 assert(FPOffset <= 0 && BPOffset <= 0 && PBPOffset <= 0 &&

1748 "Local offsets should be negative");

1749 SPAdd = FrameSize;

1750 FPOffset += FrameSize;

1751 BPOffset += FrameSize;

1752 PBPOffset += FrameSize;

1753 }

1754 } else {

1755

1756

1757 if (!HasRedZone) {

1758

1759 if (!HasFP)

1764 }

1768 }

1769 }

1770 assert(RBReg != ScratchReg && "Should have avoided ScratchReg");

1771

1772

1773

1774

1775

1776

1777 if (MustSaveCR && SingleScratchReg && MustSaveLR) {

1778

1779

1780 assert(HasRedZone && "Expecting red zone");

1782 .addImm(CRSaveOffset)

1784 for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)

1785 BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])

1787 }

1788

1789

1790

1791

1792

1793 bool LoadedLR = false;

1796 .addImm(LROffset+SPAdd)

1798 LoadedLR = true;

1799 }

1800

1801 if (MustSaveCR && !(SingleScratchReg && MustSaveLR)) {

1802 assert(RBReg == SPReg && "Should be using SP as a base register");

1804 .addImm(CRSaveOffset)

1806 }

1807

1808 if (HasFP) {

1809

1810

1811 if (HasRedZone || RBReg == SPReg)

1815 else

1819 }

1820

1825

1826 if (HasBP)

1830

1831

1832

1833 if (RBReg != SPReg || SPAdd != 0) {

1834 assert(!HasRedZone && "This should not happen with red zone");

1835

1836 if (SPAdd == 0)

1840 else

1844

1845 assert(RBReg != ScratchReg && "Should be using FP or SP as base register");

1846 if (RBReg == FPReg)

1849 .addReg(ScratchReg);

1850

1851

1856 }

1857

1858 if (MustSaveCR &&

1860 for (unsigned i = 0, e = MustSaveCRs.size(); i != e; ++i)

1861 BuildMI(MBB, MBBI, dl, MoveToCRInst, MustSaveCRs[i])

1863

1865

1866

1867 if (HasROPProtect) {

1869 const int64_t ImmOffset = MFI.getObjectOffset(SaveIndex);

1870 assert((ImmOffset <= -8 && ImmOffset >= -512) &&

1871 "ROP hash check location offset out of range.");

1872 assert(((ImmOffset & 0x7) == 0) &&

1873 "ROP hash check location offset must be 8 byte aligned.");

1874 BuildMI(MBB, StackUpdateLoc, dl, HashChk)

1878 }

1879 BuildMI(MBB, StackUpdateLoc, dl, MTLRInst).addReg(ScratchReg);

1880 }

1881

1882

1883

1884 if (IsReturnBlock) {

1885 unsigned RetOpcode = MBBI->getOpcode();

1887 (RetOpcode == PPC::BLR || RetOpcode == PPC::BLR8) &&

1891

1892 if (CallerAllocatedAmt && isInt<16>(CallerAllocatedAmt)) {

1895 } else {

1896 BuildMI(MBB, MBBI, dl, LoadImmShiftedInst, ScratchReg)

1897 .addImm(CallerAllocatedAmt >> 16);

1900 .addImm(CallerAllocatedAmt & 0xFFFF);

1904 .addReg(ScratchReg);

1905 }

1906 } else {

1907 createTailCallBranchInstr(MBB);

1908 }

1909 }

1910}

1911

1912void PPCFrameLowering::createTailCallBranchInstr(MachineBasicBlock &MBB) const {

1914

1915

1916 assert(MBBI != MBB.end() && "Failed to find the first terminator.");

1917

1920

1921

1922

1923

1924

1925

1926

1927

1928 unsigned RetOpcode = MBBI->getOpcode();

1929 if (RetOpcode == PPC::TCRETURNdi) {

1930 MBBI = MBB.getLastNonDebugInstr();

1935 else if (JumpTarget.isSymbol())

1938 else

1940 } else if (RetOpcode == PPC::TCRETURNri) {

1941 MBBI = MBB.getLastNonDebugInstr();

1942 assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");

1944 } else if (RetOpcode == PPC::TCRETURNai) {

1946 MachineOperand &JumpTarget = MBBI->getOperand(0);

1948 } else if (RetOpcode == PPC::TCRETURNdi8) {

1950 MachineOperand &JumpTarget = MBBI->getOperand(0);

1954 else if (JumpTarget.isSymbol())

1957 else

1959 } else if (RetOpcode == PPC::TCRETURNri8) {

1961 assert(MBBI->getOperand(0).isReg() && "Expecting register operand.");

1963 } else if (RetOpcode == PPC::TCRETURNai8) {

1965 MachineOperand &JumpTarget = MBBI->getOperand(0);

1967 }

1968}

1969

1974 if (Subtarget.isAIXABI())

1976

1977 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

1978

1979

1980

1981 SavedRegs.reset(PPC::VSRp26);

1982 SavedRegs.reset(PPC::VSRp27);

1983 SavedRegs.reset(PPC::VSRp28);

1984 SavedRegs.reset(PPC::VSRp29);

1985 SavedRegs.reset(PPC::VSRp30);

1986 SavedRegs.reset(PPC::VSRp31);

1987

1988

1990 MCRegister LR = RegInfo->getRARegister();

1992 SavedRegs.reset(LR);

1993

1994

1996 const bool isPPC64 = Subtarget.isPPC64();

1998

1999

2000 if (!FPSI && needsFP(MF)) {

2001

2003

2005

2007 }

2008

2010 if (!BPSI && RegInfo->hasBasePointer(MF)) {

2012

2014

2016 }

2017

2018

2019

2023 }

2024

2025

2026

2027

2028

2030 SavedRegs.reset(isPPC64 ? PPC::X31 : PPC::R31);

2031 if (RegInfo->hasBasePointer(MF)) {

2032 SavedRegs.reset(RegInfo->getBaseRegister(MF));

2033

2034

2035 if (needsFP(MF) && !SavedRegs.test(isPPC64 ? PPC::X31 : PPC::R31) &&

2036 Subtarget.isAIXABI()) {

2038 (RegInfo->getBaseRegister(MF) == (isPPC64 ? PPC::X30 : PPC::R30)) &&

2039 "Invalid base register on AIX!");

2040 SavedRegs.set(isPPC64 ? PPC::X31 : PPC::R31);

2041 }

2042 }

2044 SavedRegs.reset(PPC::R30);

2045

2046

2047 int TCSPDelta = 0;

2051 }

2052

2053

2054

2055

2056

2057

2058

2059 if ((SavedRegs.test(PPC::CR2) || SavedRegs.test(PPC::CR3) ||

2060 SavedRegs.test(PPC::CR4))) {

2061 const uint64_t SpillSize = 4;

2062 const int64_t SpillOffset =

2063 Subtarget.isPPC64() ? 8 : Subtarget.isAIXABI() ? 4 : -4;

2064 int FrameIdx =

2066 true, false);

2068 }

2069}

2070

2073

2076

2077

2078

2079

2080

2083 "MFI can't contain multiple restore points!");

2086 createTailCallBranchInstr(MBB);

2087 }

2088 }

2089

2090

2091 if (CSI.empty() && needsFP(MF)) {

2093 return;

2094 }

2095

2096 unsigned MinGPR = PPC::R31;

2097 unsigned MinG8R = PPC::X31;

2098 unsigned MinFPR = PPC::F31;

2099 unsigned MinVR = Subtarget.hasSPE() ? PPC::S31 : PPC::V31;

2100

2101 bool HasGPSaveArea = false;

2102 bool HasG8SaveArea = false;

2103 bool HasFPSaveArea = false;

2104 bool HasVRSaveArea = false;

2105

2110

2114 (Reg != PPC::X2 && Reg != PPC::R2)) &&

2115 "Not expecting to try to spill R2 in a function that must save TOC");

2116 if (PPC::GPRCRegClass.contains(Reg)) {

2117 HasGPSaveArea = true;

2118

2120

2121 if (Reg < MinGPR) {

2122 MinGPR = Reg;

2123 }

2124 } else if (PPC::G8RCRegClass.contains(Reg)) {

2125 HasG8SaveArea = true;

2126

2128

2129 if (Reg < MinG8R) {

2130 MinG8R = Reg;

2131 }

2132 } else if (PPC::F8RCRegClass.contains(Reg)) {

2133 HasFPSaveArea = true;

2134

2136

2137 if (Reg < MinFPR) {

2138 MinFPR = Reg;

2139 }

2140 } else if (PPC::CRBITRCRegClass.contains(Reg) ||

2141 PPC::CRRCRegClass.contains(Reg)) {

2142 ;

2143 } else if (PPC::VRRCRegClass.contains(Reg) ||

2144 PPC::SPERCRegClass.contains(Reg)) {

2145

2146

2147 HasVRSaveArea = true;

2148

2150

2151 if (Reg < MinVR) {

2152 MinVR = Reg;

2153 }

2154 } else {

2156 }

2157 }

2158

2161

2162 int64_t LowerBound = 0;

2163

2164

2165 int TCSPDelta = 0;

2168 LowerBound = TCSPDelta;

2169 }

2170

2171

2172

2173 if (HasFPSaveArea) {

2175 int FI = FPReg.getFrameIdx();

2176

2178 }

2179

2180 LowerBound -= (31 - TRI->getEncodingValue(MinFPR) + 1) * 8;

2181 }

2182

2183

2184

2187 assert(FI && "No Frame Pointer Save Slot!");

2189

2190 HasGPSaveArea = true;

2191 }

2192

2195 assert(FI && "No PIC Base Pointer Save Slot!");

2197

2198 MinGPR = std::min(MinGPR, PPC::R30);

2199 HasGPSaveArea = true;

2200 }

2201

2202 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

2203 if (RegInfo->hasBasePointer(MF)) {

2205 assert(FI && "No Base Pointer Save Slot!");

2207

2208 Register BP = RegInfo->getBaseRegister(MF);

2209 if (PPC::G8RCRegClass.contains(BP)) {

2210 MinG8R = std::min(MinG8R, BP);

2211 HasG8SaveArea = true;

2212 } else if (PPC::GPRCRegClass.contains(BP)) {

2213 MinGPR = std::min(MinGPR, BP);

2214 HasGPSaveArea = true;

2215 }

2216 }

2217

2218

2219

2220 if (HasGPSaveArea || HasG8SaveArea) {

2221

2222

2224 if (!GPReg.isSpilledToReg()) {

2225 int FI = GPReg.getFrameIdx();

2227 }

2228 }

2229

2230

2231

2233 if (!G8Reg.isSpilledToReg()) {

2234 int FI = G8Reg.getFrameIdx();

2236 }

2237 }

2238

2239 unsigned MinReg =

2240 std::min(TRI->getEncodingValue(MinGPR),

2241 TRI->getEncodingValue(MinG8R));

2242

2243 const unsigned GPRegSize = Subtarget.isPPC64() ? 8 : 4;

2244 LowerBound -= (31 - MinReg + 1) * GPRegSize;

2245 }

2246

2247

2248

2249

2250

2251

2252 if (spillsCR(MF) && Subtarget.is32BitELFABI()) {

2253

2254 for (const auto &CSInfo : CSI) {

2255 if (CSInfo.getReg() == PPC::CR2) {

2256 int FI = CSInfo.getFrameIdx();

2258 break;

2259 }

2260 }

2261

2262 LowerBound -= 4;

2263 }

2264

2265

2266

2267 if (HasVRSaveArea) {

2268

2269

2270

2271

2272

2273 assert(LowerBound <= 0 && "Expect LowerBound have a non-positive value!");

2274 LowerBound &= ~(15);

2275

2277 int FI = VReg.getFrameIdx();

2278

2280 }

2281 }

2282

2284}

2285

2286void

2289

2290

2291

2292

2293

2294

2295

2296

2297

2298

2299

2300

2301

2304 bool NeedSpills = Subtarget.hasSPE() ? isInt<8>(StackSize) : isInt<16>(StackSize);

2305

2307 (hasSpills(MF) && NeedSpills)) {

2312 unsigned Size = TRI.getSpillSize(RC);

2313 Align Alignment = TRI.getSpillAlign(RC);

2315

2316

2317 bool HasAlVars =

2319

2320

2321 if (spillsCR(MF) || HasAlVars)

2323 }

2324}

2325

2326

2327

2328

2329

2330

2333 std::vector &CSI) const {

2334

2335 if (CSI.empty())

2336 return true;

2337

2338 const PPCRegisterInfo *RegInfo = Subtarget.getRegisterInfo();

2339 const MCPhysReg *CSRegs = RegInfo->getCalleeSavedRegs(&MF);

2341

2342 if (Subtarget.hasSPE()) {

2343

2344

2345

2346 for (auto &CalleeSaveReg : CSI) {

2347 MCRegister Reg = CalleeSaveReg.getReg();

2348 MCRegister Lower = RegInfo->getSubReg(Reg, PPC::sub_32);

2349 MCRegister Higher = RegInfo->getSubReg(Reg, PPC::sub_32_hi_phony);

2350

2351 if (

2353

2354 MRI.isPhysRegModified(Higher))

2356 }

2357 }

2358

2359

2362 return false;

2363

2364

2365 BitVector BVAllocatable = TRI->getAllocatableSet(MF);

2367 for (unsigned i = 0; CSRegs[i]; ++i)

2368 BVCalleeSaved.set(CSRegs[i]);

2369

2370 for (unsigned Reg : BVAllocatable.set_bits()) {

2371

2372

2373 if (BVCalleeSaved[Reg] || !PPC::VSRCRegClass.contains(Reg) ||

2374 MRI.isPhysRegUsed(Reg))

2375 BVAllocatable.reset(Reg);

2376 }

2377

2378 bool AllSpilledToReg = true;

2379 unsigned LastVSRUsedForSpill = 0;

2380 for (auto &CS : CSI) {

2381 if (BVAllocatable.none())

2382 return false;

2383

2385

2386 if (!PPC::G8RCRegClass.contains(Reg)) {

2387 AllSpilledToReg = false;

2388 continue;

2389 }

2390

2391

2392

2393 if (LastVSRUsedForSpill != 0) {

2394 CS.setDstReg(LastVSRUsedForSpill);

2395 BVAllocatable.reset(LastVSRUsedForSpill);

2396 LastVSRUsedForSpill = 0;

2397 continue;

2398 }

2399

2400 unsigned VolatileVFReg = BVAllocatable.find_first();

2401 if (VolatileVFReg < BVAllocatable.size()) {

2402 CS.setDstReg(VolatileVFReg);

2403 LastVSRUsedForSpill = VolatileVFReg;

2404 } else {

2405 AllSpilledToReg = false;

2406 }

2407 }

2408 return AllSpilledToReg;

2409}

2410

2414

2420 bool CRSpilled = false;

2423

2424 VSRContainingGPRs.clear();

2425

2426

2427

2429 if (Info.isSpilledToReg()) {

2430 auto &SpilledVSR = VSRContainingGPRs[Info.getDstReg()];

2431 assert(SpilledVSR.second == 0 &&

2432 "Can't spill more than two GPRs into VSR!");

2433 if (SpilledVSR.first == 0)

2434 SpilledVSR.first = Info.getReg();

2435 else

2436 SpilledVSR.second = Info.getReg();

2437 }

2438 }

2439

2442

2443

2444 bool IsCRField = PPC::CR2 <= Reg && Reg <= PPC::CR4;

2445

2446

2447

2448

2449

2450

2452 bool IsLiveIn = MRI.isLiveIn(Reg);

2453 if (!IsLiveIn)

2454 MBB.addLiveIn(Reg);

2455

2456 if (CRSpilled && IsCRField) {

2458 continue;

2459 }

2460

2461

2462 if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)

2463 continue;

2464

2465

2466 if (IsCRField) {

2468 if (!Subtarget.is32BitELFABI()) {

2469

2471 } else {

2472 CRSpilled = true;

2474

2475

2476

2477 CRMIB = BuildMI(*MF, DL, TII.get(PPC::MFCR), PPC::R12)

2479

2480 MBB.insert(MI, CRMIB);

2484 I.getFrameIdx()));

2485 }

2486 } else {

2487 if (I.isSpilledToReg()) {

2488 unsigned Dst = I.getDstReg();

2489

2490 if (Spilled[Dst])

2491 continue;

2492

2493 const auto &VSR = VSRContainingGPRs[Dst];

2494 if (VSR.second != 0) {

2495 assert(Subtarget.hasP9Vector() &&

2496 "mtvsrdd is unavailable on pre-P9 targets.");

2497

2498 NumPESpillVSR += 2;

2502 } else if (VSR.second == 0) {

2503 assert(Subtarget.hasP8Vector() &&

2504 "Can't move GPR to VSR on pre-P8 targets.");

2505

2506 ++NumPESpillVSR;

2508 TRI->getSubReg(Dst, PPC::sub_64))

2510 } else {

2512 }

2513 Spilled.set(Dst);

2514 } else {

2516

2517

2518

2519

2520

2521 if (Subtarget.needsSwapsForVSXMemOps() &&

2523 TII.storeRegToStackSlotNoUpd(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(),

2524 RC);

2525 else

2526 TII.storeRegToStackSlot(MBB, MI, Reg, !IsLiveIn, I.getFrameIdx(), RC,

2528 }

2529 }

2530 }

2531 return true;

2532}

2533

2534static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled,

2538

2542 unsigned MoveReg = PPC::R12;

2543

2544

2547 CSI[CSIIndex].getFrameIdx()));

2548

2549 unsigned RestoreOp = PPC::MTOCRF;

2550 if (CR2Spilled)

2553

2554 if (CR3Spilled)

2557

2558 if (CR4Spilled)

2561}

2562

2568 I->getOpcode() == PPC::ADJCALLSTACKUP) {

2569

2570 if (int CalleeAmt = I->getOperand(1).getImm()) {

2571 bool is64Bit = Subtarget.isPPC64();

2572 CalleeAmt *= -1;

2573 unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;

2574 unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;

2575 unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;

2576 unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;

2577 unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;

2578 unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;

2579 const DebugLoc &dl = I->getDebugLoc();

2580

2585 } else {

2588 .addImm(CalleeAmt >> 16);

2591 .addImm(CalleeAmt & 0xFFFF);

2595 }

2596 }

2597 }

2598

2599 return MBB.erase(I);

2600}

2601

2603 return PPC::CR2 == Reg || Reg == PPC::CR3 || Reg == PPC::CR4;

2604}

2605

2613 bool CR2Spilled = false;

2614 bool CR3Spilled = false;

2615 bool CR4Spilled = false;

2616 unsigned CSIIndex = 0;

2618

2619

2620

2622 bool AtStart = I == MBB.begin();

2623

2624 if (!AtStart)

2625 --BeforeI;

2626

2627 for (unsigned i = 0, e = CSI.size(); i != e; ++i) {

2629

2630 if ((Reg == PPC::X2 || Reg == PPC::R2) && MustSaveTOC)

2631 continue;

2632

2633

2634

2636 continue;

2637

2638 if (Reg == PPC::CR2) {

2639 CR2Spilled = true;

2640

2641

2642 CSIIndex = i;

2643 continue;

2644 } else if (Reg == PPC::CR3) {

2645 CR3Spilled = true;

2646 continue;

2647 } else if (Reg == PPC::CR4) {

2648 CR4Spilled = true;

2649 continue;

2650 } else {

2651

2652

2653 if (CR2Spilled || CR3Spilled || CR4Spilled) {

2654 bool is31 = needsFP(*MF);

2655 restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI,

2656 CSIIndex);

2657 CR2Spilled = CR3Spilled = CR4Spilled = false;

2658 }

2659

2660 if (CSI[i].isSpilledToReg()) {

2662 unsigned Dst = CSI[i].getDstReg();

2663

2664 if (Restored[Dst])

2665 continue;

2666

2667 const auto &VSR = VSRContainingGPRs[Dst];

2668 if (VSR.second != 0) {

2669 assert(Subtarget.hasP9Vector());

2670 NumPEReloadVSR += 2;

2674 } else if (VSR.second == 0) {

2675 assert(Subtarget.hasP8Vector());

2676 ++NumPEReloadVSR;

2679 } else {

2681 }

2682

2683 Restored.set(Dst);

2684

2685 } else {

2686

2688

2689

2690

2691 if (Subtarget.needsSwapsForVSXMemOps() &&

2693 TII.loadRegFromStackSlotNoUpd(MBB, I, Reg, CSI[i].getFrameIdx(), RC);

2694 else

2695 TII.loadRegFromStackSlot(MBB, I, Reg, CSI[i].getFrameIdx(), RC,

2697

2699 "loadRegFromStackSlot didn't insert any code!");

2700 }

2701 }

2702

2703

2704 if (AtStart)

2705 I = MBB.begin();

2706 else {

2707 I = BeforeI;

2708 ++I;

2709 }

2710 }

2711

2712

2713 if (CR2Spilled || CR3Spilled || CR4Spilled) {

2714 assert(Subtarget.is32BitELFABI() &&

2715 "Only set CR[2|3|4]Spilled on 32-bit SVR4.");

2716 bool is31 = needsFP(*MF);

2717 restoreCRs(is31, CR2Spilled, CR3Spilled, CR4Spilled, MBB, I, CSI, CSIIndex);

2718 }

2719

2720 return true;

2721}

2722

2724 return TOCSaveOffset;

2725}

2726

2728 return FramePointerSaveOffset;

2729}

2730

2732 return BasePointerSaveOffset;

2733}

2734

2740

2743

2744

2745

2746

2747

2748

2749

2750 assert(Subtarget.isAIXABI() &&

2751 "Function updateCalleeSaves should only be called for AIX.");

2752

2753

2754 if (SavedRegs.none())

2755 return;

2756

2758 Subtarget.getRegisterInfo()->getCalleeSavedRegs(&MF);

2763

2764

2765

2766

2767

2768 for (int i = 0; CSRegs[i]; i++) {

2769

2770

2772 if (!SavedRegs.test(Cand))

2773 continue;

2774

2775

2776

2777 if (Cand == PPC::X2 || Cand == PPC::R2) {

2778 SavedRegs.set(Cand);

2779 continue;

2780 }

2781

2782 if (PPC::GPRCRegClass.contains(Cand) && Cand < LowestGPR)

2783 LowestGPR = Cand;

2784 else if (PPC::G8RCRegClass.contains(Cand) && Cand < LowestG8R)

2785 LowestG8R = Cand;

2786 else if ((PPC::F4RCRegClass.contains(Cand) ||

2787 PPC::F8RCRegClass.contains(Cand)) &&

2788 Cand < LowestFPR)

2789 LowestFPR = Cand;

2790 else if (PPC::VRRCRegClass.contains(Cand) && Cand < LowestVR)

2791 LowestVR = Cand;

2792 }

2793

2794 for (int i = 0; CSRegs[i]; i++) {

2796 if ((PPC::GPRCRegClass.contains(Cand) && Cand > LowestGPR) ||

2797 (PPC::G8RCRegClass.contains(Cand) && Cand > LowestG8R) ||

2798 ((PPC::F4RCRegClass.contains(Cand) ||

2799 PPC::F8RCRegClass.contains(Cand)) &&

2800 Cand > LowestFPR) ||

2801 (PPC::VRRCRegClass.contains(Cand) && Cand > LowestVR))

2802 SavedRegs.set(Cand);

2803 }

2804}

2805

2807

2808

2809

2810

2811

2812

2813

2814 if (Subtarget.isPPC64())

2815 return LONG_MAX;

2816

2818}

unsigned const MachineRegisterInfo * MRI

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

const TargetInstrInfo & TII

MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL

MachineBasicBlock MachineBasicBlock::iterator MBBI

This file implements the LivePhysRegs utility for tracking liveness of physical registers.

Register const TargetRegisterInfo * TRI

Promote Memory to Register

static bool MustSaveLR(const MachineFunction &MF, MCRegister LR)

MustSaveLR - Return true if this function requires that we save the LR register onto the stack in the...

Definition PPCFrameLowering.cpp:270

static bool hasSpills(const MachineFunction &MF)

Definition PPCFrameLowering.cpp:257

static unsigned computeCRSaveOffset(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:78

static void restoreCRs(bool is31, bool CR2Spilled, bool CR3Spilled, bool CR4Spilled, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, unsigned CSIIndex)

Definition PPCFrameLowering.cpp:2534

static unsigned computeReturnSaveOffset(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:43

#define CALLEE_SAVED_FPRS

static cl::opt< bool > EnablePEVectorSpills("ppc-enable-pe-vector-spills", cl::desc("Enable spills in prologue to vector registers."), cl::init(false), cl::Hidden)

#define CALLEE_SAVED_GPRS32

#define CALLEE_SAVED_GPRS64

static unsigned computeLinkageSize(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:61

static unsigned computeFramePointerSaveOffset(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:56

static bool isCalleeSavedCR(unsigned Reg)

Definition PPCFrameLowering.cpp:2602

static unsigned computeTOCSaveOffset(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:50

static bool hasNonRISpills(const MachineFunction &MF)

Definition PPCFrameLowering.cpp:262

static bool spillsCR(const MachineFunction &MF)

Definition PPCFrameLowering.cpp:252

static unsigned computeBasePointerSaveOffset(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:69

static constexpr MCPhysReg FPReg

static constexpr MCPhysReg SPReg

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)

static void buildDefCFAReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, const DebugLoc &DL, unsigned Reg, const SystemZInstrInfo *ZII)

static bool is64Bit(const char *name)

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

size_t size() const

size - Get the array size.

LLVM Basic Block Representation.

bool test(unsigned Idx) const

int find_first() const

find_first - Returns the index of the first set bit, -1 if none of the bits are set.

size_type count() const

count - Returns the number of bits which are set.

int find_next(unsigned Prev) const

find_next - Returns the index of the next set bit following the "Prev" bit.

bool none() const

none - Returns true if none of the bits are set.

iterator_range< const_set_bits_iterator > set_bits() const

size_type size() const

size - Returns the number of bits in this bitvector.

The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...

CallingConv::ID getCallingConv() const

getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...

bool hasFnAttribute(Attribute::AttrKind Kind) const

Return true if the function has the attribute.

An instruction for reading from memory.

static MCCFIInstruction createDefCfaRegister(MCSymbol *L, unsigned Register, SMLoc Loc={})

.cfi_def_cfa_register modifies a rule for computing CFA.

static MCCFIInstruction createRegister(MCSymbol *L, unsigned Register1, unsigned Register2, SMLoc Loc={})

.cfi_register Previous value of Register1 is saved in register Register2.

static MCCFIInstruction cfiDefCfa(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})

.cfi_def_cfa defines a rule for computing CFA as: take address from Register and add Offset to it.

static MCCFIInstruction createOffset(MCSymbol *L, unsigned Register, int64_t Offset, SMLoc Loc={})

.cfi_offset Previous value of Register is saved at offset Offset from CFA.

static MCCFIInstruction cfiDefCfaOffset(MCSymbol *L, int64_t Offset, SMLoc Loc={})

.cfi_def_cfa_offset modifies a rule for computing CFA.

const MCRegisterInfo * getRegisterInfo() const

Describe properties that are true of each instruction in the target description file.

const MCInstrDesc & get(unsigned Opcode) const

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

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Wrapper class representing physical registers. Should be passed by value.

LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)

Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...

const BasicBlock * getBasicBlock() const

Return the LLVM basic block that this instance corresponded to originally.

LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())

Add Succ as a successor of this MachineBasicBlock.

LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)

Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.

LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)

Returns an iterator to the last non-debug instruction in the basic block, or end().

const MachineFunction * getParent() const

Return the MachineFunction containing this basic block.

void splice(iterator Where, MachineBasicBlock *Other, iterator From)

Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...

MachineInstrBundleIterator< MachineInstr > iterator

The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.

void setMaxCallFrameSize(uint64_t S)

LLVM_ABI int CreateFixedObject(uint64_t Size, int64_t SPOffset, bool IsImmutable, bool isAliased=false)

Create a new object at a fixed location on the stack.

bool hasVarSizedObjects() const

This method may be called any time after instruction selection is complete to determine if the stack ...

uint64_t getStackSize() const

Return the number of bytes that must be allocated to hold all of the fixed size frame objects.

bool adjustsStack() const

Return true if this function adjusts the stack – e.g., when calling another function.

bool hasCalls() const

Return true if the current function has any function calls.

bool isFrameAddressTaken() const

This method may be called any time after instruction selection is complete to determine if there is a...

Align getMaxAlign() const

Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...

void setObjectOffset(int ObjectIdx, int64_t SPOffset)

Set the stack frame offset of the specified object.

uint64_t getMaxCallFrameSize() const

Return the maximum size of a call frame that must be allocated for an outgoing function call.

bool hasPatchPoint() const

This method may be called any time after instruction selection is complete to determine if there is a...

LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment)

Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...

LLVM_ABI uint64_t estimateStackSize(const MachineFunction &MF) const

Estimate and return the size of the stack frame.

bool hasTailCall() const

Returns true if the function contains a tail call.

bool hasStackMap() const

This method may be called any time after instruction selection is complete to determine if there is a...

const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const

Returns a reference to call saved info vector for the current function.

const SaveRestorePoints & getRestorePoints() const

int64_t getObjectOffset(int ObjectIdx) const

Return the assigned stack offset of the specified object from the incoming stack pointer.

void setStackSize(uint64_t Size)

Set the size of the stack.

bool isFixedObjectIndex(int ObjectIdx) const

Returns true if the specified index corresponds to a fixed stack object.

const SaveRestorePoints & getSavePoints() const

unsigned addFrameInst(const MCCFIInstruction &Inst)

const TargetSubtargetInfo & getSubtarget() const

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

bool exposesReturnsTwice() const

exposesReturnsTwice - Returns true if the function calls setjmp or any other similar functions with a...

bool needsFrameMoves() const

True if this function needs frame moves for debug or exceptions.

MachineFrameInfo & getFrameInfo()

getFrameInfo - Return the frame info object for the current function.

MCContext & getContext() const

MachineRegisterInfo & getRegInfo()

getRegInfo - Return information about the registers currently in use.

Function & getFunction()

Return the LLVM function that this machine code represents.

BasicBlockListType::iterator iterator

Ty * getInfo()

getInfo - Keep track of various per-function pieces of information for backends that would like to do...

MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)

CreateMachineInstr - Allocate a new MachineInstr.

void insert(iterator MBBI, MachineBasicBlock *MBB)

const TargetMachine & getTarget() const

getTarget - Return the target machine this machine code is compiled with

const MachineInstrBuilder & addCFIIndex(unsigned CFIIndex) const

const MachineInstrBuilder & addImm(int64_t Val) const

Add a new immediate operand.

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

Add a virtual register definition operand.

Representation of each machine instruction.

MachineOperand class - Representation of each machine instruction operand.

const GlobalValue * getGlobal() const

bool isImm() const

isImm - Tests if this is a MO_Immediate operand.

bool isSymbol() const

isSymbol - Tests if this is a MO_ExternalSymbol operand.

bool isGlobal() const

isGlobal - Tests if this is a MO_GlobalAddress operand.

const char * getSymbolName() const

int64_t getOffset() const

Return the offset from the symbol in this operand.

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

def_iterator def_begin(Register RegNo) const

defusechain_iterator< false, true, false, true, false > def_iterator

def_iterator/def_begin/def_end - Walk all defs of the specified register.

static def_iterator def_end()

MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...

uint64_t getReturnSaveOffset() const

getReturnSaveOffset - Return the previous frame offset to save the return address.

bool needsFP(const MachineFunction &MF) const

Definition PPCFrameLowering.cpp:371

void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override

Definition PPCFrameLowering.cpp:1542

bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override

Check whether or not the given MBB can be used as a epilogue for the target.

Definition PPCFrameLowering.cpp:558

uint64_t getStackThreshold() const override

getStackThreshold - Return the maximum stack size

Definition PPCFrameLowering.cpp:2806

void processFunctionBeforeFrameFinalized(MachineFunction &MF, RegScavenger *RS=nullptr) const override

processFunctionBeforeFrameFinalized - This method is called immediately before the specified function...

Definition PPCFrameLowering.cpp:2071

bool hasFPImpl(const MachineFunction &MF) const override

Definition PPCFrameLowering.cpp:360

uint64_t getFramePointerSaveOffset() const

getFramePointerSaveOffset - Return the previous frame offset to save the frame pointer.

Definition PPCFrameLowering.cpp:2727

bool spillCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, ArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override

spillCalleeSavedRegisters - Issues instruction(s) to spill all callee saved registers and returns tru...

Definition PPCFrameLowering.cpp:2411

unsigned getLinkageSize() const

getLinkageSize - Return the size of the PowerPC ABI linkage area.

MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator I) const override

This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...

Definition PPCFrameLowering.cpp:2564

const SpillSlot * getCalleeSavedSpillSlots(unsigned &NumEntries) const override

getCalleeSavedSpillSlots - This method returns a pointer to an array of pairs, that contains an entry...

Definition PPCFrameLowering.cpp:93

void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const override

This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...

Definition PPCFrameLowering.cpp:1970

bool canUseAsPrologue(const MachineBasicBlock &MBB) const override

Methods used by shrink wrapping to determine if MBB can be used for the function prologue/epilogue.

Definition PPCFrameLowering.cpp:551

void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override

emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.

Definition PPCFrameLowering.cpp:608

bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, MutableArrayRef< CalleeSavedInfo > CSI, const TargetRegisterInfo *TRI) const override

restoreCalleeSavedRegisters - Issues instruction(s) to restore all callee saved registers and returns...

Definition PPCFrameLowering.cpp:2606

void replaceFPWithRealFP(MachineFunction &MF) const

Definition PPCFrameLowering.cpp:386

bool enableShrinkWrapping(const MachineFunction &MF) const override

Returns true if the target will correctly handle shrink wrapping.

Definition PPCFrameLowering.cpp:2735

uint64_t determineFrameLayout(const MachineFunction &MF, bool UseEstimate=false, unsigned *NewMaxCallFrameSize=nullptr) const

Determine the frame layout but do not update the machine function.

Definition PPCFrameLowering.cpp:297

void addScavengingSpillSlot(MachineFunction &MF, RegScavenger *RS) const

Definition PPCFrameLowering.cpp:2287

PPCFrameLowering(const PPCSubtarget &STI)

Definition PPCFrameLowering.cpp:82

bool assignCalleeSavedSpillSlots(MachineFunction &MF, const TargetRegisterInfo *TRI, std::vector< CalleeSavedInfo > &CSI) const override

This function will assign callee saved gprs to volatile vector registers for prologue spills when app...

Definition PPCFrameLowering.cpp:2331

uint64_t determineFrameLayoutAndUpdate(MachineFunction &MF, bool UseEstimate=false) const

Determine the frame layout and update the machine function.

Definition PPCFrameLowering.cpp:284

void updateCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const

Definition PPCFrameLowering.cpp:2741

void inlineStackProbe(MachineFunction &MF, MachineBasicBlock &PrologMBB) const override

Replace a StackProbe stub (if any) with the actual probe code inline.

Definition PPCFrameLowering.cpp:1238

uint64_t getTOCSaveOffset() const

getTOCSaveOffset - Return the previous frame offset to save the TOC register – 64-bit SVR4 ABI only.

Definition PPCFrameLowering.cpp:2723

uint64_t getBasePointerSaveOffset() const

getBasePointerSaveOffset - Return the previous frame offset to save the base pointer.

Definition PPCFrameLowering.cpp:2731

PPCFunctionInfo - This class is derived from MachineFunction private PowerPC target-specific informat...

int getTailCallSPDelta() const

const SmallVectorImpl< Register > & getMustSaveCRs() const

int getPICBasePointerSaveIndex() const

bool shrinkWrapDisabled() const

int getFramePointerSaveIndex() const

void addMustSaveCR(Register Reg)

void setBasePointerSaveIndex(int Idx)

bool hasNonRISpills() const

bool isLRStoreRequired() const

void setPICBasePointerSaveIndex(int Idx)

int getROPProtectionHashSaveIndex() const

unsigned getMinReservedArea() const

void setMustSaveLR(bool U)

MustSaveLR - This is set when the prolog/epilog inserter does its initial scan of the function.

void setCRSpillFrameIndex(int idx)

int getBasePointerSaveIndex() const

void setFramePointerSaveIndex(int Idx)

bool hasBasePointer(const MachineFunction &MF) const

const MCPhysReg * getCalleeSavedRegs(const MachineFunction *MF) const override

Code Generation virtual methods...

bool is32BitELFABI() const

const PPCInstrInfo * getInstrInfo() const override

unsigned getRedZoneSize() const

const PPCTargetMachine & getTargetMachine() const

const PPCRegisterInfo * getRegisterInfo() const override

bool hasInlineStackProbe(const MachineFunction &MF) const override

unsigned getStackProbeSize(const MachineFunction &MF) const

Wrapper class representing virtual and physical registers.

This class consists of common code factored out of the SmallVector class to reduce code duplication b...

void push_back(const T &Elt)

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

An instruction for storing to memory.

bool hasFP(const MachineFunction &MF) const

hasFP - Return true if the specified function should have a dedicated frame pointer register.

virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const

This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...

virtual uint64_t getStackThreshold() const

getStackThreshold - Return the maximum stack size

TargetFrameLowering(StackDirection D, Align StackAl, int LAO, Align TransAl=Align(1), bool StackReal=true)

Align getStackAlign() const

getStackAlignment - This method returns the number of bytes to which the stack pointer must be aligne...

TargetInstrInfo - Interface to description of machine instruction set.

bool isPositionIndependent() const

LLVM_ABI bool DisableFramePointerElim(const MachineFunction &MF) const

DisableFramePointerElim - This returns true if frame pointer elimination optimization should be disab...

unsigned GuaranteedTailCallOpt

GuaranteedTailCallOpt - This flag is enabled when -tailcallopt is specified on the commandline.

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

self_iterator getIterator()

#define llvm_unreachable(msg)

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

constexpr char Align[]

Key for Kernel::Arg::Metadata::mAlign.

@ Fast

Attempts to make calls as fast as possible (e.g.

@ Kill

The last use of a register.

initializer< Ty > init(const Ty &Val)

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.

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

constexpr bool isPowerOf2_64(uint64_t Value)

Return true if the argument is a power of two > 0 (64 bit edition.)

unsigned getKillRegState(bool B)

uint16_t MCPhysReg

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

uint64_t alignTo(uint64_t Size, Align A)

Returns a multiple of A needed to store Size bytes.

auto find_if(R &&Range, UnaryPredicate P)

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

unsigned Log2(Align A)

Returns the log2 of the alignment.

void fullyRecomputeLiveIns(ArrayRef< MachineBasicBlock * > MBBs)

Convenience function for recomputing live-in's for a set of MBBs until the computation converges.

This struct is a compact representation of a valid (non-zero power of two) alignment.