-
Notifications
You must be signed in to change notification settings - Fork 5.8k
8334571: Extract control dependency rewiring out of PhaseIdealLoop::dominated_by() into separate method #19806
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
Conversation
…ominated_by() into separate method
👋 Welcome back chagedorn! A progress list of the required criteria for merging this PR into |
@chhagedorn This change now passes all automated pre-integration checks. ℹ️ This project also has non-automated pre-integration requirements. Please see the file CONTRIBUTING.md for details. After integration, the commit message for the final commit will be:
You can use pull request commands such as /summary, /contributor and /issue to adjust it as needed. At the time when this comment was updated there had been 45 new commits pushed to the
As there are no conflicts, your changes will automatically be rebased on top of these commits when integrating. If you prefer to avoid this automatic rebasing, please check the documentation for the /integrate command for further details. ➡️ To integrate this PR with the above commit message to the |
@chhagedorn The following label will be automatically applied to this pull request:
When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command. |
// Eliminate the old If in the loop body. | ||
dominated_by(hoisted_check_predicate_proj, iff, negated); | ||
|
||
C->print_method(PHASE_AFTER_LOOP_PREDICATION_IC, 4, hoisted_check_predicate_proj->in(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.
Additional benefit: This now dumps the graph after eliminating the hoisted check out of the loop. Same for the range checks.
for (DUIterator_Fast imax, i = source->fast_outs(imax); i < imax; i++) { | ||
Node* out = source->fast_out(i); // Control-dependent node | ||
// Do not rewire Div and Mod nodes which could have a zero divisor to avoid skipping their zero check. | ||
if (cd->depends_only_on_test() && _igvn.no_dependent_zero_check(cd)) { | ||
assert(cd->in(0) == dp, ""); | ||
_igvn.replace_input_of(cd, 0, prevdom); | ||
if (out->depends_only_on_test() && _igvn.no_dependent_zero_check(out)) { | ||
assert(out->in(0) == source, "must be control dependent on source"); | ||
_igvn.replace_input_of(out, 0, dominator); | ||
if (pin_array_access_nodes) { | ||
// Because of Loop Predication, Loads and range check Cast nodes that are control dependent on this range | ||
// check (that is about to be removed) now depend on multiple dominating Hoisted Check Predicates. After the | ||
// removal of this range check, these control dependent nodes end up at the lowest/nearest dominating predicate | ||
// in the graph. To ensure that these Loads/Casts do not float above any of the dominating checks (even when the | ||
// lowest dominating check is later replaced by yet another dominating check), we need to pin them at the lowest | ||
// dominating check. | ||
Node* clone = cd->pin_array_access_node(); | ||
Node* clone = out->pin_array_access_node(); | ||
if (clone != nullptr) { | ||
clone = _igvn.register_new_node_with_optimizer(clone, cd); | ||
_igvn.replace_node(cd, clone); | ||
cd = clone; | ||
clone = _igvn.register_new_node_with_optimizer(clone, out); | ||
_igvn.replace_node(out, clone); | ||
out = clone; | ||
} | ||
} | ||
set_early_ctrl(cd, false); | ||
IdealLoopTree* new_loop = get_loop(get_ctrl(cd)); | ||
set_early_ctrl(out, false); | ||
IdealLoopTree* new_loop = get_loop(get_ctrl(out)); | ||
if (old_loop != new_loop) { | ||
if (!old_loop->_child) { | ||
old_loop->_body.yank(cd); | ||
old_loop->_body.yank(out); | ||
} | ||
if (!new_loop->_child) { | ||
new_loop->_body.push(cd); | ||
new_loop->_body.push(out); |
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.
Renaming only and adding assertion message
void PhaseIdealLoop::eliminate_hoisted_range_check(IfTrueNode* hoisted_check_proj, | ||
IfTrueNode* template_assertion_predicate_proj) { | ||
_igvn.replace_input_of(hoisted_check_proj->in(0), 1, _igvn.intcon(1)); | ||
rewire_safe_outputs_to_dominator(hoisted_check_proj, template_assertion_predicate_proj, true); |
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.
pin_array_access_nodes = true
since this is called only for range checks now.
@@ -1281,24 +1292,21 @@ bool PhaseIdealLoop::loop_predication_impl_helper(IdealLoopTree* loop, IfProjNod | |||
// with uncommon trap. | |||
return false; | |||
} | |||
assert(new_predicate_proj != nullptr, "sanity"); | |||
// Success - attach condition (new_predicate_bol) to predicate if | |||
invar.map_ctrl(if_success_proj, new_predicate_proj); // so that invariance test can be appropriate |
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.
Moved to invariant checks and range checks separately.
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.
Looks reasonable to me.
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.
Looks good.
Thanks Roland and Vladimir for your reviews! |
/integrate |
Going to push as commit ca5a438.
Your commit was automatically rebased without conflicts. |
@chhagedorn Pushed as commit ca5a438. 💡 You may see a message that your pull request was closed with unmerged commits. This can be safely ignored. |
This is another patch split off from the full Assertion Predicates fix.
PhaseIdealLoop::dominated_by()
only works for anIfNode
that dominates anotherIfNode
. However, at some point, we want to replace the twoIfNodes
that are generated as Template Assertion Predicate for a hoisted range check with a single dedicatedTemplateAssertionPredicateNode
. To still be able to rewire the control dependencies in Loop Predication from the hoisted range check to the newTemplateAssertionPredicateNode
outside the loop (instead of to the secondIfNode
projection of the Template Assertion Predicate as done today), we can extract the rewiring part out ofdominated_by()
into a separate methodrewire_safe_outputs_to_dominator()
and use that one instead.We get the following in Loop Predication:
dominated_by()
which callsrewire_safe_outputs_to_dominator()
eliminate_hoisted_range_check()
which callsrewire_safe_outputs_to_dominator()
.Thanks,
Christian
Progress
Issue
Reviewers
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/19806/head:pull/19806
$ git checkout pull/19806
Update a local copy of the PR:
$ git checkout pull/19806
$ git pull https://git.openjdk.org/jdk.git pull/19806/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 19806
View PR using the GUI difftool:
$ git pr show -t 19806
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/19806.diff
Webrev
Link to Webrev Comment