-
Notifications
You must be signed in to change notification settings - Fork 5.4k
JIT: Don't compact away block in cond-to-return folding #113931
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 |
|---|---|---|
|
|
@@ -1698,18 +1698,19 @@ bool Compiler::fgFoldCondToReturnBlock(BasicBlock* block) | |
| } | ||
|
|
||
| // Both edges must be BBJ_RETURN | ||
| BasicBlock* retFalseBb = block->GetFalseTarget(); | ||
| BasicBlock* retTrueBb = block->GetTrueTarget(); | ||
| BasicBlock* const retFalseBb = block->GetFalseTarget(); | ||
| BasicBlock* const retTrueBb = block->GetTrueTarget(); | ||
|
|
||
| // Although, we might want to fold fallthrough BBJ_ALWAYS blocks first | ||
| if (fgCanCompactBlock(retTrueBb)) | ||
| // We might want to compact BBJ_ALWAYS blocks first, | ||
| // but don't compact the conditional block away in the process | ||
| if (fgCanCompactBlock(retTrueBb) && !retTrueBb->TargetIs(block)) | ||
| { | ||
| fgCompactBlock(retTrueBb); | ||
| modified = true; | ||
| } | ||
| // By the time we get to the retFalseBb, it might be removed by fgCompactBlock() | ||
| // so we need to check if it is still valid. | ||
| if (!retFalseBb->HasFlag(BBF_REMOVED) && fgCanCompactBlock(retFalseBb)) | ||
| if (!retFalseBb->HasFlag(BBF_REMOVED) && fgCanCompactBlock(retFalseBb) && !retFalseBb->TargetIs(block)) | ||
| { | ||
| fgCompactBlock(retFalseBb); | ||
| modified = true; | ||
|
|
@@ -1720,8 +1721,8 @@ bool Compiler::fgFoldCondToReturnBlock(BasicBlock* block) | |
| return modified; | ||
| } | ||
|
|
||
| retTrueBb = block->GetTrueTarget(); | ||
| retFalseBb = block->GetFalseTarget(); | ||
| assert(block->TrueTargetIs(retTrueBb)); | ||
|
Member
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. there is
Contributor
Author
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 don't think we can remove this: Suppose the true target jumps to the false target, and we compact the false target into the true target. This will make the conditional block degenerate, since it now branches to the same target in either case. |
||
| assert(block->FalseTargetIs(retFalseBb)); | ||
| if (!retTrueBb->KindIs(BBJ_RETURN) || !retFalseBb->KindIs(BBJ_RETURN) || | ||
| !BasicBlock::sameEHRegion(block, retTrueBb) || !BasicBlock::sameEHRegion(block, retFalseBb) || | ||
| (retTrueBb == genReturnBB) || (retFalseBb == genReturnBB)) | ||
|
|
||
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.
presumably you also don't need
!retFalseBb->HasFlag(BBF_REMOVED)checkThere 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.
I think we still need this too in the case of the diamond shape: If the true target jumps to the false target and we compact them,
retFalseBbwill be removed from the flowgraph. This check currently defends against this case.