src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/loopnode.cpp Fri Apr 1 14:29:04 2016
--- new/src/share/vm/opto/loopnode.cpp Fri Apr 1 14:29:04 2016
*** 461,472 ****
--- 461,470 ----
assert(x->Opcode() == Op_Loop, "regular loops only");
C->print_method(PHASE_BEFORE_CLOOPS, 3);
Node *hook = new Node(6);
if (LoopLimitCheck) {
// ===================================================
// Generate loop limit check to avoid integer overflow
// in cases like next (cyclic loops):
//
// for (i=0; i <= max_jint; i++) {}
*** 591,697 ****
--- 589,598 ----
else
ShouldNotReachHere();
}
set_subtree_ctrl( limit );
} else { // LoopLimitCheck
// If compare points to incr, we are ok. Otherwise the compare
// can directly point to the phi; in this case adjust the compare so that
// it points to the incr by adjusting the limit.
if (cmp->in(1) == phi || cmp->in(2) == phi)
limit = gvn->transform(new AddINode(limit,stride));
// trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride.
// Final value for iterator should be: trip_count * stride + init_trip.
Node *one_p = gvn->intcon( 1);
Node *one_m = gvn->intcon(-1);
Node *trip_count = NULL;
switch( bt ) {
case BoolTest::eq:
ShouldNotReachHere();
case BoolTest::ne: // Ahh, the case we desire
if (stride_con == 1)
trip_count = gvn->transform(new SubINode(limit,init_trip));
else if (stride_con == -1)
trip_count = gvn->transform(new SubINode(init_trip,limit));
else
ShouldNotReachHere();
set_subtree_ctrl(trip_count);
//_loop.map(trip_count->_idx,loop(limit));
break;
case BoolTest::le: // Maybe convert to '<' case
limit = gvn->transform(new AddINode(limit,one_p));
set_subtree_ctrl( limit );
hook->init_req(4, limit);
bt = BoolTest::lt;
// Make the new limit be in the same loop nest as the old limit
//_loop.map(limit->_idx,limit_loop);
// Fall into next case
case BoolTest::lt: { // Maybe convert to '!=' case
if (stride_con < 0) // Count down loop rolls through MAXINT
ShouldNotReachHere();
Node *range = gvn->transform(new SubINode(limit,init_trip));
set_subtree_ctrl( range );
hook->init_req(0, range);
Node *bias = gvn->transform(new AddINode(range,stride));
set_subtree_ctrl( bias );
hook->init_req(1, bias);
Node *bias1 = gvn->transform(new AddINode(bias,one_m));
set_subtree_ctrl( bias1 );
hook->init_req(2, bias1);
trip_count = gvn->transform(new DivINode(0,bias1,stride));
set_subtree_ctrl( trip_count );
hook->init_req(3, trip_count);
break;
}
case BoolTest::ge: // Maybe convert to '>' case
limit = gvn->transform(new AddINode(limit,one_m));
set_subtree_ctrl( limit );
hook->init_req(4 ,limit);
bt = BoolTest::gt;
// Make the new limit be in the same loop nest as the old limit
//_loop.map(limit->_idx,limit_loop);
// Fall into next case
case BoolTest::gt: { // Maybe convert to '!=' case
if (stride_con > 0) // count up loop rolls through MININT
ShouldNotReachHere();
Node *range = gvn->transform(new SubINode(limit,init_trip));
set_subtree_ctrl( range );
hook->init_req(0, range);
Node *bias = gvn->transform(new AddINode(range,stride));
set_subtree_ctrl( bias );
hook->init_req(1, bias);
Node *bias1 = gvn->transform(new AddINode(bias,one_p));
set_subtree_ctrl( bias1 );
hook->init_req(2, bias1);
trip_count = gvn->transform(new DivINode(0,bias1,stride));
set_subtree_ctrl( trip_count );
hook->init_req(3, trip_count);
break;
}
} // switch( bt )
Node *span = gvn->transform(new MulINode(trip_count,stride));
set_subtree_ctrl( span );
hook->init_req(5, span);
limit = gvn->transform(new AddINode(span,init_trip));
set_subtree_ctrl( limit );
} // LoopLimitCheck
if (!UseCountedLoopSafepoints) {
// Check for SafePoint on backedge and remove
Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue );
*** 827,837 ****
--- 728,738 ----
Node* PhaseIdealLoop::exact_limit( IdealLoopTree *loop ) {
assert(loop->_head->is_CountedLoop(), "");
CountedLoopNode *cl = loop->_head->as_CountedLoop();
assert(cl->is_valid_counted_loop(), "");
- if (!LoopLimitCheck || ABS(cl->stride_con()) == 1 ||
cl->limit()->Opcode() == Op_LoopLimit) {
// Old code has exact limit (it could be incorrect in case of int overflow).
// Loop limit is exact with stride == 1. And loop may already have exact limit.
return cl->limit();
}
*** 1895,1911 ****
--- 1796,1810 ----
for (uint i=0; i<_nest; i++)
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
Node* entry = _head->in(LoopNode::EntryControl);
if (LoopLimitCheck) {
Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
if (predicate != NULL ) {
tty->print(" limit_check");
entry = entry->in(0)->in(0);
}
}
if (UseLoopPredicate) {
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
}
*** 2320,2330 ****
--- 2219,2229 ----
}
// Some parser-inserted loop predicates could never be used by loop
// predication or they were moved away from loop during some optimizations.
// For example, peeling. Eliminate them before next loop optimizations.
- if (UseLoopPredicate || LoopLimitCheck) {
eliminate_useless_predicates();
}
#ifndef PRODUCT
C->verify_graph_edges();
src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File