8324790: ifnode::fold_compares_helper cleanup

Reviewed-by: chagedorn, epeter
This commit is contained in:
Joshua Cao 2024-03-01 05:35:33 +00:00 committed by Emanuel Peter
parent 0d35450362
commit 12404a5efb

View File

@ -1031,7 +1031,7 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f
const TypeInt* type2 = filtered_int_type(igvn, n, fail);
if (type2 != nullptr) {
failtype = failtype->join(type2)->is_int();
if (failtype->_lo > failtype->_hi) {
if (failtype->empty()) {
// previous if determines the result of this if so
// replace Bool with constant
igvn->replace_input_of(this, 1, igvn->intcon(success->_con));
@ -1039,55 +1039,49 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f
}
}
}
lo = nullptr;
hi = nullptr;
return false;
}
if (lo && hi) {
Node* hook = new Node(1);
hook->init_req(0, lo); // Add a use to lo to prevent him from dying
// Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo))
Node* adjusted_val = igvn->transform(new SubINode(n, lo));
if (adjusted_lim == nullptr) {
adjusted_lim = igvn->transform(new SubINode(hi, lo));
}
hook->destruct(igvn);
int lo = igvn->type(adjusted_lim)->is_int()->_lo;
if (lo < 0) {
// If range check elimination applies to this comparison, it includes code to protect from overflows that may
// cause the main loop to be skipped entirely. Delay this transformation.
// Example:
// for (int i = 0; i < limit; i++) {
// if (i < max_jint && i > min_jint) {...
// }
// Comparisons folded as:
// i - min_jint - 1 <u -2
// when RC applies, main loop limit becomes:
// min(limit, max(-2 + min_jint + 1, min_jint))
// = min(limit, min_jint)
// = min_jint
if (!igvn->C->post_loop_opts_phase()) {
if (adjusted_val->outcnt() == 0) {
igvn->remove_dead_node(adjusted_val);
}
if (adjusted_lim->outcnt() == 0) {
igvn->remove_dead_node(adjusted_lim);
}
igvn->C->record_for_post_loop_opts_igvn(this);
return false;
}
}
Node* newcmp = igvn->transform(new CmpUNode(adjusted_val, adjusted_lim));
Node* newbool = igvn->transform(new BoolNode(newcmp, cond));
igvn->replace_input_of(dom_iff, 1, igvn->intcon(proj->_con));
igvn->replace_input_of(this, 1, newbool);
return true;
assert(lo != nullptr && hi != nullptr, "sanity");
Node* hook = new Node(lo); // Add a use to lo to prevent him from dying
// Merge the two compares into a single unsigned compare by building (CmpU (n - lo) (hi - lo))
Node* adjusted_val = igvn->transform(new SubINode(n, lo));
if (adjusted_lim == nullptr) {
adjusted_lim = igvn->transform(new SubINode(hi, lo));
}
return false;
hook->destruct(igvn);
if (igvn->type(adjusted_lim)->is_int()->_lo < 0 &&
!igvn->C->post_loop_opts_phase()) {
// If range check elimination applies to this comparison, it includes code to protect from overflows that may
// cause the main loop to be skipped entirely. Delay this transformation.
// Example:
// for (int i = 0; i < limit; i++) {
// if (i < max_jint && i > min_jint) {...
// }
// Comparisons folded as:
// i - min_jint - 1 <u -2
// when RC applies, main loop limit becomes:
// min(limit, max(-2 + min_jint + 1, min_jint))
// = min(limit, min_jint)
// = min_jint
if (adjusted_val->outcnt() == 0) {
igvn->remove_dead_node(adjusted_val);
}
if (adjusted_lim->outcnt() == 0) {
igvn->remove_dead_node(adjusted_lim);
}
igvn->C->record_for_post_loop_opts_igvn(this);
return false;
}
Node* newcmp = igvn->transform(new CmpUNode(adjusted_val, adjusted_lim));
Node* newbool = igvn->transform(new BoolNode(newcmp, cond));
igvn->replace_input_of(dom_iff, 1, igvn->intcon(proj->_con));
igvn->replace_input_of(this, 1, newbool);
return true;
}
// Merge the branches that trap for this If and the dominating If into