LLVM: lib/Target/ARM/Thumb1FrameLowering.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
39#include
40#include
41#include
42
43#define DEBUG_TYPE "arm-frame-lowering"
44
45using namespace llvm;
46
49
53
54
55
56
57 if (CFSize >= ((1 << 8) - 1) * 4 / 2)
58 return false;
59
61}
62
63static void
68 unsigned ScratchReg, unsigned MIFlags) {
69
70
71 if (std::abs(NumBytes) > 508 * 3) {
72
73
74
75
76 if (ScratchReg == ARM::NoRegister)
80 if (ST.genExecuteOnly()) {
81 unsigned XOInstr = ST.useMovt() ? ARM::t2MOVi32imm : ARM::tMOVi32imm;
84 } else {
86 0, MIFlags);
87 }
93 return;
94 }
95
96
98 MRI, MIFlags);
99
100}
101
110
111
120
121
122
125 unsigned Amount = TII.getFrameSize(Old);
126 if (Amount != 0) {
127
128
129
131
132
134 if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
136 } else {
137 assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
139 }
140 }
141 }
143}
144
154
157 assert(NumBytes >= ArgRegsSaveSize &&
158 "ArgRegsSaveSize is included in NumBytes");
161 "Must use R7 spilt for Thumb1");
162
163
164
166
168 Register BasePtr = RegInfo->getBaseRegister();
169 int CFAOffset = 0;
170
171
172 NumBytes = (NumBytes + 3) & ~3;
174
175
176
177 unsigned FRSize = 0, GPRCS1Size = 0, GPRCS2Size = 0, DPRCSSize = 0;
178 int FramePtrSpillFI = 0;
180
181 if (ArgRegsSaveSize) {
184 CFAOffset += ArgRegsSaveSize;
186 }
187
189 if (NumBytes - ArgRegsSaveSize != 0) {
191 -(NumBytes - ArgRegsSaveSize),
193 CFAOffset += NumBytes - ArgRegsSaveSize;
195 }
196 return;
197 }
198
199 bool HasFrameRecordArea = hasFP(MF) && ARM::hGPRRegClass.contains(FramePtr);
200
203 int FI = I.getFrameIdx();
204 if (Reg == FramePtr.asMCReg())
205 FramePtrSpillFI = FI;
206 switch (Reg) {
207 case ARM::R11:
208 if (HasFrameRecordArea) {
209 FRSize += 4;
210 break;
211 }
212 [[fallthrough]];
213 case ARM::R8:
214 case ARM::R9:
215 case ARM::R10:
216 GPRCS2Size += 4;
217 break;
218 case ARM::LR:
219 if (HasFrameRecordArea) {
220 FRSize += 4;
221 break;
222 }
223 [[fallthrough]];
224 case ARM::R4:
225 case ARM::R5:
226 case ARM::R6:
227 case ARM::R7:
228 GPRCS1Size += 4;
229 break;
230 default:
231 DPRCSSize += 8;
232 }
233 }
234
236 if (HasFrameRecordArea) {
237
238
239
240
241 std::advance(MBBI, 2);
242 FRPush = MBBI++;
243 }
244
245 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH) {
246 GPRCS1Push = MBBI;
248 }
249
250
251
252 while (true) {
254
255 while (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tMOVr &&
258 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPUSH &&
260 GPRCS2Push = MBBI;
262 } else {
263
264
265
266 MBBI = OldMBBI;
267 break;
268 }
269 }
270
271
272
273
274
275 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tLDRspi &&
278 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tMOVr &&
279 MBBI->getOperand(0).getReg() == ARM::LR &&
282 }
283 }
284
285
286 unsigned DPRCSOffset = NumBytes - ArgRegsSaveSize -
287 (FRSize + GPRCS1Size + GPRCS2Size + DPRCSSize);
288 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
289 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
290 bool HasFP = hasFP(MF);
291 if (HasFP)
293 NumBytes);
294 if (HasFrameRecordArea)
299 NumBytes = DPRCSOffset;
300
301 int FramePtrOffsetInBlock = 0;
302 unsigned adjustedGPRCS1Size = GPRCS1Size;
303 if (GPRCS1Size > 0 && GPRCS2Size == 0 &&
305 FramePtrOffsetInBlock = NumBytes;
306 adjustedGPRCS1Size += NumBytes;
307 NumBytes = 0;
308 }
309 CFAOffset += adjustedGPRCS1Size;
310
311
312 if (HasFP) {
314 HasFrameRecordArea ? std::next(FRPush) : std::next(GPRCS1Push);
315 if (HasFrameRecordArea) {
316
317
322 } else {
323 FramePtrOffsetInBlock +=
324 MFI.getObjectOffset(FramePtrSpillFI) + GPRCS1Size + ArgRegsSaveSize;
327 .addImm(FramePtrOffsetInBlock / 4)
330 }
331
333 if (FramePtrOffsetInBlock)
335 else
337 if (NumBytes > 508)
338
339
341 }
342
343
344 if (GPRCS1Size > 0) {
346 if (adjustedGPRCS1Size)
349 switch (I.getReg()) {
350 case ARM::R8:
351 case ARM::R9:
352 case ARM::R10:
353 case ARM::R11:
354 case ARM::R12:
355 break;
356 case ARM::R0:
357 case ARM::R1:
358 case ARM::R2:
359 case ARM::R3:
360 case ARM::R4:
361 case ARM::R5:
362 case ARM::R6:
363 case ARM::R7:
364 case ARM::LR:
367 break;
368 }
369 }
370 }
371
372
373 if (GPRCS2Size > 0) {
375 for (auto &I : CSI) {
376 switch (I.getReg()) {
377 case ARM::R8:
378 case ARM::R9:
379 case ARM::R10:
380 case ARM::R11:
381 case ARM::R12:
384 break;
385 default:
386 break;
387 }
388 }
389 }
390
391 if (NumBytes) {
392
393
394
395
396
397 unsigned ScratchRegister = ARM::NoRegister;
398 for (auto &I : CSI) {
401 ScratchRegister = Reg;
402 break;
403 }
404 }
407 if (!HasFP) {
408 CFAOffset += NumBytes;
410 }
411 }
412
413 if (STI.isTargetELF() && HasFP)
416
420
421 if (RegInfo->hasStackRealignment(MF)) {
423
424
425
426
427
428
432
436 .addImm(NrBitsToZero)
438
442 .addImm(NrBitsToZero)
444
448
450 }
451
452
453
454
455
456 if (RegInfo->hasBasePointer(MF))
460
461
462
463
466
467
468
470}
471
482
485 assert((unsigned)NumBytes >= ArgRegsSaveSize &&
486 "ArgRegsSaveSize is included in NumBytes");
488
490 if (NumBytes - ArgRegsSaveSize != 0)
492 NumBytes - ArgRegsSaveSize, ARM::NoRegister,
494 } else {
495
496 if (MBBI != MBB.begin()) {
497 do
502 }
503
504
505 NumBytes -=
509
510
511
512 unsigned ScratchRegister = ARM::NoRegister;
513 bool HasFP = hasFP(MF);
517 ScratchRegister = Reg;
518 break;
519 }
520 }
521
524
525
526
527 if (NumBytes) {
528 assert(ScratchRegister != ARM::NoRegister &&
529 "No scratch register to restore SP from FP!");
533 .addReg(ScratchRegister)
536 } else
541 } else {
542 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tBX_RET &&
543 &MBB.front() != &*MBBI && std::prev(MBBI)->getOpcode() == ARM::tPOP) {
551 }
552 }
553
554 if (needPopSpecialFixUp(MF)) {
555 bool Done = emitPopSpecialFixUp(MBB, true);
557 assert(Done && "Emission of the special fixup failed!?");
558 }
559}
560
562 if (!needPopSpecialFixUp(*MBB.getParent()))
563 return true;
564
566 return emitPopSpecialFixUp(*TmpMBB, false);
567}
568
569bool Thumb1FrameLowering::needPopSpecialFixUp(const MachineFunction &MF) const {
571 const_cast<MachineFunction *>(&MF)->getInfo();
573 return true;
574
575
577 if (CSI.getReg() == ARM::LR)
578 return true;
579
580 return false;
581}
582
585 const LiveRegUnits &UsedRegs, unsigned &PopReg,
587 PopReg = TmpReg = 0;
590
591 if (PopFriendly.test(Reg)) {
592 PopReg = Reg;
593 TmpReg = 0;
594 break;
595 }
596
597
598 TmpReg = Reg;
599 }
600 }
601}
602
604 bool DoIt) const {
606 ARMFunctionInfo *AFI = MF.getInfo();
608 const TargetInstrInfo &TII = *STI.getInstrInfo();
609 const ThumbRegisterInfo *RegInfo =
610 static_cast<const ThumbRegisterInfo *>(STI.getRegisterInfo());
611
612
613
614
615
616
617
618
620 bool CanRestoreDirectly = STI.hasV5TOps() && !ArgRegsSaveSize;
621 if (CanRestoreDirectly) {
622 if (MBBI != MBB.end() && MBBI->getOpcode() != ARM::tB)
623 CanRestoreDirectly = (MBBI->getOpcode() == ARM::tBX_RET ||
624 MBBI->getOpcode() == ARM::tPOP_RET);
625 else {
626 auto MBBI_prev = MBBI;
627 MBBI_prev--;
628 assert(MBBI_prev->getOpcode() == ARM::tPOP);
630 if ((*MBB.succ_begin())->begin()->getOpcode() == ARM::tBX_RET)
631 MBBI = MBBI_prev;
632 else
633 CanRestoreDirectly = false;
634 }
635 }
636
637 if (CanRestoreDirectly) {
638 if (!DoIt || MBBI->getOpcode() == ARM::tPOP_RET)
639 return true;
640 MachineInstrBuilder MIB =
644
645 for (auto MO: MBBI->operands())
646 if (MO.isReg() && (MO.isImplicit() || MO.isDef()))
647 MIB.add(MO);
649
651 return true;
652 }
653
654
655
656 const TargetRegisterInfo &TRI = *STI.getRegisterInfo();
657 LiveRegUnits UsedRegs(TRI);
658 UsedRegs.addLiveOuts(MBB);
659
660
661
662
663 const MCPhysReg *CSRegs = TRI.getCalleeSavedRegs(&MF);
664 for (unsigned i = 0; CSRegs[i]; ++i)
665 UsedRegs.addReg(CSRegs[i]);
666
669 dl = MBBI->getDebugLoc();
670 auto InstUpToMBBI = MBB.end();
671 while (InstUpToMBBI != MBBI)
672
673
674 UsedRegs.stepBackward(*--InstUpToMBBI);
675 }
676
677
678 unsigned PopReg = 0;
679
680 unsigned TemporaryReg = 0;
681 BitVector PopFriendly =
682 TRI.getAllocatableSet(MF, TRI.getRegClass(ARM::tGPRRegClassID));
683
684 assert(PopFriendly.any() && "No allocatable pop-friendly register?!");
685
686
687 BitVector GPRsNoLRSP =
688 TRI.getAllocatableSet(MF, TRI.getRegClass(ARM::hGPRRegClassID));
689 GPRsNoLRSP |= PopFriendly;
690 GPRsNoLRSP.reset(ARM::LR);
691 GPRsNoLRSP.reset(ARM::SP);
692 GPRsNoLRSP.reset(ARM::PC);
693 findTemporariesForLR(GPRsNoLRSP, PopFriendly, UsedRegs, PopReg, TemporaryReg,
695
696
697
698
699 bool UseLDRSP = false;
701 auto PrevMBBI = MBBI;
702 PrevMBBI--;
703 if (PrevMBBI->getOpcode() == ARM::tPOP) {
704 UsedRegs.stepBackward(*PrevMBBI);
707 if (PopReg) {
708 MBBI = PrevMBBI;
709 UseLDRSP = true;
710 }
711 }
712 }
713
714 if (!DoIt && !PopReg && !TemporaryReg)
715 return false;
716
717 assert((PopReg || TemporaryReg) && "Cannot get LR");
718
719 if (UseLDRSP) {
720 assert(PopReg && "Do not know how to get LR");
721
725 .addImm(MBBI->getNumExplicitOperands() - 2)
728
734
736
738 ArgRegsSaveSize + 4, ARM::NoRegister,
740 return true;
741 }
742
743 if (TemporaryReg) {
744 assert(!PopReg && "Unnecessary MOV is about to be inserted");
751 }
752
753 if (MBBI != MBB.end() && MBBI->getOpcode() == ARM::tPOP_RET) {
754
755
756 MachineInstrBuilder MIB =
760 bool Popped = false;
761 for (auto MO: MBBI->operands())
762 if (MO.isReg() && (MO.isImplicit() || MO.isDef()) &&
763 MO.getReg() != ARM::PC) {
764 MIB.add(MO);
765 if (!MO.isImplicit())
766 Popped = true;
767 }
768
769 if (!Popped)
771
776 }
777
778 assert(PopReg && "Do not know how to get LR");
783
786
792
793 if (TemporaryReg)
799
800 return true;
801}
802
808 ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
809 ARM::R5, ARM::R6, ARM::R7, ARM::LR};
810
812 std::set &LowRegs,
813 std::set &HighRegs) {
815 if (ARM::tGPRRegClass.contains(Reg) || Reg == ARM::LR) {
816 LowRegs.insert(Reg);
817 } else if (ARM::hGPRRegClass.contains(Reg) && Reg != ARM::LR) {
818 HighRegs.insert(Reg);
819 } else {
820 llvm_unreachable("callee-saved register of unexpected class");
821 }
822 }
823}
824
825template
827 const std::set &RegSet) {
828 return std::find_if(OrderedStartIt, OrderedEndIt,
830}
831
835 const std::set &RegsToSave,
836 const std::set &CopyRegs,
837 bool &UsedLRAsTemp) {
841
842 std::set LowRegs, HighRegs;
844
845
846 if (!LowRegs.empty()) {
850 if (LowRegs.count(Reg)) {
851 bool isKill = .isLiveIn(Reg);
852 if (isKill && .isReserved(Reg))
854
856 }
857 }
859 }
860
861
862
863
864
865
866
867
868
869
870
871
874 HighRegs);
875
877
880 CopyRegs);
881
882
886
890 if (HighRegs.count(*HiRegToSave)) {
891 bool isKill = .isLiveIn(*HiRegToSave);
892 if (isKill && .isReserved(*HiRegToSave))
893 MBB.addLiveIn(*HiRegToSave);
894 if (*CopyRegIt == ARM::LR)
895 UsedLRAsTemp = true;
896
897
903
904
905 RegsToPush.push_back(*CopyRegIt);
906
909 CopyRegs);
912 HighRegs);
913 }
914 }
915
916
919
920
922 }
923}
924
928 const std::set &RegsToRestore,
929 const std::set &AvailableCopyRegs,
930 bool IsVarArg, bool HasV5Ops) {
931 if (RegsToRestore.empty())
932 return;
933
937
938 std::set LowRegs, HighRegs;
940
941
942
943
944
945
946
947
950 HighRegs);
951
952 std::set CopyRegs = AvailableCopyRegs;
954 if (!HighRegs.empty() && CopyRegs.empty()) {
955
956
957 LowScratchReg = ARM::R0;
963 CopyRegs.insert(LowScratchReg);
964 }
965
967 assert(!CopyRegs.empty());
968
971 CopyRegs);
972
973
977
980
982
983
989
992 CopyRegs);
995 HighRegs);
996 }
997 }
998
999
1000 if (LowScratchReg.isValid()) {
1006 }
1007
1008
1009 if (!LowRegs.empty()) {
1013
1014 bool NeedsPop = false;
1016 if (!LowRegs.count(Reg))
1017 continue;
1018
1019 if (Reg == ARM::LR) {
1020 if (.succ_empty() || MI->getOpcode() == ARM::TCRETURNdi ||
1021 MI->getOpcode() == ARM::TCRETURNri ||
1022 MI->getOpcode() == ARM::TCRETURNrinotr12)
1023
1024
1025
1026
1027
1028
1029 continue;
1030
1031 if (IsVarArg)
1032 continue;
1033
1034 if (!HasV5Ops)
1035 continue;
1036
1037
1039 continue;
1040
1041
1042 Reg = ARM::PC;
1043 (*MIB).setDesc(TII.get(ARM::tPOP_RET));
1047 }
1049 NeedsPop = true;
1050 }
1051
1052
1053 if (NeedsPop)
1055 else
1056 MF.deleteMachineInstr(MIB);
1057 }
1058}
1059
1063 if (CSI.empty())
1064 return false;
1065
1071
1072
1073
1074 bool NeedsFrameRecordPush = hasFP(MF) && ARM::hGPRRegClass.contains(FPReg);
1076 bool UsedLRAsTemp = false;
1077
1078 std::set FrameRecord;
1079 std::set SpilledGPRs;
1082 if (NeedsFrameRecordPush && (Reg == FPReg.asMCReg() || Reg == ARM::LR))
1083 FrameRecord.insert(Reg);
1084 else
1085 SpilledGPRs.insert(Reg);
1086 }
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096 std::set FrameRecordCopyRegs;
1097 for (unsigned ArgReg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3})
1099 FrameRecordCopyRegs.insert(ArgReg);
1100 if (FrameRecordCopyRegs.empty())
1101 FrameRecordCopyRegs.insert(ARM::LR);
1102
1104
1105
1106
1107
1108 std::set CopyRegs;
1109 for (Register Reg : SpilledGPRs)
1110 if ((ARM::tGPRRegClass.contains(Reg) || Reg == ARM::LR) &&
1112 CopyRegs.insert(Reg);
1113 for (unsigned ArgReg : {ARM::R0, ARM::R1, ARM::R2, ARM::R3})
1115 CopyRegs.insert(ArgReg);
1116
1118
1119
1120
1121
1122
1123
1124 if (LRLiveIn && UsedLRAsTemp) {
1128 unsigned NumRegsPushed = FrameRecord.size() + SpilledGPRs.size();
1130 dbgs() << "LR is live-in but clobbered in prologue, restoring via "
1131 << RegInfo->getName(*CopyRegIt) << "\n");
1132
1135 .addImm(NumRegsPushed - 1)
1138
1143 }
1144
1145 return true;
1146}
1147
1151 if (CSI.empty())
1152 return false;
1153
1161
1162
1163
1164 bool NeedsFrameRecordPop = hasFP(MF) && ARM::hGPRRegClass.contains(FPReg);
1165
1166 std::set FrameRecord;
1167 std::set SpilledGPRs;
1170 if (NeedsFrameRecordPop && (Reg == FPReg.asMCReg() || Reg == ARM::LR))
1171 FrameRecord.insert(Reg);
1172 else
1173 SpilledGPRs.insert(Reg);
1174
1175 if (Reg == ARM::LR)
1176 I.setRestored(false);
1177 }
1178
1179
1180
1181
1182 std::set CopyRegs;
1183 std::set UnusedReturnRegs;
1184 for (Register Reg : SpilledGPRs)
1185 if ((ARM::tGPRRegClass.contains(Reg)) && !(hasFP(MF) && Reg == FPReg))
1186 CopyRegs.insert(Reg);
1187 auto Terminator = MBB.getFirstTerminator();
1188 if (Terminator != MBB.end() && Terminator->getOpcode() == ARM::tBX_RET) {
1189 UnusedReturnRegs.insert(ARM::R0);
1190 UnusedReturnRegs.insert(ARM::R1);
1191 UnusedReturnRegs.insert(ARM::R2);
1192 UnusedReturnRegs.insert(ARM::R3);
1193 for (auto Op : Terminator->implicit_operands()) {
1194 if (Op.isReg())
1195 UnusedReturnRegs.erase(Op.getReg());
1196 }
1197 }
1198 CopyRegs.insert(UnusedReturnRegs.begin(), UnusedReturnRegs.end());
1199
1200
1202 STI.hasV5TOps());
1203
1204
1205
1206 assert((!SpilledGPRs.count(ARM::LR) || FrameRecord.empty()) &&
1207 "Can't insert pop after return sequence");
1208
1209
1210
1212 STI.hasV5TOps());
1213
1214 return true;
1215}
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 BitVector class.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
static constexpr MCPhysReg FPReg
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
static void emitCallSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned MIFlags=MachineInstr::NoFlags)
Definition Thumb1FrameLowering.cpp:102
static void pushRegsToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToSave, const std::set< Register > &CopyRegs, bool &UsedLRAsTemp)
Definition Thumb1FrameLowering.cpp:832
static const SmallVector< Register > OrderedCopyRegs
Definition Thumb1FrameLowering.cpp:807
static const SmallVector< Register > OrderedLowRegs
Definition Thumb1FrameLowering.cpp:803
static void splitLowAndHighRegs(const std::set< Register > &Regs, std::set< Register > &LowRegs, std::set< Register > &HighRegs)
Definition Thumb1FrameLowering.cpp:811
It getNextOrderedReg(It OrderedStartIt, It OrderedEndIt, const std::set< Register > &RegSet)
Definition Thumb1FrameLowering.cpp:826
static void emitPrologueEpilogueSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const TargetInstrInfo &TII, const DebugLoc &dl, const ThumbRegisterInfo &MRI, int NumBytes, unsigned ScratchReg, unsigned MIFlags)
Definition Thumb1FrameLowering.cpp:64
static const SmallVector< Register > OrderedHighRegs
Definition Thumb1FrameLowering.cpp:805
static void popRegsFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MI, const TargetInstrInfo &TII, const std::set< Register > &RegsToRestore, const std::set< Register > &AvailableCopyRegs, bool IsVarArg, bool HasV5Ops)
Definition Thumb1FrameLowering.cpp:925
static void findTemporariesForLR(const BitVector &GPRsNoLRSP, const BitVector &PopFriendly, const LiveRegUnits &UsedRegs, unsigned &PopReg, unsigned &TmpReg, MachineRegisterInfo &MRI)
Definition Thumb1FrameLowering.cpp:583
static const unsigned FramePtr
ARMFrameLowering(const ARMSubtarget &sti)
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool hasStackFrame() const
unsigned getGPRCalleeSavedArea1Size() const
unsigned getDPRCalleeSavedArea1Size() const
void setDPRCalleeSavedArea1Offset(unsigned o)
void setGPRCalleeSavedArea2Size(unsigned s)
void setFramePtrSpillOffset(unsigned o)
unsigned getGPRCalleeSavedArea2Size() const
void setGPRCalleeSavedArea1Size(unsigned s)
bool isCmseNSEntryFunction() const
unsigned getFramePtrSpillOffset() const
bool shouldRestoreSPFromFP() const
void setFrameRecordSavedAreaSize(unsigned s)
unsigned getArgRegsSaveSize() const
void setGPRCalleeSavedArea2Offset(unsigned o)
unsigned getFrameRecordSavedAreaSize() const
void setGPRCalleeSavedArea1Offset(unsigned o)
void setDPRCalleeSavedArea1Size(unsigned s)
void setShouldRestoreSPFromFP(bool s)
@ SplitR7
R7 and LR must be adjacent, because R7 is the frame pointer, and must point to a frame record consist...
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
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.
bool any() const
any - Returns true if any bit is set.
iterator_range< const_set_bits_iterator > set_bits() const
Helper class for creating CFI instructions and inserting them into MIR.
void buildDefCFAOffset(int64_t Offset, MCSymbol *Label=nullptr) const
void buildDefCFARegister(MCRegister Reg) const
void buildOffset(MCRegister Reg, int64_t Offset) const
void buildDefCFA(MCRegister Reg, int64_t Offset) const
void setInsertPoint(MachineBasicBlock::iterator IP)
The CalleeSavedInfo class tracks the information need to locate where a callee saved register is in t...
A set of register units used to track register liveness.
bool available(MCRegister Reg) const
Returns true if no part of physical register Reg is live.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Wrapper class representing physical registers. Should be passed by value.
succ_iterator succ_begin()
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
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.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
uint64_t getMaxCallFrameSize() const
Return the maximum size of a call frame that must be allocated for an outgoing function call.
int64_t getOffsetAdjustment() const
Return the correction for frame offsets.
const std::vector< CalleeSavedInfo > & getCalleeSavedInfo() const
Returns a reference to call saved info vector for the current function.
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.
void setOffsetAdjustment(int64_t Adj)
Set the correction for frame offsets.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & setMIFlag(MachineInstr::MIFlag Flag) const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool isLiveIn(Register Reg) const
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MachineBasicBlock::iterator eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override
This method is called during prolog/epilog code insertion to eliminate call frame setup and destroy p...
Definition Thumb1FrameLowering.cpp:113
Thumb1FrameLowering(const ARMSubtarget &sti)
Definition Thumb1FrameLowering.cpp:47
void emitPrologue(MachineFunction &MF, MachineBasicBlock &MBB) const override
emitProlog/emitEpilog - These methods insert prolog and epilog code into the function.
Definition Thumb1FrameLowering.cpp:145
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const override
Definition Thumb1FrameLowering.cpp:472
bool canUseAsEpilogue(const MachineBasicBlock &MBB) const override
Check whether or not the given MBB can be used as a epilogue for the target.
Definition Thumb1FrameLowering.cpp:561
bool hasReservedCallFrame(const MachineFunction &MF) const override
hasReservedCallFrame - Under normal circumstances, when a frame pointer is not required,...
Definition Thumb1FrameLowering.cpp:50
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 Thumb1FrameLowering.cpp:1148
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 Thumb1FrameLowering.cpp:1060
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Define
Register definition.
@ Kill
The last use of a register.
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.
static bool isARMLowRegister(MCRegister Reg)
isARMLowRegister - Returns true if the register is a low register (r0-r7).
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
bool tryFoldSPUpdateIntoPushPop(const ARMSubtarget &Subtarget, MachineFunction &MF, MachineInstr *MI, unsigned NumBytes)
Tries to add registers to the reglist of a given base-updating push/pop instruction to adjust the sta...
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
unsigned getDefRegState(bool B)
unsigned getKillRegState(bool B)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
emitThumbRegPlusImmediate - Emits a series of instructions to materialize a destreg = basereg + immed...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
DWARFExpression::Operation Op
unsigned Log2(Align A)
Returns the log2 of the alignment.