2086 // (2) stride*scale < 0 |
2086 // (2) stride*scale < 0 |
2087 // max(scale*i + offset) = scale*init + offset |
2087 // max(scale*i + offset) = scale*init + offset |
2088 BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl, |
2088 BoolNode* PhaseIdealLoop::rc_predicate(Node* ctrl, |
2089 int scale, Node* offset, |
2089 int scale, Node* offset, |
2090 Node* init, Node* limit, Node* stride, |
2090 Node* init, Node* limit, Node* stride, |
2091 Node* range) { |
2091 Node* range, bool upper) { |
|
2092 DEBUG_ONLY(ttyLocker ttyl); |
|
2093 if (TraceLoopPredicate) tty->print("rc_predicate "); |
|
2094 |
2092 Node* max_idx_expr = init; |
2095 Node* max_idx_expr = init; |
2093 int stride_con = stride->get_int(); |
2096 int stride_con = stride->get_int(); |
2094 if ((stride_con > 0) == (scale > 0)) { |
2097 if ((stride_con > 0) == (scale > 0) == upper) { |
2095 max_idx_expr = new (C, 3) SubINode(limit, stride); |
2098 max_idx_expr = new (C, 3) SubINode(limit, stride); |
2096 register_new_node(max_idx_expr, ctrl); |
2099 register_new_node(max_idx_expr, ctrl); |
|
2100 if (TraceLoopPredicate) tty->print("(limit - stride) "); |
|
2101 } else { |
|
2102 if (TraceLoopPredicate) tty->print("init "); |
2097 } |
2103 } |
2098 |
2104 |
2099 if (scale != 1) { |
2105 if (scale != 1) { |
2100 ConNode* con_scale = _igvn.intcon(scale); |
2106 ConNode* con_scale = _igvn.intcon(scale); |
2101 max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale); |
2107 max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale); |
2102 register_new_node(max_idx_expr, ctrl); |
2108 register_new_node(max_idx_expr, ctrl); |
|
2109 if (TraceLoopPredicate) tty->print("* %d ", scale); |
2103 } |
2110 } |
2104 |
2111 |
2105 if (offset && (!offset->is_Con() || offset->get_int() != 0)){ |
2112 if (offset && (!offset->is_Con() || offset->get_int() != 0)){ |
2106 max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset); |
2113 max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset); |
2107 register_new_node(max_idx_expr, ctrl); |
2114 register_new_node(max_idx_expr, ctrl); |
|
2115 if (TraceLoopPredicate) |
|
2116 if (offset->is_Con()) tty->print("+ %d ", offset->get_int()); |
|
2117 else tty->print("+ offset "); |
2108 } |
2118 } |
2109 |
2119 |
2110 CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range); |
2120 CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range); |
2111 register_new_node(cmp, ctrl); |
2121 register_new_node(cmp, ctrl); |
2112 BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt); |
2122 BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt); |
2113 register_new_node(bol, ctrl); |
2123 register_new_node(bol, ctrl); |
|
2124 |
|
2125 if (TraceLoopPredicate) tty->print_cr("<u range"); |
2114 return bol; |
2126 return bol; |
2115 } |
2127 } |
2116 |
2128 |
2117 //------------------------------ loop_predication_impl-------------------------- |
2129 //------------------------------ loop_predication_impl-------------------------- |
2118 // Insert loop predicates for null checks and range checks |
2130 // Insert loop predicates for null checks and range checks |
2216 BoolNode* bol = test->as_Bool(); |
2227 BoolNode* bol = test->as_Bool(); |
2217 if (invar.is_invariant(bol)) { |
2228 if (invar.is_invariant(bol)) { |
2218 // Invariant test |
2229 // Invariant test |
2219 new_predicate_proj = create_new_if_for_predicate(predicate_proj); |
2230 new_predicate_proj = create_new_if_for_predicate(predicate_proj); |
2220 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0); |
2231 Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0); |
2221 new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); |
2232 BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool(); |
2222 if (TraceLoopPredicate) tty->print("invariant"); |
2233 |
|
2234 // Negate test if necessary |
|
2235 bool negated = false; |
|
2236 if (proj->_con != predicate_proj->_con) { |
|
2237 new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); |
|
2238 register_new_node(new_predicate_bol, ctrl); |
|
2239 negated = true; |
|
2240 } |
|
2241 IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If(); |
|
2242 _igvn.hash_delete(new_predicate_iff); |
|
2243 new_predicate_iff->set_req(1, new_predicate_bol); |
|
2244 if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx); |
|
2245 |
2223 } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { |
2246 } else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) { |
2224 // Range check (only for counted loops) |
2247 assert(proj->_con == predicate_proj->_con, "must match"); |
2225 new_predicate_proj = create_new_if_for_predicate(predicate_proj); |
2248 |
2226 Node *ctrl = new_predicate_proj->in(0)->as_If()->in(0); |
2249 // Range check for counted loops |
2227 const Node* cmp = bol->in(1)->as_Cmp(); |
2250 const Node* cmp = bol->in(1)->as_Cmp(); |
2228 Node* idx = cmp->in(1); |
2251 Node* idx = cmp->in(1); |
2229 assert(!invar.is_invariant(idx), "index is variant"); |
2252 assert(!invar.is_invariant(idx), "index is variant"); |
2230 assert(cmp->in(2)->Opcode() == Op_LoadRange, "must be"); |
2253 assert(cmp->in(2)->Opcode() == Op_LoadRange, "must be"); |
2231 LoadRangeNode* ld_rng = (LoadRangeNode*)cmp->in(2); // LoadRangeNode |
2254 Node* ld_rng = cmp->in(2); // LoadRangeNode |
2232 assert(invar.is_invariant(ld_rng), "load range must be invariant"); |
2255 assert(invar.is_invariant(ld_rng), "load range must be invariant"); |
2233 ld_rng = (LoadRangeNode*)invar.clone(ld_rng, ctrl); |
|
2234 int scale = 1; |
2256 int scale = 1; |
2235 Node* offset = zero; |
2257 Node* offset = zero; |
2236 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); |
2258 bool ok = is_scaled_iv_plus_offset(idx, cl->phi(), &scale, &offset); |
2237 assert(ok, "must be index expression"); |
2259 assert(ok, "must be index expression"); |
|
2260 |
|
2261 Node* init = cl->init_trip(); |
|
2262 Node* limit = cl->limit(); |
|
2263 Node* stride = cl->stride(); |
|
2264 |
|
2265 // Build if's for the upper and lower bound tests. The |
|
2266 // lower_bound test will dominate the upper bound test and all |
|
2267 // cloned or created nodes will use the lower bound test as |
|
2268 // their declared control. |
|
2269 ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj); |
|
2270 ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj); |
|
2271 assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate"); |
|
2272 Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0); |
|
2273 |
|
2274 // Perform cloning to keep Invariance state correct since the |
|
2275 // late schedule will place invariant things in the loop. |
|
2276 ld_rng = invar.clone(ld_rng, ctrl); |
2238 if (offset && offset != zero) { |
2277 if (offset && offset != zero) { |
2239 assert(invar.is_invariant(offset), "offset must be loop invariant"); |
2278 assert(invar.is_invariant(offset), "offset must be loop invariant"); |
2240 offset = invar.clone(offset, ctrl); |
2279 offset = invar.clone(offset, ctrl); |
2241 } |
2280 } |
2242 Node* init = cl->init_trip(); |
2281 |
2243 Node* limit = cl->limit(); |
2282 // Test the lower bound |
2244 Node* stride = cl->stride(); |
2283 Node* lower_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, false); |
2245 new_predicate_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng); |
2284 IfNode* lower_bound_iff = lower_bound_proj->in(0)->as_If(); |
2246 if (TraceLoopPredicate) tty->print("range check"); |
2285 _igvn.hash_delete(lower_bound_iff); |
2247 } |
2286 lower_bound_iff->set_req(1, lower_bound_bol); |
2248 |
2287 if (TraceLoopPredicate) tty->print_cr("lower bound check if: %d", lower_bound_iff->_idx); |
2249 if (new_predicate_proj == NULL) { |
2288 |
|
2289 // Test the upper bound |
|
2290 Node* upper_bound_bol = rc_predicate(ctrl, scale, offset, init, limit, stride, ld_rng, true); |
|
2291 IfNode* upper_bound_iff = upper_bound_proj->in(0)->as_If(); |
|
2292 _igvn.hash_delete(upper_bound_iff); |
|
2293 upper_bound_iff->set_req(1, upper_bound_bol); |
|
2294 if (TraceLoopPredicate) tty->print_cr("upper bound check if: %d", lower_bound_iff->_idx); |
|
2295 |
|
2296 // Fall through into rest of the clean up code which will move |
|
2297 // any dependent nodes onto the upper bound test. |
|
2298 new_predicate_proj = upper_bound_proj; |
|
2299 } else { |
2250 // The other proj of the "iff" is a uncommon trap projection, and we can assume |
2300 // The other proj of the "iff" is a uncommon trap projection, and we can assume |
2251 // the other proj will not be executed ("executed" means uct raised). |
2301 // the other proj will not be executed ("executed" means uct raised). |
2252 continue; |
2302 continue; |
2253 } else { |
2303 } |
2254 // Success - attach condition (new_predicate_bol) to predicate if |
2304 |
2255 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate |
2305 // Success - attach condition (new_predicate_bol) to predicate if |
2256 IfNode* new_iff = new_predicate_proj->in(0)->as_If(); |
2306 invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate |
2257 |
2307 |
2258 // Negate test if necessary |
2308 // Eliminate the old if in the loop body |
2259 if (proj->_con != predicate_proj->_con) { |
2309 _igvn.hash_delete(iff); |
2260 new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate()); |
2310 iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true); |
2261 register_new_node(new_predicate_bol, new_iff->in(0)); |
2311 |
2262 if (TraceLoopPredicate) tty->print_cr(" if negated: %d", iff->_idx); |
2312 Node* ctrl = new_predicate_proj; // new control |
2263 } else { |
2313 ProjNode* dp = proj; // old control |
2264 if (TraceLoopPredicate) tty->print_cr(" if: %d", iff->_idx); |
2314 assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj"); |
2265 } |
2315 // Find nodes (depends only on the test) off the surviving projection; |
2266 |
2316 // move them outside the loop with the control of proj_clone |
2267 _igvn.hash_delete(new_iff); |
2317 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { |
2268 new_iff->set_req(1, new_predicate_bol); |
2318 Node* cd = dp->fast_out(i); // Control-dependent node |
2269 |
2319 if (cd->depends_only_on_test()) { |
2270 _igvn.hash_delete(iff); |
2320 assert(cd->in(0) == dp, ""); |
2271 iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true); |
2321 _igvn.hash_delete(cd); |
2272 |
2322 cd->set_req(0, ctrl); // ctrl, not NULL |
2273 Node* ctrl = new_predicate_proj; // new control |
2323 set_early_ctrl(cd); |
2274 ProjNode* dp = proj; // old control |
2324 _igvn._worklist.push(cd); |
2275 assert(get_loop(dp) == loop, "guarenteed at the time of collecting proj"); |
2325 IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); |
2276 // Find nodes (depends only on the test) off the surviving projection; |
2326 if (new_loop != loop) { |
2277 // move them outside the loop with the control of proj_clone |
2327 if (!loop->_child) loop->_body.yank(cd); |
2278 for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) { |
2328 if (!new_loop->_child ) new_loop->_body.push(cd); |
2279 Node* cd = dp->fast_out(i); // Control-dependent node |
|
2280 if (cd->depends_only_on_test()) { |
|
2281 assert(cd->in(0) == dp, ""); |
|
2282 _igvn.hash_delete(cd); |
|
2283 cd->set_req(0, ctrl); // ctrl, not NULL |
|
2284 set_early_ctrl(cd); |
|
2285 _igvn._worklist.push(cd); |
|
2286 IdealLoopTree *new_loop = get_loop(get_ctrl(cd)); |
|
2287 if (new_loop != loop) { |
|
2288 if (!loop->_child) loop->_body.yank(cd); |
|
2289 if (!new_loop->_child ) new_loop->_body.push(cd); |
|
2290 } |
|
2291 --i; |
|
2292 --imax; |
|
2293 } |
2329 } |
2294 } |
2330 --i; |
2295 |
2331 --imax; |
2296 hoisted = true; |
2332 } |
2297 C->set_major_progress(); |
2333 } |
2298 } |
2334 |
|
2335 hoisted = true; |
|
2336 C->set_major_progress(); |
2299 } // end while |
2337 } // end while |
2300 |
2338 |
2301 #ifndef PRODUCT |
2339 #ifndef PRODUCT |
2302 // report that the loop predication has been actually performed |
2340 // report that the loop predication has been actually performed |
2303 // for this loop |
2341 // for this loop |
2304 if (TraceLoopPredicate && hoisted) { |
2342 if (TraceLoopPredicate && hoisted) { |
2305 tty->print("Loop Predication Performed:"); |
2343 tty->print("Loop Predication Performed:"); |
2306 loop->dump_head(); |
2344 loop->dump_head(); |
2307 } |
2345 } |
2308 #endif |
2346 #endif |
2309 |
2347 |
2310 return hoisted; |
2348 return hoisted; |
2311 } |
2349 } |
2312 |
2350 |