Skip to content

Commit 9be0be0

Browse files
authored
JIT: Remove uses of old ABI information (#112818)
- Remove uses of `compArgSize`. This value is computed by the old LclVarDsc ABI classification code and used to derive the amount of stack spaced consumed for parameters. Replace it with the value from the new ABI information instead. - Remove `LclVarDsc::lvSize` and `LclVarDsc::lvArgStackSize`. Generally `LclVarDsc::lvExactSize` is the right replacement, unless specifically the stack home size is needed, in which case the replacement is `Compiler::lvaLclStackHomeSize`. - Remove uses of `LclVarDsc` HFA information. This was the primary motivation for removing `LclVarDsc::lvSize` since it was querying HFA information.
1 parent 5f97ddf commit 9be0be0

19 files changed

+163
-226
lines changed

src/coreclr/jit/codegenarm64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1781,7 +1781,7 @@ void CodeGen::genCaptureFuncletPrologEpilogInfo()
17811781
// We furthermore allocate the "monitor acquired" bool between PSP and
17821782
// the saved registers because this is part of the EnC header.
17831783
// Note that OSR methods reuse the monitor bool created by tier 0.
1784-
saveRegsPlusPSPSize += compiler->lvaLclSize(compiler->lvaMonAcquired);
1784+
saveRegsPlusPSPSize += compiler->lvaLclStackHomeSize(compiler->lvaMonAcquired);
17851785
}
17861786

