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: strengthen checking of the loop table #71184

Merged
merged 8 commits into from
Jun 28, 2022
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
26 changes: 14 additions & 12 deletions src/coreclr/jit/assertionprop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -462,12 +462,13 @@ Compiler::fgWalkResult Compiler::optAddCopiesCallback(GenTree** pTree, fgWalkDat
return WALK_CONTINUE;
}

/*****************************************************************************
*
* Add new copies before Assertion Prop.
*/

void Compiler::optAddCopies()
//------------------------------------------------------------------------------
// optAddCopies: Add new copies before Assertion Prop.
//
// Returns:
// suitable phase satus
//
PhaseStatus Compiler::optAddCopies()
{
unsigned lclNum;
LclVarDsc* varDsc;
Expand All @@ -477,19 +478,16 @@ void Compiler::optAddCopies()
{
printf("\n*************** In optAddCopies()\n\n");
}
if (verboseTrees)
{
printf("Blocks/Trees at start of phase\n");
fgDispBasicBlocks(true);
}
#endif

// Don't add any copies if we have reached the tracking limit.
if (lvaHaveManyLocals())
{
return;
return PhaseStatus::MODIFIED_NOTHING;
}

bool modified = false;

for (lclNum = 0, varDsc = lvaTable; lclNum < lvaCount; lclNum++, varDsc++)
{
var_types typ = varDsc->TypeGet();
Expand Down Expand Up @@ -893,6 +891,8 @@ void Compiler::optAddCopies()
tree->gtFlags |= (copyAsgn->gtFlags & GTF_ALL_EFFECT);
}

modified = true;

#ifdef DEBUG
if (verbose)
{
Expand All @@ -902,6 +902,8 @@ void Compiler::optAddCopies()
}
#endif
}

return modified ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
}

//------------------------------------------------------------------------------
Expand Down
12 changes: 8 additions & 4 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4840,11 +4840,14 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

if (opts.OptimizationEnabled())
{
// Introduce copies for some single-def locals to make them more
// amenable to optimization
//
DoPhase(this, PHASE_OPTIMIZE_ADD_COPIES, &Compiler::optAddCopies);

// Optimize boolean conditions
//
DoPhase(this, PHASE_OPTIMIZE_BOOLS, &Compiler::optOptimizeBools);

// optOptimizeBools() might have changed the number of blocks; the dominators/reachability might be bad.
}

// Figure out the order in which operators are to be evaluated
Expand All @@ -4854,7 +4857,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
// Weave the tree lists. Anyone who modifies the tree shapes after
// this point is responsible for calling fgSetStmtSeq() to keep the
// nodes properly linked.
// This can create GC poll calls, and create new BasicBlocks (without updating dominators/reachability).
//
DoPhase(this, PHASE_SET_BLOCK_ORDER, &Compiler::fgSetBlockOrder);

Expand Down Expand Up @@ -4983,7 +4985,9 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
#endif

// Dominator and reachability sets are no longer valid.
fgDomsComputed = false;
// The loop table is no longer valid.
fgDomsComputed = false;
optLoopTableValid = false;

// Insert GC Polls
DoPhase(this, PHASE_INSERT_GC_POLLS, &Compiler::fgInsertGCPolls);
Expand Down
49 changes: 22 additions & 27 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1415,8 +1415,10 @@ enum class PhaseChecks
// Specify compiler data that a phase might modify
enum class PhaseStatus : unsigned
{
MODIFIED_NOTHING,
MODIFIED_EVERYTHING
MODIFIED_NOTHING, // Phase did not make any changes that warrant running post-phase checks or dumping
// the main jit data strutures.
MODIFIED_EVERYTHING, // Phase made changes that warrant running post-phase checks or dumping
// the main jit data strutures.
};

// The following enum provides a simple 1:1 mapping to CLR API's
Expand Down Expand Up @@ -3245,7 +3247,7 @@ class Compiler

void lvaSortByRefCount();

void lvaMarkLocalVars(); // Local variable ref-counting
PhaseStatus lvaMarkLocalVars(); // Local variable ref-counting
void lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers);
void lvaMarkLocalVars(BasicBlock* block, bool isRecompute);

Expand Down Expand Up @@ -4713,7 +4715,7 @@ class Compiler
inline bool PreciseRefCountsRequired();

// Performs SSA conversion.
void fgSsaBuild();
PhaseStatus fgSsaBuild();

// Reset any data structures to the state expected by "fgSsaBuild", so it can be run again.
void fgResetForSsa();
Expand All @@ -4737,7 +4739,7 @@ class Compiler

// Do value numbering (assign a value number to each
// tree node).
void fgValueNumber();
PhaseStatus fgValueNumber();

void fgValueNumberLocalStore(GenTree* storeNode,
GenTreeLclVarCommon* lclDefNode,
Expand Down Expand Up @@ -5180,7 +5182,7 @@ class Compiler

bool fgCheckRemoveStmt(BasicBlock* block, Statement* stmt);

void fgCreateLoopPreHeader(unsigned lnum);
bool fgCreateLoopPreHeader(unsigned lnum);

void fgUnreachableBlock(BasicBlock* block);

Expand Down Expand Up @@ -5263,12 +5265,12 @@ class Compiler

bool fgUpdateFlowGraph(bool doTailDup = false);

void fgFindOperOrder();
PhaseStatus fgFindOperOrder();

// method that returns if you should split here
typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);

void fgSetBlockOrder();
PhaseStatus fgSetBlockOrder();

void fgRemoveReturnBlock(BasicBlock* block);

Expand Down Expand Up @@ -5917,7 +5919,7 @@ class Compiler

