Skip to content

Commit

Permalink
Delete LCL_VAR_ADDR (#84185)
Browse files Browse the repository at this point in the history
* Delete GT_LCL_VAR_ADDR

The node is exactly equivalent to LCL_FLD_ADDR at offset zero.

There is no reason to have two representations for the same thing.

* Delete OperIsLocalAddr

No longer needed.

* GT_LCL_FLD_ADDR -> GT_LCL_ADDR

The generalized "local address" node.

* Help MSVC

Turns a 0.05% TP regression into a 0.05% TP win.

* gtNewLclFldAddrNode -> gtNewLclAddrNode

* Fix formatting
  • Loading branch information
SingleAccretion authored Apr 3, 2023
1 parent 8b1d1ea commit 730a030
Show file tree
Hide file tree
Showing 44 changed files with 308 additions and 390 deletions.
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#endif // TARGET_XARCH

void genCodeForCast(GenTreeOp* tree);
void genCodeForLclAddr(GenTreeLclVarCommon* lclAddrNode);
void genCodeForLclAddr(GenTreeLclFld* lclAddrNode);
void genCodeForIndexAddr(GenTreeIndexAddr* tree);
void genCodeForIndir(GenTreeIndir* tree);
void genCodeForNegNot(GenTree* tree);
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
sourceIsLocal = true;
}

bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIsLocalAddr();
bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIs(GT_LCL_ADDR);

#ifdef DEBUG
assert(!dstAddr->isContained());
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegenarm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3565,7 +3565,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
sourceIsLocal = true;
}

bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIsLocalAddr();
bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIs(GT_LCL_ADDR);

#ifdef DEBUG
assert(!dstAddr->isContained());
Expand Down
17 changes: 8 additions & 9 deletions src/coreclr/jit/codegenarmarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForBitCast(treeNode->AsOp());
break;

case GT_LCL_FLD_ADDR:
case GT_LCL_VAR_ADDR:
genCodeForLclAddr(treeNode->AsLclVarCommon());
case GT_LCL_ADDR:
genCodeForLclAddr(treeNode->AsLclFld());
break;

case GT_LCL_FLD:
Expand Down Expand Up @@ -1676,14 +1675,14 @@ void CodeGen::genCodeForShift(GenTree* tree)
}

//------------------------------------------------------------------------
// genCodeForLclAddr: Generates the code for GT_LCL_FLD_ADDR/GT_LCL_VAR_ADDR.
// genCodeForLclAddr: Generates the code for GT_LCL_ADDR.
//
// Arguments:
// lclAddrNode - the node.
//
void CodeGen::genCodeForLclAddr(GenTreeLclVarCommon* lclAddrNode)
void CodeGen::genCodeForLclAddr(GenTreeLclFld* lclAddrNode)
{
assert(lclAddrNode->OperIs(GT_LCL_FLD_ADDR, GT_LCL_VAR_ADDR));
assert(lclAddrNode->OperIs(GT_LCL_ADDR));

var_types targetType = lclAddrNode->TypeGet();
emitAttr size = emitTypeSize(targetType);
Expand Down Expand Up @@ -2568,7 +2567,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -2735,7 +2734,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -2768,7 +2767,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
}
else
{
assert(srcAddr->OperIsLocalAddr());
assert(srcAddr->OperIs(GT_LCL_ADDR));
srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2781,7 +2781,7 @@ void CodeGen::genGCWriteBarrier(GenTreeStoreInd* store, GCInfo::WriteBarrierForm
wbKind = varDsc->lvIsParam ? CWBKind_ByRefArg : CWBKind_OtherByRefLocal;
}
}
else if (tgtAddr->OperIsLocalAddr())
else if (tgtAddr->OperIs(GT_LCL_ADDR))
{
// Ideally, we should have eliminated the barrier for this case.
wbKind = CWBKind_AddrOfLocal;
Expand Down
39 changes: 19 additions & 20 deletions src/coreclr/jit/codegenloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2788,7 +2788,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -2921,7 +2921,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
sourceIsLocal = true;
}

bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIsLocalAddr();
bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIs(GT_LCL_ADDR);

#ifdef DEBUG
assert(!dstAddr->isContained());
Expand Down Expand Up @@ -5000,9 +5000,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForBitCast(treeNode->AsOp());
break;

case GT_LCL_FLD_ADDR:
case GT_LCL_VAR_ADDR:
genCodeForLclAddr(treeNode->AsLclVarCommon());
case GT_LCL_ADDR:
genCodeForLclAddr(treeNode->AsLclFld());
break;

case GT_LCL_FLD:
Expand Down Expand Up @@ -5503,15 +5502,15 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* treeNode)

addrNode = source->AsOp()->gtOp1;

// addrNode can either be a GT_LCL_VAR_ADDR or an address expression
// addrNode can either be a GT_LCL_ADDR<0> or an address expression
//
if (addrNode->OperGet() == GT_LCL_VAR_ADDR)
if (addrNode->IsLclVarAddr())
{
// We have a GT_OBJ(GT_LCL_VAR_ADDR)
// We have a GT_OBJ(GT_LCL_ADDR<0>)
//
// We will treat this case the same as above
// (i.e if we just had this GT_LCL_VAR directly as the source)
// so update 'source' to point this GT_LCL_VAR_ADDR node
// so update 'source' to point this GT_LCL_ADDR node
// and continue to the codegen for the LCL_VAR node below
//
varNode = addrNode->AsLclVarCommon();
Expand Down Expand Up @@ -5778,15 +5777,15 @@ void CodeGen::genPutArgSplit(GenTreePutArgSplit* treeNode)

addrNode = source->AsOp()->gtOp1;

// addrNode can either be a GT_LCL_VAR_ADDR or an address expression
// addrNode can either be a GT_LCL_ADDR<0> or an address expression
//
if (addrNode->OperGet() == GT_LCL_VAR_ADDR)
if (addrNode->IsLclVarAddr())
{
// We have a GT_OBJ(GT_LCL_VAR_ADDR)
// We have a GT_OBJ(GT_LCL_ADDR<0>)
//
// We will treat this case the same as above
// (i.e if we just had this GT_LCL_VAR directly as the source)
// so update 'source' to point this GT_LCL_VAR_ADDR node
// so update 'source' to point this GT_LCL_ADDR node
// and continue to the codegen for the LCL_VAR node below
//
varNode = addrNode->AsLclVarCommon();
Expand Down Expand Up @@ -6185,14 +6184,14 @@ void CodeGen::genCodeForShift(GenTree* tree)
}

//------------------------------------------------------------------------
// genCodeForLclAddr: Generates the code for GT_LCL_FLD_ADDR/GT_LCL_VAR_ADDR.
// genCodeForLclAddr: Generates the code for GT_LCL_ADDR.
//
// Arguments:
// tree - the node.
//
void CodeGen::genCodeForLclAddr(GenTreeLclVarCommon* lclAddrNode)
void CodeGen::genCodeForLclAddr(GenTreeLclFld* lclAddrNode)
{
assert(lclAddrNode->OperIs(GT_LCL_FLD_ADDR, GT_LCL_VAR_ADDR));
assert(lclAddrNode->OperIs(GT_LCL_ADDR));

var_types targetType = lclAddrNode->TypeGet();
emitAttr size = emitTypeSize(targetType);
Expand Down Expand Up @@ -6481,7 +6480,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -6514,7 +6513,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)
}
else
{
assert(srcAddr->OperIsLocalAddr());
assert(srcAddr->OperIs(GT_LCL_ADDR));
srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -6661,9 +6660,9 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst
{
emitter* emit = GetEmitter();

if (base->OperIsLocalAddr())
if (base->OperIs(GT_LCL_ADDR))
{
if (base->gtOper == GT_LCL_FLD_ADDR)
if (base->gtOper == GT_LCL_ADDR)
{
offset += base->AsLclFld()->GetLclOffs();
}
Expand Down
36 changes: 17 additions & 19 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1841,9 +1841,8 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
genCodeForBitCast(treeNode->AsOp());
break;

case GT_LCL_FLD_ADDR:
case GT_LCL_VAR_ADDR:
genCodeForLclAddr(treeNode->AsLclVarCommon());
case GT_LCL_ADDR:
genCodeForLclAddr(treeNode->AsLclFld());
break;

case GT_LCL_FLD:
Expand Down Expand Up @@ -3159,7 +3158,7 @@ void CodeGen::genCodeForInitBlkUnroll(GenTreeBlk* node)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
dstLclNum = dstAddr->AsLclVarCommon()->GetLclNum();
dstOffset = dstAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -3446,7 +3445,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
}
else
{
assert(dstAddr->OperIsLocalAddr());
assert(dstAddr->OperIs(GT_LCL_ADDR));
const GenTreeLclVarCommon* lclVar = dstAddr->AsLclVarCommon();
dstLclNum = lclVar->GetLclNum();
dstOffset = lclVar->GetLclOffs();
Expand Down Expand Up @@ -3494,7 +3493,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* node)
}
else
{
assert(srcAddr->OperIsLocalAddr());
assert(srcAddr->OperIs(GT_LCL_ADDR));
srcLclNum = srcAddr->AsLclVarCommon()->GetLclNum();
srcOffset = srcAddr->AsLclVarCommon()->GetLclOffs();
}
Expand Down Expand Up @@ -4145,7 +4144,7 @@ void CodeGen::genCodeForCpObj(GenTreeObj* cpObjNode)
GenTree* dstAddr = cpObjNode->Addr();
GenTree* source = cpObjNode->Data();
var_types srcAddrType = TYP_BYREF;
bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIsLocalAddr();
bool dstOnStack = dstAddr->gtSkipReloadOrCopy()->OperIs(GT_LCL_ADDR);

// If the GenTree node has data about GC pointers, this means we're dealing
// with CpObj, so this requires special logic.
Expand Down Expand Up @@ -5078,14 +5077,14 @@ void CodeGen::genCodeForShiftRMW(GenTreeStoreInd* storeInd)
}

