src/share/vm/opto/loopnode.cpp

changeset 3135
2c24ef16533d
parent 3048
6987871cfb9b
child 3260
670a74b863fc
     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);

mercurial