--- old/src/share/vm/compiler/compileBroker.cpp Mon Nov 7 13:52:42 2011 +++ new/src/share/vm/compiler/compileBroker.cpp Mon Nov 7 13:52:41 2011 @@ -1743,7 +1743,7 @@ 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 ? "%" : " ")); --- old/src/share/vm/opto/compile.cpp Mon Nov 7 13:52:42 2011 +++ new/src/share/vm/opto/compile.cpp Mon Nov 7 13:52:42 2011 @@ -346,15 +346,15 @@ // 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,9 +362,16 @@ } } 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 @@ 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,6 +1699,13 @@ // 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); @@ -1697,7 +1712,7 @@ if (failing()) return; igvn.optimize(); - print_method("Iter GVN 3", 2); + print_method("Iter GVN after EA", 2); if (failing()) return; --- old/src/share/vm/opto/loopnode.cpp Mon Nov 7 13:52:43 2011 +++ new/src/share/vm/opto/loopnode.cpp Mon Nov 7 13:52:43 2011 @@ -1883,7 +1883,7 @@ //----------------------------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 @@ } #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()) { --- old/src/share/vm/opto/loopnode.hpp Mon Nov 7 13:52:43 2011 +++ new/src/share/vm/opto/loopnode.hpp Mon Nov 7 13:52:43 2011 @@ -747,11 +747,11 @@ _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 @@ 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 @@ _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 --- old/src/share/vm/opto/loopopts.cpp Mon Nov 7 13:52:44 2011 +++ new/src/share/vm/opto/loopopts.cpp Mon Nov 7 13:52:44 2011 @@ -629,9 +629,10 @@ 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 --- old/src/share/vm/opto/matcher.cpp Mon Nov 7 13:52:44 2011 +++ new/src/share/vm/opto/matcher.cpp Mon Nov 7 13:52:44 2011 @@ -1915,7 +1915,7 @@ 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: --- old/src/share/vm/opto/memnode.cpp Mon Nov 7 13:52:45 2011 +++ new/src/share/vm/opto/memnode.cpp Mon Nov 7 13:52:45 2011 @@ -1421,6 +1421,12 @@ 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; --- old/src/share/vm/opto/phaseX.cpp Mon Nov 7 13:52:46 2011 +++ new/src/share/vm/opto/phaseX.cpp Mon Nov 7 13:52:45 2011 @@ -322,11 +322,12 @@ 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); --- old/src/share/vm/runtime/globals.hpp Mon Nov 7 13:52:46 2011 +++ new/src/share/vm/runtime/globals.hpp Mon Nov 7 13:52:46 2011 @@ -904,7 +904,7 @@ 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, \