@@ -5639,9 +5639,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5639
5639
#endif
5640
5640
5641
5641
// 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;
5645
5643
5646
5644
#ifdef TARGET_XARCH
5647
5645
delta += REGSIZE_BYTES; // pushed PC (return address) for x86/x64
@@ -5666,25 +5664,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5666
5664
// We set FP to be after LR, FP
5667
5665
delta += 2 * REGSIZE_BYTES;
5668
5666
}
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)
5688
5668
else
5689
5669
{
5690
5670
// FP is used.
@@ -5752,7 +5732,7 @@ void Compiler::lvaFixVirtualFrameOffsets()
5752
5732
5753
5733
#if defined(TARGET_X86)
5754
5734
// 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 .
5756
5736
if ((!varDsc->lvIsParam || parentvarDsc->lvIsParam) && promotionType == PROMOTION_TYPE_DEPENDENT)
5757
5737
#else
5758
5738
if (!varDsc->lvIsParam && promotionType == PROMOTION_TYPE_DEPENDENT)
@@ -5772,23 +5752,15 @@ void Compiler::lvaFixVirtualFrameOffsets()
5772
5752
5773
5753
if (doAssignStkOffs)
5774
5754
{
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);
5785
5757
5786
5758
#if DOUBLE_ALIGN
5787
5759
if (genDoubleAlign() && !codeGen->isFramePointerUsed())
5788
5760
{
5789
5761
if (varDsc->lvFramePointerBased)
5790
5762
{
5791
- varDsc->SetStackOffset(varDsc->GetStackOffset() - localDelta );
5763
+ varDsc->SetStackOffset(varDsc->GetStackOffset() - delta );
5792
5764
5793
5765
// We need to re-adjust the offsets of the parameters so they are EBP
5794
5766
// relative rather than stack/frame pointer relative
@@ -5810,13 +5782,9 @@ void Compiler::lvaFixVirtualFrameOffsets()
5810
5782
assert(codeGen->regSet.tmpAllFree());
5811
5783
for (TempDsc* temp = codeGen->regSet.tmpListBeg(); temp != nullptr; temp = codeGen->regSet.tmpListNxt(temp))
5812
5784
{
5813
- temp->tdAdjustTempOffs(delta + frameLocalsDelta );
5785
+ temp->tdAdjustTempOffs(delta);
5814
5786
}
5815
5787
5816
- if (lvaCachedGenericContextArgOffs < frameBoundary)
5817
- {
5818
- lvaCachedGenericContextArgOffs += frameLocalsDelta;
5819
- }
5820
5788
lvaCachedGenericContextArgOffs += delta;
5821
5789
5822
5790
#if FEATURE_FIXED_OUT_ARGS
@@ -6072,6 +6040,30 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6072
6040
codeGen->setFramePointerUsed(codeGen->isFramePointerRequired());
6073
6041
}
6074
6042
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
+
6075
6067
#ifdef TARGET_XARCH
6076
6068
// On x86/amd64, the return address has already been pushed by the call instruction in the caller.
6077
6069
stkOffs -= TARGET_POINTER_SIZE; // return address;
@@ -6120,13 +6112,9 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6120
6112
#endif // !TARGET_ARM
6121
6113
6122
6114
#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).
6130
6118
6131
6119
int initialStkOffs = 0;
6132
6120
if (info.compIsVarArgs)
@@ -6137,7 +6125,17 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6137
6125
stkOffs -= initialStkOffs;
6138
6126
}
6139
6127
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
+ }
6141
6139
6142
6140
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
6143
6141
@@ -6807,6 +6805,15 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6807
6805
}
6808
6806
#endif // TARGET_AMD64
6809
6807
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
+
6810
6817
#if FEATURE_FIXED_OUT_ARGS
6811
6818
if (lvaOutgoingArgSpaceSize > 0)
6812
6819
{
@@ -6844,44 +6851,6 @@ void Compiler::lvaAssignVirtualFrameOffsetsToLocals()
6844
6851
6845
6852
noway_assert(compLclFrameSize + originalFrameSize ==
6846
6853
(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
6885
6854
}
6886
6855
6887
6856
//------------------------------------------------------------------------
0 commit comments