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