@@ -5644,9 +5644,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5644
5644
#endif
5645
5645
5646
5646
// 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;
5650
5648
5651
5649
#ifdef TARGET_XARCH
5652
5650
delta += REGSIZE_BYTES; // pushed PC (return address) for x86/x64
@@ -5671,25 +5669,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5671
5669
// We set FP to be after LR, FP
5672
5670
delta += 2 * REGSIZE_BYTES;
5673
5671
}
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)
5693
5673
else
5694
5674
{
5695
5675
// FP is used.
@@ -5757,7 +5737,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5757
5737
5758
5738
#if defined(TARGET_X86)
5759
5739
// 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 .
5761
5741
if ((!varDsc->lvIsParam || parentvarDsc->lvIsParam) && promotionType == PROMOTION_TYPE_DEPENDENT)
5762
5742
#else
5763
5743
if (!varDsc->lvIsParam && promotionType == PROMOTION_TYPE_DEPENDENT)
@@ -5777,23 +5757,15 @@ void Compiler::lvaFixVirtualFrameOffsets()
5777
5757
5778
5758
if (doAssignStkOffs)
5779
5759
{
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);
5790
5762
5791
5763
#if DOUBLE_ALIGN
5792
5764
if (genDoubleAlign() && !codeGen->isFramePointerUsed())
5793
5765
{
5794
5766
if (varDsc->lvFramePointerBased)
5795
5767
{
5796
- varDsc->SetStackOffset(varDsc->GetStackOffset() - localDelta );
5768
+ varDsc->SetStackOffset(varDsc->GetStackOffset() - delta );
5797
5769
5798
5770
// We need to re-adjust the offsets of the parameters so they are EBP
5799
5771
// relative rather than stack/frame pointer relative
@@ -5815,13 +5787,9 @@ void Compiler::lvaFixVirtualFrameOffsets()
5815
5787
assert(codeGen->regSet.tmpAllFree());
5816
5788
for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
5817
5789
{
5818
- temp->tdAdjustTempOffs(delta + frameLocalsDelta );
5790
+ temp->tdAdjustTempOffs(delta);
5819
5791
}
5820
5792
5821
- if (lvaCachedGenericContextArgOffs < frameBoundary)
5822
- {
5823
- lvaCachedGenericContextArgOffs += frameLocalsDelta;
5824
- }
5825
5793
lvaCachedGenericContextArgOffs += delta;
5826
5794
5827
5795
#if FEATURE_FIXED_OUT_ARGS
@@ -6077,6 +6045,30 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6077
6045
codeGen->setFramePointerUsed(codeGen->isFramePointerRequired());
6078
6046
}
6079
6047
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
+
6080
6072
#ifdef TARGET_XARCH
6081
6073
// On x86/amd64, the return address has already been pushed by the call instruction in the caller.
6082
6074
stkOffs -= TARGET_POINTER_SIZE; // return address;
@@ -6125,13 +6117,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6125
6117
#endif // !TARGET_ARM
6126
6118
6127
6119
#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).
6135
6123
6136
6124
int initialStkOffs = 0;
6137
6125
if (info.compIsVarArgs)
@@ -6142,7 +6130,17 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6142
6130
stkOffs -= initialStkOffs;
6143
6131
}
6144
6132
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
+ }
6146
6144
6147
6145
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
6148
6146
@@ -6812,6 +6810,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6812
6810
}
6813
6811
#endif // TARGET_AMD64
6814
6812
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
+
6815
6822
#if FEATURE_FIXED_OUT_ARGS
6816
6823
if (lvaOutgoingArgSpaceSize > 0)
6817
6824
{
@@ -6849,44 +6856,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6849
6856
6850
6857
noway_assert(compLclFrameSize + originalFrameSize ==
6851
6858
(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
6890
6859
}
6891
6860
6892
6861
//------------------------------------------------------------------------
0 commit comments