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 (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
478 }
479
480
481
482
483
484 if (.isRegUsed(R0) &&
.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 = (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 = (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 || (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 = (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 ((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() && (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() ? (StackSize) :
(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 .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
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
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)
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.