src/share/vm/opto/loopnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7035946 Cdiff src/share/vm/opto/loopnode.cpp

src/share/vm/opto/loopnode.cpp

Print this page

        

*** 580,603 **** loop->_tail = iftrue; } // Build a canonical trip test. // Clone code, as old values may be in use. - Node* nphi = PhiNode::make(x, init_trip, TypeInt::INT); - nphi = _igvn.register_new_node_with_optimizer(nphi); - set_ctrl(nphi, get_ctrl(phi)); - incr = incr->clone(); ! incr->set_req(1,nphi); incr->set_req(2,stride); incr = _igvn.register_new_node_with_optimizer(incr); set_early_ctrl( incr ); ! nphi->set_req(LoopNode::LoopBackControl, incr); _igvn.replace_node(phi, nphi); phi = nphi->as_Phi(); ! cmp = cmp->clone(); cmp->set_req(1,incr); cmp->set_req(2,limit); cmp = _igvn.register_new_node_with_optimizer(cmp); set_ctrl(cmp, iff->in(0)); --- 580,608 ---- loop->_tail = iftrue; } // Build a canonical trip test. // Clone code, as old values may be in use. incr = incr->clone(); ! incr->set_req(1,phi); incr->set_req(2,stride); incr = _igvn.register_new_node_with_optimizer(incr); set_early_ctrl( incr ); + _igvn.hash_delete(phi); + phi->set_req_X( LoopNode::LoopBackControl, incr, &_igvn ); ! // If phi type is more restrictive than Int, raise to ! // Int to prevent (almost) infinite recursion in igvn ! // which can only handle integer types for constants or minint..maxint. ! if (!TypeInt::INT->higher_equal(phi->bottom_type())) { ! Node* nphi = PhiNode::make(phi->in(0), phi->in(LoopNode::EntryControl), TypeInt::INT); ! nphi->set_req(LoopNode::LoopBackControl, phi->in(LoopNode::LoopBackControl)); ! nphi = _igvn.register_new_node_with_optimizer(nphi); ! set_ctrl(nphi, get_ctrl(phi)); _igvn.replace_node(phi, nphi); phi = nphi->as_Phi(); ! } cmp = cmp->clone(); cmp->set_req(1,incr); cmp->set_req(2,limit); cmp = _igvn.register_new_node_with_optimizer(cmp); set_ctrl(cmp, iff->in(0));
*** 1616,1627 **** return; // Dead loop? Node *init = cl->init_trip(); Node *phi = cl->phi(); int stride_con = cl->stride_con(); - PhaseGVN *gvn = &_igvn; - // Visit all children, looking for Phis for (DUIterator i = cl->outs(); cl->has_out(i); i++) { Node *out = cl->out(i); // Look for other phis (secondary IVs). Skip dead ones if (!out->is_Phi() || out == phi || !has_node(out)) --- 1621,1630 ----
*** 1653,1681 **** // where +/-1 is the common case, but other integer multiples are // also easy to handle. int ratio_con = stride_con2/stride_con; if ((ratio_con * stride_con) == stride_con2) { // Check for exact // Convert to using the trip counter. The parallel induction // variable differs from the trip counter by a loop-invariant // amount, the difference between their respective initial values. // It is scaled by the 'ratio_con'. - // Perform local Ideal transformation since in most cases ratio == 1. Node* ratio = _igvn.intcon(ratio_con); set_ctrl(ratio, C->root()); ! Node* hook = new (C, 3) Node(3); ! Node* ratio_init = gvn->transform(new (C, 3) MulINode(init, ratio)); ! hook->init_req(0, ratio_init); ! Node* diff = gvn->transform(new (C, 3) SubINode(init2, ratio_init)); ! hook->init_req(1, diff); ! Node* ratio_idx = gvn->transform(new (C, 3) MulINode(phi, ratio)); ! hook->init_req(2, ratio_idx); ! Node* add = gvn->transform(new (C, 3) AddINode(ratio_idx, diff)); ! set_subtree_ctrl(add); _igvn.replace_node( phi2, add ); - // Free up intermediate goo - _igvn.remove_dead_node(hook); // Sometimes an induction variable is unused if (add->outcnt() == 0) { _igvn.remove_dead_node(add); } --i; // deleted this phi; rescan starting with next position --- 1656,1690 ---- // where +/-1 is the common case, but other integer multiples are // also easy to handle. int ratio_con = stride_con2/stride_con; if ((ratio_con * stride_con) == stride_con2) { // Check for exact + #ifndef PRODUCT + if (TraceLoopOpts) { + tty->print("Parallel IV: %d ", phi2->_idx); + loop->dump_head(); + } + #endif // Convert to using the trip counter. The parallel induction // variable differs from the trip counter by a loop-invariant // amount, the difference between their respective initial values. // It is scaled by the 'ratio_con'. Node* ratio = _igvn.intcon(ratio_con); set_ctrl(ratio, C->root()); ! Node* ratio_init = new (C, 3) MulINode(init, ratio); ! _igvn.register_new_node_with_optimizer(ratio_init, init); ! set_early_ctrl(ratio_init); ! Node* diff = new (C, 3) SubINode(init2, ratio_init); ! _igvn.register_new_node_with_optimizer(diff, init2); ! set_early_ctrl(diff); ! Node* ratio_idx = new (C, 3) MulINode(phi, ratio); ! _igvn.register_new_node_with_optimizer(ratio_idx, phi); ! set_ctrl(ratio_idx, cl); ! Node* add = new (C, 3) AddINode(ratio_idx, diff); ! _igvn.register_new_node_with_optimizer(add); ! set_ctrl(add, cl); _igvn.replace_node( phi2, add ); // Sometimes an induction variable is unused if (add->outcnt() == 0) { _igvn.remove_dead_node(add); } --i; // deleted this phi; rescan starting with next position
src/share/vm/opto/loopnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File