Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit d497ef1

Browse files
author
Krzysztof Parzyszek
committed
[Hexagon] Fix debug information for local objects
- Isolate the check for the existence of a stack frame into hasFP. - Implement getFrameIndexReference for DWARF address computation. - Use getFrameIndexReference for offset computation in eliminateFrameIndex. - Preserve debug information for dynamically allocated stack objects. - Prefer FP to access local objects at -O0. - Add experimental code to skip allocframe when not strictly necessary (disabled by default). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250718 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 6e76a23 commit d497ef1

File tree

4 files changed

+170
-117
lines changed

4 files changed

+170
-117
lines changed

lib/Target/Hexagon/HexagonFrameLowering.cpp

+151-46
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ static cl::opt<unsigned> ShrinkLimit("shrink-frame-limit", cl::init(UINT_MAX),
147147
cl::Hidden, cl::ZeroOrMore, cl::desc("Max count of stack frame "
148148
"shrink-wraps"));
149149

150+
static cl::opt<bool> UseAllocframe("use-allocframe", cl::init(true),
151+
cl::Hidden, cl::desc("Use allocframe more conservatively"));
152+
150153

151154
namespace llvm {
152155
void initializeHexagonCallFrameInformationPass(PassRegistry&);
@@ -422,7 +425,6 @@ void HexagonFrameLowering::emitPrologue(MachineFunction &MF,
422425
void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
423426
MachineFunction &MF = *MBB.getParent();
424427
MachineFrameInfo *MFI = MF.getFrameInfo();
425-
auto &HTM = static_cast<const HexagonTargetMachine&>(MF.getTarget());
426428
auto &HST = MF.getSubtarget<HexagonSubtarget>();
427429
auto &HII = *HST.getInstrInfo();
428430
auto &HRI = *HST.getRegisterInfo();
@@ -457,14 +459,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
457459
MI->eraseFromParent();
458460
}
459461

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))
468463
return;
469464

470465
// Check for overflow.
@@ -506,11 +501,7 @@ void HexagonFrameLowering::insertPrologueInBlock(MachineBasicBlock &MBB) const {
506501

507502
void HexagonFrameLowering::insertEpilogueInBlock(MachineBasicBlock &MBB) const {
508503
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))
514505
return;
515506

516507
auto &HST = static_cast<const HexagonSubtarget&>(MF.getSubtarget());
@@ -634,24 +625,33 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
634625

635626
MCSymbol *FrameLabel = MMI.getContext().createTempSymbol();
636627

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+
}
655655

656656
static unsigned int RegsToMove[] = {
657657
Hexagon::R1, Hexagon::R0, Hexagon::R3, Hexagon::R2,
@@ -709,11 +709,40 @@ void HexagonFrameLowering::insertCFIInstructionsAt(MachineBasicBlock &MBB,
709709

710710

711711
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;
717746
}
718747

719748

@@ -795,15 +824,90 @@ static void addCalleeSaveRegistersAsImpOperand(MachineInstr *Inst,
795824
}
796825
}
797826

827+
798828
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+
}
802864

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");
805868

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;
807911
}
808912

809913

@@ -915,9 +1019,9 @@ void HexagonFrameLowering::processFunctionBeforeFrameFinalized(
9151019
// via AP, which may not be available at the particular place in the program.
9161020
MachineFrameInfo *MFI = MF.getFrameInfo();
9171021
bool HasAlloca = MFI->hasVarSizedObjects();
918-
bool HasAligna = (MFI->getMaxAlignment() > getStackAlignment());
1022+
bool NeedsAlign = (MFI->getMaxAlignment() > getStackAlignment());
9191023

920-
if (!HasAlloca || !HasAligna)
1024+
if (!HasAlloca || !NeedsAlign)
9211025
return;
9221026

9231027
unsigned LFS = MFI->getLocalFrameSize();
@@ -1293,7 +1397,8 @@ bool HexagonFrameLowering::needsAligna(const MachineFunction &MF) const {
12931397
}
12941398

12951399

1296-
MachineInstr *HexagonFrameLowering::getAlignaInstr(MachineFunction &MF) const {
1400+
const MachineInstr *HexagonFrameLowering::getAlignaInstr(
1401+
const MachineFunction &MF) const {
12971402
for (auto &B : MF)
12981403
for (auto &I : B)
12991404
if (I.getOpcode() == Hexagon::ALIGNA)

lib/Target/Hexagon/HexagonFrameLowering.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class HexagonFrameLowering : public TargetFrameLowering {
5252
return true;
5353
}
5454
int getFrameIndexReference(const MachineFunction &MF, int FI,
55-
unsigned &FrameReg) const override;
55+
unsigned &FrameReg) const;
5656
bool hasFP(const MachineFunction &MF) const override;
5757

5858
const SpillSlot *getCalleeSavedSpillSlots(unsigned &NumEntries)
@@ -74,7 +74,7 @@ class HexagonFrameLowering : public TargetFrameLowering {
7474
const override;
7575

7676
bool needsAligna(const MachineFunction &MF) const;
77-
MachineInstr *getAlignaInstr(MachineFunction &MF) const;
77+
const MachineInstr *getAlignaInstr(const MachineFunction &MF) const;
7878

7979
void insertCFIInstructions(MachineFunction &MF) const;
8080

lib/Target/Hexagon/HexagonISelLowering.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -851,7 +851,10 @@ HexagonTargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
851851

852852
SDValue AC = DAG.getConstant(A, dl, MVT::i32);
853853
SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other);
854-
return DAG.getNode(HexagonISD::ALLOCA, dl, VTs, Chain, Size, AC);
854+
SDValue AA = DAG.getNode(HexagonISD::ALLOCA, dl, VTs, Chain, Size, AC);
855+
if (Op.getNode()->getHasDebugValue())
856+
DAG.TransferDbgValues(Op, AA);
857+
return AA;
855858
}
856859

857860
SDValue

0 commit comments

Comments
 (0)