Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JIT: Unify struct arg morphing #112612

Merged
merged 6 commits into from
Feb 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/coreclr/jit/codegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -1194,12 +1194,10 @@ class CodeGen final : public CodeGenInterface
void genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg);
void genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg);

#ifdef FEATURE_PUT_STRUCT_ARG_STK
void genConsumePutStructArgStk(GenTreePutArgStk* putArgStkNode,
regNumber dstReg,
regNumber srcReg,
regNumber sizeReg);
#endif // FEATURE_PUT_STRUCT_ARG_STK
#if FEATURE_ARG_SPLIT
void genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode);
#endif // FEATURE_ARG_SPLIT
Expand Down Expand Up @@ -1287,7 +1285,6 @@ class CodeGen final : public CodeGenInterface
void genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum);
#endif // !TARGET_X86

#ifdef FEATURE_PUT_STRUCT_ARG_STK
#ifdef TARGET_X86
bool genAdjustStackForPutArgStk(GenTreePutArgStk* putArgStk);
void genPushReg(var_types type, regNumber srcReg);
Expand All @@ -1309,7 +1306,6 @@ class CodeGen final : public CodeGenInterface
#else
void genStructPutArgPartialRepMovs(GenTreePutArgStk* putArgStkNode);
#endif
#endif // FEATURE_PUT_STRUCT_ARG_STK

void genCodeForStoreBlk(GenTreeBlk* storeBlkNode);
void genCodeForInitBlkLoop(GenTreeBlk* initBlkNode);
Expand Down Expand Up @@ -1403,14 +1399,12 @@ class CodeGen final : public CodeGenInterface
return compiler->lvaGetDesc(tree->AsLclVarCommon())->lvIsRegCandidate();
}

#ifdef FEATURE_PUT_STRUCT_ARG_STK
#ifdef TARGET_X86
bool m_pushStkArg;
#else // !TARGET_X86
unsigned m_stkArgVarNum;
unsigned m_stkArgOffset;
#endif // !TARGET_X86
#endif // !FEATURE_PUT_STRUCT_ARG_STK

#if defined(DEBUG) && defined(TARGET_XARCH)
void genStackPointerCheck(bool doStackPointerCheck,
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 @@ -201,7 +201,7 @@ void CodeGenInterface::CopyRegisterInfo()
CodeGen::CodeGen(Compiler* theCompiler)
: CodeGenInterface(theCompiler)
{
#if defined(FEATURE_PUT_STRUCT_ARG_STK) && !defined(TARGET_X86)
#if !defined(TARGET_X86)
m_stkArgVarNum = BAD_VAR_NUM;
#endif

Expand Down
4 changes: 1 addition & 3 deletions src/coreclr/jit/codegenlinear.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1741,7 +1741,6 @@ void CodeGen::genConsumeMultiOpOperands(GenTreeMultiOp* tree)
}
#endif // defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)

#if FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
// Also loads in the right register the addresses of the
Expand Down Expand Up @@ -1824,7 +1823,6 @@ void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
}
}
#endif // FEATURE_PUT_STRUCT_ARG_STK

#if FEATURE_ARG_SPLIT
//------------------------------------------------------------------------
Expand Down Expand Up @@ -1899,7 +1897,7 @@ void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArg
#if FEATURE_FASTTAILCALL
if (putArgStk->gtCall->IsFastTailCall())
{
areaSize = compiler->info.compArgStackSize;
areaSize = compiler->lvaParameterStackSize;
}
#endif

Expand Down
11 changes: 0 additions & 11 deletions src/coreclr/jit/codegenxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3485,7 +3485,6 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
}
}

#ifdef FEATURE_PUT_STRUCT_ARG_STK
// Generate code for a load from some address + offset
// base: tree node which can be either a local or an indir
// offset: distance from the "base" location from which to load
Expand All @@ -3502,7 +3501,6 @@ void CodeGen::genCodeForLoadOffset(instruction ins, emitAttr size, regNumber dst
GetEmitter()->emitIns_R_AR(ins, size, dst, base->AsIndir()->Addr()->GetRegNum(), offset);
}
}
#endif // FEATURE_PUT_STRUCT_ARG_STK

//----------------------------------------------------------------------------------
// genCodeForCpBlkUnroll - Generate unrolled block copy code.
Expand Down Expand Up @@ -3790,7 +3788,6 @@ void CodeGen::genCodeForCpBlkRepMovs(GenTreeBlk* cpBlkNode)
instGen(INS_r_movsb);
}