17871787
unsigned const saveRegsPlusPSPSizeAligned = roundUp(saveRegsPlusPSPSize, STACK_ALIGN);
@@ -2966,7 +2966,7 @@ void CodeGen::genCodeForStoreLclVar(GenTreeLclVar* lclNode)
29662966
if (lclNode->IsMultiReg())
29672967
{
29682968
// This is the case of storing to a multi-reg HFA local from a fixed-size SIMD type.
2969-
assert(varTypeIsSIMD(data) && varDsc->lvIsHfa() && (varDsc->GetHfaType() == TYP_FLOAT));
2969+
assert(varTypeIsSIMD(data));
29702970
regNumber operandReg = genConsumeReg(data);
29712971
unsigned int regCount = varDsc->lvFieldCnt;
29722972
for (unsigned i = 0; i < regCount; ++i)

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
792792
if (treeNode->putInIncomingArgArea())
793793
{
794794
varNumOut = getFirstArgWithStackSlot();
795-
argOffsetMax = compiler->compArgSize;
795+
argOffsetMax = compiler->lvaParameterStackSize;
796796
#if FEATURE_FASTTAILCALL
797797
// This must be a fast tail call.
798798
assert(treeNode->gtCall->IsFastTailCall());

src/coreclr/jit/codegencommon.cpp

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3823,7 +3823,7 @@ void CodeGen::genCheckUseBlockInit()
38233823
{
38243824
// Var is on the stack at entry.
38253825
initStkLclCnt +=
3826-
roundUp(compiler->lvaLclSize(varNum), TARGET_POINTER_SIZE) / sizeof(int);
3826+
roundUp(compiler->lvaLclStackHomeSize(varNum), TARGET_POINTER_SIZE) / sizeof(int);
38273827
counted = true;
38283828
}
38293829
}
@@ -3872,7 +3872,8 @@ void CodeGen::genCheckUseBlockInit()
38723872

38733873
if (!counted)
38743874
{
3875-
initStkLclCnt += roundUp(compiler->lvaLclSize(varNum), TARGET_POINTER_SIZE) / sizeof(int);
3875+
initStkLclCnt +=
3876+
roundUp(compiler->lvaLclStackHomeSize(varNum), TARGET_POINTER_SIZE) / sizeof(int);
38763877
counted = true;
38773878
}
38783879
}
@@ -4133,7 +4134,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
41334134
(varDsc->lvExactSize() >= TARGET_POINTER_SIZE))
41344135
{
41354136
// We only initialize the GC variables in the TYP_STRUCT
4136-
const unsigned slots = (unsigned)compiler->lvaLclSize(varNum) / REGSIZE_BYTES;
4137+
const unsigned slots = (unsigned)compiler->lvaLclStackHomeSize(varNum) / REGSIZE_BYTES;
41374138
ClassLayout* layout = varDsc->GetLayout();
41384139

41394140
for (unsigned i = 0; i < slots; i++)
@@ -4150,7 +4151,7 @@ void CodeGen::genZeroInitFrame(int untrLclHi, int untrLclLo, regNumber initReg,
41504151
regNumber zeroReg = genGetZeroReg(initReg, pInitRegZeroed);
41514152

41524153
// zero out the whole thing rounded up to a single stack slot size
4153-
unsigned lclSize = roundUp(compiler->lvaLclSize(varNum), (unsigned)sizeof(int));
4154+
unsigned lclSize = roundUp(compiler->lvaLclStackHomeSize(varNum), (unsigned)sizeof(int));
41544155
unsigned i;
41554156
for (i = 0; i + REGSIZE_BYTES <= lclSize; i += REGSIZE_BYTES)
41564157
{
@@ -4592,21 +4593,6 @@ void CodeGen::genReportGenericContextArg(regNumber initReg, bool* pInitRegZeroed
45924593
}
45934594
else
45944595
{
4595-
if (isFramePointerUsed())
4596-
{
4597-
#if defined(TARGET_ARM)
4598-
// GetStackOffset() is always valid for incoming stack-arguments, even if the argument
4599-
// will become enregistered.
4600-
// On Arm compiler->compArgSize doesn't include r11 and lr sizes and hence we need to add 2*REGSIZE_BYTES
4601-
noway_assert((2 * REGSIZE_BYTES <= varDsc->GetStackOffset()) &&
4602-
(size_t(varDsc->GetStackOffset()) < compiler->compArgSize + 2 * REGSIZE_BYTES));
4603-
#else
4604-
// GetStackOffset() is always valid for incoming stack-arguments, even if the argument
4605-
// will become enregistered.
4606-
noway_assert((0 < varDsc->GetStackOffset()) && (size_t(varDsc->GetStackOffset()) < compiler->compArgSize));
4607-
#endif
4608-
}
4609-
46104596
// We will just use the initReg since it is an available register
46114597
// and we are probably done using it anyway...
46124598
reg = initReg;
@@ -5215,7 +5201,7 @@ void CodeGen::genFnProlog()
52155201
}
52165202

52175203
signed int loOffs = varDsc->GetStackOffset();
5218-
signed int hiOffs = varDsc->GetStackOffset() + compiler->lvaLclSize(varNum);
5204+
signed int hiOffs = varDsc->GetStackOffset() + compiler->lvaLclStackHomeSize(varNum);
52195205

52205206
/* We need to know the offset range of tracked stack GC refs */
52215207
/* We assume that the GC reference can be anywhere in the TYP_STRUCT */
@@ -5672,7 +5658,7 @@ void CodeGen::genFnProlog()
56725658
{
56735659
// The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
56745660
unsigned filterEndOffsetSlotOffs =
5675-
compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE;
5661+
compiler->lvaLclStackHomeSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE;
56765662

56775663
// Zero out the slot for nesting level 0
56785664
unsigned firstSlotOffs = filterEndOffsetSlotOffs - TARGET_POINTER_SIZE;
@@ -7883,12 +7869,13 @@ void CodeGen::genMultiRegStoreToLocal(GenTreeLclVar* lclNode)
78837869
offset += genTypeSize(srcType);
78847870

78857871
#ifdef DEBUG
7872+
unsigned stackHomeSize = compiler->lvaLclStackHomeSize(lclNum);
78867873
#ifdef TARGET_64BIT
7887-
assert(offset <= varDsc->lvSize());
7874+
assert(offset <= stackHomeSize);
78887875
#else // !TARGET_64BIT
78897876
if (varTypeIsStruct(varDsc))
78907877
{
7891-
assert(offset <= varDsc->lvSize());
7878+
assert(offset <= stackHomeSize);
78927879
}
78937880
else
78947881
{
@@ -8203,7 +8190,7 @@ void CodeGen::genPoisonFrame(regMaskTP regLiveIn)
82038190

82048191
assert(varDsc->lvOnFrame);
82058192

8206-
unsigned int size = compiler->lvaLclSize(varNum);
8193+
unsigned int size = compiler->lvaLclStackHomeSize(varNum);
82078194
if ((size / TARGET_POINTER_SIZE) > 16)
82088195
{
82098196
// This will require more than 16 instructions, switch to rep stosd/memset call.

src/coreclr/jit/codegenlinear.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1893,7 +1893,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg
18931893
// We can't write beyond the arg area unless this is a tail call, in which case we use
18941894
// the first stack arg as the base of the incoming arg area.
18951895
#ifdef DEBUG
1896-
unsigned areaSize = compiler->lvaLclSize(outArgVarNum);
1896+
unsigned areaSize = compiler->lvaLclStackHomeSize(outArgVarNum);
18971897
#if FEATURE_FASTTAILCALL
18981898
if (putArgStk->gtCall->IsFastTailCall())
18991899
{

src/coreclr/jit/codegenloongarch64.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4841,8 +4841,8 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
48414841
assert(varDsc->lvType == TYP_STRUCT);
48424842
assert(varDsc->lvOnFrame && !varDsc->lvRegister);
48434843

4844-
srcSize = varDsc->lvSize(); // This yields the roundUp size, but that is fine
4845-
// as that is how much stack is allocated for this LclVar
4844+
srcSize = compiler->lvaLclStackHomeSize(varNode->GetLclNum());
4845+
48464846
layout = varDsc->GetLayout();
48474847
}
48484848
else // we must have a GT_BLK
@@ -4870,8 +4870,7 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)
48704870
if (varNode != nullptr)
48714871
{
48724872
// If we have a varNode, even if it was casted using `OBJ`, we can read its original memory size.
4873-
const LclVarDsc* varDsc = compiler->lvaGetDesc(varNode);
4874-
const unsigned varStackSize = varDsc->lvSize();
4873+
const unsigned varStackSize = compiler->lvaLclStackHomeSize(varNode->GetLclNum());
48754874
if (varStackSize >= srcSize)
48764875
{
48774876
srcSize = varStackSize;

src/coreclr/jit/codegenxarch.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,8 @@ BasicBlock* CodeGen::genCallFinally(BasicBlock* block)
279279

280280
// The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
281281
unsigned filterEndOffsetSlotOffs;
282-
filterEndOffsetSlotOffs = (unsigned)(compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
282+
filterEndOffsetSlotOffs =
283+
(unsigned)(compiler->lvaLclStackHomeSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
283284

284285
unsigned curNestingSlotOffs;
285286
curNestingSlotOffs = (unsigned)(filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE));
@@ -2210,10 +2211,9 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
22102211

22112212
// The last slot is reserved for ICodeManager::FixContext(ppEndRegion)
22122213
unsigned filterEndOffsetSlotOffs;
2213-
PREFIX_ASSUME(compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) > TARGET_POINTER_SIZE); // below doesn't
2214-
// underflow.
2214+
assert(compiler->lvaLclStackHomeSize(compiler->lvaShadowSPslotsVar) > TARGET_POINTER_SIZE);
22152215
filterEndOffsetSlotOffs =
2216-
(unsigned)(compiler->lvaLclSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
2216+
(unsigned)(compiler->lvaLclStackHomeSize(compiler->lvaShadowSPslotsVar) - TARGET_POINTER_SIZE);
22172217

22182218
size_t curNestingSlotOffs;
22192219
curNestingSlotOffs = filterEndOffsetSlotOffs - ((finallyNesting + 1) * TARGET_POINTER_SIZE);
@@ -10752,10 +10752,8 @@ void CodeGen::genFnEpilog(BasicBlock* block)
1075210752

1075310753
if (fCalleePop)
1075410754
{
10755-
noway_assert(compiler->compArgSize >= intRegState.rsCalleeRegArgCount * REGSIZE_BYTES);
10756-
stkArgSize = compiler->compArgSize - intRegState.rsCalleeRegArgCount * REGSIZE_BYTES;
10757-
10758-
noway_assert(compiler->compArgSize < 0x10000); // "ret" only has 2 byte operand
10755+
stkArgSize = compiler->lvaParameterStackSize;
10756+
noway_assert(stkArgSize < 0x10000); // "ret" only has 2 byte operand
1075910757
}
1076010758

1076110759
#ifdef UNIX_X86_ABI

src/coreclr/jit/compiler.h

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ class LclVarDsc
625625
#endif // FEATURE_HFA_FIELDS_PRESENT
626626

627627
#ifdef DEBUG
628-
// TODO-Cleanup: See the note on lvSize() - this flag is only in use by asserts that are checking for struct
628+
// TODO-Cleanup: this flag is only in use by asserts that are checking for struct
629629
// types, and is needed because of cases where TYP_STRUCT is bashed to an integral type.
630630
// Consider cleaning this up so this workaround is not required.
631631
unsigned char lvUnusedStruct : 1; // All references to this promoted struct are through its field locals.
@@ -1118,9 +1118,6 @@ class LclVarDsc
11181118
}
11191119

11201120
unsigned lvExactSize() const;
1121-
unsigned lvSize() const;
1122-
1123-
size_t lvArgStackSize() const;
11241121

11251122
unsigned lvSlotNum; // original slot # (if remapped)
11261123

@@ -4312,7 +4309,7 @@ class Compiler
43124309
return varNum;
43134310
}
43144311

4315-
unsigned lvaLclSize(unsigned varNum);
4312+
unsigned lvaLclStackHomeSize(unsigned varNum);
43164313
unsigned lvaLclExactSize(unsigned varNum);
43174314

43184315
bool lvaHaveManyLocals(float percent = 1.0f) const;
@@ -4437,6 +4434,7 @@ class Compiler
44374434
bool ShouldPromoteStructVar(unsigned lclNum);
44384435
void PromoteStructVar(unsigned lclNum);
44394436
void SortStructFields();
4437+
bool IsArmHfaParameter(unsigned lclNum);
44404438

44414439
var_types TryPromoteValueClassAsPrimitive(CORINFO_TYPE_LAYOUT_NODE* treeNodes, size_t maxTreeNodes, size_t index);
44424440
void AdvanceSubTree(CORINFO_TYPE_LAYOUT_NODE* treeNodes, size_t maxTreeNodes, size_t* index);
@@ -4457,27 +4455,26 @@ class Compiler
44574455
bool lvaIsGCTracked(const LclVarDsc* varDsc);
44584456

44594457
#if defined(FEATURE_SIMD)
4460-
bool lvaMapSimd12ToSimd16(const LclVarDsc* varDsc)
4458+
bool lvaMapSimd12ToSimd16(unsigned varNum)
44614459
{
4462-
assert(varDsc->lvType == TYP_SIMD12);
4460+
LclVarDsc* varDsc = lvaGetDesc(varNum);
4461+
assert(varDsc->TypeGet() == TYP_SIMD12);
44634462

4464-
#if defined(TARGET_64BIT)
4465-
assert(compAppleArm64Abi() || varDsc->lvSize() == 16);
4466-
#endif // defined(TARGET_64BIT)
4463+
unsigned stackHomeSize = lvaLclStackHomeSize(varNum);
44674464

44684465
// We make local variable SIMD12 types 16 bytes instead of just 12.
4469-
// lvSize() will return 16 bytes for SIMD12, even for fields.
4466+
// lvaLclStackHomeSize() will return 16 bytes for SIMD12, even for fields.
44704467
// However, we can't do that mapping if the var is a dependently promoted struct field.
44714468
// Such a field must remain its exact size within its parent struct unless it is a single
44724469
// field *and* it is the only field in a struct of 16 bytes.
4473-
if (varDsc->lvSize() != 16)
4470+
if (stackHomeSize != 16)
44744471
{
44754472
return false;
44764473
}
44774474
if (lvaIsFieldOfDependentlyPromotedStruct(varDsc))
44784475
{
44794476
LclVarDsc* parentVarDsc = lvaGetDesc(varDsc->lvParentLcl);
4480-
return (parentVarDsc->lvFieldCnt == 1) && (parentVarDsc->lvSize() == 16);
4477+
return (parentVarDsc->lvFieldCnt == 1) && (lvaLclStackHomeSize(varDsc->lvParentLcl) == 16);
44814478
}
44824479
return true;
44834480
}

src/coreclr/jit/compiler.hpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4085,6 +4085,17 @@ inline bool Compiler::impIsPrimitive(CorInfoType jitType)
40854085

40864086
inline Compiler::lvaPromotionType Compiler::lvaGetPromotionType(const LclVarDsc* varDsc)
40874087
{
4088+
// TODO-Review: Sometimes we get called on ARM with HFA struct variables that have been promoted,
4089+
// where the struct itself is no longer used because all access is via its member fields.
4090+
// When that happens, the struct is marked as unused and its type has been changed to
4091+
// TYP_INT (to keep the GC tracking code from looking at it).
4092+
// See Compiler::raAssignVars() for details. For example:
4093+
// N002 ( 4, 3) [00EA067C] ------------- return struct $346
4094+
// N001 ( 3, 2) [00EA0628] ------------- lclVar struct(U) V03 loc2
4095+
// float V03.f1 (offs=0x00) -> V12 tmp7
4096+
// f8 (last use) (last use) $345
4097+
// Here, the "struct(U)" shows that the "V03 loc2" variable is unused. Not shown is that V03
4098+
// is now TYP_INT in the local variable table. It's not really unused, because it's in the tree.
40884099
assert(!varDsc->lvPromoted || varTypeIsPromotable(varDsc) || varDsc->lvUnusedStruct);
40894100

40904101
if (!varDsc->lvPromoted)
@@ -4322,19 +4333,20 @@ bool Compiler::fgVarNeedsExplicitZeroInit(unsigned varNum, bool bbInALoop, bool
43224333
return false;
43234334
}
43244335

4325-
// Below conditions guarantee block initialization, which will initialize
4326-
// all struct fields. If the logic for block initialization in CodeGen::genCheckUseBlockInit()
4327-
// changes, these conditions need to be updated.
4336+
// Below conditions guarantee block initialization, which will initialize
4337+
// all struct fields. If the logic for block initialization in CodeGen::genCheckUseBlockInit()
4338+
// changes, these conditions need to be updated.
4339+
unsigned stackHomeSize = lvaLclStackHomeSize(varNum);
43284340
#ifdef TARGET_64BIT
43294341
#if defined(TARGET_AMD64)
43304342
// We can clear using aligned SIMD so the threshold is lower,
43314343
// and clears in order which is better for auto-prefetching
4332-
if (roundUp(varDsc->lvSize(), TARGET_POINTER_SIZE) / sizeof(int) > 4)
4344+
if (roundUp(stackHomeSize, TARGET_POINTER_SIZE) / sizeof(int) > 4)
43334345
#else // !defined(TARGET_AMD64)
4334-
if (roundUp(varDsc->lvSize(), TARGET_POINTER_SIZE) / sizeof(int) > 8)
4346+
if (roundUp(stackHomeSize, TARGET_POINTER_SIZE) / sizeof(int) > 8)
43354347
#endif
43364348
#else
4337-
if (roundUp(varDsc->lvSize(), TARGET_POINTER_SIZE) / sizeof(int) > 4)
4349+
if (roundUp(stackHomeSize, TARGET_POINTER_SIZE) / sizeof(int) > 4)
43384350
#endif
43394351
{
43404352
return false;

src/coreclr/jit/gcencode.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,10 +1588,9 @@ size_t GCInfo::gcInfoBlockHdrSave(
15881588
assert(header->revPInvokeOffset != INVALID_REV_PINVOKE_OFFSET);
15891589
}
15901590

1591-
assert((compiler->compArgSize & 0x3) == 0);
1592-
1593-
size_t argCount =
1594-
(compiler->compArgSize - (compiler->codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES)) / REGSIZE_BYTES;
1591+
assert(compiler->lvaParameterStackSize ==
1592+
(compiler->compArgSize - compiler->codeGen->intRegState.rsCalleeRegArgCount * REGSIZE_BYTES));
1593+
size_t argCount = compiler->lvaParameterStackSize / REGSIZE_BYTES;
15951594
assert(argCount <= MAX_USHORT_SIZE_T);
15961595
header->argCount = static_cast<unsigned short>(argCount);
15971596

src/coreclr/jit/gentree.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27052,9 +27052,9 @@ GenTree* Compiler::gtNewSimdWithElementNode(
2705227052
//
2705327053
GenTreeFieldList* Compiler::gtConvertTableOpToFieldList(GenTree* op, unsigned fieldCount)
2705427054
{
27055-
LclVarDsc* opVarDsc = lvaGetDesc(op->AsLclVar());
27056-
unsigned lclNum = lvaGetLclNum(opVarDsc);
27057-
unsigned fieldSize = opVarDsc->lvSize() / fieldCount;
27055+
unsigned lclNum = op->AsLclVar()->GetLclNum();
27056+
LclVarDsc* opVarDsc = lvaGetDesc(lclNum);
27057+
unsigned fieldSize = opVarDsc->lvExactSize() / fieldCount;
2705827058
var_types fieldType = Compiler::getSIMDTypeForSize(fieldSize);
2705927059

2706027060
GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList();
@@ -27083,9 +27083,9 @@ GenTreeFieldList* Compiler::gtConvertTableOpToFieldList(GenTree* op, unsigned fi
2708327083
//
2708427084
GenTreeFieldList* Compiler::gtConvertParamOpToFieldList(GenTree* op, unsigned fieldCount, CORINFO_CLASS_HANDLE clsHnd)
2708527085
{
27086-
LclVarDsc* opVarDsc = lvaGetDesc(op->AsLclVar());
27087-
unsigned lclNum = lvaGetLclNum(opVarDsc);
27088-
unsigned fieldSize = opVarDsc->lvSize() / fieldCount;
27086+
unsigned lclNum = op->AsLclVar()->GetLclNum();
27087+
LclVarDsc* opVarDsc = lvaGetDesc(lclNum);
27088+
unsigned fieldSize = opVarDsc->lvExactSize() / fieldCount;
2708927089
GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList();
2709027090
int offset = 0;
2709127091
unsigned sizeBytes = 0;

0 commit comments

Comments
 (0)