comparison src/share/vm/opto/loopTransform.cpp @ 1303:c047da02984c

6930043: C2: SIGSEGV in javasoft.sqe.tests.lang.arr017.arr01702.arr01702.loop_forw(II)I Reviewed-by: kvn
author never
date Wed, 17 Mar 2010 16:40:25 -0700
parents 336c6c200f5f
children c18cbe5936b8
comparison
equal deleted inserted replaced
1302:2484f4d6a54e 1303:c047da02984c
1 /* 1 /*
2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved. 2 * Copyright 2000-2010 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
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
2185 2197
2186 bool hoisted = false; // true if at least one proj is promoted 2198 bool hoisted = false; // true if at least one proj is promoted
2187 while (if_proj_list.size() > 0) { 2199 while (if_proj_list.size() > 0) {
2188 // Following are changed to nonnull when a predicate can be hoisted 2200 // Following are changed to nonnull when a predicate can be hoisted
2189 ProjNode* new_predicate_proj = NULL; 2201 ProjNode* new_predicate_proj = NULL;
2190 BoolNode* new_predicate_bol = NULL;
2191 2202
2192 ProjNode* proj = if_proj_list.pop()->as_Proj(); 2203 ProjNode* proj = if_proj_list.pop()->as_Proj();
2193 IfNode* iff = proj->in(0)->as_If(); 2204 IfNode* iff = proj->in(0)->as_If();
2194 2205
2195 if (!is_uncommon_trap_if_pattern(proj)) { 2206 if (!is_uncommon_trap_if_pattern(proj)) {
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