#ifdef FEATURE_PUT_STRUCT_ARG_STK
//------------------------------------------------------------------------
// CodeGen::genMove8IfNeeded: Conditionally move 8 bytes of a struct to the argument area
//
Expand Down Expand Up @@ -4219,7 +4216,6 @@ void CodeGen::genClearStackVec3ArgUpperBits()
}
}
#endif // defined(UNIX_AMD64_ABI) && defined(FEATURE_SIMD)
#endif // FEATURE_PUT_STRUCT_ARG_STK

//
// genCodeForCpObj - Generate code for CpObj nodes to copy structs that have interleaved
Expand Down Expand Up @@ -5993,13 +5989,11 @@ void CodeGen::genCall(GenTreeCall* call)

#ifdef DEBUG
assert(argSize == arg.AbiInfo.ByteSize);
#ifdef FEATURE_PUT_STRUCT_ARG_STK
if (source->TypeIs(TYP_STRUCT) && !source->OperIs(GT_FIELD_LIST))
{
unsigned loadSize = source->GetLayout(compiler)->GetSize();
assert(argSize == roundUp(loadSize, TARGET_POINTER_SIZE));
}
#endif // FEATURE_PUT_STRUCT_ARG_STK
#endif // DEBUG
}
}
Expand Down Expand Up @@ -8392,8 +8386,6 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
{
unsigned baseVarNum = getBaseVarForPutArgStk(putArgStk);

#ifdef UNIX_AMD64_ABI

if (data->OperIs(GT_FIELD_LIST))
{
genPutArgStkFieldList(putArgStk, baseVarNum);
Expand All @@ -8407,7 +8399,6 @@ void CodeGen::genPutArgStk(GenTreePutArgStk* putArgStk)
m_stkArgVarNum = BAD_VAR_NUM;
return;
}
#endif // UNIX_AMD64_ABI

noway_assert(targetType != TYP_STRUCT);

Expand Down Expand Up @@ -8509,7 +8500,6 @@ void CodeGen::genPushReg(var_types type, regNumber srcReg)
}
#endif // TARGET_X86

#if defined(FEATURE_PUT_STRUCT_ARG_STK)
// genStoreRegToStackArg: Store a register value into the stack argument area
//
// Arguments:
Expand Down Expand Up @@ -8649,7 +8639,6 @@ void CodeGen::genPutStructArgStk(GenTreePutArgStk* putArgStk)
unreached();
}
}
#endif // defined(FEATURE_PUT_STRUCT_ARG_STK)

