aboutsummaryrefslogtreecommitdiff
path: root/src/share
diff options
context:
space:
mode:
authorkvn <none@none>2011-11-09 07:25:51 -0800
committerkvn <none@none>2011-11-09 07:25:51 -0800
commitdb637f30f5b54d0331c55880ff7f7c8885b89b41 (patch)
tree0a907a1970909c5f62ccecd9f7e05bc9fa3eb591 /src/share
parent6990e4d5dc834b295c68221bae0f9dd958d5d984 (diff)
7107042: assert(no_dead_loop) failed: dead loop detected
Summary: Use dead nodes elimination code in PhaseIdealLoop before executing EA. Reviewed-by: never, twisti
Diffstat (limited to 'src/share')
-rw-r--r--src/share/vm/compiler/compileBroker.cpp5
-rw-r--r--src/share/vm/opto/compile.cpp29
-rw-r--r--src/share/vm/opto/loopnode.cpp12
-rw-r--r--src/share/vm/opto/loopnode.hpp10
-rw-r--r--src/share/vm/opto/loopopts.cpp3
-rw-r--r--src/share/vm/opto/matcher.cpp2
-rw-r--r--src/share/vm/opto/memnode.cpp6
-rw-r--r--src/share/vm/opto/phaseX.cpp11
-rw-r--r--src/share/vm/runtime/globals.hpp2
9 files changed, 57 insertions, 23 deletions
diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp
index 4b5017650..55ef1e464 100644
--- a/src/share/vm/compiler/compileBroker.cpp
+++ b/src/share/vm/compiler/compileBroker.cpp
@@ -1743,11 +1743,12 @@ void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
collect_statistics(thread, time, task);
- if (PrintCompilation && PrintInlining) {
+ if (PrintCompilation && PrintCompilation2) {
tty->print("%7d ", (int) tty->time_stamp().milliseconds()); // print timestamp
tty->print("%4d ", compile_id); // print compilation number
tty->print("%s ", (is_osr ? "%" : " "));
- tty->print_cr("size: %d time: %d inlined: %d bytes", task->code()->total_size(), time.milliseconds(), task->num_inlined_bytecodes());
+ int code_size = (task->code() == NULL) ? 0 : task->code()->total_size();
+ tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, time.milliseconds(), task->num_inlined_bytecodes());
}
if (compilable == ciEnv::MethodCompilable_never) {
diff --git a/src/share/vm/opto/compile.cpp b/src/share/vm/opto/compile.cpp
index 2f0f294be..358be6286 100644
--- a/src/share/vm/opto/compile.cpp
+++ b/src/share/vm/opto/compile.cpp
@@ -346,15 +346,15 @@ void Compile::identify_useful_nodes(Unique_Node_List &useful) {
// Disconnect all useless nodes by disconnecting those at the boundary.
void Compile::remove_useless_nodes(Unique_Node_List &useful) {
uint next = 0;
- while( next < useful.size() ) {
+ while (next < useful.size()) {
Node *n = useful.at(next++);
// Use raw traversal of out edges since this code removes out edges
int max = n->outcnt();
- for (int j = 0; j < max; ++j ) {
+ for (int j = 0; j < max; ++j) {
Node* child = n->raw_out(j);
- if( ! useful.member(child) ) {
- assert( !child->is_top() || child != top(),
- "If top is cached in Compile object it is in useful list");
+ if (! useful.member(child)) {
+ assert(!child->is_top() || child != top(),
+ "If top is cached in Compile object it is in useful list");
// Only need to remove this out-edge to the useless node
n->raw_del_out(j);
--j;
@@ -362,7 +362,14 @@ void Compile::remove_useless_nodes(Unique_Node_List &useful) {
}
}
if (n->outcnt() == 1 && n->has_special_unique_user()) {
- record_for_igvn( n->unique_out() );
+ record_for_igvn(n->unique_out());
+ }
+ }
+ // Remove useless macro and predicate opaq nodes
+ for (int i = C->macro_count()-1; i >= 0; i--) {
+ Node* n = C->macro_node(i);
+ if (!useful.member(n)) {
+ remove_macro_node(n);
}
}
debug_only(verify_graph_edges(true/*check for no_dead_code*/);)
@@ -719,6 +726,7 @@ Compile::Compile( ciEnv* ci_env, C2Compiler* compiler, ciMethod* target, int osr
while (_late_inlines.length() > 0) {
CallGenerator* cg = _late_inlines.pop();
cg->do_late_inline();
+ if (failing()) return;
}
}
assert(_late_inlines.length() == 0, "should have been processed");
@@ -1691,13 +1699,20 @@ void Compile::Optimize() {
// Perform escape analysis
if (_do_escape_analysis && ConnectionGraph::has_candidates(this)) {
+ if (has_loops()) {
+ // Cleanup graph (remove dead nodes).
+ TracePhase t2("idealLoop", &_t_idealLoop, true);
+ PhaseIdealLoop ideal_loop( igvn, false, true );
+ if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
+ if (failing()) return;
+ }
TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
ConnectionGraph::do_analysis(this, &igvn);
if (failing()) return;
igvn.optimize();
- print_method("Iter GVN 3", 2);
+ print_method("Iter GVN after EA", 2);
if (failing()) return;
diff --git a/src/share/vm/opto/loopnode.cpp b/src/share/vm/opto/loopnode.cpp
index 2243c39e5..3bd04ad33 100644
--- a/src/share/vm/opto/loopnode.cpp
+++ b/src/share/vm/opto/loopnode.cpp
@@ -1883,7 +1883,7 @@ void PhaseIdealLoop::eliminate_useless_predicates() {
//----------------------------build_and_optimize-------------------------------
// Create a PhaseLoop. Build the ideal Loop tree. Map each Ideal Node to
// its corresponding LoopNode. If 'optimize' is true, do some loop cleanups.
-void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
+void PhaseIdealLoop::build_and_optimize(bool do_split_ifs, bool skip_loop_opts) {
ResourceMark rm;
int old_progress = C->major_progress();
@@ -2072,6 +2072,16 @@ void PhaseIdealLoop::build_and_optimize(bool do_split_ifs) {
}
#endif
+ if (skip_loop_opts) {
+ // Cleanup any modified bits
+ _igvn.optimize();
+
+ if (C->log() != NULL) {
+ log_loop_tree(_ltree_root, _ltree_root, C->log());
+ }
+ return;
+ }
+
if (ReassociateInvariants) {
// Reassociate invariants and prep for split_thru_phi
for (LoopTreeIterator iter(_ltree_root); !iter.done(); iter.next()) {
diff --git a/src/share/vm/opto/loopnode.hpp b/src/share/vm/opto/loopnode.hpp
index 817124bb0..9b4c38a5f 100644
--- a/src/share/vm/opto/loopnode.hpp
+++ b/src/share/vm/opto/loopnode.hpp
@@ -747,11 +747,11 @@ private:
_dom_lca_tags(arena()), // Thread::resource_area
_verify_me(NULL),
_verify_only(true) {
- build_and_optimize(false);
+ build_and_optimize(false, false);
}
// build the loop tree and perform any requested optimizations
- void build_and_optimize(bool do_split_if);
+ void build_and_optimize(bool do_split_if, bool skip_loop_opts);
public:
// Dominators for the sea of nodes
@@ -762,13 +762,13 @@ public:
Node *dom_lca_internal( Node *n1, Node *n2 ) const;
// Compute the Ideal Node to Loop mapping
- PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs) :
+ PhaseIdealLoop( PhaseIterGVN &igvn, bool do_split_ifs, bool skip_loop_opts = false) :
PhaseTransform(Ideal_Loop),
_igvn(igvn),
_dom_lca_tags(arena()), // Thread::resource_area
_verify_me(NULL),
_verify_only(false) {
- build_and_optimize(do_split_ifs);
+ build_and_optimize(do_split_ifs, skip_loop_opts);
}
// Verify that verify_me made the same decisions as a fresh run.
@@ -778,7 +778,7 @@ public:
_dom_lca_tags(arena()), // Thread::resource_area
_verify_me(verify_me),
_verify_only(false) {
- build_and_optimize(false);
+ build_and_optimize(false, false);
}
// Build and verify the loop tree without modifying the graph. This
diff --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp
index 25d3451d1..93c181973 100644
--- a/src/share/vm/opto/loopopts.cpp
+++ b/src/share/vm/opto/loopopts.cpp
@@ -629,9 +629,10 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) {
if (TraceLoopOpts) {
tty->print("CMOV ");
r_loop->dump_head();
- if (Verbose)
+ if (Verbose) {
bol->in(1)->dump(1);
cmov->dump(1);
+ }
}
if (VerifyLoopOptimizations) verify();
#endif
diff --git a/src/share/vm/opto/matcher.cpp b/src/share/vm/opto/matcher.cpp
index 3244a944b..1200d2541 100644
--- a/src/share/vm/opto/matcher.cpp
+++ b/src/share/vm/opto/matcher.cpp
@@ -1915,7 +1915,7 @@ void Matcher::find_shared( Node *n ) {
set_dontcare(n);
break;
case Op_Jump:
- mstack.push(n->in(1), Visit); // Switch Value
+ mstack.push(n->in(1), Pre_Visit); // Switch Value (could be shared)
mstack.push(n->in(0), Pre_Visit); // Visit Control input
continue; // while (mstack.is_nonempty())
case Op_StrComp:
diff --git a/src/share/vm/opto/memnode.cpp b/src/share/vm/opto/memnode.cpp
index 4f6dc0851..5d4afb0e4 100644
--- a/src/share/vm/opto/memnode.cpp
+++ b/src/share/vm/opto/memnode.cpp
@@ -1421,6 +1421,12 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
if (can_reshape && opt_mem->is_Phi() &&
(t_oop != NULL) && t_oop->is_known_instance_field()) {
+ PhaseIterGVN *igvn = phase->is_IterGVN();
+ if (igvn != NULL && igvn->_worklist.member(opt_mem)) {
+ // Delay this transformation until memory Phi is processed.
+ phase->is_IterGVN()->_worklist.push(this);
+ return NULL;
+ }
// Split instance field load through Phi.
Node* result = split_through_phi(phase);
if (result != NULL) return result;
diff --git a/src/share/vm/opto/phaseX.cpp b/src/share/vm/opto/phaseX.cpp
index 541744ac8..99b7393b4 100644
--- a/src/share/vm/opto/phaseX.cpp
+++ b/src/share/vm/opto/phaseX.cpp
@@ -322,11 +322,12 @@ void NodeHash::remove_useless_nodes(VectorSet &useful) {
void NodeHash::dump() {
_total_inserts += _inserts;
_total_insert_probes += _insert_probes;
- if( PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0) ) { // PrintOptoGVN
- if( PrintCompilation2 ) {
- for( uint i=0; i<_max; i++ )
- if( _table[i] )
- tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx);
+ if (PrintCompilation && PrintOptoStatistics && Verbose && (_inserts > 0)) {
+ if (WizardMode) {
+ for (uint i=0; i<_max; i++) {
+ if (_table[i])
+ tty->print("%d/%d/%d ",i,_table[i]->hash()&(_max-1),_table[i]->_idx);
+ }
}
tty->print("\nGVN Hash stats: %d grows to %d max_size\n", _grows, _max);
tty->print(" %d/%d (%8.1f%% full)\n", _inserts, _max, (double)_inserts/_max*100.0);
diff --git a/src/share/vm/runtime/globals.hpp b/src/share/vm/runtime/globals.hpp
index f3072f861..6faff3452 100644
--- a/src/share/vm/runtime/globals.hpp
+++ b/src/share/vm/runtime/globals.hpp
@@ -904,7 +904,7 @@ class CommandLineFlags {
product(bool, AlwaysRestoreFPU, false, \
"Restore the FPU control word after every JNI call (expensive)") \
\
- notproduct(bool, PrintCompilation2, false, \
+ diagnostic(bool, PrintCompilation2, false, \
"Print additional statistics per compilation") \
\
diagnostic(bool, PrintAdapterHandlers, false, \