Skip to content

Commit

Permalink
Move assignment rationalization to before the late helper expansion p…
Browse files Browse the repository at this point in the history
…hases (#85585)

* Flags dump for STOREIND

* gtNewAssignNode assert

* Call morphing

* GenTree::GetLayout fixup

* If Conversion

* Tail duplication

* Costing

* Move assignment rationalization before GC Poll insertion

* Block morphing (part 1)

* Block morphing: switch dst<->src around

* Finish block morphing

* Helper expansion phases

* Fix formatting
  • Loading branch information
SingleAccretion authored May 2, 2023
1 parent 4ead807 commit 53b4cd0
Show file tree
Hide file tree
Showing 13 changed files with 945 additions and 675 deletions.
4 changes: 2 additions & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5031,6 +5031,8 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
optLoopTableValid = false;
optLoopsRequirePreHeaders = false;

DoPhase(this, PHASE_RATIONALIZE_ASSIGNMENTS, &Compiler::fgRationalizeAssignments);

#ifdef DEBUG
DoPhase(this, PHASE_STRESS_SPLIT_TREE, &Compiler::StressSplitTree);
#endif
Expand Down Expand Up @@ -5069,8 +5071,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_DETERMINE_FIRST_COLD_BLOCK, &Compiler::fgDetermineFirstColdBlock);

DoPhase(this, PHASE_RATIONALIZE_ASSIGNMENTS, &Compiler::fgRationalizeAssignments);

#ifdef DEBUG
// Stash the current estimate of the function's size if necessary.
if (verbose)
Expand Down
18 changes: 18 additions & 0 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2536,6 +2536,7 @@ class Compiler
void* compileTimeHandle);

GenTreeLclVar* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET));
GenTreeLclVar* gtNewLclVarNode(unsigned lclNum, var_types type = TYP_UNDEF);
GenTreeLclVar* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSET offs = BAD_IL_OFFSET));

GenTreeLclFld* gtNewLclVarAddrNode(unsigned lclNum, var_types type = TYP_I_IMPL);
Expand Down Expand Up @@ -2838,6 +2839,12 @@ class Compiler

GenTreeIndir* gtNewIndir(var_types typ, GenTree* addr, GenTreeFlags indirFlags = GTF_EMPTY);

GenTreeBlk* gtNewStoreBlkNode(
ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY);

GenTreeStoreInd* gtNewStoreIndNode(
var_types type, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY);

GenTree* gtNewLoadValueNode(
var_types type, ClassLayout* layout, GenTree* addr, GenTreeFlags indirFlags = GTF_EMPTY);

Expand All @@ -2851,6 +2858,14 @@ class Compiler
return gtNewLoadValueNode(type, nullptr, addr, indirFlags);
}

GenTree* gtNewStoreValueNode(
var_types type, ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY);

GenTree* gtNewStoreValueNode(ClassLayout* layout, GenTree* addr, GenTree* data, GenTreeFlags indirFlags = GTF_EMPTY)
{
return gtNewStoreValueNode(layout->GetType(), layout, addr, data, indirFlags);
}

GenTree* gtNewNullCheck(GenTree* addr, BasicBlock* basicBlock);

var_types gtTypeForNullCheck(GenTree* tree);
Expand Down Expand Up @@ -2962,6 +2977,9 @@ class Compiler

void gtPrepareCost(GenTree* tree);
bool gtIsLikelyRegVar(GenTree* tree);
void gtGetLclVarNodeCost(GenTreeLclVar* node, int* pCostEx, int* pCostSz, bool isLikelyRegVar);
void gtGetLclFldNodeCost(GenTreeLclFld* node, int* pCostEx, int* pCostSz);
bool gtGetIndNodeCost(GenTreeIndir* node, int* pCostEx, int* pCostSz);

// Returns true iff the secondNode can be swapped with firstNode.
bool gtCanSwapOrder(GenTree* firstNode, GenTree* secondNode);
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1230,6 +1230,7 @@ inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
break;
#endif
case GT_LCL_FLD:
case GT_STORE_LCL_FLD:
AsLclFld()->SetLclOffs(0);
AsLclFld()->SetLayout(nullptr);
break;
Expand Down
6 changes: 2 additions & 4 deletions src/coreclr/jit/decomposelongs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -514,10 +514,8 @@ GenTree* DecomposeLongs::DecomposeStoreLclFld(LIR::Use& use)
loStore->gtFlags |= GTF_VAR_USEASG;

