src/hotspot/share/opto/loopTransform.cpp
changeset 53169 98580226126d
parent 53167 030429d6baac
child 53306 8e260023fc53
equal deleted inserted replaced
53168:f019e5a7b118 53169:98580226126d
  2037   }
  2037   }
  2038 }
  2038 }
  2039 
  2039 
  2040 //------------------------------adjust_limit-----------------------------------
  2040 //------------------------------adjust_limit-----------------------------------
  2041 // Helper function for add_constraint().
  2041 // Helper function for add_constraint().
  2042 Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) {
  2042 Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl, bool round_up) {
  2043   // Compute "I :: (limit-offset)/scale"
  2043   // Compute "I :: (limit-offset)/scale"
  2044   Node *con = new SubINode(rc_limit, offset);
  2044   Node *con = new SubINode(rc_limit, offset);
  2045   register_new_node(con, pre_ctrl);
  2045   register_new_node(con, pre_ctrl);
  2046   Node *X = new DivINode(0, con, scale);
  2046   Node *X = new DivINode(0, con, scale);
  2047   register_new_node(X, pre_ctrl);
  2047   register_new_node(X, pre_ctrl);
       
  2048 
       
  2049   // When the absolute value of scale is greater than one, the integer
       
  2050   // division may round limit down so add one to the limit.
       
  2051   if (round_up) {
       
  2052     X = new AddINode(X, _igvn.intcon(1));
       
  2053     register_new_node(X, pre_ctrl);
       
  2054   }
  2048 
  2055 
  2049   // Adjust loop limit
  2056   // Adjust loop limit
  2050   loop_limit = (stride_con > 0)
  2057   loop_limit = (stride_con > 0)
  2051                ? (Node*)(new MinINode(loop_limit, X))
  2058                ? (Node*)(new MinINode(loop_limit, X))
  2052                : (Node*)(new MaxINode(loop_limit, X));
  2059                : (Node*)(new MaxINode(loop_limit, X));
  2084     //   )
  2091     //   )
  2085     //
  2092     //
  2086     // (upper_limit-offset) may overflow or underflow.
  2093     // (upper_limit-offset) may overflow or underflow.
  2087     // But it is fine since main loop will either have
  2094     // But it is fine since main loop will either have
  2088     // less iterations or will be skipped in such case.
  2095     // less iterations or will be skipped in such case.
  2089     *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl);
  2096     *main_limit = adjust_limit(stride_con, scale, offset, upper_limit, *main_limit, pre_ctrl, false);
  2090 
  2097 
  2091     // The underflow limit: low_limit <= scale*I+offset.
  2098     // The underflow limit: low_limit <= scale*I+offset.
  2092     // For pre-loop compute
  2099     // For pre-loop compute
  2093     //   NOT(scale*I+offset >= low_limit)
  2100     //   NOT(scale*I+offset >= low_limit)
  2094     //   scale*I+offset < low_limit
  2101     //   scale*I+offset < low_limit
  2119       // since (0-min_int) == min_int. It may be fine for stride > 0
  2126       // since (0-min_int) == min_int. It may be fine for stride > 0
  2120       // but for stride < 0 X will be < original_limit. To avoid it
  2127       // but for stride < 0 X will be < original_limit. To avoid it
  2121       // max(pre_limit, original_limit) is used in do_range_check().
  2128       // max(pre_limit, original_limit) is used in do_range_check().
  2122     }
  2129     }
  2123     // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
  2130     // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
  2124     *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl);
  2131     *pre_limit = adjust_limit((-stride_con), scale, offset, low_limit, *pre_limit, pre_ctrl,
       
  2132                               scale_con > 1 && stride_con > 0);
  2125 
  2133 
  2126   } else { // stride_con*scale_con < 0
  2134   } else { // stride_con*scale_con < 0
  2127     // For negative stride*scale pre-loop checks for overflow and
  2135     // For negative stride*scale pre-loop checks for overflow and
  2128     // post-loop for underflow.
  2136     // post-loop for underflow.
  2129     //
  2137     //
  2145     set_ctrl(one, C->root());
  2153     set_ctrl(one, C->root());
  2146 
  2154 
  2147     Node *plus_one = new AddINode(offset, one);
  2155     Node *plus_one = new AddINode(offset, one);
  2148     register_new_node( plus_one, pre_ctrl );
  2156     register_new_node( plus_one, pre_ctrl );
  2149     // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
  2157     // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
  2150     *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
  2158     *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl,
       
  2159                               scale_con < -1 && stride_con > 0);
  2151 
  2160 
  2152     if (low_limit->get_int() == -max_jint) {
  2161     if (low_limit->get_int() == -max_jint) {
  2153       // We need this guard when scale*main_limit+offset >= limit
  2162       // We need this guard when scale*main_limit+offset >= limit
  2154       // due to underflow. So we need execute main-loop while
  2163       // due to underflow. So we need execute main-loop while
  2155       // scale*I+offset+1 > min_int. But (min_int-offset-1) will
  2164       // scale*I+offset+1 > min_int. But (min_int-offset-1) will
  2179     //       I < (low_limit-(offset+1))/scale
  2188     //       I < (low_limit-(offset+1))/scale
  2180     //     else /* scale > 0 and stride < 0 */
  2189     //     else /* scale > 0 and stride < 0 */
  2181     //       I > (low_limit-(offset+1))/scale
  2190     //       I > (low_limit-(offset+1))/scale
  2182     //   )
  2191     //   )
  2183 
  2192 
  2184     *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl);
  2193     *main_limit = adjust_limit(stride_con, scale, plus_one, low_limit, *main_limit, pre_ctrl,
       
  2194                                false);
  2185   }
  2195   }
  2186 }
  2196 }
  2187 
  2197 
  2188 
  2198 
  2189 //------------------------------is_scaled_iv---------------------------------
  2199 //------------------------------is_scaled_iv---------------------------------