protected:
// Do hoisting for all loops.
void optHoistLoopCode();
PhaseStatus optHoistLoopCode();

// To represent sets of VN's that have already been hoisted in outer loops.
typedef JitHashTable<ValueNum, JitSmallPrimitiveKeyFuncs<ValueNum>, bool> VNSet;
Expand Down Expand Up @@ -5958,17 +5960,10 @@ class Compiler

// Do hoisting of all loops nested within loop "lnum" (an index into the optLoopTable), followed
// by the loop "lnum" itself.
//
// "m_pHoistedInCurLoop" helps a lot in eliminating duplicate expressions getting hoisted
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason this comment was deleted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like an inadvertent edit -- at one point I had modified the signature of optHoistLoopNest.

// and reducing the count of total expressions hoisted out of loop. When calculating the
// profitability, we compare this with number of registers and hence, lower the number of expressions
// getting hoisted, better chances that they will get enregistered and CSE considering them.
//
void optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt);
bool optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt);

// Do hoisting for a particular loop ("lnum" is an index into the optLoopTable.)
// Returns the new preheaders created.
void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt, BasicBlockList* existingPreHeaders);
bool optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt, BasicBlockList* existingPreHeaders);

// Hoist all expressions in "blocks" that are invariant in loop "loopNum" (an index into the optLoopTable)
// outside of that loop.
Expand Down Expand Up @@ -6018,7 +6013,7 @@ class Compiler
void optPerformHoistExpr(GenTree* expr, BasicBlock* exprBb, unsigned lnum);

public:
void optOptimizeBools();
PhaseStatus optOptimizeBools();

public:
PhaseStatus optInvertLoops(); // Invert loops so they're entered at top and tested at bottom.
Expand Down Expand Up @@ -6107,6 +6102,8 @@ class Compiler
int lpLoopVarFPCount; // The register count for the FP LclVars that are read/written inside this loop
int lpVarInOutFPCount; // The register count for the FP LclVars that are alive inside or across this loop

bool lpHoistAddedPreheader; // The loop preheader was added during hoisting

typedef JitHashTable<CORINFO_FIELD_HANDLE, JitPtrKeyFuncs<struct CORINFO_FIELD_STRUCT_>, FieldKindForVN>
FieldHandleSet;
FieldHandleSet* lpFieldsModified; // This has entries for all static field and object instance fields modified
Expand Down Expand Up @@ -6273,6 +6270,7 @@ class Compiler

public:
LoopDsc* optLoopTable; // loop descriptor table
bool optLoopTableValid; // info in loop table should be valid
unsigned char optLoopCount; // number of tracked loops
unsigned char loopAlignCandidates; // number of loops identified for alignment

Expand All @@ -6298,7 +6296,7 @@ class Compiler
BasicBlock* exit,
unsigned char exitCnt);

void optClearLoopIterInfo();
PhaseStatus optClearLoopIterInfo();

#ifdef DEBUG
void optPrintLoopInfo(unsigned lnum, bool printVerbose = false);
Expand Down Expand Up @@ -6909,9 +6907,9 @@ class Compiler
GenTree* optPropGetValue(unsigned lclNum, unsigned ssaNum, optPropKind valueKind);
GenTree* optEarlyPropRewriteTree(GenTree* tree, LocalNumberToNullCheckTreeMap* nullCheckMap);
bool optDoEarlyPropForBlock(BasicBlock* block);
bool optDoEarlyPropForFunc();
void optEarlyProp();
void optFoldNullCheck(GenTree* tree, LocalNumberToNullCheckTreeMap* nullCheckMap);
bool optDoEarlyPropForFunc();
PhaseStatus optEarlyProp();
bool optFoldNullCheck(GenTree* tree, LocalNumberToNullCheckTreeMap* nullCheckMap);
GenTree* optFindNullCheckToFold(GenTree* tree, LocalNumberToNullCheckTreeMap* nullCheckMap);
bool optIsNullCheckFoldingLegal(GenTree* tree,
GenTree* nullCheckTree,
Expand Down Expand Up @@ -7310,7 +7308,7 @@ class Compiler
static void optDumpAssertionIndices(const char* header, ASSERT_TP assertions, const char* footer = nullptr);
static void optDumpAssertionIndices(ASSERT_TP assertions, const char* footer = nullptr);

void optAddCopies();
PhaseStatus optAddCopies();

/**************************************************************************
* Range checks
Expand Down Expand Up @@ -7366,9 +7364,6 @@ class Compiler

bool optReachWithoutCall(BasicBlock* srcBB, BasicBlock* dstBB);

protected:
bool optLoopsMarked;

/*
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/compphases.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ CompPhaseNameMacro(PHASE_UNROLL_LOOPS, "Unroll loops",
CompPhaseNameMacro(PHASE_CLEAR_LOOP_INFO, "Clear loop info", "LP-CLEAR", false, -1, false)
CompPhaseNameMacro(PHASE_HOIST_LOOP_CODE, "Hoist loop code", "LP-HOIST", false, -1, false)
CompPhaseNameMacro(PHASE_MARK_LOCAL_VARS, "Mark local vars", "MARK-LCL", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_ADD_COPIES, "Opt add copies", "OPT-ADD-CP", false, -1, false)
CompPhaseNameMacro(PHASE_OPTIMIZE_BOOLS, "Optimize bools", "OPT-BOOL", false, -1, false)
CompPhaseNameMacro(PHASE_FIND_OPER_ORDER, "Find oper order", "OPER-ORD", false, -1, false)
CompPhaseNameMacro(PHASE_SET_BLOCK_ORDER, "Set block order", "BLK-ORD", false, -1, true)
Expand Down
Loading