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--------------------------------- |