< prev index next >

src/hotspot/share/opto/loopopts.cpp

Print this page

        

*** 1409,1425 **** if( n_loop->is_member( u_loop ) ) break; // Found use in inner loop if( u->Opcode() == Op_Opaque1 ) break; // Found loop limit, bugfix for 4677003 } bool did_break = (i < imax); // Did we break out of the previous loop? if (!did_break && n->outcnt() > 1) { // All uses in outer loops! ! Node *late_load_ctrl = NULL; if (n->is_Load()) { // If n is a load, get and save the result from get_late_ctrl(), // to be later used in calculating the control for n's clones. clear_dom_lca_tags(); late_load_ctrl = get_late_ctrl(n, n_ctrl); } // If n is a load, and the late control is the same as the current // control, then the cloning of n is a pointless exercise, because // GVN will ensure that we end up where we started. if (!n->is_Load() || late_load_ctrl != n_ctrl) { for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) { --- 1409,1433 ---- if( n_loop->is_member( u_loop ) ) break; // Found use in inner loop if( u->Opcode() == Op_Opaque1 ) break; // Found loop limit, bugfix for 4677003 } bool did_break = (i < imax); // Did we break out of the previous loop? if (!did_break && n->outcnt() > 1) { // All uses in outer loops! ! Node* late_load_ctrl = NULL; ! Node* outer_strip_mined_loop_exit = NULL; if (n->is_Load()) { // If n is a load, get and save the result from get_late_ctrl(), // to be later used in calculating the control for n's clones. clear_dom_lca_tags(); late_load_ctrl = get_late_ctrl(n, n_ctrl); + if (n_loop->head()->is_Loop() && n_loop->head()->as_Loop()->is_strip_mined() && !n_loop->head()->is_OuterStripMinedLoop() + && n_loop->tail()->in(0) == late_load_ctrl->in(0)) { + // late_load_ctrl is a loop exit of an inner loop of an outer strip mined loop. + // Use the outer strip mined loop exit instead later if it dominates x_ctrl. + outer_strip_mined_loop_exit = n_loop->_parent->head()->as_OuterStripMinedLoop()->outer_loop_exit(); } + } + // If n is a load, and the late control is the same as the current // control, then the cloning of n is a pointless exercise, because // GVN will ensure that we end up where we started. if (!n->is_Load() || late_load_ctrl != n_ctrl) { for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) {
*** 1455,1468 **** if (n->is_Load()) { // For loads, add a control edge to a CFG node outside of the loop // to force them to not combine and return back inside the loop // during GVN optimization (4641526). // ! // Because we are setting the actual control input, factor in ! // the result from get_late_ctrl() so we respect any ! // anti-dependences. (6233005). x_ctrl = dom_lca(late_load_ctrl, x_ctrl); // Don't allow the control input to be a CFG splitting node. // Such nodes should only have ProjNodes as outs, e.g. IfNode // should only have IfTrueNode and IfFalseNode (4985384). x_ctrl = find_non_split_ctrl(x_ctrl); --- 1463,1483 ---- if (n->is_Load()) { // For loads, add a control edge to a CFG node outside of the loop // to force them to not combine and return back inside the loop // during GVN optimization (4641526). // ! // Because we are setting the actual control input, factor in the result from get_late_ctrl() so we respect ! // any anti-dependences (6233005). If late_load_ctrl is an inner loop exit inside an outer strip mined loop ! // whose exit dominates the latest possible placement for x, then use this outer strip mined loop exit ! // instead of the inner loop exit (= late_load_ctrl) to move the load completely out of the loop. ! // This still respects any anti-dependencies in get_late_ctrl(). ! if (outer_strip_mined_loop_exit != NULL && is_dominator(outer_strip_mined_loop_exit, get_late_ctrl(x, late_load_ctrl))) { ! assert(dom_lca(outer_strip_mined_loop_exit, x_ctrl) == outer_strip_mined_loop_exit, "must be the same result"); ! x_ctrl = outer_strip_mined_loop_exit; ! } else { x_ctrl = dom_lca(late_load_ctrl, x_ctrl); + } // Don't allow the control input to be a CFG splitting node. // Such nodes should only have ProjNodes as outs, e.g. IfNode // should only have IfTrueNode and IfFalseNode (4985384). x_ctrl = find_non_split_ctrl(x_ctrl);
< prev index next >