summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
diff options
context:
space:
mode:
authorLogan Chien <tzuhsiang.chien@gmail.com>2019-11-27 22:56:34 -0800
committerLogan Chien <tzuhsiang.chien@gmail.com>2019-12-14 10:23:20 -0800
commitd4e10e6adb1b629b3fc1b78f7e281fbcec392edb (patch)
treeef2210c30ca6feb97a1153a29cacf5460d2b376b /llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
parent2c59c4ffb9c111f8d87a65839697d03fc485c51c (diff)
downloadbcm5719-llvm-d4e10e6adb1b629b3fc1b78f7e281fbcec392edb.tar.gz
bcm5719-llvm-d4e10e6adb1b629b3fc1b78f7e281fbcec392edb.zip
AArch64: Fix frame record chain
The commit r369122 may keep LR and FP register (aka. frame record) in the middle of a frame, thus we must add the offsets to ensure the FP register always points to innermost frame record on the stack. According to AAPCS64[1], a conforming code shall construct a linked list of stack frames that can be traversed with frame records. This commit is also essential to frame-pointer-based stack unwinder (e.g. the stack unwinder in linx-perf-tools.) [1] https://github.com/ARM-software/software-standards/blob/master/abi/aapcs64/aapcs64.rst#the-frame-pointer Test: llvm-lit ${LLVM_SRC}/test/CodeGen/AArch64/framelayout-frame-record.ll Test: llvm-lit ${LLVM_SRC}/test/CodeGen/AArch64 Differential Revision: https://reviews.llvm.org/D70800
Diffstat (limited to 'llvm/lib/Target/AArch64/AArch64FrameLowering.cpp')
-rw-r--r--llvm/lib/Target/AArch64/AArch64FrameLowering.cpp37
1 files changed, 21 insertions, 16 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
index c732106014e..50d1c986948 100644
--- a/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
+++ b/llvm/lib/Target/AArch64/AArch64FrameLowering.cpp
@@ -832,10 +832,6 @@ static bool needsWinCFI(const MachineFunction &MF) {
F.needsUnwindTableEntry();
}
-static bool isTargetDarwin(const MachineFunction &MF) {
- return MF.getSubtarget<AArch64Subtarget>().isTargetDarwin();
-}
-
// Convenience function to determine whether I is an SVE callee save.
bool IsSVECalleeSave(MachineBasicBlock::iterator I) {
switch (I->getOpcode()) {
@@ -1016,7 +1012,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
if (HasFP) {
// Only set up FP if we actually need to.
- int64_t FPOffset = isTargetDarwin(MF) ? (AFI->getCalleeSavedStackSize() - 16) : 0;
+ int64_t FPOffset = AFI->getCalleeSaveBaseToFrameRecordOffset();
if (CombineSPBump)
FPOffset += AFI->getLocalStackSize();
@@ -1229,11 +1225,6 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
}
if (needsFrameMoves) {
- const DataLayout &TD = MF.getDataLayout();
- const int StackGrowth = isTargetDarwin(MF)
- ? (2 * -TD.getPointerSize(0))
- : -AFI->getCalleeSavedStackSize();
- Register FramePtr = RegInfo->getFrameRegister(MF);
// An example of the prologue:
//
// .globl __foo
@@ -1301,10 +1292,15 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
// .cfi_offset w28, -32
if (HasFP) {
+ const int OffsetToFirstCalleeSaveFromFP =
+ AFI->getCalleeSaveBaseToFrameRecordOffset() -
+ AFI->getCalleeSavedStackSize();
+ Register FramePtr = RegInfo->getFrameRegister(MF);
+
// Define the current CFA rule to use the provided FP.
unsigned Reg = RegInfo->getDwarfRegNum(FramePtr, true);
unsigned CFIIndex = MF.addFrameInst(MCCFIInstruction::createDefCfa(
- nullptr, Reg, StackGrowth - FixedObject));
+ nullptr, Reg, OffsetToFirstCalleeSaveFromFP - FixedObject));
BuildMI(MBB, MBBI, DL, TII->get(TargetOpcode::CFI_INSTRUCTION))
.addCFIIndex(CFIIndex)
.setMIFlags(MachineInstr::FrameSetup);
@@ -1611,10 +1607,8 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
// non-post-indexed loads for the restores if we aren't actually going to
// be able to save any instructions.
if (!IsFunclet && (MFI.hasVarSizedObjects() || AFI->isStackRealigned())) {
- int64_t OffsetToFrameRecord =
- isTargetDarwin(MF) ? (-(int64_t)AFI->getCalleeSavedStackSize() + 16) : 0;
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::FP,
- {OffsetToFrameRecord, MVT::i8},
+ {-AFI->getCalleeSaveBaseToFrameRecordOffset(), MVT::i8},
TII, MachineInstr::FrameDestroy, false, NeedsWinCFI);
} else if (NumBytes)
emitFrameOffset(MBB, LastPopI, DL, AArch64::SP, AArch64::SP,
@@ -1676,8 +1670,8 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
bool IsWin64 =
Subtarget.isCallingConvWin64(MF.getFunction().getCallingConv());
unsigned FixedObject = IsWin64 ? alignTo(AFI->getVarArgsGPRSize(), 16) : 0;
- unsigned FPAdjust = isTargetDarwin(MF)
- ? 16 : AFI->getCalleeSavedStackSize(MF.getFrameInfo());
+ unsigned FPAdjust = AFI->getCalleeSavedStackSize(MF.getFrameInfo()) -
+ AFI->getCalleeSaveBaseToFrameRecordOffset();
return {ObjectOffset + FixedObject + FPAdjust, MVT::i8};
}
@@ -1934,6 +1928,9 @@ static void computeCalleeSaveRegisterPairs(
if (CSI.empty())
return;
+ const bool IsTargetWindows =
+ MF.getSubtarget<AArch64Subtarget>().isTargetWindows();
+
bool NeedsWinCFI = needsWinCFI(MF);
AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>();
MachineFrameInfo &MFI = MF.getFrameInfo();
@@ -2058,6 +2055,14 @@ static void computeCalleeSaveRegisterPairs(
(RPI.isScalable() && RPI.Offset >= -256 && RPI.Offset <= 255)) &&
"Offset out of bounds for LDP/STP immediate");
+ // Save the offset to frame record so that the FP register can point to the
+ // innermost frame record (spilled FP and LR registers).
+ if (NeedsFrameRecord && ((!IsTargetWindows && RPI.Reg1 == AArch64::LR &&
+ RPI.Reg2 == AArch64::FP) ||
+ (IsTargetWindows && RPI.Reg1 == AArch64::FP &&
+ RPI.Reg2 == AArch64::LR)))
+ AFI->setCalleeSaveBaseToFrameRecordOffset(Offset);
+
RegPairs.push_back(RPI);
if (RPI.isPaired())
++i;
OpenPOWER on IntegriCloud