-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Check if loop body occured before loopTop and if so unmark alignment #91854
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5276,6 +5276,13 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | |
weight_t minBlockSoFar = BB_MAX_WEIGHT; | ||
BasicBlock* bbHavingAlign = nullptr; | ||
BasicBlock::loopNumber currentAlignedLoopNum = BasicBlock::NOT_IN_LOOP; | ||
bool visitedLoopNum[BasicBlock::MAX_LOOP_NUM]; | ||
memset(visitedLoopNum, false, sizeof(visitedLoopNum)); | ||
|
||
#ifdef DEBUG | ||
int visitedBlockForLoopNum[BasicBlock::MAX_LOOP_NUM]; | ||
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. block nums can't be negative; use |
||
memset(visitedBlockForLoopNum, false, sizeof(visitedBlockForLoopNum)); | ||
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. It's weird to use |
||
#endif | ||
|
||
if ((fgFirstBB != nullptr) && fgFirstBB->isLoopAlign()) | ||
{ | ||
|
@@ -5298,7 +5305,7 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | |
} | ||
} | ||
|
||
// If there is a unconditional jump (which is not part of callf/always pair) | ||
// If there is an unconditional jump (which is not part of callf/always pair) | ||
if (opts.compJitHideAlignBehindJmp && (block->bbJumpKind == BBJ_ALWAYS) && !block->isBBCallAlwaysPairTail()) | ||
{ | ||
// Track the lower weight blocks | ||
|
@@ -5352,12 +5359,19 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | |
madeChanges = true; | ||
unmarkedLoopAlign = true; | ||
} | ||
else if ((block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) && (block->bbNatLoopNum == loopTop->bbNatLoopNum)) | ||
else if (visitedLoopNum[loopTop->bbNatLoopNum]) | ||
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. Don't you need to check that 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. Not really. 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. Oh, sorry, I meant, don't you need to check It appears that sometimes it does equal NOT_IN_LOOP, leading to reading beyond the array bounds. |
||
{ | ||
#ifdef DEBUG | ||
char buffer[50]; | ||
sprintf_s(buffer, 50, "loop block " FMT_BB " appears before top of loop", | ||
visitedBlockForLoopNum[loopTop->bbNatLoopNum]); | ||
#endif | ||
|
||
// In some odd cases we may see blocks within the loop before we see the | ||
// top block of the loop. Just bail on aligning such loops. | ||
// | ||
loopTop->unmarkLoopAlign(this DEBUG_ARG("loop block appears before top of loop")); | ||
|
||
loopTop->unmarkLoopAlign(this DEBUG_ARG(buffer)); | ||
madeChanges = true; | ||
unmarkedLoopAlign = true; | ||
} | ||
|
@@ -5392,6 +5406,20 @@ PhaseStatus Compiler::placeLoopAlignInstructions() | |
break; | ||
} | ||
} | ||
|
||
if (block->bbNatLoopNum != BasicBlock::NOT_IN_LOOP) | ||
{ | ||
#ifdef DEBUG | ||
if (!visitedLoopNum[block->bbNatLoopNum]) | ||
{ | ||
// Record the first block for which bbNatLoopNum was seen for | ||
// debugging purpose. | ||
visitedBlockForLoopNum[block->bbNatLoopNum] = block->bbNum; | ||
} | ||
#endif | ||
// If this block is part of loop, mark the loopNum as visited. | ||
visitedLoopNum[block->bbNatLoopNum] = true; | ||
} | ||
} | ||
|
||
assert(loopsToProcess == 0); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's weird to use
memset
to zero abool
array, but ok.