Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.6k
JIT: Add a primitive to split statements at a specified tree#83005
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
3ddd7c362909891a366772615537b5038ba5a9aa91776b40311660610c70dcb2a8644f7e6575e57e875c7940227c1dcff1c8402e507cb53aba9d3517a7a683f052a51dc6e220ca9de34ef4943bFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1776,6 +1776,7 @@ void Compiler::compInit(ArenaAllocator* pAlloc, | ||
| // set this early so we can use it without relying on random memory values | ||
| verbose = compIsForInlining() ? impInlineInfo->InlinerCompiler->verbose : false; | ||
| compNumStatementLinksTraversed = 0; | ||
| compPoisoningAnyImplicitByrefs = false; | ||
| #endif | ||
| @@ -4995,6 +4996,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl | ||
| fgDomsComputed = false; | ||
| optLoopTableValid = false; | ||
| #ifdef DEBUG | ||
| DoPhase(this, PHASE_STRESS_SPLIT_TREE, &Compiler::StressSplitTree); | ||
| #endif | ||
| // Insert GC Polls | ||
| DoPhase(this, PHASE_INSERT_GC_POLLS, &Compiler::fgInsertGCPolls); | ||
| @@ -5336,6 +5341,163 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | ||
| } | ||
| #endif | ||
| //------------------------------------------------------------------------ | ||
| // StressSplitTree: A phase that stresses the gtSplitTree function. | ||
| // | ||
| // Returns: | ||
| // Suitable phase status | ||
| // | ||
| // Notes: | ||
| // Stress is applied on a function-by-function basis | ||
| // | ||
| PhaseStatus Compiler::StressSplitTree() | ||
| { | ||
| if (compStressCompile(STRESS_SPLIT_TREES_RANDOMLY, 10)) | ||
| { | ||
| SplitTreesRandomly(); | ||
| return PhaseStatus::MODIFIED_EVERYTHING; | ||
| } | ||
| if (compStressCompile(STRESS_SPLIT_TREES_REMOVE_COMMAS, 10)) | ||
| { | ||
| SplitTreesRemoveCommas(); | ||
| return PhaseStatus::MODIFIED_EVERYTHING; | ||
| } | ||
| return PhaseStatus::MODIFIED_NOTHING; | ||
| } | ||
| //------------------------------------------------------------------------ | ||
| // SplitTreesRandomly: Split all statements at a random location. | ||
| // | ||
| void Compiler::SplitTreesRandomly() | ||
| { | ||
| #ifdef DEBUG | ||
| CLRRandom rng; | ||
| rng.Init(info.compMethodHash() ^ 0x077cc4d4); | ||
| for (BasicBlock* block : Blocks()) | ||
| { | ||
| for (Statement* stmt : block->NonPhiStatements()) | ||
| { | ||
| int numTrees = 0; | ||
| for (GenTree* tree : stmt->TreeList()) | ||
| { | ||
| if (tree->OperIs(GT_JTRUE)) // Due to relop invariant | ||
| { | ||
| continue; | ||
| } | ||
| numTrees++; | ||
| } | ||
| int splitTree = rng.Next(numTrees); | ||
| for (GenTree* tree : stmt->TreeList()) | ||
| { | ||
| if (tree->OperIs(GT_JTRUE)) | ||
| continue; | ||
| if (splitTree == 0) | ||
| { | ||
| JITDUMP("Splitting " FMT_STMT " at [%06u]\n", stmt->GetID(), dspTreeID(tree)); | ||
| Statement* newStmt; | ||
| GenTree** use; | ||
| if (gtSplitTree(block, stmt, tree, &newStmt, &use)) | ||
| { | ||
| while ((newStmt != nullptr) && (newStmt != stmt)) | ||
| { | ||
| fgMorphStmtBlockOps(block, newStmt); | ||
| newStmt = newStmt->GetNextStmt(); | ||
| } | ||
| fgMorphStmtBlockOps(block, stmt); | ||
| gtUpdateStmtSideEffects(stmt); | ||
| } | ||
Comment on lines
+5405
to
+5415
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @EgorBo Your PR will need to do something similar like this, but note that calling | ||
| break; | ||
| } | ||
| splitTree--; | ||
| } | ||
| } | ||
| } | ||
jakobbotsch marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| #endif | ||
| } | ||
| //------------------------------------------------------------------------ | ||
| // SplitTreesRemoveCommas: Split trees to remove all commas. | ||
| // | ||
| void Compiler::SplitTreesRemoveCommas() | ||
| { | ||
| for (BasicBlock* block : Blocks()) | ||
| { | ||
| Statement* stmt = block->FirstNonPhiDef(); | ||
| while (stmt != nullptr) | ||
| { | ||
| Statement* nextStmt = stmt->GetNextStmt(); | ||
| for (GenTree* tree : stmt->TreeList()) | ||
| { | ||
| if (!tree->OperIs(GT_COMMA)) | ||
| { | ||
| continue; | ||
| } | ||
| // Supporting this weird construct would require additional | ||
| // handling, we need to sort of move the comma into to the | ||
| // next node in execution order. We don't see this so just | ||
| // skip it. | ||
| assert(!tree->IsReverseOp()); | ||
| JITDUMP("Removing COMMA [%06u]\n", dspTreeID(tree)); | ||
| Statement* newStmt; | ||
| GenTree** use; | ||
| gtSplitTree(block, stmt, tree, &newStmt, &use); | ||
| GenTree* op1SideEffects = nullptr; | ||
| gtExtractSideEffList(tree->gtGetOp1(), &op1SideEffects); | ||
| if (op1SideEffects != nullptr) | ||
| { | ||
| Statement* op1Stmt = fgNewStmtFromTree(op1SideEffects); | ||
| fgInsertStmtBefore(block, stmt, op1Stmt); | ||
| if (newStmt == nullptr) | ||
| { | ||
| newStmt = op1Stmt; | ||
| } | ||
| } | ||
| *use = tree->gtGetOp2(); | ||
| for (Statement* cur = newStmt; (cur != nullptr) && (cur != stmt); cur = cur->GetNextStmt()) | ||
| { | ||
| fgMorphStmtBlockOps(block, cur); | ||
| } | ||
| fgMorphStmtBlockOps(block, stmt); | ||
| gtUpdateStmtSideEffects(stmt); | ||
| // Morphing block ops can introduce commas (and the original | ||
| // statement can also have more commas left). Proceed from the | ||
| // earliest newly introduced statement. | ||
| nextStmt = newStmt != nullptr ? newStmt : stmt; | ||
| break; | ||
| } | ||
| stmt = nextStmt; | ||
| } | ||
| } | ||
| for (BasicBlock* block : Blocks()) | ||
| { | ||
| for (Statement* stmt : block->NonPhiStatements()) | ||
| { | ||
| for (GenTree* tree : stmt->TreeList()) | ||
| { | ||
| assert(!tree->OperIs(GT_COMMA)); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| //------------------------------------------------------------------------ | ||
| // generatePatchpointInfo: allocate and fill in patchpoint info data, | ||
| // and report it to the VM | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -18,7 +18,7 @@ bool Compiler::fgBlockContainsStatementBounded(BasicBlock* block, | ||
| Statement* stmt, | ||
| bool answerOnBoundExceeded /*= true*/) | ||
| { | ||
| const __int64 maxLinks = 1000000000; | ||
| const __int64 maxLinks = 100000000; | ||
MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought this limit was a bit on the high side before. | ||
| __int64* numTraversed = &JitTls::GetCompiler()->compNumStatementLinksTraversed; | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.