Skip to content

Commit bbe2cb9

Browse files
authored
Revert "[NativeAOT/ARM64] Generate frames compatible with Apple compact unwinding (#107766)" (#111405)
This reverts commit 4536b96.
1 parent d785363 commit bbe2cb9

File tree

7 files changed

+86
-329
lines changed

7 files changed

+86
-329
lines changed

src/coreclr/jit/codegen.h

-1
Original file line numberDiff line numberDiff line change
@@ -659,7 +659,6 @@ class CodeGen final : public CodeGenInterface
659659
virtual bool IsSaveFpLrWithAllCalleeSavedRegisters() const;
660660
bool genSaveFpLrWithAllCalleeSavedRegisters;
661661
bool genForceFuncletFrameType5;
662-
bool genReverseAndPairCalleeSavedRegisters;
663662
#endif // TARGET_ARM64
664663

665664
//-------------------------------------------------------------------------

src/coreclr/jit/codegenarm64.cpp

+8-38
Original file line numberDiff line numberDiff line change
@@ -845,19 +845,12 @@ void CodeGen::genSaveCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta, i
845845

846846
for (int i = 0; i < regStack.Height(); ++i)
847847
{
848-
RegPair regPair = genReverseAndPairCalleeSavedRegisters ? regStack.Top(i) : regStack.Bottom(i);
848+
RegPair regPair = regStack.Bottom(i);
849849
if (regPair.reg2 != REG_NA)
850850
{
851851
// We can use a STP instruction.
852-
if (genReverseAndPairCalleeSavedRegisters)
853-
{
854-
genPrologSaveRegPair(regPair.reg2, regPair.reg1, spOffset, spDelta, false, REG_IP0, nullptr);
855-
}
856-
else
857-
{
858-
genPrologSaveRegPair(regPair.reg1, regPair.reg2, spOffset, spDelta, regPair.useSaveNextPair, REG_IP0,
859-
nullptr);
860-
}
852+
genPrologSaveRegPair(regPair.reg1, regPair.reg2, spOffset, spDelta, regPair.useSaveNextPair, REG_IP0,
853+
nullptr);
861854

862855
spOffset += 2 * slotSize;
863856
}
@@ -933,9 +926,8 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
933926

934927
// Save integer registers at higher addresses than floating-point registers.
935928

936-
regMaskTP maskSaveRegsFrame = regsToSaveMask & (RBM_FP | RBM_LR);
937929
regMaskTP maskSaveRegsFloat = regsToSaveMask & RBM_ALLFLOAT;
938-
regMaskTP maskSaveRegsInt = regsToSaveMask & ~maskSaveRegsFloat & ~maskSaveRegsFrame;
930+
regMaskTP maskSaveRegsInt = regsToSaveMask & ~maskSaveRegsFloat;
939931

940932
if (maskSaveRegsFloat != RBM_NONE)
941933
{
@@ -947,13 +939,6 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
947939
if (maskSaveRegsInt != RBM_NONE)
948940
{
949941
genSaveCalleeSavedRegisterGroup(maskSaveRegsInt, spDelta, lowestCalleeSavedOffset);
950-
spDelta = 0;
951-
lowestCalleeSavedOffset += genCountBits(maskSaveRegsInt) * FPSAVE_REGSIZE_BYTES;
952-
}
953-
954-
if (maskSaveRegsFrame != RBM_NONE)
955-
{
956-
genPrologSaveRegPair(REG_FP, REG_LR, lowestCalleeSavedOffset, spDelta, false, REG_IP0, nullptr);
957942
// No need to update spDelta, lowestCalleeSavedOffset since they're not used after this.
958943
}
959944
}
@@ -985,20 +970,13 @@ void CodeGen::genRestoreCalleeSavedRegisterGroup(regMaskTP regsMask, int spDelta
985970
stackDelta = spDelta;
986971
}
987972

988-
RegPair regPair = genReverseAndPairCalleeSavedRegisters ? regStack.Bottom(i) : regStack.Top(i);
973+
RegPair regPair = regStack.Top(i);
989974
if (regPair.reg2 != REG_NA)
990975
{
991976
spOffset -= 2 * slotSize;
992977

993-
if (genReverseAndPairCalleeSavedRegisters)
994-
{
995-
genEpilogRestoreRegPair(regPair.reg2, regPair.reg1, spOffset, stackDelta, false, REG_IP1, nullptr);
996-
}
997-
else
998-
{
999-
genEpilogRestoreRegPair(regPair.reg1, regPair.reg2, spOffset, stackDelta, regPair.useSaveNextPair,
1000-
REG_IP1, nullptr);
1001-
}
978+
genEpilogRestoreRegPair(regPair.reg1, regPair.reg2, spOffset, stackDelta, regPair.useSaveNextPair, REG_IP1,
979+
nullptr);
1002980
}
1003981
else
1004982
{
@@ -1065,19 +1043,11 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
10651043

10661044
// Save integer registers at higher addresses than floating-point registers.
10671045

1068-
regMaskTP maskRestoreRegsFrame = regsToRestoreMask & (RBM_FP | RBM_LR);
10691046
regMaskTP maskRestoreRegsFloat = regsToRestoreMask & RBM_ALLFLOAT;
1070-
regMaskTP maskRestoreRegsInt = regsToRestoreMask & ~maskRestoreRegsFloat & ~maskRestoreRegsFrame;
1047+
regMaskTP maskRestoreRegsInt = regsToRestoreMask & ~maskRestoreRegsFloat;
10711048

10721049
// Restore in the opposite order of saving.
10731050

1074-
if (maskRestoreRegsFrame != RBM_NONE)
1075-
{
1076-
int spFrameDelta = (maskRestoreRegsFloat != RBM_NONE || maskRestoreRegsInt != RBM_NONE) ? 0 : spDelta;
1077-
spOffset -= 2 * REGSIZE_BYTES;
1078-
genEpilogRestoreRegPair(REG_FP, REG_LR, spOffset, spFrameDelta, false, REG_IP1, nullptr);
1079-
}
1080-
10811051
if (maskRestoreRegsInt != RBM_NONE)
10821052
{
10831053
int spIntDelta = (maskRestoreRegsFloat != RBM_NONE) ? 0 : spDelta; // should we delay the SP adjustment?

src/coreclr/jit/codegencommon.cpp

-24
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,6 @@ CodeGen::CodeGen(Compiler* theCompiler)
255255
#ifdef TARGET_ARM64
256256
genSaveFpLrWithAllCalleeSavedRegisters = false;
257257
genForceFuncletFrameType5 = false;
258-
genReverseAndPairCalleeSavedRegisters = false;
259258
#endif // TARGET_ARM64
260259
}
261260

@@ -4828,29 +4827,6 @@ void CodeGen::genFinalizeFrame()
48284827
}
48294828
#endif // TARGET_ARM
48304829

4831-
#ifdef TARGET_ARM64
4832-
if (compiler->IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsApplePlatform)
4833-
{
4834-
JITDUMP("Setting genReverseAndPairCalleeSavedRegisters = true");
4835-
4836-
genReverseAndPairCalleeSavedRegisters = true;
4837-
4838-
// Make sure we push the registers in pairs if possible. If we only allocate a contiguous
4839-
// block of registers this should add at most one integer and at most one floating point
4840-
// register to the list. The stack has to be 16-byte aligned, so in worst case it results
4841-
// in allocating 16 bytes more space on stack if odd number of integer and odd number of
4842-
// FP registers were occupied. Same number of instructions will be generated, just the
4843-
// STR instructions are replaced with STP (store pair).
4844-
regMaskTP maskModifiedRegs = regSet.rsGetModifiedRegsMask();
4845-
regMaskTP maskPairRegs = ((maskModifiedRegs & (RBM_V8 | RBM_V10 | RBM_V12 | RBM_V14)).getLow() << 1) |
4846-
((maskModifiedRegs & (RBM_R19 | RBM_R21 | RBM_R23 | RBM_R25 | RBM_R27)).getLow() << 1);
4847-
if (maskPairRegs != RBM_NONE)
4848-
{
4849-
regSet.rsSetRegsModified(maskPairRegs);
4850-
}
4851-
}
4852-
#endif
4853-
48544830
#ifdef DEBUG
48554831
if (verbose)
48564832
{

src/coreclr/jit/compiler.hpp

-10
Original file line numberDiff line numberDiff line change
@@ -2808,16 +2808,6 @@ inline
28082808
{
28092809
*pBaseReg = REG_SPBASE;
28102810
}
2811-
#elif defined(TARGET_ARM64)
2812-
if (FPbased && !codeGen->isFramePointerRequired() && varOffset < 0 && !opts.IsOSR() &&
2813-
lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT && codeGen->IsSaveFpLrWithAllCalleeSavedRegisters())
2814-
{
2815-
int spVarOffset = varOffset + codeGen->genSPtoFPdelta();
2816-
JITDUMP("lvaFrameAddress optimization for V%02u: [FP-%d] -> [SP+%d]\n", varNum, -varOffset, spVarOffset);
2817-
FPbased = false;
2818-
varOffset = spVarOffset;
2819-
}
2820-
*pFPbased = FPbased;
28212811
#else
28222812
*pFPbased = FPbased;
28232813
#endif

src/coreclr/jit/lclvars.cpp

+54-85
Original file line numberDiff line numberDiff line change
@@ -5639,9 +5639,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56395639
#endif
56405640

56415641
// The delta to be added to virtual offset to adjust it relative to frame pointer or SP
5642-
int delta = 0;
5643-
int frameLocalsDelta = 0;
5644-
int frameBoundary = 0;
5642+
int delta = 0;
56455643

56465644
#ifdef TARGET_XARCH
56475645
delta += REGSIZE_BYTES; // pushed PC (return address) for x86/x64
@@ -5666,25 +5664,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56665664
// We set FP to be after LR, FP
56675665
delta += 2 * REGSIZE_BYTES;
56685666
}
5669-
#elif defined(TARGET_ARM64)
5670-
else
5671-
{
5672-
// FP is used.
5673-
delta += codeGen->genTotalFrameSize() - codeGen->genSPtoFPdelta();
5674-
5675-
// If we placed FP/LR at the bottom of the frame we need to shift all the variables
5676-
// on the new frame to account for it. See lvaAssignVirtualFrameOffsetsToLocals.
5677-
if (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters())
5678-
{
5679-
// We set FP to be after LR, FP
5680-
frameLocalsDelta = 2 * REGSIZE_BYTES;
5681-
frameBoundary = opts.IsOSR() ? -info.compPatchpointInfo->TotalFrameSize() : 0;
5682-
if (info.compIsVarArgs)
5683-
frameBoundary -= MAX_REG_ARG * REGSIZE_BYTES;
5684-
}
5685-
JITDUMP("--- delta bump %d for FP frame, %d inside frame for FP/LR relocation\n", delta, frameLocalsDelta);
5686-
}
5687-
#elif defined(TARGET_AMD64)
5667+
#elif defined(TARGET_AMD64) || defined(TARGET_ARM64)
56885668
else
56895669
{
56905670
// FP is used.
@@ -5752,7 +5732,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
57525732

57535733
#if defined(TARGET_X86)
57545734
// On x86, we set the stack offset for a promoted field
5755-
// to match a struct parameter in lvaAssignFrameOffsetsToPromotedStructs.
5735+
// to match a struct parameter in lvAssignFrameOffsetsToPromotedStructs.
57565736
if ((!varDsc->lvIsParam || parentvarDsc->lvIsParam) && promotionType == PROMOTION_TYPE_DEPENDENT)
57575737
#else
57585738
if (!varDsc->lvIsParam && promotionType == PROMOTION_TYPE_DEPENDENT)
@@ -5772,23 +5752,15 @@ void Compiler::lvaFixVirtualFrameOffsets()
57725752

57735753
if (doAssignStkOffs)
57745754
{
5775-
int localDelta = delta;
5776-
5777-
if (frameLocalsDelta != 0 && varDsc->GetStackOffset() < frameBoundary)
5778-
{
5779-
localDelta += frameLocalsDelta;
5780-
}
5781-
5782-
JITDUMP("-- V%02u was %d, now %d\n", lclNum, varDsc->GetStackOffset(),
5783-
varDsc->GetStackOffset() + localDelta);
5784-
varDsc->SetStackOffset(varDsc->GetStackOffset() + localDelta);
5755+
JITDUMP("-- V%02u was %d, now %d\n", lclNum, varDsc->GetStackOffset(), varDsc->GetStackOffset() + delta);
5756+
varDsc->SetStackOffset(varDsc->GetStackOffset() + delta);
57855757

57865758
#if DOUBLE_ALIGN
57875759
if (genDoubleAlign() && !codeGen->isFramePointerUsed())
57885760
{
57895761
if (varDsc->lvFramePointerBased)
57905762
{
5791-
varDsc->SetStackOffset(varDsc->GetStackOffset() - localDelta);
5763+
varDsc->SetStackOffset(varDsc->GetStackOffset() - delta);
57925764

57935765
// We need to re-adjust the offsets of the parameters so they are EBP
57945766
// relative rather than stack/frame pointer relative
@@ -5810,13 +5782,9 @@ void Compiler::lvaFixVirtualFrameOffsets()
58105782
assert(codeGen->regSet.tmpAllFree());
58115783
for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
58125784
{
5813-
temp->tdAdjustTempOffs(delta + frameLocalsDelta);
5785+
temp->tdAdjustTempOffs(delta);
58145786
}
58155787

5816-
if (lvaCachedGenericContextArgOffs < frameBoundary)
5817-
{
5818-
lvaCachedGenericContextArgOffs += frameLocalsDelta;
5819-
}
58205788
lvaCachedGenericContextArgOffs += delta;
58215789

58225790
#if FEATURE_FIXED_OUT_ARGS
@@ -6072,6 +6040,30 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
60726040
codeGen->setFramePointerUsed(codeGen->isFramePointerRequired());
60736041
}
60746042

6043+
#ifdef TARGET_ARM64
6044+
// Decide where to save FP and LR registers. We store FP/LR registers at the bottom of the frame if there is
6045+
// a frame pointer used (so we get positive offsets from the frame pointer to access locals), but not if we
6046+
// need a GS cookie AND localloc is used, since we need the GS cookie to protect the saved return value,
6047+
// and also the saved frame pointer. See CodeGen::genPushCalleeSavedRegisters() for more details about the
6048+
// frame types. Since saving FP/LR at high addresses is a relatively rare case, force using it during stress.
6049+
// (It should be legal to use these frame types for every frame).
6050+
6051+
if (opts.compJitSaveFpLrWithCalleeSavedRegisters == 0)
6052+
{
6053+
// Default configuration
6054+
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters((getNeedsGSSecurityCookie() && compLocallocUsed) ||
6055+
opts.compDbgEnC || compStressCompile(STRESS_GENERIC_VARN, 20));
6056+
}
6057+
else if (opts.compJitSaveFpLrWithCalleeSavedRegisters == 1)
6058+
{
6059+
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters(false); // Disable using new frames
6060+
}
6061+
else if ((opts.compJitSaveFpLrWithCalleeSavedRegisters == 2) || (opts.compJitSaveFpLrWithCalleeSavedRegisters == 3))
6062+
{
6063+
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters(true); // Force using new frames
6064+
}
6065+
#endif // TARGET_ARM64
6066+
60756067
#ifdef TARGET_XARCH
60766068
// On x86/amd64, the return address has already been pushed by the call instruction in the caller.
60776069
stkOffs -= TARGET_POINTER_SIZE; // return address;
@@ -6120,13 +6112,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
61206112
#endif // !TARGET_ARM
61216113

61226114
#ifdef TARGET_ARM64
6123-
// If the frame pointer is used, then we'll save FP/LR either at the bottom of the stack
6124-
// or at the top of the stack depending on frame type. We make the decision after assigning
6125-
// the variables on the frame and then fix up the offsets in lvaFixVirtualFrameOffsets.
6126-
// For now, we proceed as if FP/LR were saved with the callee registers. If we later
6127-
// decide to move the FP/LR to the bottom of the frame it shifts all the assigned
6128-
// variables and temporaries by 16 bytes. The largest alignment we currently make is 16
6129-
// bytes for SIMD.
6115+
// If the frame pointer is used, then we'll save FP/LR at the bottom of the stack.
6116+
// Otherwise, we won't store FP, and we'll store LR at the top, with the other callee-save
6117+
// registers (if any).
61306118

61316119
int initialStkOffs = 0;
61326120
if (info.compIsVarArgs)
@@ -6137,7 +6125,17 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
61376125
stkOffs -= initialStkOffs;
61386126
}
61396127

6140-
stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6128+
if (codeGen->IsSaveFpLrWithAllCalleeSavedRegisters() || !isFramePointerUsed()) // Note that currently we always have
6129+
// a frame pointer
6130+
{
6131+
stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6132+
}
6133+
else
6134+
{
6135+
// Subtract off FP and LR.
6136+
assert(compCalleeRegsPushed >= 2);
6137+
stkOffs -= (compCalleeRegsPushed - 2) * REGSIZE_BYTES;
6138+
}
61416139

61426140
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
61436141

@@ -6807,6 +6805,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68076805
}
68086806
#endif // TARGET_AMD64
68096807

6808+
#ifdef TARGET_ARM64
6809+
if (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters() && isFramePointerUsed()) // Note that currently we always have
6810+
// a frame pointer
6811+
{
6812+
// Create space for saving FP and LR.
6813+
stkOffs -= 2 * REGSIZE_BYTES;
6814+
}
6815+
#endif // TARGET_ARM64
6816+
68106817
#if FEATURE_FIXED_OUT_ARGS
68116818
if (lvaOutgoingArgSpaceSize > 0)
68126819
{
@@ -6844,44 +6851,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68446851

68456852
noway_assert(compLclFrameSize + originalFrameSize ==
68466853
(unsigned)-(stkOffs + (pushedCount * (int)TARGET_POINTER_SIZE)));
6847-
6848-
#ifdef TARGET_ARM64
6849-
// Decide where to save FP and LR registers. We store FP/LR registers at the bottom of the frame if there is
6850-
// a frame pointer used (so we get positive offsets from the frame pointer to access locals), but not if we
6851-
// need a GS cookie AND localloc is used, since we need the GS cookie to protect the saved return value,
6852-
// and also the saved frame pointer. See CodeGen::genPushCalleeSavedRegisters() for more details about the
6853-
// frame types. Since saving FP/LR at high addresses is a relatively rare case, force using it during stress.
6854-
// (It should be legal to use these frame types for every frame).
6855-
//
6856-
// For Apple NativeAOT ABI we try to save the FP/LR registers on top to get canonical frame layout that can
6857-
// be represented with compact unwinding information. In order to maintain code quality we only do it when
6858-
// we can use SP-based addressing (!isFramePointerRequired) through lvaFrameAddress optimization, or if the
6859-
// whole frame is small enough that the negative FP-based addressing can address the whole frame.
6860-
6861-
if (opts.compJitSaveFpLrWithCalleeSavedRegisters == 0)
6862-
{
6863-
if (IsTargetAbi(CORINFO_NATIVEAOT_ABI) && TargetOS::IsApplePlatform &&
6864-
(!codeGen->isFramePointerRequired() || codeGen->genTotalFrameSize() < 0x100))
6865-
{
6866-
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters(true);
6867-
}
6868-
else
6869-
{
6870-
// Default configuration
6871-
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters((getNeedsGSSecurityCookie() && compLocallocUsed) ||
6872-
opts.compDbgEnC ||
6873-
compStressCompile(Compiler::STRESS_GENERIC_VARN, 20));
6874-
}
6875-
}
6876-
else if (opts.compJitSaveFpLrWithCalleeSavedRegisters == 1)
6877-
{
6878-
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters(false); // Disable using new frames
6879-
}
6880-
else if ((opts.compJitSaveFpLrWithCalleeSavedRegisters == 2) || (opts.compJitSaveFpLrWithCalleeSavedRegisters == 3))
6881-
{
6882-
codeGen->SetSaveFpLrWithAllCalleeSavedRegisters(true); // Force using new frames
6883-
}
6884-
#endif // TARGET_ARM64
68856854
}
68866855

68876856
//------------------------------------------------------------------------

src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ObjectWriter/MachNative.cs

-13
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,5 @@ internal static class MachNative
120120
public const uint PLATFORM_TVOSSIMULATOR = 8;
121121
public const uint PLATFORM_WATCHOSSIMULATOR = 9;
122122
public const uint PLATFORM_DRIVERKIT = 10;
123-
124-
public const uint UNWIND_ARM64_MODE_FRAMELESS = 0x02000000;
125-
public const uint UNWIND_ARM64_MODE_DWARF = 0x03000000;
126-
public const uint UNWIND_ARM64_MODE_FRAME = 0x04000000;
127-
public const uint UNWIND_ARM64_FRAME_X19_X20_PAIR = 0x00000001;
128-
public const uint UNWIND_ARM64_FRAME_X21_X22_PAIR = 0x00000002;
129-
public const uint UNWIND_ARM64_FRAME_X23_X24_PAIR = 0x00000004;
130-
public const uint UNWIND_ARM64_FRAME_X25_X26_PAIR = 0x00000008;
131-
public const uint UNWIND_ARM64_FRAME_X27_X28_PAIR = 0x00000010;
132-
public const uint UNWIND_ARM64_FRAME_D8_D9_PAIR = 0x00000100;
133-
public const uint UNWIND_ARM64_FRAME_D10_D11_PAIR = 0x00000200;
134-
public const uint UNWIND_ARM64_FRAME_D12_D13_PAIR = 0x00000400;
135-
public const uint UNWIND_ARM64_FRAME_D14_D15_PAIR = 0x00000800;
136123
}
137124
}

0 commit comments

Comments
 (0)