Skip to content

Commit 584b5ba

Browse files
committed
Revert "[NativeAOT/ARM64] Generate frames compatible with Apple compact unwinding (dotnet#107766)"
This reverts commit 4536b96.
1 parent a5a7a3a commit 584b5ba

File tree

7 files changed

+86
-329
lines changed

7 files changed

+86
-329
lines changed

src/coreclr/jit/codegen.h

Lines changed: 0 additions & 1 deletion
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

Lines changed: 8 additions & 38 deletions
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

Lines changed: 0 additions & 24 deletions
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

Lines changed: 0 additions & 10 deletions
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

Lines changed: 54 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -5644,9 +5644,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56445644
#endif
56455645

56465646
// The delta to be added to virtual offset to adjust it relative to frame pointer or SP
5647-
int delta = 0;
5648-
int frameLocalsDelta = 0;
5649-
int frameBoundary = 0;
5647+
int delta = 0;
56505648

56515649
#ifdef TARGET_XARCH
56525650
delta += REGSIZE_BYTES; // pushed PC (return address) for x86/x64
@@ -5671,25 +5669,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
56715669
// We set FP to be after LR, FP
56725670
delta += 2 * REGSIZE_BYTES;
56735671
}
5674-
#elif defined(TARGET_ARM64)
5675-
else
5676-
{
5677-
// FP is used.
5678-
delta += codeGen->genTotalFrameSize() - codeGen->genSPtoFPdelta();
5679-
5680-
// If we placed FP/LR at the bottom of the frame we need to shift all the variables
5681-
// on the new frame to account for it. See lvaAssignVirtualFrameOffsetsToLocals.
5682-
if (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters())
5683-
{
5684-
// We set FP to be after LR, FP
5685-
frameLocalsDelta = 2 * REGSIZE_BYTES;
5686-
frameBoundary = opts.IsOSR() ? -info.compPatchpointInfo->TotalFrameSize() : 0;
5687-
if (info.compIsVarArgs)
5688-
frameBoundary -= MAX_REG_ARG * REGSIZE_BYTES;
5689-
}
5690-
JITDUMP("--- delta bump %d for FP frame, %d inside frame for FP/LR relocation\n", delta, frameLocalsDelta);
5691-
}
5692-
#elif defined(TARGET_AMD64)
5672+
#elif defined(TARGET_AMD64) || defined(TARGET_ARM64)
56935673
else
56945674
{
56955675
// FP is used.
@@ -5757,7 +5737,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
57575737

57585738
#if defined(TARGET_X86)
57595739
// On x86, we set the stack offset for a promoted field
5760-
// to match a struct parameter in lvaAssignFrameOffsetsToPromotedStructs.
5740+
// to match a struct parameter in lvAssignFrameOffsetsToPromotedStructs.
57615741
if ((!varDsc->lvIsParam || parentvarDsc->lvIsParam) && promotionType == PROMOTION_TYPE_DEPENDENT)
57625742
#else
57635743
if (!varDsc->lvIsParam && promotionType == PROMOTION_TYPE_DEPENDENT)
@@ -5777,23 +5757,15 @@ void Compiler::lvaFixVirtualFrameOffsets()
57775757

57785758
if (doAssignStkOffs)
57795759
{
5780-
int localDelta = delta;
5781-
5782-
if (frameLocalsDelta != 0 && varDsc->GetStackOffset() < frameBoundary)
5783-
{
5784-
localDelta += frameLocalsDelta;
5785-
}
5786-
5787-
JITDUMP("-- V%02u was %d, now %d\n", lclNum, varDsc->GetStackOffset(),
5788-
varDsc->GetStackOffset() + localDelta);
5789-
varDsc->SetStackOffset(varDsc->GetStackOffset() + localDelta);
5760+
JITDUMP("-- V%02u was %d, now %d\n", lclNum, varDsc->GetStackOffset(), varDsc->GetStackOffset() + delta);
5761+
varDsc->SetStackOffset(varDsc->GetStackOffset() + delta);
57905762

57915763
#if DOUBLE_ALIGN
57925764
if (genDoubleAlign() && !codeGen->isFramePointerUsed())
57935765
{
57945766
if (varDsc->lvFramePointerBased)
57955767
{
5796-
varDsc->SetStackOffset(varDsc->GetStackOffset() - localDelta);
5768+
varDsc->SetStackOffset(varDsc->GetStackOffset() - delta);
57975769

57985770
// We need to re-adjust the offsets of the parameters so they are EBP
57995771
// relative rather than stack/frame pointer relative
@@ -5815,13 +5787,9 @@ void Compiler::lvaFixVirtualFrameOffsets()
58155787
assert(codeGen->regSet.tmpAllFree());
58165788
for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
58175789
{
5818-
temp->tdAdjustTempOffs(delta + frameLocalsDelta);
5790+
temp->tdAdjustTempOffs(delta);
58195791
}
58205792

5821-
if (lvaCachedGenericContextArgOffs < frameBoundary)
5822-
{
5823-
lvaCachedGenericContextArgOffs += frameLocalsDelta;
5824-
}
58255793
lvaCachedGenericContextArgOffs += delta;
58265794

58275795
#if FEATURE_FIXED_OUT_ARGS
@@ -6077,6 +6045,30 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
60776045
codeGen->setFramePointerUsed(codeGen->isFramePointerRequired());
60786046
}
60796047

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

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

61366124
int initialStkOffs = 0;
61376125
if (info.compIsVarArgs)
@@ -6142,7 +6130,17 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
61426130
stkOffs -= initialStkOffs;
61436131
}
61446132

6145-
stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6133+
if (codeGen->IsSaveFpLrWithAllCalleeSavedRegisters() || !isFramePointerUsed()) // Note that currently we always have
6134+
// a frame pointer
6135+
{
6136+
stkOffs -= compCalleeRegsPushed * REGSIZE_BYTES;
6137+
}
6138+
else
6139+
{
6140+
// Subtract off FP and LR.
6141+
assert(compCalleeRegsPushed >= 2);
6142+
stkOffs -= (compCalleeRegsPushed - 2) * REGSIZE_BYTES;
6143+
}
61466144

61476145
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
61486146

@@ -6812,6 +6810,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68126810
}
68136811
#endif // TARGET_AMD64
68146812

6813+
#ifdef TARGET_ARM64
6814+
if (!codeGen->IsSaveFpLrWithAllCalleeSavedRegisters() && isFramePointerUsed()) // Note that currently we always have
6815+
// a frame pointer
6816+
{
6817+
// Create space for saving FP and LR.
6818+
stkOffs -= 2 * REGSIZE_BYTES;
6819+
}
6820+
#endif // TARGET_ARM64
6821+
68156822
#if FEATURE_FIXED_OUT_ARGS
68166823
if (lvaOutgoingArgSpaceSize > 0)
68176824
{
@@ -6849,44 +6856,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
68496856

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

68926861
//------------------------------------------------------------------------

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

Lines changed: 0 additions & 13 deletions
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)