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

Extract fgMorph(Init/Copy)Block into their own classes. #53983

Merged
merged 3 commits into from
Jun 26, 2021
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
1 change: 1 addition & 0 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ set( JIT_SOURCES
lsra.cpp
lsrabuild.cpp
morph.cpp
morphblock.cpp
objectalloc.cpp
optcse.cpp
optimizer.cpp
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4684,7 +4684,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// local variable allocation on the stack.
ObjectAllocator objectAllocator(this); // PHASE_ALLOCATE_OBJECTS

if (JitConfig.JitObjectStackAllocation() && opts.OptimizationEnabled())
if (compObjectStackAllocation() && opts.OptimizationEnabled())
{
objectAllocator.EnableObjectStackAllocation();
}
Expand Down
14 changes: 10 additions & 4 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2333,6 +2333,8 @@ class Compiler
friend class ObjectAllocator;
friend class LocalAddressVisitor;
friend struct GenTree;
friend class MorphInitBlockHelper;
friend class MorphCopyBlockHelper;

#ifdef FEATURE_HW_INTRINSICS
friend struct HWIntrinsicInfo;
Expand Down Expand Up @@ -2850,8 +2852,8 @@ class Compiler
GenTree* ctxTree,
void* compileTimeHandle);

GenTree* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));
GenTree* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));
GenTreeLclVar* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));
GenTreeLclVar* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));

GenTreeLclVar* gtNewLclVarAddrNode(unsigned lclNum, var_types type = TYP_I_IMPL);
GenTreeLclFld* gtNewLclFldAddrNode(unsigned lclNum,
Expand Down Expand Up @@ -6017,8 +6019,7 @@ class Compiler
GenTree* fgMorphInitBlock(GenTree* tree);
GenTree* fgMorphPromoteLocalInitBlock(GenTreeLclVar* destLclNode, GenTree* initVal, unsigned blockSize);
GenTree* fgMorphGetStructAddr(GenTree** pTree, CORINFO_CLASS_HANDLE clsHnd, bool isRValue = false);
GenTree* fgMorphBlkNode(GenTree* tree, bool isDest);
GenTree* fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigned blockWidth, bool isDest);
GenTree* fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigned blockWidth, bool isBlkReqd);
GenTree* fgMorphCopyBlock(GenTree* tree);
GenTree* fgMorphForRegisterFP(GenTree* tree);
GenTree* fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac = nullptr);
Expand Down Expand Up @@ -9782,6 +9783,11 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
return (JitConfig.JitEnregStructLocals() != 0);
}

bool compObjectStackAllocation()
{
return (JitConfig.JitObjectStackAllocation() != 0);
}

// Returns true if the method returns a value in more than one return register,
// it should replace/be merged with compMethodReturnsMultiRegRetType when #36868 is fixed.
// The difference from original `compMethodReturnsMultiRegRetType` is in ARM64 SIMD* handling,
Expand Down
6 changes: 6 additions & 0 deletions src/coreclr/jit/fgdiagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2992,6 +2992,12 @@ void Compiler::fgDebugCheckFlags(GenTree* tree)
}
break;

case GT_ASG:
{
// Can't CSE dst.
assert((tree->gtGetOp1()->gtFlags & GTF_DONT_CSE) != 0);
break;
}
default:
break;
}
Expand Down
52 changes: 41 additions & 11 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6494,7 +6494,7 @@ GenTreeCall* Compiler::gtNewCallNode(
return node;
}

GenTree* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs))
GenTreeLclVar* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs))
{
assert(type != TYP_VOID);
// We need to ensure that all struct values are normalized.
Expand All @@ -6514,7 +6514,7 @@ GenTree* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSE
assert((type == varDsc->lvType) || simd12ToSimd16Widening ||
(lvaIsImplicitByRefLocal(lnum) && fgGlobalMorph && (varDsc->lvType == TYP_BYREF)));
}
GenTree* node = new (this, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, type, lnum DEBUGARG(ILoffs));
GenTreeLclVar* node = new (this, GT_LCL_VAR) GenTreeLclVar(GT_LCL_VAR, type, lnum DEBUGARG(ILoffs));

/* Cannot have this assert because the inliner uses this function
* to add temporaries */
Expand All @@ -6524,7 +6524,7 @@ GenTree* Compiler::gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSE
return node;
}

