Skip to content

Commit

Permalink
Enable TYP_STRUCT LCL_VAR/LCL_FLD call args on LA (dotnet#71327)
Browse files Browse the repository at this point in the history
* Support "PUTARG_STK/SPLIT(STRUCT LCL_VAR/LCL_FLD)" on LA

* LA: [local] morph

* Delete now-not-needed "OBJ(ADDR(LCL_VAR))" wrapping
  • Loading branch information
SingleAccretion authored Jul 2, 2022
1 parent 6b8d056 commit c9140d6
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 35 deletions.
6 changes: 3 additions & 3 deletions src/coreclr/jit/lclmorph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1068,7 +1068,7 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>
// | Partial | LCL_FLD | LCL_FLD | LCL_FLD |
// |------------|---------|---------|---------|
//
// * - On XArch/Arm64 only.
// * - On XArch/Arm64/LA only.
//
// |------------|------|------|--------|----------|
// | SIMD | CALL | ASG | RETURN | HWI/SIMD |
Expand All @@ -1086,9 +1086,9 @@ class LocalAddressVisitor final : public GenTreeVisitor<LocalAddressVisitor>

if (user->IsCall())
{
#if !defined(TARGET_XARCH) && !defined(TARGET_ARM64)
#ifdef TARGET_ARM
return IndirTransform::None;
#endif // !defined(TARGET_XARCH) && !defined(TARGET_ARM64)
#endif // TARGET_ARM
}

if (match == StructMatch::Compatible)
Expand Down
32 changes: 31 additions & 1 deletion src/coreclr/jit/lowerloongarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,37 @@ void Lowering::LowerPutArgStkOrSplit(GenTreePutArgStk* putArgNode)
// STRUCT args (FIELD_LIST / OBJ) will always be contained.
MakeSrcContained(putArgNode, src);

// Additionally, codegen supports containment of local addresses under OBJs.
// Currently, codegen does not support LCL_VAR/LCL_FLD sources, so we morph them to OBJs.
// TODO-ADDR: support the local nodes in codegen and remove this code.
if (src->OperIsLocalRead())
{
unsigned lclNum = src->AsLclVarCommon()->GetLclNum();
ClassLayout* layout = nullptr;
GenTree* lclAddr = nullptr;

if (src->OperIs(GT_LCL_VAR))
{
layout = comp->lvaGetDesc(lclNum)->GetLayout();
lclAddr = comp->gtNewLclVarAddrNode(lclNum);

comp->lvaSetVarDoNotEnregister(lclNum DEBUGARG(DoNotEnregisterReason::IsStructArg));
}
else
{
layout = src->AsLclFld()->GetLayout();
lclAddr = comp->gtNewLclFldAddrNode(lclNum, src->AsLclFld()->GetLclOffs());
}

src->ChangeOper(GT_OBJ);
src->AsObj()->SetAddr(lclAddr);
src->AsObj()->SetLayout(layout);
src->AsObj()->gtBlkOpKind = GenTreeBlk::BlkOpKindInvalid;
src->AsObj()->gtBlkOpGcUnsafe = false;

BlockRange().InsertBefore(src, lclAddr);
}

// Codegen supports containment of local addresses under OBJs.
if (src->OperIs(GT_OBJ) && src->AsObj()->Addr()->OperIs(GT_LCL_VAR_ADDR))
{
// TODO-LOONGARCH64-CQ: support containment of LCL_FLD_ADDR too.
Expand Down
37 changes: 6 additions & 31 deletions src/coreclr/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1500,14 +1500,6 @@ GenTree* CallArgs::MakeTmpArgNode(Compiler* comp, CallArg* arg)
{
// We are passing this struct by value in multiple registers and/or on stack.
argNode = comp->gtNewLclvNode(lclNum, argType);

#ifndef TARGET_XARCH
// ARM/ARM64/LoongArch64 backends do not support LCL_VARs as sources of some stack args.
// Wrap it in an "OBJ(ADDR(...))". TODO-ADDR: delete this code once all backends support
// LCL_VAR stack args.
argNode = comp->gtNewOperNode(GT_ADDR, TYP_BYREF, argNode);
argNode = comp->gtNewObjNode(varDsc->GetLayout(), argNode);
#endif // !TARGET_XARCH
}
}
else
Expand Down Expand Up @@ -3694,35 +3686,18 @@ GenTree* Compiler::fgMorphMultiregStructArg(CallArg* arg)
{
lcl = actualArg->AsLclVar();
}
if (lcl != nullptr)
if ((lcl != nullptr) && (lvaGetPromotionType(lcl->GetLclNum()) == PROMOTION_TYPE_INDEPENDENT))
{
if (lvaGetPromotionType(lcl->GetLclNum()) == PROMOTION_TYPE_INDEPENDENT)
if (argNode->OperIs(GT_LCL_VAR) ||
ClassLayout::AreCompatible(argNode->AsObj()->GetLayout(), lvaGetDesc(lcl)->GetLayout()))
{
if (argNode->OperIs(GT_LCL_VAR) ||
ClassLayout::AreCompatible(argNode->AsObj()->GetLayout(), lvaGetDesc(lcl)->GetLayout()))
{
argNode = fgMorphLclArgToFieldlist(lcl);
}
else
{
// Set DNER to block independent promotion.
lvaSetVarDoNotEnregister(lcl->GetLclNum() DEBUGARG(DoNotEnregisterReason::IsStructArg));
}
argNode = fgMorphLclArgToFieldlist(lcl);
}
#ifdef TARGET_LOONGARCH64
else if (argNode->TypeGet() == TYP_STRUCT)
else
{
// LoongArch64 backend does not support local nodes as sources of some stack args.
if (!actualArg->OperIs(GT_OBJ))
{
// Create an Obj of the temp to use it as a call argument.
argNode = gtNewOperNode(GT_ADDR, TYP_I_IMPL, argNode);
argNode = gtNewObjNode(lvaGetStruct(lcl->GetLclNum()), argNode);
}
// Its fields will need to be accessed by address.
// Set DNER to block independent promotion.
lvaSetVarDoNotEnregister(lcl->GetLclNum() DEBUGARG(DoNotEnregisterReason::IsStructArg));
}
#endif // TARGET_LOONGARCH64
}

return argNode;
Expand Down

0 comments on commit c9140d6

Please sign in to comment.