//------------------------------------------------------------------------
// genCodeForLclAddr: Generates the code for GT_LCL_FLD_ADDR/GT_LCL_VAR_ADDR.
// genCodeForLclAddr: Generates the code for GT_LCL_ADDR.
//
// Arguments:
// lclAddrNode - the node.
//
void CodeGen::genCodeForLclAddr(GenTreeLclVarCommon* lclAddrNode)
void CodeGen::genCodeForLclAddr(GenTreeLclFld* lclAddrNode)
{
assert(lclAddrNode->OperIs(GT_LCL_FLD_ADDR, GT_LCL_VAR_ADDR));
assert(lclAddrNode->OperIs(GT_LCL_ADDR));

var_types targetType = lclAddrNode->TypeGet();
emitAttr size = emitTypeSize(targetType);
Expand Down Expand Up @@ -7470,13 +7469,13 @@ void CodeGen::genIntToFloatCast(GenTree* treeNode)

// Since xarch emitter doesn't handle reporting gc-info correctly while casting away gc-ness we
// ensure srcType of a cast is non gc-type. Codegen should never see BYREF as source type except
// for GT_LCL_VAR_ADDR and GT_LCL_FLD_ADDR that represent stack addresses and can be considered
// as TYP_I_IMPL. In all other cases where src operand is a gc-type and not known to be on stack,
// Front-end (see fgMorphCast()) ensures this by assigning gc-type local to a non gc-type
// temp and using temp as operand of cast operation.
// for GT_LCL_ADDR that represent stack addresses and can be considered as TYP_I_IMPL. In all other
// cases where src operand is a gc-type and not known to be on stack, Front-end (see fgMorphCast())
// ensures this by assigning gc-type local to a non gc-type temp and using temp as operand of cast
// operation.
if (srcType == TYP_BYREF)
{
noway_assert(op1->OperGet() == GT_LCL_VAR_ADDR || op1->OperGet() == GT_LCL_FLD_ADDR);
noway_assert(op1->OperGet() == GT_LCL_ADDR);
srcType = TYP_I_IMPL;
}

Expand Down Expand Up @@ -8011,12 +8010,11 @@ void CodeGen::genSSE41RoundOp(GenTreeOp* treeNode)

switch (memBase->OperGet())
{
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD_ADDR:
case GT_LCL_ADDR:
{
assert(memBase->isContained());
varNum = memBase->AsLclVarCommon()->GetLclNum();
offset = memBase->AsLclVarCommon()->GetLclOffs();
varNum = memBase->AsLclFld()->GetLclNum();
offset = memBase->AsLclFld()->GetLclOffs();

// Ensure that all the GenTreeIndir values are set to their defaults.
assert(memBase->GetRegNum() == REG_NA);
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9605,9 +9605,8 @@ void cTreeFlags(Compiler* comp, GenTree* tree)
switch (op)
{
case GT_LCL_VAR:
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD:
case GT_LCL_FLD_ADDR:
case GT_LCL_ADDR:
case GT_STORE_LCL_FLD:
case GT_STORE_LCL_VAR:
if (tree->gtFlags & GTF_VAR_DEF)
Expand Down
7 changes: 3 additions & 4 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2526,8 +2526,8 @@ class Compiler
GenTreeLclVar* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET));
GenTreeLclVar* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET));

