提交 08398f56 编写于 作者: K kvn

7107042: assert(no_dead_loop) failed: dead loop detected

Summary: Use dead nodes elimination code in PhaseIdealLoop before executing EA.
Reviewed-by: never, twisti
上级 f2a17338
......@@ -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) {
......
......@@ -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;
......
......@@ -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()) {
......
......@@ -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
......
......@@ -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
......
......@@ -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:
......
......@@ -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;
......
......@@ -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);
......
......@@ -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, \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册