diff --git a/src/share/vm/compiler/compileBroker.cpp b/src/share/vm/compiler/compileBroker.cpp index 4b50176502169ebbbe2569c552f812c8a97989b7..55ef1e464b045dd9c2c1599d776a90c488973e80 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 2f0f294bed3875cbc6dd5d7754c3cabe328efc05..358be6286fc23464c87ca1f4915c5d6a22a5b8f6 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 2243c39e55321d34ae90e063e82c844f2f4bf75f..3bd04ad338f0cbf7b4244016b1332a97b4526940 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 817124bb05ce5d6e2c7a59d86b0c74734de7fd4c..9b4c38a5f5d0e1749becf36433ab2e1df4f93ba5 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 25d3451d1dca6d3ef71f7c6fef310a49ac537479..93c181973a4897e2a36c3f4ba47e7e2b9a5e6cf4 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 3244a944bbd01c496818040413d8041688638764..1200d2541c784b85e55689cc07e3a3604524327f 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 4f6dc0851210576a7fd4a9cace5790dc25714bf5..5d4afb0e4e4066d4c28ca617f6cbd9b36cfcf8b7 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 541744ac8a5638960dcbfcd481788a3e9700e24f..99b7393b4cf359d3439ff0a12553050ceaa27e4e 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 f3072f861c056c664b8104a73404cbe06d99676a..6faff3452f136d0902a8a682bc1c8868e2a8900b 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, \