GenTreeLclVar* gtNewLclVarAddrNode(unsigned lclNum, var_types type = TYP_I_IMPL);
GenTreeLclFld* gtNewLclFldAddrNode(unsigned lclNum, unsigned lclOffs, var_types type = TYP_I_IMPL);
GenTreeLclFld* gtNewLclVarAddrNode(unsigned lclNum, var_types type = TYP_I_IMPL);
GenTreeLclFld* gtNewLclAddrNode(unsigned lclNum, unsigned lclOffs, var_types type = TYP_I_IMPL);

GenTreeConditional* gtNewConditionalNode(
genTreeOps oper, GenTree* cond, GenTree* op1, GenTree* op2, var_types type);
Expand Down Expand Up @@ -11068,8 +11068,7 @@ class GenTreeVisitor
// Leaf lclVars
case GT_LCL_VAR:
case GT_LCL_FLD:
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD_ADDR:
case GT_LCL_ADDR:
if (TVisitor::DoLclVarsOnly)
{
result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,10 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
AsLclFld()->SetLayout(nullptr);
break;

case GT_LCL_ADDR:
AsLclFld()->SetLayout(nullptr);
break;

case GT_CALL:
new (&AsCall()->gtArgs, jitstd::placement_t()) CallArgs();
break;
Expand Down Expand Up @@ -4008,8 +4012,7 @@ void GenTree::VisitOperands(TVisitor visitor)
// Leaf nodes
case GT_LCL_VAR:
case GT_LCL_FLD:
case GT_LCL_VAR_ADDR:
case GT_LCL_FLD_ADDR:
case GT_LCL_ADDR:
case GT_CATCH_ARG:
case GT_LABEL:
case GT_FTN_ADDR:
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/emitarm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7912,7 +7912,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR

if (addr->isContained())
{
assert(addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR, GT_LEA));
assert(addr->OperIs(GT_LCL_ADDR, GT_LEA));

DWORD lsl = 0;

Expand Down Expand Up @@ -7997,7 +7997,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
}
else // no Index
{
if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR))
if (addr->OperIs(GT_LCL_ADDR))
{
GenTreeLclVarCommon* varNode = addr->AsLclVarCommon();
unsigned lclNum = varNode->GetLclNum();
Expand Down Expand Up @@ -8032,7 +8032,7 @@ void emitter::emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataR
else
{
#ifdef DEBUG
if (addr->OperIs(GT_LCL_VAR_ADDR, GT_LCL_FLD_ADDR))
if (addr->OperIs(GT_LCL_ADDR))
{
// If the local var is a gcref or byref, the local var better be untracked, because we have
// no logic here to track local variable lifetime changes, like we do in the contained case
Expand Down
Loading

0 comments on commit 730a030

Please sign in to comment.