hotspot/src/share/vm/opto/loopTransform.cpp
changeset 5054 6d42dc4dd98c
parent 5031 80fd89e1bd57
child 5547 f4b087cbb361
equal deleted inserted replaced
5053:4079ecbb654b 5054:6d42dc4dd98c
     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