// Create the store for the upper half of the GT_LONG and insert it after the low store.
GenTreeLclFld* hiStore = m_compiler->gtNewLclFldNode(loStore->GetLclNum(), TYP_INT, loStore->GetLclOffs() + 4);
hiStore->SetOper(GT_STORE_LCL_FLD);
hiStore->gtOp1 = value->gtOp2;
hiStore->gtFlags |= (GTF_VAR_DEF | GTF_VAR_USEASG);
GenTreeLclFld* hiStore =
m_compiler->gtNewStoreLclFldNode(loStore->GetLclNum(), TYP_INT, loStore->GetLclOffs() + 4, value->gtOp2);

Range().InsertAfter(loStore, hiStore);

Expand Down
41 changes: 12 additions & 29 deletions src/coreclr/jit/fgopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3445,24 +3445,14 @@ bool Compiler::fgBlockEndFavorsTailDuplication(BasicBlock* block, unsigned lclNu
while (count < limit)
{
count++;
unsigned storeLclNum;
GenTree* const tree = stmt->GetRootNode();
if (tree->OperIs(GT_ASG) && !tree->OperIsBlkOp())
if (tree->OperIsStoreLcl(&storeLclNum) && (storeLclNum == lclNum) && !tree->OperIsBlkOp())
{
GenTree* const op1 = tree->AsOp()->gtOp1;

if (op1->IsLocal())
GenTree* const data = tree->Data();
if (data->OperIsArrLength() || data->OperIsConst() || data->OperIsCompare())
{
const unsigned op1LclNum = op1->AsLclVarCommon()->GetLclNum();

if (op1LclNum == lclNum)
{
GenTree* const op2 = tree->AsOp()->gtOp2;

if (op2->OperIsArrLength() || op2->OperIsConst() || op2->OperIsCompare())
{
return true;
}
}
return true;
}
}

Expand Down Expand Up @@ -3616,36 +3606,29 @@ bool Compiler::fgBlockIsGoodTailDuplicationCandidate(BasicBlock* target, unsigne
// Otherwise check the first stmt.
// Verify the branch is just a simple local compare.
//
unsigned storeLclNum;
GenTree* const firstTree = firstStmt->GetRootNode();

if (firstTree->gtOper != GT_ASG)
{
return false;
}

GenTree* const lhs = firstTree->AsOp()->gtOp1;
if (!lhs->OperIs(GT_LCL_VAR))
if (!firstTree->OperIsStoreLclVar(&storeLclNum))
{
return false;
}

const unsigned lhsLcl = lhs->AsLclVarCommon()->GetLclNum();
if (lhsLcl != *lclNum)
if (storeLclNum != *lclNum)
{
return false;
}

// Could allow unary here too...
//
GenTree* const rhs = firstTree->AsOp()->gtOp2;
if (!rhs->OperIsBinary())
GenTree* const data = firstTree->Data();
if (!data->OperIsBinary())
{
return false;
}

// op1 must be some combinations of casts of local or constant
// (or unary)
op1 = rhs->AsOp()->gtOp1;
op1 = data->AsOp()->gtOp1;
while (op1->gtOper == GT_CAST)
{
op1 = op1->AsOp()->gtOp1;
Expand All @@ -3658,7 +3641,7 @@ bool Compiler::fgBlockIsGoodTailDuplicationCandidate(BasicBlock* target, unsigne

// op2 must be some combinations of casts of local or constant
// (or unary)
op2 = rhs->AsOp()->gtOp2;
op2 = data->AsOp()->gtOp2;

// A binop may not actually have an op2.
//
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/flowgraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2979,6 +2979,7 @@ GenTree* Compiler::fgRationalizeAssignment(GenTreeOp* assignment)
{
store->SetReverseOp();
}
store->CopyRawCosts(assignment);

if (storeOp == GT_STOREIND)
{
Expand Down
Loading

0 comments on commit 53b4cd0

Please sign in to comment.