1.1 --- a/src/share/vm/opto/loopnode.cpp Fri Sep 09 12:44:37 2011 -0700 1.2 +++ b/src/share/vm/opto/loopnode.cpp Fri Sep 09 13:47:11 2011 -0700 1.3 @@ -582,20 +582,25 @@ 1.4 1.5 // Build a canonical trip test. 1.6 // Clone code, as old values may be in use. 1.7 - Node* nphi = PhiNode::make(x, init_trip, TypeInt::INT); 1.8 - nphi = _igvn.register_new_node_with_optimizer(nphi); 1.9 - set_ctrl(nphi, get_ctrl(phi)); 1.10 - 1.11 incr = incr->clone(); 1.12 - incr->set_req(1,nphi); 1.13 + incr->set_req(1,phi); 1.14 incr->set_req(2,stride); 1.15 incr = _igvn.register_new_node_with_optimizer(incr); 1.16 set_early_ctrl( incr ); 1.17 - 1.18 - nphi->set_req(LoopNode::LoopBackControl, incr); 1.19 - _igvn.replace_node(phi, nphi); 1.20 - phi = nphi->as_Phi(); 1.21 - 1.22 + _igvn.hash_delete(phi); 1.23 + phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn ); 1.24 + 1.25 + // If phi type is more restrictive than Int, raise to 1.26 + // Int to prevent (almost) infinite recursion in igvn 1.27 + // which can only handle integer types for constants or minint..maxint. 1.28 + if (!TypeInt::INT->higher_equal(phi->bottom_type())) { 1.29 + Node* nphi = PhiNode::make(phi->in(0), phi->in(LoopNode::EntryControl), TypeInt::INT); 1.30 + nphi->set_req(LoopNode::LoopBackControl, phi->in(LoopNode::LoopBackControl)); 1.31 + nphi = _igvn.register_new_node_with_optimizer(nphi); 1.32 + set_ctrl(nphi, get_ctrl(phi)); 1.33 + _igvn.replace_node(phi, nphi); 1.34 + phi = nphi->as_Phi(); 1.35 + } 1.36 cmp = cmp->clone(); 1.37 cmp->set_req(1,incr); 1.38 cmp->set_req(2,limit); 1.39 @@ -1618,8 +1623,6 @@ 1.40 Node *phi = cl->phi(); 1.41 int stride_con = cl->stride_con(); 1.42 1.43 - PhaseGVN *gvn = &_igvn; 1.44 - 1.45 // Visit all children, looking for Phis 1.46 for (DUIterator i = cl->outs(); cl->has_out(i); i++) { 1.47 Node *out = cl->out(i); 1.48 @@ -1655,25 +1658,31 @@ 1.49 int ratio_con = stride_con2/stride_con; 1.50 1.51 if ((ratio_con * stride_con) == stride_con2) { // Check for exact 1.52 +#ifndef PRODUCT 1.53 + if (TraceLoopOpts) { 1.54 + tty->print("Parallel IV: %d ", phi2->_idx); 1.55 + loop->dump_head(); 1.56 + } 1.57 +#endif 1.58 // Convert to using the trip counter. The parallel induction 1.59 // variable differs from the trip counter by a loop-invariant 1.60 // amount, the difference between their respective initial values. 1.61 // It is scaled by the 'ratio_con'. 1.62 - // Perform local Ideal transformation since in most cases ratio == 1. 1.63 Node* ratio = _igvn.intcon(ratio_con); 1.64 set_ctrl(ratio, C->root()); 1.65 - Node* hook = new (C, 3) Node(3); 1.66 - Node* ratio_init = gvn->transform(new (C, 3) MulINode(init, ratio)); 1.67 - hook->init_req(0, ratio_init); 1.68 - Node* diff = gvn->transform(new (C, 3) SubINode(init2, ratio_init)); 1.69 - hook->init_req(1, diff); 1.70 - Node* ratio_idx = gvn->transform(new (C, 3) MulINode(phi, ratio)); 1.71 - hook->init_req(2, ratio_idx); 1.72 - Node* add = gvn->transform(new (C, 3) AddINode(ratio_idx, diff)); 1.73 - set_subtree_ctrl(add); 1.74 + Node* ratio_init = new (C, 3) MulINode(init, ratio); 1.75 + _igvn.register_new_node_with_optimizer(ratio_init, init); 1.76 + set_early_ctrl(ratio_init); 1.77 + Node* diff = new (C, 3) SubINode(init2, ratio_init); 1.78 + _igvn.register_new_node_with_optimizer(diff, init2); 1.79 + set_early_ctrl(diff); 1.80 + Node* ratio_idx = new (C, 3) MulINode(phi, ratio); 1.81 + _igvn.register_new_node_with_optimizer(ratio_idx, phi); 1.82 + set_ctrl(ratio_idx, cl); 1.83 + Node* add = new (C, 3) AddINode(ratio_idx, diff); 1.84 + _igvn.register_new_node_with_optimizer(add); 1.85 + set_ctrl(add, cl); 1.86 _igvn.replace_node( phi2, add ); 1.87 - // Free up intermediate goo 1.88 - _igvn.remove_dead_node(hook); 1.89 // Sometimes an induction variable is unused 1.90 if (add->outcnt() == 0) { 1.91 _igvn.remove_dead_node(add);