aboutsummaryrefslogtreecommitdiff
path: root/src/share
diff options
context:
space:
mode:
authorkvn <none@none>2011-03-21 11:28:14 -0700
committerkvn <none@none>2011-03-21 11:28:14 -0700
commit73ca1b6ce8807c6f82056410d89ee2db3fcf6518 (patch)
treee41da43e88066096d0d72eb4a747a6e596911030 /src/share
parent913215a6f1f34e97f77dd04e375162cbc26e6400 (diff)
7008866: Missing loop predicate for loop with multiple entries
Summary: Add predicates when loop head bytecode is parsed instead of when back branch bytecode is parsed. Reviewed-by: never
Diffstat (limited to 'src/share')
-rw-r--r--src/share/vm/opto/c2_globals.hpp3
-rw-r--r--src/share/vm/opto/graphKit.cpp43
-rw-r--r--src/share/vm/opto/graphKit.hpp4
-rw-r--r--src/share/vm/opto/idealKit.cpp12
-rw-r--r--src/share/vm/opto/idealKit.hpp3
-rw-r--r--src/share/vm/opto/library_call.cpp6
-rw-r--r--src/share/vm/opto/loopTransform.cpp345
-rw-r--r--src/share/vm/opto/loopUnswitch.cpp7
-rw-r--r--src/share/vm/opto/loopnode.cpp467
-rw-r--r--src/share/vm/opto/loopnode.hpp31
-rw-r--r--src/share/vm/opto/loopopts.cpp136
-rw-r--r--src/share/vm/opto/parse.hpp18
-rw-r--r--src/share/vm/opto/parse1.cpp76
-rw-r--r--src/share/vm/opto/parse2.cpp27
-rw-r--r--src/share/vm/opto/stringopts.cpp7
15 files changed, 704 insertions, 481 deletions
diff --git a/src/share/vm/opto/c2_globals.hpp b/src/share/vm/opto/c2_globals.hpp
index 159b28050..033074dad 100644
--- a/src/share/vm/opto/c2_globals.hpp
+++ b/src/share/vm/opto/c2_globals.hpp
@@ -180,6 +180,9 @@
develop(bool, TraceLoopPredicate, false, \
"Trace generation of loop predicates") \
\
+ develop(bool, TraceLoopOpts, false, \
+ "Trace executed loop optimizations") \
+ \
product(bool, OptimizeFill, false, \
"convert fill/copy loops into intrinsic") \
\
diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
index 80101d2da..b20513e67 100644
--- a/src/share/vm/opto/graphKit.cpp
+++ b/src/share/vm/opto/graphKit.cpp
@@ -3338,6 +3338,49 @@ InitializeNode* AllocateNode::initialization() {
return NULL;
}
+//----------------------------- loop predicates ---------------------------
+
+//------------------------------add_predicate_impl----------------------------
+void GraphKit::add_predicate_impl(Deoptimization::DeoptReason reason, int nargs) {
+ // Too many traps seen?
+ if (too_many_traps(reason)) {
+#ifdef ASSERT
+ if (TraceLoopPredicate) {
+ int tc = C->trap_count(reason);
+ tty->print("too many traps=%s tcount=%d in ",
+ Deoptimization::trap_reason_name(reason), tc);
+ method()->print(); // which method has too many predicate traps
+ tty->cr();
+ }
+#endif
+ // We cannot afford to take more traps here,
+ // do not generate predicate.
+ return;
+ }
+
+ Node *cont = _gvn.intcon(1);
+ Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont));
+ Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq));
+ IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
+ Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff));
+ C->add_predicate_opaq(opq);
+ {
+ PreserveJVMState pjvms(this);
+ set_control(iffalse);
+ _sp += nargs;
+ uncommon_trap(reason, Deoptimization::Action_maybe_recompile);
+ }
+ Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff));
+ set_control(iftrue);
+}
+
+//------------------------------add_predicate---------------------------------
+void GraphKit::add_predicate(int nargs) {
+ if (UseLoopPredicate) {
+ add_predicate_impl(Deoptimization::Reason_predicate, nargs);
+ }
+}
+
//----------------------------- store barriers ----------------------------
#define __ ideal.
diff --git a/src/share/vm/opto/graphKit.hpp b/src/share/vm/opto/graphKit.hpp
index 721bd8640..2f7a7d5ab 100644
--- a/src/share/vm/opto/graphKit.hpp
+++ b/src/share/vm/opto/graphKit.hpp
@@ -793,6 +793,10 @@ class GraphKit : public Phase {
if (!tst->is_Con()) record_for_igvn(iff); // Range-check and Null-check removal is later
return iff;
}
+
+ // Insert a loop predicate into the graph
+ void add_predicate(int nargs = 0);
+ void add_predicate_impl(Deoptimization::DeoptReason reason, int nargs);
};
// Helper class to support building of control flow branches. Upon
diff --git a/src/share/vm/opto/idealKit.cpp b/src/share/vm/opto/idealKit.cpp
index 5cd6f9bde..bc7aaaa6a 100644
--- a/src/share/vm/opto/idealKit.cpp
+++ b/src/share/vm/opto/idealKit.cpp
@@ -154,8 +154,18 @@ void IdealKit::end_if() {
//
// Pushes the loop top cvstate first, then the else (loop exit) cvstate
// onto the stack.
-void IdealKit::loop(IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
+void IdealKit::loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask relop, Node* limit, float prob, float cnt) {
assert((state() & (BlockS|LoopS|IfThenS|ElseS)), "bad state for new loop");
+
+ // Sync IdealKit and graphKit.
+ gkit->set_all_memory(this->merged_memory());
+ gkit->set_control(this->ctrl());
+ // Add loop predicate.
+ gkit->add_predicate(nargs);
+ // Update IdealKit memory.
+ this->set_all_memory(gkit->merged_memory());
+ this->set_ctrl(gkit->control());
+
set(iv, init);
Node* head = make_label(1);
bind(head);
diff --git a/src/share/vm/opto/idealKit.hpp b/src/share/vm/opto/idealKit.hpp
index b5d894ca2..8192a4462 100644
--- a/src/share/vm/opto/idealKit.hpp
+++ b/src/share/vm/opto/idealKit.hpp
@@ -29,6 +29,7 @@
#include "opto/cfgnode.hpp"
#include "opto/connode.hpp"
#include "opto/divnode.hpp"
+#include "opto/graphKit.hpp"
#include "opto/mulnode.hpp"
#include "opto/phaseX.hpp"
#include "opto/subnode.hpp"
@@ -160,7 +161,7 @@ class IdealKit: public StackObj {
bool push_new_state = true);
void else_();
void end_if();
- void loop(IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit,
+ void loop(GraphKit* gkit, int nargs, IdealVariable& iv, Node* init, BoolTest::mask cmp, Node* limit,
float prob = PROB_LIKELY(0.9), float cnt = COUNT_UNKNOWN);
void end_loop();
Node* make_label(int goto_ct);
diff --git a/src/share/vm/opto/library_call.cpp b/src/share/vm/opto/library_call.cpp
index 6a6ca27fe..3a9524ae4 100644
--- a/src/share/vm/opto/library_call.cpp
+++ b/src/share/vm/opto/library_call.cpp
@@ -1101,6 +1101,8 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
float likely = PROB_LIKELY(0.9);
float unlikely = PROB_UNLIKELY(0.9);
+ const int nargs = 2; // number of arguments to push back for uncommon trap in predicate
+
const int value_offset = java_lang_String::value_offset_in_bytes();
const int count_offset = java_lang_String::count_offset_in_bytes();
const int offset_offset = java_lang_String::offset_offset_in_bytes();
@@ -1138,12 +1140,12 @@ Node* LibraryCallKit::string_indexOf(Node* string_object, ciTypeArray* target_ar
Node* return_ = __ make_label(1);
__ set(rtn,__ ConI(-1));
- __ loop(i, sourceOffset, BoolTest::lt, sourceEnd); {
+ __ loop(this, nargs, i, sourceOffset, BoolTest::lt, sourceEnd); {
Node* i2 = __ AddI(__ value(i), targetCountLess1);
// pin to prohibit loading of "next iteration" value which may SEGV (rare)
Node* src = load_array_element(__ ctrl(), source, i2, TypeAryPtr::CHARS);
__ if_then(src, BoolTest::eq, lastChar, unlikely); {
- __ loop(j, zero, BoolTest::lt, targetCountLess1); {
+ __ loop(this, nargs, j, zero, BoolTest::lt, targetCountLess1); {
Node* tpj = __ AddI(targetOffset, __ value(j));
Node* targ = load_array_element(no_ctrl, target, tpj, target_type);
Node* ipj = __ AddI(__ value(i), __ value(j));
diff --git a/src/share/vm/opto/loopTransform.cpp b/src/share/vm/opto/loopTransform.cpp
index 9de938d25..dfccee43d 100644
--- a/src/share/vm/opto/loopTransform.cpp
+++ b/src/share/vm/opto/loopTransform.cpp
@@ -205,6 +205,8 @@ Node* IdealLoopTree::reassociate_add_sub(Node* n1, PhaseIdealLoop *phase) {
}
phase->register_new_node(addx, phase->get_ctrl(x));
phase->_igvn.replace_node(n1, addx);
+ assert(phase->get_loop(phase->get_ctrl(n1)) == this, "");
+ _body.yank(n1);
return addx;
}
@@ -307,15 +309,21 @@ void PhaseIdealLoop::do_peeling( IdealLoopTree *loop, Node_List &old_new ) {
// iterations adjusted. Therefore, we need to declare this loop as
// no longer a 'main' loop; it will need new pre and post loops before
// we can do further RCE.
+#ifndef PRODUCT
+ if (TraceLoopOpts) {
+ tty->print("Peel ");
+ loop->dump_head();
+ }
+#endif
Node *h = loop->_head;
- if( h->is_CountedLoop() ) {
+ if (h->is_CountedLoop()) {
CountedLoopNode *cl = h->as_CountedLoop();
assert(cl->trip_count() > 0, "peeling a fully unrolled loop");
cl->set_trip_count(cl->trip_count() - 1);
- if( cl->is_main_loop() ) {
+ if (cl->is_main_loop()) {
cl->set_normal_loop();
#ifndef PRODUCT
- if( PrintOpto && VerifyLoopOptimizations ) {
+ if (PrintOpto && VerifyLoopOptimizations) {
tty->print("Peeling a 'main' loop; resetting to 'normal' ");
loop->dump_head();
}
@@ -645,6 +653,15 @@ Node *PhaseIdealLoop::clone_up_backedge_goo( Node *back_ctrl, Node *preheader_ct
// alignment. Useful to unroll loops that do no array accesses.
void PhaseIdealLoop::insert_pre_post_loops( IdealLoopTree *loop, Node_List &old_new, bool peel_only ) {
+#ifndef PRODUCT
+ if (TraceLoopOpts) {
+ if (peel_only)
+ tty->print("PeelMainPost ");
+ else
+ tty->print("PreMainPost ");
+ loop->dump_head();
+ }
+#endif
C->set_major_progress();
// Find common pieces of the loop being guarded with pre & post loops
@@ -897,16 +914,19 @@ bool IdealLoopTree::is_invariant(Node* n) const {
//------------------------------do_unroll--------------------------------------
// Unroll the loop body one step - make each trip do 2 iterations.
void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool adjust_min_trip ) {
- assert( LoopUnrollLimit, "" );
+ assert(LoopUnrollLimit, "");
+ CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
+ CountedLoopEndNode *loop_end = loop_head->loopexit();
+ assert(loop_end, "");
#ifndef PRODUCT
- if( PrintOpto && VerifyLoopOptimizations ) {
+ if (PrintOpto && VerifyLoopOptimizations) {
tty->print("Unrolling ");
loop->dump_head();
+ } else if (TraceLoopOpts) {
+ tty->print("Unroll %d ", loop_head->unrolled_count()*2);
+ loop->dump_head();
}
#endif
- CountedLoopNode *loop_head = loop->_head->as_CountedLoop();
- CountedLoopEndNode *loop_end = loop_head->loopexit();
- assert( loop_end, "" );
// Remember loop node count before unrolling to detect
// if rounds of unroll,optimize are making progress
@@ -915,7 +935,7 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
Node *ctrl = loop_head->in(LoopNode::EntryControl);
Node *limit = loop_head->limit();
Node *init = loop_head->init_trip();
- Node *strid = loop_head->stride();
+ Node *stride = loop_head->stride();
Node *opaq = NULL;
if( adjust_min_trip ) { // If not maximally unrolling, need adjustment
@@ -955,13 +975,13 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
// odd iteration: (trip_cnt & ~1). Then back compute a new limit.
Node *span = new (C, 3) SubINode( limit, init );
register_new_node( span, ctrl );
- Node *trip = new (C, 3) DivINode( 0, span, strid );
+ Node *trip = new (C, 3) DivINode( 0, span, stride );
register_new_node( trip, ctrl );
Node *mtwo = _igvn.intcon(-2);
set_ctrl(mtwo, C->root());
Node *rond = new (C, 3) AndINode( trip, mtwo );
register_new_node( rond, ctrl );
- Node *spn2 = new (C, 3) MulINode( rond, strid );
+ Node *spn2 = new (C, 3) MulINode( rond, stride );
register_new_node( spn2, ctrl );
Node *lim2 = new (C, 3) AddINode( spn2, init );
register_new_node( lim2, ctrl );
@@ -1040,17 +1060,23 @@ void PhaseIdealLoop::do_unroll( IdealLoopTree *loop, Node_List &old_new, bool ad
void PhaseIdealLoop::do_maximally_unroll( IdealLoopTree *loop, Node_List &old_new ) {
CountedLoopNode *cl = loop->_head->as_CountedLoop();
- assert( cl->trip_count() > 0, "");
+ assert(cl->trip_count() > 0, "");
+#ifndef PRODUCT
+ if (TraceLoopOpts) {
+ tty->print("MaxUnroll %d ", cl->trip_count());
+ loop->dump_head();
+ }
+#endif
// If loop is tripping an odd number of times, peel odd iteration
- if( (cl->trip_count() & 1) == 1 ) {
- do_peeling( loop, old_new );
+ if ((cl->trip_count() & 1) == 1) {
+ do_peeling(loop, old_new);
}
// Now its tripping an even number of times remaining. Double loop body.
// Do not adjust pre-guards; they are not needed and do not exist.
- if( cl->trip_count() > 0 ) {
- do_unroll( loop, old_new, false );
+ if (cl->trip_count() > 0) {
+ do_unroll(loop, old_new, false);
}
}
@@ -1227,35 +1253,55 @@ bool PhaseIdealLoop::is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale,
// Eliminate range-checks and other trip-counter vs loop-invariant tests.
void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
#ifndef PRODUCT
- if( PrintOpto && VerifyLoopOptimizations ) {
+ if (PrintOpto && VerifyLoopOptimizations) {
tty->print("Range Check Elimination ");
loop->dump_head();
+ } else if (TraceLoopOpts) {
+ tty->print("RangeCheck ");
+ loop->dump_head();
}
#endif
- assert( RangeCheckElimination, "" );
+ assert(RangeCheckElimination, "");
CountedLoopNode *cl = loop->_head->as_CountedLoop();
- assert( cl->is_main_loop(), "" );
+ assert(cl->is_main_loop(), "");
+
+ // protect against stride not being a constant
+ if (!cl->stride_is_con())
+ return;
// Find the trip counter; we are iteration splitting based on it
Node *trip_counter = cl->phi();
// Find the main loop limit; we will trim it's iterations
// to not ever trip end tests
Node *main_limit = cl->limit();
- // Find the pre-loop limit; we will expand it's iterations to
- // not ever trip low tests.
+
+ // Need to find the main-loop zero-trip guard
Node *ctrl = cl->in(LoopNode::EntryControl);
- assert( ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "" );
+ assert(ctrl->Opcode() == Op_IfTrue || ctrl->Opcode() == Op_IfFalse, "");
Node *iffm = ctrl->in(0);
- assert( iffm->Opcode() == Op_If, "" );
+ assert(iffm->Opcode() == Op_If, "");
+ Node *bolzm = iffm->in(1);
+ assert(bolzm->Opcode() == Op_Bool, "");
+ Node *cmpzm = bolzm->in(1);
+ assert(cmpzm->is_Cmp(), "");
+ Node *opqzm = cmpzm->in(2);
+ // Can not optimize a loop if pre-loop Opaque1 node is optimized
+ // away and then another round of loop opts attempted.
+ if (opqzm->Opcode() != Op_Opaque1)
+ return;
+ assert(opqzm->in(1) == main_limit, "do not understand situation");
+
+ // Find the pre-loop limit; we will expand it's iterations to
+ // not ever trip low tests.
Node *p_f = iffm->in(0);
- assert( p_f->Opcode() == Op_IfFalse, "" );
+ assert(p_f->Opcode() == Op_IfFalse, "");
CountedLoopEndNode *pre_end = p_f->in(0)->as_CountedLoopEnd();
- assert( pre_end->loopnode()->is_pre_loop(), "" );
+ assert(pre_end->loopnode()->is_pre_loop(), "");
Node *pre_opaq1 = pre_end->limit();
// Occasionally it's possible for a pre-loop Opaque1 node to be
// optimized away and then another round of loop opts attempted.
// We can not optimize this particular loop in that case.
- if( pre_opaq1->Opcode() != Op_Opaque1 )
+ if (pre_opaq1->Opcode() != Op_Opaque1)
return;
Opaque1Node *pre_opaq = (Opaque1Node*)pre_opaq1;
Node *pre_limit = pre_opaq->in(1);
@@ -1266,25 +1312,11 @@ void PhaseIdealLoop::do_range_check( IdealLoopTree *loop, Node_List &old_new ) {
// Ensure the original loop limit is available from the
// pre-loop Opaque1 node.
Node *orig_limit = pre_opaq->original_loop_limit();
- if( orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP )
- return;
-
- // Need to find the main-loop zero-trip guard
- Node *bolzm = iffm->in(1);
- assert( bolzm->Opcode() == Op_Bool, "" );
- Node *cmpzm = bolzm->in(1);
- assert( cmpzm->is_Cmp(), "" );
- Node *opqzm = cmpzm->in(2);
- if( opqzm->Opcode() != Op_Opaque1 )
+ if (orig_limit == NULL || _igvn.type(orig_limit) == Type::TOP)
return;
- assert( opqzm->in(1) == main_limit, "do not understand situation" );
// Must know if its a count-up or count-down loop
- // protect against stride not being a constant
- if ( !cl->stride_is_con() ) {
- return;
- }
int stride_con = cl->stride_con();
Node *zero = _igvn.intcon(0);
Node *one = _igvn.intcon(1);
@@ -1566,16 +1598,24 @@ void IdealLoopTree::adjust_loop_exit_prob( PhaseIdealLoop *phase ) {
// have on the last iteration. This will break the loop.
bool IdealLoopTree::policy_do_remove_empty_loop( PhaseIdealLoop *phase ) {
// Minimum size must be empty loop
- if( _body.size() > 7/*number of nodes in an empty loop*/ ) return false;
+ if (_body.size() > 7/*number of nodes in an empty loop*/)
+ return false;
- if( !_head->is_CountedLoop() ) return false; // Dead loop
+ if (!_head->is_CountedLoop())
+ return false; // Dead loop
CountedLoopNode *cl = _head->as_CountedLoop();
- if( !cl->loopexit() ) return false; // Malformed loop
- if( !phase->is_member(this,phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue)) ) )
+ if (!cl->loopexit())
+ return false; // Malformed loop
+ if (!phase->is_member(this, phase->get_ctrl(cl->loopexit()->in(CountedLoopEndNode::TestValue))))
return false; // Infinite loop
#ifndef PRODUCT
- if( PrintOpto )
- tty->print_cr("Removing empty loop");
+ if (PrintOpto) {
+ tty->print("Removing empty loop");
+ this->dump_head();
+ } else if (TraceLoopOpts) {
+ tty->print("Empty ");
+ this->dump_head();
+ }
#endif
#ifdef ASSERT
// Ensure only one phi which is the iv.
@@ -1720,7 +1760,7 @@ bool IdealLoopTree::iteration_split_impl( PhaseIdealLoop *phase, Node_List &old_
//------------------------------iteration_split--------------------------------
bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new ) {
// Recursively iteration split nested loops
- if( _child && !_child->iteration_split( phase, old_new ))
+ if (_child && !_child->iteration_split(phase, old_new))
return false;
// Clean out prior deadwood
@@ -1729,21 +1769,20 @@ bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new )
// Look for loop-exit tests with my 50/50 guesses from the Parsing stage.
// Replace with a 1-in-10 exit guess.
- if( _parent /*not the root loop*/ &&
+ if (_parent /*not the root loop*/ &&
!_irreducible &&
// Also ignore the occasional dead backedge
- !tail()->is_top() ) {
+ !tail()->is_top()) {
adjust_loop_exit_prob(phase);
}
-
// Gate unrolling, RCE and peeling efforts.
- if( !_child && // If not an inner loop, do not split
+ if (!_child && // If not an inner loop, do not split
!_irreducible &&
_allow_optimizations &&
- !tail()->is_top() ) { // Also ignore the occasional dead backedge
+ !tail()->is_top()) { // Also ignore the occasional dead backedge
if (!_has_call) {
- if (!iteration_split_impl( phase, old_new )) {
+ if (!iteration_split_impl(phase, old_new)) {
return false;
}
} else if (policy_unswitching(phase)) {
@@ -1752,16 +1791,17 @@ bool IdealLoopTree::iteration_split( PhaseIdealLoop *phase, Node_List &old_new )
}
// Minor offset re-organization to remove loop-fallout uses of
- // trip counter.
- if( _head->is_CountedLoop() ) phase->reorg_offsets( this );
- if( _next && !_next->iteration_split( phase, old_new ))
+ // trip counter when there was no major reshaping.
+ phase->reorg_offsets(this);
+
+ if (_next && !_next->iteration_split(phase, old_new))
return false;
return true;
}
//-------------------------------is_uncommon_trap_proj----------------------------
// Return true if proj is the form of "proj->[region->..]call_uct"
-bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, bool must_reason_predicate) {
+bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason) {
int path_limit = 10;
assert(proj, "invalid argument");
Node* out = proj;
@@ -1772,8 +1812,8 @@ bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, bool must_reason_pred
if (out->is_CallStaticJava()) {
int req = out->as_CallStaticJava()->uncommon_trap_request();
if (req != 0) {
- Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(req);
- if (!must_reason_predicate || reason == Deoptimization::Reason_predicate){
+ Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
+ if (trap_reason == reason || reason == Deoptimization::Reason_none) {
return true;
}
}
@@ -1790,15 +1830,15 @@ bool PhaseIdealLoop::is_uncommon_trap_proj(ProjNode* proj, bool must_reason_pred
// other_proj->[region->..]call_uct"
//
// "must_reason_predicate" means the uct reason must be Reason_predicate
-bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reason_predicate) {
+bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, Deoptimization::DeoptReason reason) {
Node *in0 = proj->in(0);
if (!in0->is_If()) return false;
// Variation of a dead If node.
if (in0->outcnt() < 2) return false;
IfNode* iff = in0->as_If();
- // we need "If(Conv2B(Opaque1(...)))" pattern for must_reason_predicate
- if (must_reason_predicate) {
+ // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate
+ if (reason != Deoptimization::Reason_none) {
if (iff->in(1)->Opcode() != Op_Conv2B ||
iff->in(1)->in(1)->Opcode() != Op_Opaque1) {
return false;
@@ -1806,7 +1846,19 @@ bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reaso
}
ProjNode* other_proj = iff->proj_out(1-proj->_con)->as_Proj();
- return is_uncommon_trap_proj(other_proj, must_reason_predicate);
+ return is_uncommon_trap_proj(other_proj, reason);
+}
+
+//-------------------------------register_control-------------------------
+void PhaseIdealLoop::register_control(Node* n, IdealLoopTree *loop, Node* pred) {
+ assert(n->is_CFG(), "must be control node");
+ _igvn.register_new_node_with_optimizer(n);
+ loop->_body.push(n);
+ set_loop(n, loop);
+ // When called from beautify_loops() idom is not constructed yet.
+ if (_idom != NULL) {
+ set_idom(n, pred, dom_depth(pred));
+ }
}
//------------------------------create_new_if_for_predicate------------------------
@@ -1843,8 +1895,10 @@ bool PhaseIdealLoop::is_uncommon_trap_if_pattern(ProjNode *proj, bool must_reaso
//
// We will create a region to guard the uct call if there is no one there.
// The true projecttion (if_cont) of the new_iff is returned.
-ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj) {
- assert(is_uncommon_trap_if_pattern(cont_proj, true), "must be a uct if pattern!");
+// This code is also used to clone predicates to clonned loops.
+ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
+ Deoptimization::DeoptReason reason) {
+ assert(is_uncommon_trap_if_pattern(cont_proj, reason), "must be a uct if pattern!");
IfNode* iff = cont_proj->in(0)->as_If();
ProjNode *uncommon_proj = iff->proj_out(1 - cont_proj->_con);
@@ -1854,57 +1908,84 @@ ProjNode* PhaseIdealLoop::create_new_if_for_predicate(ProjNode* cont_proj) {
if (!rgn->is_Region()) { // create a region to guard the call
assert(rgn->is_Call(), "must be call uct");
CallNode* call = rgn->as_Call();
+ IdealLoopTree* loop = get_loop(call);
rgn = new (C, 1) RegionNode(1);
- _igvn.set_type(rgn, rgn->bottom_type());
rgn->add_req(uncommon_proj);
- set_idom(rgn, idom(uncommon_proj), dom_depth(uncommon_proj)+1);
+ register_control(rgn, loop, uncommon_proj);
_igvn.hash_delete(call);
call->set_req(0, rgn);
+ // When called from beautify_loops() idom is not constructed yet.
+ if (_idom != NULL) {
+ set_idom(call, rgn, dom_depth(rgn));
+ }
}
+ Node* entry = iff->in(0);
+ if (new_entry != NULL) {
+ // Clonning the predicate to new location.
+ entry = new_entry;
+ }
// Create new_iff
- uint iffdd = dom_depth(iff);
- IdealLoopTree* lp = get_loop(iff);
- IfNode *new_iff = new (C, 2) IfNode(iff->in(0), NULL, iff->_prob, iff->_fcnt);
- register_node(new_iff, lp, idom(iff), iffdd);
+ IdealLoopTree* lp = get_loop(entry);
+ IfNode *new_iff = new (C, 2) IfNode(entry, NULL, iff->_prob, iff->_fcnt);
+ register_control(new_iff, lp, entry);
Node *if_cont = new (C, 1) IfTrueNode(new_iff);
Node *if_uct = new (C, 1) IfFalseNode(new_iff);
if (cont_proj->is_IfFalse()) {
// Swap
Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
}
- register_node(if_cont, lp, new_iff, iffdd);
- register_node(if_uct, get_loop(rgn), new_iff, iffdd);
-
- // if_cont to iff
- _igvn.hash_delete(iff);
- iff->set_req(0, if_cont);
- set_idom(iff, if_cont, dom_depth(iff));
+ register_control(if_cont, lp, new_iff);
+ register_control(if_uct, get_loop(rgn), new_iff);
// if_uct to rgn
_igvn.hash_delete(rgn);
rgn->add_req(if_uct);
- Node* ridom = idom(rgn);
- Node* nrdom = dom_lca(ridom, new_iff);
- set_idom(rgn, nrdom, dom_depth(rgn));
-
+ // When called from beautify_loops() idom is not constructed yet.
+ if (_idom != NULL) {
+ Node* ridom = idom(rgn);
+ Node* nrdom = dom_lca(ridom, new_iff);
+ set_idom(rgn, nrdom, dom_depth(rgn));
+ }
// rgn must have no phis
assert(!rgn->as_Region()->has_phi(), "region must have no phis");
+ if (new_entry == NULL) {
+ // Attach if_cont to iff
+ _igvn.hash_delete(iff);
+ iff->set_req(0, if_cont);
+ if (_idom != NULL) {
+ set_idom(iff, if_cont, dom_depth(iff));
+ }
+ }
return if_cont->as_Proj();
}
-//------------------------------find_predicate_insertion_point--------------------------
+//--------------------------find_predicate_insertion_point-------------------
// Find a good location to insert a predicate
-ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c) {
- if (start_c == C->root() || !start_c->is_Proj())
+ProjNode* PhaseIdealLoop::find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason) {
+ if (start_c == NULL || !start_c->is_Proj())
return NULL;
- if (is_uncommon_trap_if_pattern(start_c->as_Proj(), true/*Reason_Predicate*/)) {
+ if (is_uncommon_trap_if_pattern(start_c->as_Proj(), reason)) {
return start_c->as_Proj();
}
return NULL;
}
+//--------------------------find_predicate------------------------------------
+// Find a predicate
+Node* PhaseIdealLoop::find_predicate(Node* entry) {
+ Node* predicate = NULL;
+ if (UseLoopPredicate) {
+ predicate = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+ if (predicate != NULL) { // right pattern that can be used by loop predication
+ assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+ return entry;
+ }
+ }
+ return NULL;
+}
+
//------------------------------Invariance-----------------------------------
// Helper class for loop_predication_impl to compute invariance on the fly and
// clone invariants.
@@ -2151,6 +2232,11 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
return false;
}
+ if (loop->_head->unique_ctrl_out()->Opcode() == Op_NeverBranch) {
+ // do nothing for infinite loops
+ return false;
+ }
+
CountedLoopNode *cl = NULL;
if (loop->_head->is_CountedLoop()) {
cl = loop->_head->as_CountedLoop();
@@ -2158,40 +2244,22 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
if (!cl->is_normal_loop()) return false;
}
- // Too many traps seen?
- bool tmt = C->too_many_traps(C->method(), 0, Deoptimization::Reason_predicate);
- int tc = C->trap_count(Deoptimization::Reason_predicate);
- if (tmt || tc > 0) {
- if (TraceLoopPredicate) {
- tty->print_cr("too many predicate traps: %d", tc);
- C->method()->print(); // which method has too many predicate traps
- tty->print_cr("");
- }
- return false;
- }
-
LoopNode *lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
- ProjNode *predicate_proj = find_predicate_insertion_point(entry);
- if (!predicate_proj){
+ ProjNode *predicate_proj = find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
+ if (!predicate_proj) {
#ifndef PRODUCT
if (TraceLoopPredicate) {
tty->print("missing predicate:");
loop->dump_head();
+ lpn->dump(1);
}
#endif
return false;
}
-
ConNode* zero = _igvn.intcon(0);
set_ctrl(zero, C->root());
- Node *cond_false = new (C, 2) Conv2BNode(zero);
- register_new_node(cond_false, C->root());
- ConNode* one = _igvn.intcon(1);
- set_ctrl(one, C->root());
- Node *cond_true = new (C, 2) Conv2BNode(one);
- register_new_node(cond_true, C->root());
ResourceArea *area = Thread::current()->resource_area();
Invariance invar(area, loop);
@@ -2218,7 +2286,7 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
ProjNode* proj = if_proj_list.pop()->as_Proj();
IfNode* iff = proj->in(0)->as_If();
- if (!is_uncommon_trap_if_pattern(proj)) {
+ if (!is_uncommon_trap_if_pattern(proj, Deoptimization::Reason_none)) {
if (loop->is_loop_exit(iff)) {
// stop processing the remaining projs in the list because the execution of them
// depends on the condition of "iff" (iff->in(1)).
@@ -2242,7 +2310,8 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
BoolNode* bol = test->as_Bool();
if (invar.is_invariant(bol)) {
// Invariant test
- new_predicate_proj = create_new_if_for_predicate(predicate_proj);
+ new_predicate_proj = create_new_if_for_predicate(predicate_proj, NULL,
+ Deoptimization::Reason_predicate);
Node* ctrl = new_predicate_proj->in(0)->as_If()->in(0);
BoolNode* new_predicate_bol = invar.clone(bol, ctrl)->as_Bool();
@@ -2256,8 +2325,15 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
IfNode* new_predicate_iff = new_predicate_proj->in(0)->as_If();
_igvn.hash_delete(new_predicate_iff);
new_predicate_iff->set_req(1, new_predicate_bol);
- if (TraceLoopPredicate) tty->print_cr("invariant if%s: %d", negated ? " negated" : "", new_predicate_iff->_idx);
-
+#ifndef PRODUCT
+ if (TraceLoopPredicate) {
+ tty->print("Predicate invariant if%s: %d ", negated ? " negated" : "", new_predicate_iff->_idx);
+ loop->dump_head();
+ } else if (TraceLoopOpts) {
+ tty->print("Predicate IC ");
+ loop->dump_head();
+ }
+#endif
} else if (cl != NULL && loop->is_range_check_if(iff, this, invar)) {
assert(proj->_con == predicate_proj->_con, "must match");
@@ -2281,8 +2357,8 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
// lower_bound test will dominate the upper bound test and all
// cloned or created nodes will use the lower bound test as
// their declared control.
- ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj);
- ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj);
+ ProjNode* lower_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
+ ProjNode* upper_bound_proj = create_new_if_for_predicate(predicate_proj, NULL, Deoptimization::Reason_predicate);
assert(upper_bound_proj->in(0)->as_If()->in(0) == lower_bound_proj, "should dominate");
Node *ctrl = lower_bound_proj->in(0)->as_If()->in(0);
@@ -2311,41 +2387,24 @@ bool PhaseIdealLoop::loop_predication_impl(IdealLoopTree *loop) {
// Fall through into rest of the clean up code which will move
// any dependent nodes onto the upper bound test.
new_predicate_proj = upper_bound_proj;
+
+#ifndef PRODUCT
+ if (TraceLoopOpts && !TraceLoopPredicate) {
+ tty->print("Predicate RC ");
+ loop->dump_head();
+ }
+#endif
} else {
- // The other proj of the "iff" is a uncommon trap projection, and we can assume
- // the other proj will not be executed ("executed" means uct raised).
+ // Loop variant check (for example, range check in non-counted loop)
+ // with uncommon trap.
continue;
}
-
+ assert(new_predicate_proj != NULL, "sanity");
// Success - attach condition (new_predicate_bol) to predicate if
invar.map_ctrl(proj, new_predicate_proj); // so that invariance test can be appropriate
- // Eliminate the old if in the loop body
- _igvn.hash_delete(iff);
- iff->set_req(1, proj->is_IfFalse() ? cond_false : cond_true);
-
- Node* ctrl = new_predicate_proj; // new control
- ProjNode* dp = proj; // old control
- assert(get_loop(dp) == loop, "guaranteed at the time of collecting proj");
- // Find nodes (depends only on the test) off the surviving projection;
- // move them outside the loop with the control of proj_clone
- for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
- Node* cd = dp->fast_out(i); // Control-dependent node
- if (cd->depends_only_on_test()) {
- assert(cd->in(0) == dp, "");
- _igvn.hash_delete(cd);
- cd->set_req(0, ctrl); // ctrl, not NULL
- set_early_ctrl(cd);
- _igvn._worklist.push(cd);
- IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
- if (new_loop != loop) {
- if (!loop->_child) loop->_body.yank(cd);
- if (!new_loop->_child ) new_loop->_body.push(cd);
- }
- --i;
- --imax;
- }
- }
+ // Eliminate the old If in the loop body
+ dominated_by( new_predicate_proj, iff, proj->_con != new_predicate_proj->_con );
hoisted = true;
C->set_major_progress();
diff --git a/src/share/vm/opto/loopUnswitch.cpp b/src/share/vm/opto/loopUnswitch.cpp
index 8cfd5fb6b..fa8e58a44 100644
--- a/src/share/vm/opto/loopUnswitch.cpp
+++ b/src/share/vm/opto/loopUnswitch.cpp
@@ -110,6 +110,13 @@ void PhaseIdealLoop::do_unswitching (IdealLoopTree *loop, Node_List &old_new) {
IfNode* unswitch_iff = find_unswitching_candidate((const IdealLoopTree *)loop);
assert(unswitch_iff != NULL, "should be at least one");
+#ifndef PRODUCT
+ if (TraceLoopOpts) {
+ tty->print("Unswitch %d ", head->unswitch_count()+1);
+ loop->dump_head();
+ }
+#endif
+
// Need to revert back to normal loop
if (head->is_CountedLoop() && !head->as_CountedLoop()->is_normal_loop()) {
head->as_CountedLoop()->set_normal_loop();
diff --git a/src/share/vm/opto/loopnode.cpp b/src/share/vm/opto/loopnode.cpp
index 204eeea65..cfcea4c6f 100644
--- a/src/share/vm/opto/loopnode.cpp
+++ b/src/share/vm/opto/loopnode.cpp
@@ -56,12 +56,32 @@ const Node* Node::is_loop_iv() const {
// Dump special per-node info
#ifndef PRODUCT
void LoopNode::dump_spec(outputStream *st) const {
- if( is_inner_loop () ) st->print( "inner " );
- if( is_partial_peel_loop () ) st->print( "partial_peel " );
- if( partial_peel_has_failed () ) st->print( "partial_peel_failed " );
+ if (is_inner_loop()) st->print( "inner " );
+ if (is_partial_peel_loop()) st->print( "partial_peel " );
+ if (partial_peel_has_failed()) st->print( "partial_peel_failed " );
}
#endif
+//------------------------------is_valid_counted_loop-------------------------
+bool LoopNode::is_valid_counted_loop() const {
+ if (is_CountedLoop()) {
+ CountedLoopNode* l = as_CountedLoop();
+ CountedLoopEndNode* le = l->loopexit();
+ if (le != NULL &&
+ le->proj_out(1 /* true */) == l->in(LoopNode::LoopBackControl)) {
+ Node* phi = l->phi();
+ Node* exit = le->proj_out(0 /* false */);
+ if (exit != NULL && exit->Opcode() == Op_IfFalse &&
+ phi != NULL && phi->is_Phi() &&
+ phi->in(LoopNode::LoopBackControl) == l->incr() &&
+ le->loopnode() == l && le->stride_is_con()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
//------------------------------get_early_ctrl---------------------------------
// Compute earliest legal control
Node *PhaseIdealLoop::get_early_ctrl( Node *n ) {
@@ -142,43 +162,44 @@ void PhaseIdealLoop::set_subtree_ctrl( Node *n ) {
}
//------------------------------is_counted_loop--------------------------------
-Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
+bool PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
PhaseGVN *gvn = &_igvn;
// Counted loop head must be a good RegionNode with only 3 not NULL
// control input edges: Self, Entry, LoopBack.
- if ( x->in(LoopNode::Self) == NULL || x->req() != 3 )
- return NULL;
+ if (x->in(LoopNode::Self) == NULL || x->req() != 3)
+ return false;
Node *init_control = x->in(LoopNode::EntryControl);
Node *back_control = x->in(LoopNode::LoopBackControl);
- if( init_control == NULL || back_control == NULL ) // Partially dead
- return NULL;
+ if (init_control == NULL || back_control == NULL) // Partially dead
+ return false;
// Must also check for TOP when looking for a dead loop
- if( init_control->is_top() || back_control->is_top() )
- return NULL;
+ if (init_control->is_top() || back_control->is_top())
+ return false;
// Allow funny placement of Safepoint
- if( back_control->Opcode() == Op_SafePoint )
+ if (back_control->Opcode() == Op_SafePoint)
back_control = back_control->in(TypeFunc::Control);
// Controlling test for loop
Node *iftrue = back_control;
uint iftrue_op = iftrue->Opcode();
- if( iftrue_op != Op_IfTrue &&
- iftrue_op != Op_IfFalse )
+ if (iftrue_op != Op_IfTrue &&
+ iftrue_op != Op_IfFalse)
// I have a weird back-control. Probably the loop-exit test is in
// the middle of the loop and I am looking at some trailing control-flow
// merge point. To fix this I would have to partially peel the loop.
- return NULL; // Obscure back-control
+ return false; // Obscure back-control
// Get boolean guarding loop-back test
Node *iff = iftrue->in(0);
- if( get_loop(iff) != loop || !iff->in(1)->is_Bool() ) return NULL;
+ if (get_loop(iff) != loop || !iff->in(1)->is_Bool())
+ return false;
BoolNode *test = iff->in(1)->as_Bool();
BoolTest::mask bt = test->_test._test;
float cl_prob = iff->as_If()->_prob;
- if( iftrue_op == Op_IfFalse ) {
+ if (iftrue_op == Op_IfFalse) {
bt = BoolTest(bt).negate();
cl_prob = 1.0 - cl_prob;
}
@@ -186,7 +207,7 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
Node *cmp = test->in(1);
int cmp_op = cmp->Opcode();
if( cmp_op != Op_CmpI )
- return NULL; // Avoid pointer & float compares
+ return false; // Avoid pointer & float compares
// Find the trip-counter increment & limit. Limit must be loop invariant.
Node *incr = cmp->in(1);
@@ -196,55 +217,64 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
// need 'loop()' test to tell if limit is loop invariant
// ---------
- if( !is_member( loop, get_ctrl(incr) ) ) { // Swapped trip counter and limit?
- Node *tmp = incr; // Then reverse order into the CmpI
+ if (!is_member(loop, get_ctrl(incr))) { // Swapped trip counter and limit?
+ Node *tmp = incr; // Then reverse order into the CmpI
incr = limit;
limit = tmp;
bt = BoolTest(bt).commute(); // And commute the exit test
}
- if( is_member( loop, get_ctrl(limit) ) ) // Limit must loop-invariant
- return NULL;
+ if (is_member(loop, get_ctrl(limit))) // Limit must be loop-invariant
+ return false;
+ if (!is_member(loop, get_ctrl(incr))) // Trip counter must be loop-variant
+ return false;
+ Node* phi_incr = NULL;
// Trip-counter increment must be commutative & associative.
- uint incr_op = incr->Opcode();
- if( incr_op == Op_Phi && incr->req() == 3 ) {
- incr = incr->in(2); // Assume incr is on backedge of Phi
- incr_op = incr->Opcode();
+ if (incr->is_Phi()) {
+ if (incr->as_Phi()->region() != x || incr->req() != 3)
+ return false; // Not simple trip counter expression
+ phi_incr = incr;
+ incr = phi_incr->in(LoopNode::LoopBackControl); // Assume incr is on backedge of Phi
+ if (!is_member(loop, get_ctrl(incr))) // Trip counter must be loop-variant
+ return false;
}
+
Node* trunc1 = NULL;
Node* trunc2 = NULL;
const TypeInt* iv_trunc_t = NULL;
if (!(incr = CountedLoopNode::match_incr_with_optional_truncation(incr, &trunc1, &trunc2, &iv_trunc_t))) {
- return NULL; // Funny increment opcode
+ return false; // Funny increment opcode
}
+ assert(incr->Opcode() == Op_AddI, "wrong increment code");
// Get merge point
Node *xphi = incr->in(1);
Node *stride = incr->in(2);
- if( !stride->is_Con() ) { // Oops, swap these
- if( !xphi->is_Con() ) // Is the other guy a constant?
- return NULL; // Nope, unknown stride, bail out
+ if (!stride->is_Con()) { // Oops, swap these
+ if (!xphi->is_Con()) // Is the other guy a constant?
+ return false; // Nope, unknown stride, bail out
Node *tmp = xphi; // 'incr' is commutative, so ok to swap
xphi = stride;
stride = tmp;
}
- //if( loop(xphi) != l) return NULL;// Merge point is in inner loop??
- if( !xphi->is_Phi() ) return NULL; // Too much math on the trip counter
- PhiNode *phi = xphi->as_Phi();
-
// Stride must be constant
- const Type *stride_t = stride->bottom_type();
- int stride_con = stride_t->is_int()->get_con();
- assert( stride_con, "missed some peephole opt" );
+ int stride_con = stride->get_int();
+ assert(stride_con != 0, "missed some peephole opt");
+
+ if (!xphi->is_Phi())
+ return false; // Too much math on the trip counter
+ if (phi_incr != NULL && phi_incr != xphi)
+ return false;
+ PhiNode *phi = xphi->as_Phi();
// Phi must be of loop header; backedge must wrap to increment
- if( phi->region() != x ) return NULL;
- if( trunc1 == NULL && phi->in(LoopNode::LoopBackControl) != incr ||
- trunc1 != NULL && phi->in(LoopNode::LoopBackControl) != trunc1 ) {
- return NULL;
+ if (phi->region() != x)
+ return false;
+ if (trunc1 == NULL && phi->in(LoopNode::LoopBackControl) != incr ||
+ trunc1 != NULL && phi->in(LoopNode::LoopBackControl) != trunc1) {
+ return false;
}
Node *init_trip = phi->in(LoopNode::EntryControl);
- //if (!init_trip->is_Con()) return NULL; // avoid rolling over MAXINT/MININT
// If iv trunc type is smaller than int, check for possible wrap.
if (!TypeInt::INT->higher_equal(iv_trunc_t)) {
@@ -267,12 +297,12 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
if (stride_con > 0) {
if (iv_trunc_t->_hi - phi_ft->_hi < stride_con ||
iv_trunc_t->_lo > phi_ft->_lo) {
- return NULL; // truncation may occur
+ return false; // truncation may occur
}
} else if (stride_con < 0) {
if (iv_trunc_t->_lo - phi_ft->_lo > stride_con ||
iv_trunc_t->_hi < phi_ft->_hi) {
- return NULL; // truncation may occur
+ return false; // truncation may occur
}
}
// No possibility of wrap so truncation can be discarded
@@ -281,35 +311,45 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
assert(trunc1 == NULL && trunc2 == NULL, "no truncation for int");
}
- // =================================================
- // ---- SUCCESS! Found A Trip-Counted Loop! -----
- //
- // Canonicalize the condition on the test. If we can exactly determine
- // the trip-counter exit value, then set limit to that value and use
- // a '!=' test. Otherwise use condition '<' for count-up loops and
- // '>' for count-down loops. If the condition is inverted and we will
- // be rolling through MININT to MAXINT, then bail out.
+ // If the condition is inverted and we will be rolling
+ // through MININT to MAXINT, then bail out.
+ if (bt == BoolTest::eq || // Bail out, but this loop trips at most twice!
+ // Odd stride
+ bt == BoolTest::ne && stride_con != 1 && stride_con != -1 ||
+ // Count down loop rolls through MAXINT
+ (bt == BoolTest::le || bt == BoolTest::lt) && stride_con < 0 ||
+ // Count up loop rolls through MININT
+ (bt == BoolTest::ge || bt == BoolTest::gt) && stride_con > 0 ) {
+ return false; // Bail out
+ }
- C->print_method("Before CountedLoop", 3);
+ const TypeInt* init_t = gvn->type(init_trip)->is_int();
+ const TypeInt* limit_t = gvn->type(limit)->is_int();
- // 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 );
- loop->_tail = iftrue;
+ if (stride_con > 0) {
+ long init_p = (long)init_t->_lo + stride_con;
+ if (init_p > (long)max_jint || init_p > (long)limit_t->_hi)
+ return false; // cyclic loop or this loop trips only once
+ } else {
+ long init_p = (long)init_t->_hi + stride_con;
+ if (init_p < (long)min_jint || init_p < (long)limit_t->_lo)
+ return false; // cyclic loop or this loop trips only once
}
+ // =================================================
+ // ---- SUCCESS! Found A Trip-Counted Loop! -----
+ //
+ assert(x->Opcode() == Op_Loop, "regular loops only");
+ C->print_method("Before CountedLoop", 3);
// 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 )
+ if (cmp->in(1) == phi || cmp->in(2) == phi)
limit = gvn->transform(new (C, 3) 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.
- const Type *limit_t = limit->bottom_type();
- const Type *init_t = init_trip->bottom_type();
Node *one_p = gvn->intcon( 1);
Node *one_m = gvn->intcon(-1);
@@ -317,15 +357,15 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
Node *hook = new (C, 6) Node(6);
switch( bt ) {
case BoolTest::eq:
- return NULL; // Bail out, but this loop trips at most twice!
+ ShouldNotReachHere();
case BoolTest::ne: // Ahh, the case we desire
- if( stride_con == 1 )
+ if (stride_con == 1)
trip_count = gvn->transform(new (C, 3) SubINode(limit,init_trip));
- else if( stride_con == -1 )
+ else if (stride_con == -1)
trip_count = gvn->transform(new (C, 3) SubINode(init_trip,limit));
else
- return NULL; // Odd stride; must prove we hit limit exactly
- set_subtree_ctrl( trip_count );
+ ShouldNotReachHere();
+ set_subtree_ctrl(trip_count);
//_loop.map(trip_count->_idx,loop(limit));
break;
case BoolTest::le: // Maybe convert to '<' case
@@ -338,7 +378,8 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
//_loop.map(limit->_idx,limit_loop);
// Fall into next case
case BoolTest::lt: { // Maybe convert to '!=' case
- if( stride_con < 0 ) return NULL; // Count down loop rolls through MAXINT
+ if (stride_con < 0) // Count down loop rolls through MAXINT
+ ShouldNotReachHere();
Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip));
set_subtree_ctrl( range );
hook->init_req(0, range);
@@ -367,7 +408,8 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
//_loop.map(limit->_idx,limit_loop);
// Fall into next case
case BoolTest::gt: { // Maybe convert to '!=' case
- if( stride_con > 0 ) return NULL; // count up loop rolls through MININT
+ if (stride_con > 0) // count up loop rolls through MININT
+ ShouldNotReachHere();
Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip));
set_subtree_ctrl( range );
hook->init_req(0, range);
@@ -385,7 +427,7 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
hook->init_req(3, trip_count);
break;
}
- }
+ } // switch( bt )
Node *span = gvn->transform(new (C, 3) MulINode(trip_count,stride));
set_subtree_ctrl( span );
@@ -394,83 +436,82 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
limit = gvn->transform(new (C, 3) AddINode(span,init_trip));
set_subtree_ctrl( limit );
+ // 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 );
+ 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,phi);
+ incr->set_req(1,nphi);
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();
- }
+
+ 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));
- Node *tmp = test->clone();
- assert( tmp->is_Bool(), "" );
- test = (BoolNode*)tmp;
- (*(BoolTest*)&test->_test)._test = bt; //BoolTest::ne;
+ test = test->clone()->as_Bool();
+ (*(BoolTest*)&test->_test)._test = bt;
test->set_req(1,cmp);
_igvn.register_new_node_with_optimizer(test);
set_ctrl(test, iff->in(0));
- // If the exit test is dead, STOP!
- if( test == NULL ) return NULL;
- _igvn.hash_delete(iff);
- iff->set_req_X( 1, test, &_igvn );
// Replace the old IfNode with a new LoopEndNode
- Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), iff->in(1), cl_prob, iff->as_If()->_fcnt ));
+ Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt ));
IfNode *le = lex->as_If();
uint dd = dom_depth(iff);
set_idom(le, le->in(0), dd); // Update dominance for loop exit
set_loop(le, loop);
// Get the loop-exit control
- Node *if_f = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue));
+ Node *iffalse = iff->as_If()->proj_out(!(iftrue_op == Op_IfTrue));
// Need to swap loop-exit and loop-back control?
- if( iftrue_op == Op_IfFalse ) {
+ if (iftrue_op == Op_IfFalse) {
Node *ift2=_igvn.register_new_node_with_optimizer(new (C, 1) IfTrueNode (le));
Node *iff2=_igvn.register_new_node_with_optimizer(new (C, 1) IfFalseNode(le));
loop->_tail = back_control = ift2;
set_loop(ift2, loop);
- set_loop(iff2, get_loop(if_f));
+ set_loop(iff2, get_loop(iffalse));
// Lazy update of 'get_ctrl' mechanism.
- lazy_replace_proj( if_f , iff2 );
- lazy_replace_proj( iftrue, ift2 );
+ lazy_replace_proj( iffalse, iff2 );
+ lazy_replace_proj( iftrue, ift2 );
// Swap names
- if_f = iff2;
- iftrue = ift2;
+ iffalse = iff2;
+ iftrue = ift2;
} else {
- _igvn.hash_delete(if_f );
+ _igvn.hash_delete(iffalse);
_igvn.hash_delete(iftrue);
- if_f ->set_req_X( 0, le, &_igvn );
- iftrue->set_req_X( 0, le, &_igvn );
+ iffalse->set_req_X( 0, le, &_igvn );
+ iftrue ->set_req_X( 0, le, &_igvn );
}
- set_idom(iftrue, le, dd+1);
- set_idom(if_f, le, dd+1);
+ set_idom(iftrue, le, dd+1);
+ set_idom(iffalse, le, dd+1);
+ assert(iff->outcnt() == 0, "should be dead now");
+ lazy_replace( iff, le ); // fix 'get_ctrl'
// Now setup a new CountedLoopNode to replace the existing LoopNode
CountedLoopNode *l = new (C, 3) CountedLoopNode(init_control, back_control);
+ l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve
// The following assert is approximately true, and defines the intention
// of can_be_counted_loop. It fails, however, because phase->type
// is not yet initialized for this loop and its parts.
@@ -491,10 +532,14 @@ Node *PhaseIdealLoop::is_counted_loop( Node *x, IdealLoopTree *loop ) {
// Free up intermediate goo
_igvn.remove_dead_node(hook);
+#ifdef ASSERT
+ assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
+ assert(l == loop->_head && l->phi() == phi && l->loopexit() == lex, "" );
+#endif
+
C->print_method("After CountedLoop", 3);
- // Return trip counter
- return trip_count;
+ return true;
}
@@ -1256,17 +1301,98 @@ bool PhaseIdealLoop::is_deleteable_safept(Node* sfpt) {
return true;
}
+//---------------------------replace_parallel_iv-------------------------------
+// Replace parallel induction variable (parallel to trip counter)
+void PhaseIdealLoop::replace_parallel_iv(IdealLoopTree *loop) {
+ assert(loop->_head->is_CountedLoop(), "");
+ CountedLoopNode *cl = loop->_head->as_CountedLoop();
+ Node *incr = cl->incr();
+ if (incr == NULL)
+ return; // Dead loop?
+ Node *init = cl->init_trip();
+ Node *phi = cl->phi();
+ // protect against stride not being a constant
+ if (!cl->stride_is_con())
+ return;
+ 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))
+ continue;
+ PhiNode* phi2 = out->as_Phi();
+ Node *incr2 = phi2->in( LoopNode::LoopBackControl );
+ // Look for induction variables of the form: X += constant
+ if (phi2->region() != loop->_head ||
+ incr2->req() != 3 ||
+ incr2->in(1) != phi2 ||
+ incr2 == incr ||
+ incr2->Opcode() != Op_AddI ||
+ !incr2->in(2)->is_Con())
+ continue;
+
+ // Check for parallel induction variable (parallel to trip counter)
+ // via an affine function. In particular, count-down loops with
+ // count-up array indices are common. We only RCE references off
+ // the trip-counter, so we need to convert all these to trip-counter
+ // expressions.
+ Node *init2 = phi2->in( LoopNode::EntryControl );
+ int stride_con2 = incr2->in(2)->get_int();
+
+ // The general case here gets a little tricky. We want to find the
+ // GCD of all possible parallel IV's and make a new IV using this
+ // GCD for the loop. Then all possible IVs are simple multiples of
+ // the GCD. In practice, this will cover very few extra loops.
+ // Instead we require 'stride_con2' to be a multiple of 'stride_con',
+ // 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
+ continue;
+ }
+ }
+}
+
//------------------------------counted_loop-----------------------------------
// Convert to counted loops where possible
void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
// For grins, set the inner-loop flag here
- if( !_child ) {
- if( _head->is_Loop() ) _head->as_Loop()->set_inner_loop();
+ if (!_child) {
+ if (_head->is_Loop()) _head->as_Loop()->set_inner_loop();
}
- if( _head->is_CountedLoop() ||
- phase->is_counted_loop( _head, this ) ) {
+ if (_head->is_CountedLoop() ||
+ phase->is_counted_loop(_head, this)) {
_has_sfpt = 1; // Indicate we do not need a safepoint here
// Look for a safepoint to remove
@@ -1275,79 +1401,9 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
phase->is_deleteable_safept(n))
phase->lazy_replace(n,n->in(TypeFunc::Control));
- CountedLoopNode *cl = _head->as_CountedLoop();
- Node *incr = cl->incr();
- if( !incr ) return; // Dead loop?
- Node *init = cl->init_trip();
- Node *phi = cl->phi();
- // protect against stride not being a constant
- if( !cl->stride_is_con() ) return;
- int stride_con = cl->stride_con();
-
// Look for induction variables
+ phase->replace_parallel_iv(this);
- // 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 || !phase->has_node(out)) continue;
- PhiNode* phi2 = out->as_Phi();
- Node *incr2 = phi2->in( LoopNode::LoopBackControl );
- // Look for induction variables of the form: X += constant
- if( phi2->region() != _head ||
- incr2->req() != 3 ||
- incr2->in(1) != phi2 ||
- incr2 == incr ||
- incr2->Opcode() != Op_AddI ||
- !incr2->in(2)->is_Con() )
- continue;
-
- // Check for parallel induction variable (parallel to trip counter)
- // via an affine function. In particular, count-down loops with
- // count-up array indices are common. We only RCE references off
- // the trip-counter, so we need to convert all these to trip-counter
- // expressions.
- Node *init2 = phi2->in( LoopNode::EntryControl );
- int stride_con2 = incr2->in(2)->get_int();
-
- // The general case here gets a little tricky. We want to find the
- // GCD of all possible parallel IV's and make a new IV using this
- // GCD for the loop. Then all possible IVs are simple multiples of
- // the GCD. In practice, this will cover very few extra loops.
- // Instead we require 'stride_con2' to be a multiple of 'stride_con',
- // 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'.
- Compile* C = phase->C;
- Node* ratio = phase->_igvn.intcon(ratio_con);
- phase->set_ctrl(ratio, C->root());
- Node* ratio_init = new (C, 3) MulINode(init, ratio);
- phase->_igvn.register_new_node_with_optimizer(ratio_init, init);
- phase->set_early_ctrl(ratio_init);
- Node* diff = new (C, 3) SubINode(init2, ratio_init);
- phase->_igvn.register_new_node_with_optimizer(diff, init2);
- phase->set_early_ctrl(diff);
- Node* ratio_idx = new (C, 3) MulINode(phi, ratio);
- phase->_igvn.register_new_node_with_optimizer(ratio_idx, phi);
- phase->set_ctrl(ratio_idx, cl);
- Node* add = new (C, 3) AddINode(ratio_idx, diff);
- phase->_igvn.register_new_node_with_optimizer(add);
- phase->set_ctrl(add, cl);
- phase->_igvn.replace_node( phi2, add );
- // Sometimes an induction variable is unused
- if (add->outcnt() == 0) {
- phase->_igvn.remove_dead_node(add);
- }
- --i; // deleted this phi; rescan starting with next position
- continue;
- }
- }
} else if (_parent != NULL && !_irreducible) {
// Not a counted loop.
// Look for a safepoint on the idom-path to remove, preserving the first one
@@ -1366,24 +1422,31 @@ void IdealLoopTree::counted_loop( PhaseIdealLoop *phase ) {
}
// Recursively
- if( _child ) _child->counted_loop( phase );
- if( _next ) _next ->counted_loop( phase );
+ if (_child) _child->counted_loop( phase );
+ if (_next) _next ->counted_loop( phase );
}
#ifndef PRODUCT
//------------------------------dump_head--------------------------------------
// Dump 1 liner for loop header info
void IdealLoopTree::dump_head( ) const {
- for( uint i=0; i<_nest; i++ )
+ 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");
- if( _head->is_CountedLoop() ) {
+ if (_irreducible) tty->print(" IRREDUCIBLE");
+ if (UseLoopPredicate) {
+ Node* entry = _head->in(LoopNode::EntryControl);
+ if (entry != NULL && entry->is_Proj() &&
+ PhaseIdealLoop::is_uncommon_trap_if_pattern(entry->as_Proj(), Deoptimization::Reason_predicate)) {
+ tty->print(" predicated");
+ }
+ }
+ if (_head->is_CountedLoop()) {
CountedLoopNode *cl = _head->as_CountedLoop();
tty->print(" counted");
- if( cl->is_pre_loop () ) tty->print(" pre" );
- if( cl->is_main_loop() ) tty->print(" main");
- if( cl->is_post_loop() ) tty->print(" post");
+ if (cl->is_pre_loop ()) tty->print(" pre" );
+ if (cl->is_main_loop()) tty->print(" main");
+ if (cl->is_post_loop()) tty->print(" post");
}
tty->cr();
}
@@ -1392,8 +1455,8 @@ void IdealLoopTree::dump_head( ) const {
// Dump loops by loop tree
void IdealLoopTree::dump( ) const {
dump_head();
- if( _child ) _child->dump();
- if( _next ) _next ->dump();
+ if (_child) _child->dump();
+ if (_next) _next ->dump();
}
#endif
@@ -1439,19 +1502,19 @@ void PhaseIdealLoop::collect_potentially_useful_predicates(
}
// self (only loops that we can apply loop predication may use their predicates)
- if (loop->_head->is_Loop() &&
- !loop->_irreducible &&
+ if (loop->_head->is_Loop() &&
+ !loop->_irreducible &&
!loop->tail()->is_top()) {
- LoopNode *lpn = loop->_head->as_Loop();
+ LoopNode* lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
- ProjNode *predicate_proj = find_predicate_insertion_point(entry);
+ Node* predicate_proj = find_predicate(entry);
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
- assert(entry->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
+ assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
}
}
- if ( loop->_next ) { // sibling
+ if (loop->_next) { // sibling
collect_potentially_useful_predicates(loop->_next, useful_predicates);
}
}
@@ -1459,7 +1522,8 @@ void PhaseIdealLoop::collect_potentially_useful_predicates(
//------------------------eliminate_useless_predicates-----------------------------
// Eliminate all inserted predicates if they could not be used by loop predication.
void PhaseIdealLoop::eliminate_useless_predicates() {
- if (C->predicate_count() == 0) return; // no predicate left
+ if (C->predicate_count() == 0)
+ return; // no predicate left
Unique_Node_List useful_predicates; // to store useful predicates
if (C->has_loops()) {
@@ -1647,12 +1711,15 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool do_loop_pred) {
#ifndef PRODUCT
C->verify_graph_edges();
- if( _verify_me ) { // Nested verify pass?
+ if (_verify_me) { // Nested verify pass?
// Check to see if the verify mode is broken
assert(C->unique() == unique, "non-optimize mode made Nodes? ? ?");
return;
}
- if( VerifyLoopOptimizations ) verify();
+ if(VerifyLoopOptimizations) verify();
+ if(TraceLoopOpts && C->has_loops()) {
+ _ltree_root->dump();
+ }
#endif
if (ReassociateInvariants) {
diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp
index 7f44acccf..9edcdf292 100644
--- a/src/share/vm/opto/loopnode.hpp
+++ b/src/share/vm/opto/loopnode.hpp
@@ -93,6 +93,7 @@ public:
in(1) != NULL && phase->type(in(1)) != Type::TOP &&
in(2) != NULL && phase->type(in(2)) != Type::TOP;
}
+ bool is_valid_counted_loop() const;
#ifndef PRODUCT
virtual void dump_spec(outputStream *st) const;
#endif
@@ -101,9 +102,8 @@ public:
//------------------------------Counted Loops----------------------------------
// Counted loops are all trip-counted loops, with exactly 1 trip-counter exit
// path (and maybe some other exit paths). The trip-counter exit is always
-// last in the loop. The trip-counter does not have to stride by a constant,
-// but it does have to stride by a loop-invariant amount; the exit value is
-// also loop invariant.
+// last in the loop. The trip-counter have to stride by a constant;
+// the exit value is also loop invariant.
// CountedLoopNodes and CountedLoopEndNodes come in matched pairs. The
// CountedLoopNode has the incoming loop control and the loop-back-control
@@ -112,7 +112,7 @@ public:
// CountedLoopNode if there is control flow in the loop), the post-increment
// trip-counter value, and the limit. The trip-counter value is always of
// the form (Op old-trip-counter stride). The old-trip-counter is produced
-// by a Phi connected to the CountedLoopNode. The stride is loop invariant.
+// by a Phi connected to the CountedLoopNode. The stride is constant.
// The Op is any commutable opcode, including Add, Mul, Xor. The
// CountedLoopEndNode also takes in the loop-invariant limit value.
@@ -696,6 +696,9 @@ private:
// Is safept not required by an outer loop?
bool is_deleteable_safept(Node* sfpt);
+ // Replace parallel induction variable (parallel to trip counter)
+ void replace_parallel_iv(IdealLoopTree *loop);
+
// Perform verification that the graph is valid.
PhaseIdealLoop( PhaseIterGVN &igvn) :
PhaseTransform(Ideal_Loop),
@@ -751,7 +754,7 @@ public:
// Per-Node transform
virtual Node *transform( Node *a_node ) { return 0; }
- Node *is_counted_loop( Node *x, IdealLoopTree *loop );
+ bool is_counted_loop( Node *x, IdealLoopTree *loop );
// Return a post-walked LoopNode
IdealLoopTree *get_loop( Node *n ) const {
@@ -815,16 +818,22 @@ public:
bool is_scaled_iv_plus_offset(Node* exp, Node* iv, int* p_scale, Node** p_offset, int depth = 0);
// Return true if proj is for "proj->[region->..]call_uct"
- bool is_uncommon_trap_proj(ProjNode* proj, bool must_reason_predicate = false);
+ // Return true if proj is for "proj->[region->..]call_uct"
+ static bool is_uncommon_trap_proj(ProjNode* proj, Deoptimization::DeoptReason reason);
// Return true for "if(test)-> proj -> ...
// |
// V
// other_proj->[region->..]call_uct"
- bool is_uncommon_trap_if_pattern(ProjNode* proj, bool must_reason_predicate = false);
+ static bool is_uncommon_trap_if_pattern(ProjNode* proj, Deoptimization::DeoptReason reason);
// Create a new if above the uncommon_trap_if_pattern for the predicate to be promoted
- ProjNode* create_new_if_for_predicate(ProjNode* cont_proj);
- // Find a good location to insert a predicate
- ProjNode* find_predicate_insertion_point(Node* start_c);
+ ProjNode* create_new_if_for_predicate(ProjNode* cont_proj, Node* new_entry,
+ Deoptimization::DeoptReason reason);
+ void register_control(Node* n, IdealLoopTree *loop, Node* pred);
+
+ // Find a good location to insert a predicate
+ static ProjNode* find_predicate_insertion_point(Node* start_c, Deoptimization::DeoptReason reason);
+ // Find a predicate
+ static Node* find_predicate(Node* entry);
// Construct a range check for a predicate if
BoolNode* rc_predicate(Node* ctrl,
int scale, Node* offset,
@@ -936,7 +945,7 @@ public:
Node *has_local_phi_input( Node *n );
// Mark an IfNode as being dominated by a prior test,
// without actually altering the CFG (and hence IDOM info).
- void dominated_by( Node *prevdom, Node *iff );
+ void dominated_by( Node *prevdom, Node *iff, bool flip = false );
// Split Node 'n' through merge point
Node *split_thru_region( Node *n, Node *region );
diff --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp
index 9f5669286..ae62e609f 100644
--- a/src/share/vm/opto/loopopts.cpp
+++ b/src/share/vm/opto/loopopts.cpp
@@ -42,13 +42,13 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
return NULL;
}
int wins = 0;
- assert( !n->is_CFG(), "" );
- assert( region->is_Region(), "" );
+ assert(!n->is_CFG(), "");
+ assert(region->is_Region(), "");
const Type* type = n->bottom_type();
const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
Node *phi;
- if( t_oop != NULL && t_oop->is_known_instance_field() ) {
+ if (t_oop != NULL && t_oop->is_known_instance_field()) {
int iid = t_oop->instance_id();
int index = C->get_alias_index(t_oop);
int offset = t_oop->offset();
@@ -57,20 +57,20 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
phi = PhiNode::make_blank(region, n);
}
uint old_unique = C->unique();
- for( uint i = 1; i < region->req(); i++ ) {
+ for (uint i = 1; i < region->req(); i++) {
Node *x;
Node* the_clone = NULL;
- if( region->in(i) == C->top() ) {
+ if (region->in(i) == C->top()) {
x = C->top(); // Dead path? Use a dead data op
} else {
x = n->clone(); // Else clone up the data op
the_clone = x; // Remember for possible deletion.
// Alter data node to use pre-phi inputs
- if( n->in(0) == region )
+ if (n->in(0) == region)
x->set_req( 0, region->in(i) );
- for( uint j = 1; j < n->req(); j++ ) {
+ for (uint j = 1; j < n->req(); j++) {
Node *in = n->in(j);
- if( in->is_Phi() && in->in(0) == region )
+ if (in->is_Phi() && in->in(0) == region)
x->set_req( j, in->in(i) ); // Use pre-Phi input for the clone
}
}
@@ -85,7 +85,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
// happen if the singleton occurs on loop entry, as the elimination of
// the PhiNode may cause the resulting node to migrate back to a previous
// loop iteration.
- if( singleton && t == Type::TOP ) {
+ if (singleton && t == Type::TOP) {
// Is_Loop() == false does not confirm the absence of a loop (e.g., an
// irreducible loop may not be indicated by an affirmative is_Loop());
// therefore, the only top we can split thru a phi is on a backedge of
@@ -93,7 +93,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
singleton &= region->is_Loop() && (i != LoopNode::EntryControl);
}
- if( singleton ) {
+ if (singleton) {
wins++;
x = ((PhaseGVN&)_igvn).makecon(t);
} else {
@@ -108,12 +108,12 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
// igvn->type(x) is set to x->Value() already.
x->raise_bottom_type(t);
Node *y = x->Identity(&_igvn);
- if( y != x ) {
+ if (y != x) {
wins++;
x = y;
} else {
y = _igvn.hash_find(x);
- if( y ) {
+ if (y) {
wins++;
x = y;
} else {
@@ -129,7 +129,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
phi->set_req( i, x );
}
// Too few wins?
- if( wins <= policy ) {
+ if (wins <= policy) {
_igvn.remove_dead_node(phi);
return NULL;
}
@@ -137,7 +137,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
// Record Phi
register_new_node( phi, region );
- for( uint i2 = 1; i2 < phi->req(); i2++ ) {
+ for (uint i2 = 1; i2 < phi->req(); i2++) {
Node *x = phi->in(i2);
// If we commoned up the cloned 'x' with another existing Node,
// the existing Node picks up a new use. We need to make the
@@ -145,24 +145,44 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
Node *old_ctrl;
IdealLoopTree *old_loop;
+ if (x->is_Con()) {
+ // Constant's control is always root.
+ set_ctrl(x, C->root());
+ continue;
+ }
// The occasional new node
- if( x->_idx >= old_unique ) { // Found a new, unplaced node?
- old_ctrl = x->is_Con() ? C->root() : NULL;
- old_loop = NULL; // Not in any prior loop
+ if (x->_idx >= old_unique) { // Found a new, unplaced node?
+ old_ctrl = NULL;
+ old_loop = NULL; // Not in any prior loop
} else {
- old_ctrl = x->is_Con() ? C->root() : get_ctrl(x);
+ old_ctrl = get_ctrl(x);
old_loop = get_loop(old_ctrl); // Get prior loop
}
// New late point must dominate new use
- Node *new_ctrl = dom_lca( old_ctrl, region->in(i2) );
+ Node *new_ctrl = dom_lca(old_ctrl, region->in(i2));
+ if (new_ctrl == old_ctrl) // Nothing is changed
+ continue;
+
+ IdealLoopTree *new_loop = get_loop(new_ctrl);
+
+ // Don't move x into a loop if its uses are
+ // outside of loop. Otherwise x will be cloned
+ // for each use outside of this loop.
+ IdealLoopTree *use_loop = get_loop(region);
+ if (!new_loop->is_member(use_loop) &&
+ (old_loop == NULL || !new_loop->is_member(old_loop))) {
+ // Take early control, later control will be recalculated
+ // during next iteration of loop optimizations.
+ new_ctrl = get_early_ctrl(x);
+ new_loop = get_loop(new_ctrl);
+ }
// Set new location
set_ctrl(x, new_ctrl);
- IdealLoopTree *new_loop = get_loop( new_ctrl );
// If changing loop bodies, see if we need to collect into new body
- if( old_loop != new_loop ) {
- if( old_loop && !old_loop->_child )
+ if (old_loop != new_loop) {
+ if (old_loop && !old_loop->_child)
old_loop->_body.yank(x);
- if( !new_loop->_child )
+ if (!new_loop->_child)
new_loop->_body.push(x); // Collect body info
}
}
@@ -174,9 +194,9 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
// Replace the dominated test with an obvious true or false. Place it on the
// IGVN worklist for later cleanup. Move control-dependent data Nodes on the
// live path up to the dominating control.
-void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
+void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff, bool flip ) {
#ifndef PRODUCT
- if( VerifyLoopOptimizations && PrintOpto ) tty->print_cr("dominating test");
+ if (VerifyLoopOptimizations && PrintOpto) tty->print_cr("dominating test");
#endif
@@ -185,6 +205,12 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
assert( iff->Opcode() == Op_If || iff->Opcode() == Op_CountedLoopEnd, "Check this code when new subtype is added");
int pop = prevdom->Opcode();
assert( pop == Op_IfFalse || pop == Op_IfTrue, "" );
+ if (flip) {
+ if (pop == Op_IfTrue)
+ pop = Op_IfFalse;
+ else
+ pop = Op_IfTrue;
+ }
// 'con' is set to true or false to kill the dominated test.
Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
set_ctrl(con, C->root()); // Constant gets a new use
@@ -197,7 +223,7 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
// I can assume this path reaches an infinite loop. In this case it's not
// important to optimize the data Nodes - either the whole compilation will
// be tossed or this path (and all data Nodes) will go dead.
- if( iff->outcnt() != 2 ) return;
+ if (iff->outcnt() != 2) return;
// Make control-dependent data Nodes on the live path (path that will remain
// once the dominated IF is removed) become control-dependent on the
@@ -207,16 +233,16 @@ void PhaseIdealLoop::dominated_by( Node *prevdom, Node *iff ) {
for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
Node* cd = dp->fast_out(i); // Control-dependent node
- if( cd->depends_only_on_test() ) {
- assert( cd->in(0) == dp, "" );
- _igvn.hash_delete( cd );
+ if (cd->depends_only_on_test()) {
+ assert(cd->in(0) == dp, "");
+ _igvn.hash_delete(cd);
cd->set_req(0, prevdom);
- set_early_ctrl( cd );
+ set_early_ctrl(cd);
_igvn._worklist.push(cd);
IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
- if( old_loop != new_loop ) {
- if( !old_loop->_child ) old_loop->_body.yank(cd);
- if( !new_loop->_child ) new_loop->_body.push(cd);
+ if (old_loop != new_loop) {
+ if (!old_loop->_child) old_loop->_body.yank(cd);
+ if (!new_loop->_child) new_loop->_body.push(cd);
}
--i;
--imax;
@@ -2338,6 +2364,11 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
}
#if !defined(PRODUCT)
+ if (TraceLoopOpts) {
+ tty->print("PartialPeel ");
+ loop->dump_head();
+ }
+
if (TracePartialPeeling) {
tty->print_cr("before partial peel one iteration");
Node_List wl;
@@ -2481,6 +2512,7 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// Create new loop head for new phis and to hang
// the nodes being moved (sinked) from the peel region.
LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
+ new_head->set_unswitch_count(head->unswitch_count()); // Preserve
_igvn.register_new_node_with_optimizer(new_head);
assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
first_not_peeled->set_req(0, new_head);
@@ -2651,24 +2683,23 @@ bool PhaseIdealLoop::partial_peel( IdealLoopTree *loop, Node_List &old_new ) {
// prevent loop-fallout uses of the pre-incremented trip counter (which are
// then alive with the post-incremented trip counter forcing an extra
// register move)
-void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
+void PhaseIdealLoop::reorg_offsets(IdealLoopTree *loop) {
+ // Perform it only for canonical counted loops.
+ // Loop's shape could be messed up by iteration_split_impl.
+ if (!loop->_head->is_CountedLoop())
+ return;
+ if (!loop->_head->as_Loop()->is_valid_counted_loop())
+ return;
CountedLoopNode *cl = loop->_head->as_CountedLoop();
CountedLoopEndNode *cle = cl->loopexit();
- if( !cle ) return; // The occasional dead loop
- // Find loop exit control
Node *exit = cle->proj_out(false);
- assert( exit->Opcode() == Op_IfFalse, "" );
+ Node *phi = cl->phi();
// Check for the special case of folks using the pre-incremented
// trip-counter on the fall-out path (forces the pre-incremented
// and post-incremented trip counter to be live at the same time).
// Fix this by adjusting to use the post-increment trip counter.
- Node *phi = cl->phi();
- if( !phi ) return; // Dead infinite loop
-
- // Shape messed up, probably by iteration_split_impl
- if (phi->in(LoopNode::LoopBackControl) != cl->incr()) return;
bool progress = true;
while (progress) {
@@ -2677,21 +2708,19 @@ void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
Node* use = phi->fast_out(i); // User of trip-counter
if (!has_ctrl(use)) continue;
Node *u_ctrl = get_ctrl(use);
- if( use->is_Phi() ) {
+ if (use->is_Phi()) {
u_ctrl = NULL;
- for( uint j = 1; j < use->req(); j++ )
- if( use->in(j) == phi )
- u_ctrl = dom_lca( u_ctrl, use->in(0)->in(j) );
+ for (uint j = 1; j < use->req(); j++)
+ if (use->in(j) == phi)
+ u_ctrl = dom_lca(u_ctrl, use->in(0)->in(j));
}
IdealLoopTree *u_loop = get_loop(u_ctrl);
// Look for loop-invariant use
- if( u_loop == loop ) continue;
- if( loop->is_member( u_loop ) ) continue;
+ if (u_loop == loop) continue;
+ if (loop->is_member(u_loop)) continue;
// Check that use is live out the bottom. Assuming the trip-counter
// update is right at the bottom, uses of of the loop middle are ok.
- if( dom_lca( exit, u_ctrl ) != exit ) continue;
- // protect against stride not being a constant
- if( !cle->stride_is_con() ) continue;
+ if (dom_lca(exit, u_ctrl) != exit) continue;
// Hit! Refactor use to use the post-incremented tripcounter.
// Compute a post-increment tripcounter.
Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
@@ -2702,9 +2731,10 @@ void PhaseIdealLoop::reorg_offsets( IdealLoopTree *loop ) {
register_new_node( post, u_ctrl );
_igvn.hash_delete(use);
_igvn._worklist.push(use);
- for( uint j = 1; j < use->req(); j++ )
- if( use->in(j) == phi )
+ for (uint j = 1; j < use->req(); j++) {
+ if (use->in(j) == phi)
use->set_req(j, post);
+ }
// Since DU info changed, rerun loop
progress = true;
break;
diff --git a/src/share/vm/opto/parse.hpp b/src/share/vm/opto/parse.hpp
index a8d63b55d..78f880c9d 100644
--- a/src/share/vm/opto/parse.hpp
+++ b/src/share/vm/opto/parse.hpp
@@ -136,6 +136,7 @@ class Parse : public GraphKit {
uint _count; // how many times executed? Currently only set by _goto's
bool _is_parsed; // has this block been parsed yet?
bool _is_handler; // is this block an exception handler?
+ bool _has_merged_backedge; // does this block have merged backedge?
SafePointNode* _start_map; // all values flowing into this block
MethodLivenessResult _live_locals; // lazily initialized liveness bitmap
@@ -168,6 +169,18 @@ class Parse : public GraphKit {
// True after any predecessor flows control into this block
bool is_merged() const { return _start_map != NULL; }
+#ifdef ASSERT
+ // True after backedge predecessor flows control into this block
+ bool has_merged_backedge() const { return _has_merged_backedge; }
+ void mark_merged_backedge(Block* pred) {
+ assert(is_SEL_head(), "should be loop head");
+ if (pred != NULL && is_SEL_backedge(pred)) {
+ assert(is_parsed(), "block should be parsed before merging backedges");
+ _has_merged_backedge = true;
+ }
+ }
+#endif
+
// True when all non-exception predecessors have been parsed.
bool is_ready() const { return preds_parsed() == pred_count(); }
@@ -441,11 +454,6 @@ class Parse : public GraphKit {
}
}
- // Return true if the parser should add a loop predicate
- bool should_add_predicate(int target_bci);
- // Insert a loop predicate into the graph
- void add_predicate();
-
// Note: Intrinsic generation routines may be found in library_call.cpp.
// Helper function to setup Ideal Call nodes
diff --git a/src/share/vm/opto/parse1.cpp b/src/share/vm/opto/parse1.cpp
index 3729c38b4..589a54104 100644
--- a/src/share/vm/opto/parse1.cpp
+++ b/src/share/vm/opto/parse1.cpp
@@ -637,6 +637,25 @@ void Parse::do_all_blocks() {
// (Note that dead locals do not get phis built, ever.)
ensure_phis_everywhere();
+ if (block->is_SEL_head() &&
+ UseLoopPredicate) {
+ // Add predicate to single entry (not irreducible) loop head.
+ assert(!block->has_merged_backedge(), "only entry paths should be merged for now");
+ // Need correct bci for predicate.
+ // It is fine to set it here since do_one_block() will set it anyway.
+ set_parse_bci(block->start());
+ add_predicate();
+ // Add new region for back branches.
+ int edges = block->pred_count() - block->preds_parsed() + 1; // +1 for original region
+ RegionNode *r = new (C, edges+1) RegionNode(edges+1);
+ _gvn.set_type(r, Type::CONTROL);
+ record_for_igvn(r);
+ r->init_req(edges, control());
+ set_control(r);
+ // Add new phis.
+ ensure_phis_everywhere();
+ }
+
// Leave behind an undisturbed copy of the map, for future merges.
set_map(clone_map());
}
@@ -1113,7 +1132,7 @@ void Parse::Block::init_node(Parse* outer, int rpo) {
_preds_parsed = 0;
_count = 0;
assert(pred_count() == 0 && preds_parsed() == 0, "sanity");
- assert(!(is_merged() || is_parsed() || is_handler()), "sanity");
+ assert(!(is_merged() || is_parsed() || is_handler() || has_merged_backedge()), "sanity");
assert(_live_locals.size() == 0, "sanity");
// entry point has additional predecessor
@@ -1350,10 +1369,6 @@ void Parse::do_one_block() {
set_parse_bci(iter().cur_bci());
if (bci() == block()->limit()) {
- // insert a predicate if it falls through to a loop head block
- if (should_add_predicate(bci())){
- add_predicate();
- }
// Do not walk into the next block until directed by do_all_blocks.
merge(bci());
break;
@@ -1498,17 +1513,29 @@ void Parse::merge_common(Parse::Block* target, int pnum) {
|| target->is_handler() // These have unpredictable inputs.
|| target->is_loop_head() // Known multiple inputs
|| control()->is_Region()) { // We must hide this guy.
+
+ int current_bci = bci();
+ set_parse_bci(target->start()); // Set target bci
+ if (target->is_SEL_head()) {
+ DEBUG_ONLY( target->mark_merged_backedge(block()); )
+ if (target->start() == 0) {
+ // Add loop predicate for the special case when
+ // there are backbranches to the method entry.
+ add_predicate();
+ }
+ }
// Add a Region to start the new basic block. Phis will be added
// later lazily.
int edges = target->pred_count();
if (edges < pnum) edges = pnum; // might be a new path!
- Node *r = new (C, edges+1) RegionNode(edges+1);
+ RegionNode *r = new (C, edges+1) RegionNode(edges+1);
gvn().set_type(r, Type::CONTROL);
record_for_igvn(r);
// zap all inputs to NULL for debugging (done in Node(uint) constructor)
// for (int j = 1; j < edges+1; j++) { r->init_req(j, NULL); }
r->init_req(pnum, control());
set_control(r);
+ set_parse_bci(current_bci); // Restore bci
}
// Convert the existing Parser mapping into a mapping at this bci.
@@ -1517,7 +1544,11 @@ void Parse::merge_common(Parse::Block* target, int pnum) {
} else { // Prior mapping at this bci
if (TraceOptoParse) { tty->print(" with previous state"); }
-
+#ifdef ASSERT
+ if (target->is_SEL_head()) {
+ target->mark_merged_backedge(block());
+ }
+#endif
// We must not manufacture more phis if the target is already parsed.
bool nophi = target->is_parsed();
@@ -2054,37 +2085,6 @@ void Parse::add_safepoint() {
}
}
-//------------------------------should_add_predicate--------------------------
-bool Parse::should_add_predicate(int target_bci) {
- if (!UseLoopPredicate) return false;
- Block* target = successor_for_bci(target_bci);
- if (target != NULL &&
- target->is_loop_head() &&
- block()->rpo() < target->rpo()) {
- return true;
- }
- return false;
-}
-
-//------------------------------add_predicate---------------------------------
-void Parse::add_predicate() {
- assert(UseLoopPredicate,"use only for loop predicate");
- Node *cont = _gvn.intcon(1);
- Node* opq = _gvn.transform(new (C, 2) Opaque1Node(C, cont));
- Node *bol = _gvn.transform(new (C, 2) Conv2BNode(opq));
- IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
- Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff));
- C->add_predicate_opaq(opq);
- {
- PreserveJVMState pjvms(this);
- set_control(iffalse);
- uncommon_trap(Deoptimization::Reason_predicate,
- Deoptimization::Action_maybe_recompile);
- }
- Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff));
- set_control(iftrue);
-}
-
#ifndef PRODUCT
//------------------------show_parse_info--------------------------------------
void Parse::show_parse_info() {
diff --git a/src/share/vm/opto/parse2.cpp b/src/share/vm/opto/parse2.cpp
index a9f42eb7a..162878e6a 100644
--- a/src/share/vm/opto/parse2.cpp
+++ b/src/share/vm/opto/parse2.cpp
@@ -293,11 +293,6 @@ void Parse::do_tableswitch() {
if (len < 1) {
// If this is a backward branch, add safepoint
maybe_add_safepoint(default_dest);
- if (should_add_predicate(default_dest)){
- _sp += 1; // set original stack for use by uncommon_trap
- add_predicate();
- _sp -= 1;
- }
merge(default_dest);
return;
}
@@ -344,11 +339,6 @@ void Parse::do_lookupswitch() {
if (len < 1) { // If this is a backward branch, add safepoint
maybe_add_safepoint(default_dest);
- if (should_add_predicate(default_dest)){
- _sp += 1; // set original stack for use by uncommon_trap
- add_predicate();
- _sp -= 1;
- }
merge(default_dest);
return;
}
@@ -756,9 +746,6 @@ void Parse::do_jsr() {
push(_gvn.makecon(ret_addr));
// Flow to the jsr.
- if (should_add_predicate(jsr_bci)){
- add_predicate();
- }
merge(jsr_bci);
}
@@ -1040,11 +1027,6 @@ void Parse::do_ifnull(BoolTest::mask btest, Node *c) {
profile_taken_branch(target_bci);
adjust_map_after_if(btest, c, prob, branch_block, next_block);
if (!stopped()) {
- if (should_add_predicate(target_bci)){ // add a predicate if it branches to a loop
- int nargs = repush_if_args(); // set original stack for uncommon_trap
- add_predicate();
- _sp -= nargs;
- }
merge(target_bci);
}
}
@@ -1168,11 +1150,6 @@ void Parse::do_if(BoolTest::mask btest, Node* c) {
profile_taken_branch(target_bci);
adjust_map_after_if(taken_btest, c, prob, branch_block, next_block);
if (!stopped()) {
- if (should_add_predicate(target_bci)){ // add a predicate if it branches to a loop
- int nargs = repush_if_args(); // set original stack for the uncommon_trap
- add_predicate();
- _sp -= nargs;
- }
merge(target_bci);
}
}
@@ -2166,10 +2143,6 @@ void Parse::do_one_bytecode() {
// Update method data
profile_taken_branch(target_bci);
- // Add loop predicate if it goes to a loop
- if (should_add_predicate(target_bci)){
- add_predicate();
- }
// Merge the current control into the target basic block
merge(target_bci);
diff --git a/src/share/vm/opto/stringopts.cpp b/src/share/vm/opto/stringopts.cpp
index 658fc05b1..0a9267523 100644
--- a/src/share/vm/opto/stringopts.cpp
+++ b/src/share/vm/opto/stringopts.cpp
@@ -969,6 +969,10 @@ Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
// for (int i=0; ; i++)
// if (x <= sizeTable[i])
// return i+1;
+
+ // Add loop predicate first.
+ kit.add_predicate();
+
RegionNode *loop = new (C, 3) RegionNode(3);
loop->init_req(1, kit.control());
kit.gvn().set_type(loop, Type::CONTROL);
@@ -1086,6 +1090,9 @@ void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, N
// }
{
+ // Add loop predicate first.
+ kit.add_predicate();
+
RegionNode *head = new (C, 3) RegionNode(3);
head->init_req(1, kit.control());
kit.gvn().set_type(head, Type::CONTROL);