/*****************************************************************************
*
Expand Down
5 changes: 2 additions & 3 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -6779,7 +6779,7 @@ class Compiler
#endif // FEATURE_SIMD
GenTree* fgMorphIndexAddr(GenTreeIndexAddr* tree);
GenTree* fgMorphExpandCast(GenTreeCast* tree);
GenTreeFieldList* fgMorphLclArgToFieldlist(GenTreeLclVarCommon* lcl);
GenTreeFieldList* fgMorphLclArgToFieldList(GenTreeLclVarCommon* lcl);
GenTreeCall* fgMorphArgs(GenTreeCall* call);

void fgMakeOutgoingStructArgCopy(GenTreeCall* call, CallArg* arg);
Expand Down Expand Up @@ -11802,8 +11802,7 @@ class Compiler
const CORINFO_FPSTRUCT_LOWERING* GetFpStructLowering(CORINFO_CLASS_HANDLE structHandle);
#endif // defined(UNIX_AMD64_ABI)

void fgMorphMultiregStructArgs(GenTreeCall* call);
GenTree* fgMorphMultiregStructArg(CallArg* arg);
bool fgTryMorphStructArg(CallArg* arg);

bool killGCRefs(GenTree* tree);

Expand Down
55 changes: 40 additions & 15 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,14 +261,12 @@ void GenTree::InitNodeSize()
GenTree::s_gtNodeSizes[GT_MOD] = TREE_NODE_SZ_LARGE;
GenTree::s_gtNodeSizes[GT_UMOD] = TREE_NODE_SZ_LARGE;
#endif
#ifdef FEATURE_PUT_STRUCT_ARG_STK
// TODO-Throughput: This should not need to be a large node. The object info should be
// obtained from the child node.
GenTree::s_gtNodeSizes[GT_PUTARG_STK] = TREE_NODE_SZ_LARGE;
#if FEATURE_ARG_SPLIT
GenTree::s_gtNodeSizes[GT_PUTARG_SPLIT] = TREE_NODE_SZ_LARGE;
#endif // FEATURE_ARG_SPLIT
#endif // FEATURE_PUT_STRUCT_ARG_STK

// This list of assertions should come to contain all GenTree subtypes that are declared
// "small".
Expand Down Expand Up @@ -324,16 +322,12 @@ void GenTree::InitNodeSize()
static_assert_no_msg(sizeof(GenTreeILOffset) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreePhiArg) <= TREE_NODE_SZ_SMALL);
static_assert_no_msg(sizeof(GenTreeAllocObj) <= TREE_NODE_SZ_LARGE); // *** large node
#ifndef FEATURE_PUT_STRUCT_ARG_STK
static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_SMALL);
#else // FEATURE_PUT_STRUCT_ARG_STK
// TODO-Throughput: This should not need to be a large node. The object info should be
// obtained from the child node.
static_assert_no_msg(sizeof(GenTreePutArgStk) <= TREE_NODE_SZ_LARGE);
#if FEATURE_ARG_SPLIT
static_assert_no_msg(sizeof(GenTreePutArgSplit) <= TREE_NODE_SZ_LARGE);
#endif // FEATURE_ARG_SPLIT
#endif // FEATURE_PUT_STRUCT_ARG_STK

#ifdef FEATURE_HW_INTRINSICS
static_assert_no_msg(sizeof(GenTreeHWIntrinsic) <= TREE_NODE_SZ_SMALL);
Expand Down Expand Up @@ -1147,6 +1141,27 @@ void GenTreeFieldList::InsertFieldLIR(
m_uses.InsertUse(insertAfter, new (compiler, CMK_ASTNode) Use(node, offset, type));
}

//---------------------------------------------------------------
// SoleFieldOrThis:
// If this FIELD_LIST has only one field, then return it; otherwise return
// the field list.
//
// Returns:
// Sole field, or "this".
//
GenTree* GenTreeFieldList::SoleFieldOrThis()
{
Use* head = m_uses.GetHead();
assert(head != nullptr);

if (head->GetNext() == nullptr)
{
return head->GetNode();
}

return this;
}

//---------------------------------------------------------------
// IsHfaArg: Is this arg considered a homogeneous floating-point aggregate?
//
Expand Down Expand Up @@ -2621,13 +2636,6 @@ void CallArgs::ResetFinalArgsAndABIInfo()
m_abiInformationDetermined = false;
}

#if !defined(FEATURE_PUT_STRUCT_ARG_STK)
unsigned GenTreePutArgStk::GetStackByteSize() const
{
return genTypeSize(genActualType(gtOp1->gtType));
}
#endif // !defined(FEATURE_PUT_STRUCT_ARG_STK)

/*****************************************************************************
*
* Returns non-zero if the two trees are identical.
Expand Down Expand Up @@ -3048,6 +3056,25 @@ bool GenTree::Compare(GenTree* op1, GenTree* op2, bool swapOK)
return false;
}

//------------------------------------------------------------------------
// EffectiveUse: Return the use pointer to the "effective val".
//
// Arguments:
// use - Use edge
//
// Return Value:
// Edge pointing to non-comma node.
//
GenTree** GenTree::EffectiveUse(GenTree** use)
{
while ((*use)->OperIs(GT_COMMA))
{
use = &(*use)->AsOp()->gtOp2;
}

return use;
}

//------------------------------------------------------------------------
// gtHasRef: Find out whether the given tree contains a local.
//
Expand Down Expand Up @@ -12733,7 +12760,6 @@ void Compiler::gtDispTree(GenTree* tree,
}
}
}
#if FEATURE_PUT_STRUCT_ARG_STK
else if (tree->OperGet() == GT_PUTARG_STK)
{
const GenTreePutArgStk* putArg = tree->AsPutArgStk();
Expand Down Expand Up @@ -12766,7 +12792,6 @@ void Compiler::gtDispTree(GenTree* tree,
printf(" (%d stackByteSize), (%d numRegs)", putArg->GetStackByteSize(), putArg->gtNumRegs);
}
#endif // FEATURE_ARG_SPLIT
#endif // FEATURE_PUT_STRUCT_ARG_STK

if (tree->OperIs(GT_FIELD_ADDR))
{
Expand Down
Loading
Loading