@@ -147,6 +147,9 @@ static cl::opt<unsigned> ShrinkLimit("shrink-frame-limit", cl::init(UINT_MAX),
147
147
cl::Hidden, cl::ZeroOrMore, cl::desc(" Max count of stack frame "
148
148
" shrink-wraps" ));
149
149
150
+ static cl::opt<bool > UseAllocframe (" use-allocframe" , cl::init(true ),
151
+ cl::Hidden, cl::desc(" Use allocframe more conservatively" ));
152
+
150
153
151
154
namespace llvm {
152
155
void initializeHexagonCallFrameInformationPass (PassRegistry&);
@@ -422,7 +425,6 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
422
425
void HexagonFrameLowering::insertPrologueInBlock (MachineBasicBlock &MBB) const {
423
426
MachineFunction &MF = *MBB.getParent ();
424
427
MachineFrameInfo *MFI = MF.getFrameInfo ();
425
- auto &HTM = static_cast <const HexagonTargetMachine&>(MF.getTarget ());
426
428
auto &HST = MF.getSubtarget <HexagonSubtarget>();
427
429
auto &HII = *HST.getInstrInfo ();
428
430
auto &HRI = *HST.getRegisterInfo ();
@@ -457,14 +459,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
457
459
MI->eraseFromParent ();
458
460
}
459
461
460
- //
461
- // Only insert ALLOCFRAME if we need to or at -O0 for the debugger. Think
462
- // that this shouldn't be required, but doing so now because gcc does and
463
- // gdb can't break at the start of the function without it. Will remove if
464
- // this turns out to be a gdb bug.
465
- //
466
- bool NoOpt = (HTM.getOptLevel () == CodeGenOpt::None);
467
- if (!NoOpt && !FuncInfo->hasClobberLR () && !hasFP (MF))
462
+ if (!hasFP (MF))
468
463
return ;
469
464
470
465
// Check for overflow.
@@ -506,11 +501,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
506
501
507
502
void HexagonFrameLowering::insertEpilogueInBlock (MachineBasicBlock &MBB) const {
508
503
MachineFunction &MF = *MBB.getParent ();
509
- //
510
- // Only insert deallocframe if we need to. Also at -O0. See comment
511
- // in insertPrologueInBlock above.
512
- //
513
- if (!hasFP (MF) && MF.getTarget ().getOptLevel () != CodeGenOpt::None)
504
+ if (!hasFP (MF))
514
505
return ;
515
506
516
507
auto &HST = static_cast <const HexagonSubtarget&>(MF.getSubtarget ());
@@ -634,24 +625,33 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
634
625
635
626
MCSymbol *FrameLabel = MMI.getContext ().createTempSymbol ();
636
627
637
- // Advance CFA. DW_CFA_def_cfa
638
- unsigned DwFPReg = HRI.getDwarfRegNum (HRI.getFrameRegister (), true );
639
- unsigned DwRAReg = HRI.getDwarfRegNum (HRI.getRARegister (), true );
640
-
641
- // CFA = FP + 8
642
- auto DefCfa = MCCFIInstruction::createDefCfa (FrameLabel, DwFPReg, -8 );
643
- BuildMI (MBB, At, DL, CFID)
644
- .addCFIIndex (MMI.addFrameInst (DefCfa));
645
-
646
- // R31 (return addr) = CFA - #4
647
- auto OffR31 = MCCFIInstruction::createOffset (FrameLabel, DwRAReg, -4 );
648
- BuildMI (MBB, At, DL, CFID)
649
- .addCFIIndex (MMI.addFrameInst (OffR31));
650
-
651
- // R30 (frame ptr) = CFA - #8)
652
- auto OffR30 = MCCFIInstruction::createOffset (FrameLabel, DwFPReg, -8 );
653
- BuildMI (MBB, At, DL, CFID)
654
- .addCFIIndex (MMI.addFrameInst (OffR30));
628
+ if (hasFP (MF)) {
629
+ unsigned DwFPReg = HRI.getDwarfRegNum (HRI.getFrameRegister (), true );
630
+ unsigned DwRAReg = HRI.getDwarfRegNum (HRI.getRARegister (), true );
631
+
632
+ // Define CFA via an offset from the value of FP.
633
+ //
634
+ // -8 -4 0 (SP)
635
+ // --+----+----+---------------------
636
+ // | FP | LR | increasing addresses -->
637
+ // --+----+----+---------------------
638
+ // | +-- Old SP (before allocframe)
639
+ // +-- New FP (after allocframe)
640
+ //
641
+ // MCCFIInstruction::createDefCfa subtracts the offset from the register.
642
+ // MCCFIInstruction::createOffset takes the offset without sign change.
643
+ auto DefCfa = MCCFIInstruction::createDefCfa (FrameLabel, DwFPReg, -8 );
644
+ BuildMI (MBB, At, DL, CFID)
645
+ .addCFIIndex (MMI.addFrameInst (DefCfa));
646
+ // R31 (return addr) = CFA - 4
647
+ auto OffR31 = MCCFIInstruction::createOffset (FrameLabel, DwRAReg, -4 );
648
+ BuildMI (MBB, At, DL, CFID)
649
+ .addCFIIndex (MMI.addFrameInst (OffR31));
650
+ // R30 (frame ptr) = CFA - 8
651
+ auto OffR30 = MCCFIInstruction::createOffset (FrameLabel, DwFPReg, -8 );
652
+ BuildMI (MBB, At, DL, CFID)
653
+ .addCFIIndex (MMI.addFrameInst (OffR30));
654
+ }
655
655
656
656
static unsigned int RegsToMove[] = {
657
657
Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
@@ -709,11 +709,40 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
709
709
710
710
711
711
bool HexagonFrameLowering::hasFP (const MachineFunction &MF) const {
712
- const MachineFrameInfo *MFI = MF.getFrameInfo ();
713
- const HexagonMachineFunctionInfo *FuncInfo =
714
- MF.getInfo <HexagonMachineFunctionInfo>();
715
- return MFI->hasCalls () || MFI->getStackSize () > 0 ||
716
- FuncInfo->hasClobberLR ();
712
+ auto &MFI = *MF.getFrameInfo ();
713
+ auto &HRI = *MF.getSubtarget <HexagonSubtarget>().getRegisterInfo ();
714
+
715
+ bool HasFixed = MFI.getNumFixedObjects ();
716
+ bool HasPrealloc = const_cast <MachineFrameInfo&>(MFI)
717
+ .getLocalFrameObjectCount ();
718
+ bool HasExtraAlign = HRI.needsStackRealignment (MF);
719
+ bool HasAlloca = MFI.hasVarSizedObjects ();
720
+
721
+ // Insert ALLOCFRAME if we need to or at -O0 for the debugger. Think
722
+ // that this shouldn't be required, but doing so now because gcc does and
723
+ // gdb can't break at the start of the function without it. Will remove if
724
+ // this turns out to be a gdb bug.
725
+ //
726
+ if (MF.getTarget ().getOptLevel () == CodeGenOpt::None)
727
+ return true ;
728
+
729
+ // By default we want to use SP (since it's always there). FP requires
730
+ // some setup (i.e. ALLOCFRAME).
731
+ // Fixed and preallocated objects need FP if the distance from them to
732
+ // the SP is unknown (as is with alloca or aligna).
733
+ if ((HasFixed || HasPrealloc) && (HasAlloca || HasExtraAlign))
734
+ return true ;
735
+
736
+ if (MFI.getStackSize () > 0 ) {
737
+ if (UseAllocframe)
738
+ return true ;
739
+ }
740
+
741
+ if (MFI.hasCalls () ||
742
+ MF.getInfo <HexagonMachineFunctionInfo>()->hasClobberLR ())
743
+ return true ;
744
+
745
+ return false ;
717
746
}
718
747
719
748
@@ -795,15 +824,90 @@ static void addCalleeSaveRegistersAsImpOperand(MachineInstr *Inst,
795
824
}
796
825
}
797
826
827
+
798
828
int HexagonFrameLowering::getFrameIndexReference (const MachineFunction &MF,
799
- int FI,
800
- unsigned &FrameReg) const {
801
- const TargetRegisterInfo *RI = MF.getSubtarget ().getRegisterInfo ();
829
+ int FI, unsigned &FrameReg) const {
830
+ auto &MFI = *MF.getFrameInfo ();
831
+ auto &HRI = *MF.getSubtarget <HexagonSubtarget>().getRegisterInfo ();
832
+
833
+ // Large parts of this code are shared with HRI::eliminateFrameIndex.
834
+ int Offset = MFI.getObjectOffset (FI);
835
+ bool HasAlloca = MFI.hasVarSizedObjects ();
836
+ bool HasExtraAlign = HRI.needsStackRealignment (MF);
837
+ bool NoOpt = MF.getTarget ().getOptLevel () == CodeGenOpt::None;
838
+
839
+ unsigned SP = HRI.getStackRegister (), FP = HRI.getFrameRegister ();
840
+ unsigned AP = 0 ;
841
+ if (const MachineInstr *AI = getAlignaInstr (MF))
842
+ AP = AI->getOperand (0 ).getReg ();
843
+ unsigned FrameSize = MFI.getStackSize ();
844
+
845
+ bool UseFP = false , UseAP = false ; // Default: use SP (except at -O0).
846
+ // Use FP at -O0, except when there are objects with extra alignment.
847
+ // That additional alignment requirement may cause a pad to be inserted,
848
+ // which will make it impossible to use FP to access objects located
849
+ // past the pad.
850
+ if (NoOpt && !HasExtraAlign)
851
+ UseFP = true ;
852
+ if (MFI.isFixedObjectIndex (FI) || MFI.isObjectPreAllocated (FI)) {
853
+ // Fixed and preallocated objects will be located before any padding
854
+ // so FP must be used to access them.
855
+ UseFP |= (HasAlloca || HasExtraAlign);
856
+ } else {
857
+ if (HasAlloca) {
858
+ if (HasExtraAlign)
859
+ UseAP = true ;
860
+ else
861
+ UseFP = true ;
862
+ }
863
+ }
802
864
803
- // Fill in FrameReg output argument.
804
- FrameReg = RI->getFrameRegister (MF);
865
+ // If FP was picked, then there had better be FP.
866
+ bool HasFP = hasFP (MF);
867
+ assert ((HasFP || !UseFP) && " This function must have frame pointer" );
805
868
806
- return MF.getFrameInfo ()->getObjectOffset (FI);
869
+ // Having FP implies allocframe. Allocframe will store extra 8 bytes:
870
+ // FP/LR. If the base register is used to access an object across these
871
+ // 8 bytes, then the offset will need to be adjusted by 8.
872
+ //
873
+ // After allocframe:
874
+ // HexagonISelLowering adds 8 to ---+
875
+ // the offsets of all stack-based |
876
+ // arguments (*) |
877
+ // |
878
+ // getObjectOffset < 0 0 8 getObjectOffset >= 8
879
+ // ------------------------+-----+------------------------> increasing
880
+ // <local objects> |FP/LR| <input arguments> addresses
881
+ // -----------------+------+-----+------------------------>
882
+ // | |
883
+ // SP/AP point --+ +-- FP points here (**)
884
+ // somewhere on
885
+ // this side of FP/LR
886
+ //
887
+ // (*) See LowerFormalArguments. The FP/LR is assumed to be present.
888
+ // (**) *FP == old-FP. FP+0..7 are the bytes of FP/LR.
889
+
890
+ // The lowering assumes that FP/LR is present, and so the offsets of
891
+ // the formal arguments start at 8. If FP/LR is not there we need to
892
+ // reduce the offset by 8.
893
+ if (Offset > 0 && !HasFP)
894
+ Offset -= 8 ;
895
+
896
+ if (UseFP)
897
+ FrameReg = FP;
898
+ else if (UseAP)
899
+ FrameReg = AP;
900
+ else
901
+ FrameReg = SP;
902
+
903
+ // Calculate the actual offset in the instruction. If there is no FP
904
+ // (in other words, no allocframe), then SP will not be adjusted (i.e.
905
+ // there will be no SP -= FrameSize), so the frame size should not be
906
+ // added to the calculated offset.
907
+ int RealOffset = Offset;
908
+ if (!UseFP && !UseAP && HasFP)
909
+ RealOffset = FrameSize+Offset;
910
+ return RealOffset;
807
911
}
808
912
809
913
@@ -915,9 +1019,9 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
915
1019
// via AP, which may not be available at the particular place in the program.
916
1020
MachineFrameInfo *MFI = MF.getFrameInfo ();
917
1021
bool HasAlloca = MFI->hasVarSizedObjects ();
918
- bool HasAligna = (MFI->getMaxAlignment () > getStackAlignment ());
1022
+ bool NeedsAlign = (MFI->getMaxAlignment () > getStackAlignment ());
919
1023
920
- if (!HasAlloca || !HasAligna )
1024
+ if (!HasAlloca || !NeedsAlign )
921
1025
return ;
922
1026
923
1027
unsigned LFS = MFI->getLocalFrameSize ();
@@ -1293,7 +1397,8 @@ bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const {
1293
1397
}
1294
1398
1295
1399
1296
- MachineInstr *HexagonFrameLowering::getAlignaInstr (MachineFunction &MF) const {
1400
+ const MachineInstr *HexagonFrameLowering::getAlignaInstr (
1401
+ const MachineFunction &MF) const {
1297
1402
for (auto &B : MF)
1298
1403
for (auto &I : B)
1299
1404
if (I.getOpcode () == Hexagon::ALIGNA)
0 commit comments