GenTree* Compiler::gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs))
GenTreeLclVar* Compiler::gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs))
{
// We need to ensure that all struct values are normalized.
// It might be nice to assert this in general, but we have assignments of int to long.
Expand All @@ -6538,7 +6538,7 @@ GenTree* Compiler::gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSE
}
// This local variable node may later get transformed into a large node
assert(GenTree::s_gtNodeSizes[LargeOpOpcode()] > GenTree::s_gtNodeSizes[GT_LCL_VAR]);
GenTree* node =
GenTreeLclVar* node =
new (this, LargeOpOpcode()) GenTreeLclVar(GT_LCL_VAR, type, lnum DEBUGARG(ILoffs) DEBUGARG(/*largeNode*/ true));
return node;
}
Expand Down Expand Up @@ -16611,7 +16611,27 @@ GenTreeLclVarCommon* GenTree::IsLocalAddrExpr()
return nullptr;
}

bool GenTree::IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, FieldSeqNode** pFldSeq)
//------------------------------------------------------------------------
// IsLocalAddrExpr: finds if "this" is an address of a local var/fld.
//
// Arguments:
// comp - a compiler instance;
// pLclVarTree - [out] sets to the node indicating the local variable if found;
// pFldSeq - [out] sets to the field sequence representing the field, else null;
// pOffset - [out](optional) sets to the sum offset of the lcl/fld if found,
// note it does not include pLclVarTree->GetLclOffs().
//
// Returns:
// Returns true if "this" represents the address of a local, or a field of a local.
//
// Notes:
// It is mostly used for optimizations but assertion propogation depends on it for correctness.
// So if this function does not recognize a def of a LCL_VAR we can have an incorrect optimization.
//
bool GenTree::IsLocalAddrExpr(Compiler* comp,
GenTreeLclVarCommon** pLclVarTree,
FieldSeqNode** pFldSeq,
ssize_t* pOffset /* = nullptr */)
{
if (OperGet() == GT_ADDR)
{
Expand Down Expand Up @@ -16645,23 +16665,33 @@ bool GenTree::IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree,
{
if (AsOp()->gtOp1->OperGet() == GT_CNS_INT)
{
if (AsOp()->gtOp1->AsIntCon()->gtFieldSeq == nullptr)
GenTreeIntCon* cnst = AsOp()->gtOp1->AsIntCon();
if (cnst->gtFieldSeq == nullptr)
{
return false;
}
// Otherwise, prepend this field to whatever we've already accumulated outside in.
*pFldSeq = comp->GetFieldSeqStore()->Append(AsOp()->gtOp1->AsIntCon()->gtFieldSeq, *pFldSeq);
return AsOp()->gtOp2->IsLocalAddrExpr(comp, pLclVarTree, pFldSeq);
*pFldSeq = comp->GetFieldSeqStore()->Append(cnst->gtFieldSeq, *pFldSeq);
if (pOffset != nullptr)
{
*pOffset += cnst->IconValue();
}
return AsOp()->gtOp2->IsLocalAddrExpr(comp, pLclVarTree, pFldSeq, pOffset);
}
else if (AsOp()->gtOp2->OperGet() == GT_CNS_INT)
{
if (AsOp()->gtOp2->AsIntCon()->gtFieldSeq == nullptr)
GenTreeIntCon* cnst = AsOp()->gtOp2->AsIntCon();
if (cnst->gtFieldSeq == nullptr)
{
return false;
}
// Otherwise, prepend this field to whatever we've already accumulated outside in.
*pFldSeq = comp->GetFieldSeqStore()->Append(AsOp()->gtOp2->AsIntCon()->gtFieldSeq, *pFldSeq);
return AsOp()->gtOp1->IsLocalAddrExpr(comp, pLclVarTree, pFldSeq);
*pFldSeq = comp->GetFieldSeqStore()->Append(cnst->gtFieldSeq, *pFldSeq);
if (pOffset != nullptr)
{
*pOffset += cnst->IconValue();
}
return AsOp()->gtOp1->IsLocalAddrExpr(comp, pLclVarTree, pFldSeq, pOffset);
}
}
// Otherwise...
Expand Down
8 changes: 4 additions & 4 deletions src/coreclr/jit/gentree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1982,10 +1982,10 @@ struct GenTree
// variable, or just a portion of it.
bool DefinesLocal(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire = nullptr);

// Returns true if "this" represents the address of a local, or a field of a local. If returns true, sets
// "*pLclVarTree" to the node indicating the local variable. If the address is that of a field of this node,
// sets "*pFldSeq" to the field sequence representing that field, else null.
bool IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, FieldSeqNode** pFldSeq);
bool IsLocalAddrExpr(Compiler* comp,
GenTreeLclVarCommon** pLclVarTree,
FieldSeqNode** pFldSeq,
ssize_t* pOffset = nullptr);

// Simpler variant of the above which just returns the local node if this is an expression that
// yields an address into a local
Expand Down
Loading