src/share/vm/opto/compile.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 7092905 Cdiff src/share/vm/opto/compile.cpp

src/share/vm/opto/compile.cpp

Print this page

        

*** 314,324 **** i -= uses_found; // we deleted 1 or more copies of this edge } } ! // Identify all nodes that are reachable from below, useful. // Use breadth-first pass that records state in a Unique_Node_List, // recursive traversal is slower. void Compile::identify_useful_nodes(Unique_Node_List &useful) { --- 314,329 ---- i -= uses_found; // we deleted 1 or more copies of this edge } } ! static inline bool not_a_node(const Node* n) { ! if (n == NULL) return true; ! if (((intptr_t)n & 1) != 0) return true; // uninitialized, etc. ! if (*(address*)n == badAddress) return true; // kill by Node::destruct ! return false; ! } // Identify all nodes that are reachable from below, useful. // Use breadth-first pass that records state in a Unique_Node_List, // recursive traversal is slower. void Compile::identify_useful_nodes(Unique_Node_List &useful) {
*** 335,350 **** assert( next < unique(), "Unique useful nodes < total nodes"); Node *n = useful.at(next); uint max = n->len(); for( uint i = 0; i < max; ++i ) { Node *m = n->in(i); ! if( m == NULL ) continue; useful.push(m); } } } // 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()) { Node *n = useful.at(next++); --- 340,370 ---- assert( next < unique(), "Unique useful nodes < total nodes"); Node *n = useful.at(next); uint max = n->len(); for( uint i = 0; i < max; ++i ) { Node *m = n->in(i); ! if (not_a_node(m)) continue; useful.push(m); } } } + // Update dead_node_list with any missing dead nodes using useful + // list. Consider all non-useful nodes to be useless i.e., dead nodes. + void Compile::update_dead_node_list(Unique_Node_List &useful) { + uint max_idx = unique(); + VectorSet& useful_node_set = useful.member_set(); + + for (uint node_idx = 0; node_idx < max_idx; node_idx++) { + // If node with index node_idx is not in useful set, + // mark it as dead in dead node list. + if (! useful_node_set.test(node_idx) ) { + record_dead_node(node_idx); + } + } + } + // 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()) { Node *n = useful.at(next++);
*** 580,589 **** --- 600,611 ---- _node_bundling_base(NULL), _java_calls(0), _inner_loops(0), _scratch_const_size(-1), _in_scratch_emit_size(false), + _dead_node_list(comp_arena()), + _dead_node_count(0), #ifndef PRODUCT _trace_opto_output(TraceOptoOutput || method()->has_option("TraceOptoOutput")), _printer(IdealGraphPrinter::printer()), #endif _congraph(NULL) {
*** 871,880 **** --- 893,904 ---- _inner_loops(0), #ifndef PRODUCT _trace_opto_output(TraceOptoOutput), _printer(NULL), #endif + _dead_node_list(comp_arena()), + _dead_node_count(0), _congraph(NULL) { C = this; #ifndef PRODUCT TraceTime t1(NULL, &_t_totalCompilation, TimeCompiler, false);
*** 1067,1076 **** --- 1091,1166 ---- if (_top != NULL) _top->setup_is_top(); if (old_top != NULL) old_top->setup_is_top(); assert(_top == NULL || top()->is_top(), ""); } + #ifdef ASSERT + uint Compile::count_live_nodes_by_graph_walk() { + Unique_Node_List useful(comp_arena()); + // Get useful node list by walking the graph. + identify_useful_nodes(useful); + return useful.size(); + } + + void Compile::print_missing_nodes() { + + // Return if CompileLog is NULL and PrintIdealNodeCount is false. + if ((_log == NULL) && (! PrintIdealNodeCount)) { + return; + } + + // This is an expensive function. It is executed only when the user + // specifies VerifyIdealNodeCount option or otherwise knows the + // additional work that needs to be done to identify reachable nodes + // by walking the flow graph and find the missing ones using + // _dead_node_list. + + Unique_Node_List useful(comp_arena()); + // Get useful node list by walking the graph. + identify_useful_nodes(useful); + + uint l_nodes = C->live_nodes(); + uint l_nodes_by_walk = useful.size(); + + if (l_nodes != l_nodes_by_walk) { + if (_log != NULL) { + _log->begin_head("mismatched_nodes count='%d'", abs((int) (l_nodes - l_nodes_by_walk))); + _log->stamp(); + _log->end_head(); + } + VectorSet& useful_member_set = useful.member_set(); + int last_idx = l_nodes_by_walk; + for (int i = 0; i < last_idx; i++) { + if (useful_member_set.test(i)) { + if (_dead_node_list.test(i)) { + if (_log != NULL) { + _log->elem("mismatched_node_info node_idx='%d' type='both live and dead'", i); + } + if (PrintIdealNodeCount) { + // Print the log message to tty + tty->print_cr("mismatched_node idx='%d' both live and dead'", i); + useful.at(i)->dump(); + } + } + } + else if (! _dead_node_list.test(i)) { + if (_log != NULL) { + _log->elem("mismatched_node_info node_idx='%d' type='neither live nor dead'", i); + } + if (PrintIdealNodeCount) { + // Print the log message to tty + tty->print_cr("mismatched_node idx='%d' type='neither live nor dead'", i); + } + } + } + if (_log != NULL) { + _log->tail("mismatched_nodes"); + } + } + } + #endif + #ifndef PRODUCT void Compile::verify_top(Node* tn) const { if (tn != NULL) { assert(tn->is_Con(), "top node must be a constant"); assert(((ConNode*)tn)->type() == Type::TOP, "top node must have correct type");
*** 2085,2095 **** // Note that OffsetBot and OffsetTop are very negative. } // Eliminate trivially redundant StoreCMs and accumulate their // precedence edges. ! static void eliminate_redundant_card_marks(Node* n) { assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); if (n->in(MemNode::Address)->outcnt() > 1) { // There are multiple users of the same address so it might be // possible to eliminate some of the StoreCMs Node* mem = n->in(MemNode::Memory); --- 2175,2185 ---- // Note that OffsetBot and OffsetTop are very negative. } // Eliminate trivially redundant StoreCMs and accumulate their // precedence edges. ! void Compile::eliminate_redundant_card_marks(Node* n) { assert(n->Opcode() == Op_StoreCM, "expected StoreCM"); if (n->in(MemNode::Address)->outcnt() > 1) { // There are multiple users of the same address so it might be // possible to eliminate some of the StoreCMs Node* mem = n->in(MemNode::Memory);
*** 2120,2141 **** done = true; } // Eliminate the previous StoreCM prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); assert(mem->outcnt() == 0, "should be dead"); ! mem->disconnect_inputs(NULL); } else { prev = mem; } mem = prev->in(MemNode::Memory); } } } //------------------------------final_graph_reshaping_impl---------------------- // Implement items 1-5 from final_graph_reshaping below. ! static void final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc ) { if ( n->outcnt() == 0 ) return; // dead node uint nop = n->Opcode(); // Check for 2-input instruction with "last use" on right input. --- 2210,2231 ---- done = true; } // Eliminate the previous StoreCM prev->set_req(MemNode::Memory, mem->in(MemNode::Memory)); assert(mem->outcnt() == 0, "should be dead"); ! mem->disconnect_inputs(NULL, this); } else { prev = mem; } mem = prev->in(MemNode::Memory); } } } //------------------------------final_graph_reshaping_impl---------------------- // Implement items 1-5 from final_graph_reshaping below. ! void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) { if ( n->outcnt() == 0 ) return; // dead node uint nop = n->Opcode(); // Check for 2-input instruction with "last use" on right input.
*** 2161,2172 **** } } #ifdef ASSERT if( n->is_Mem() ) { ! Compile* C = Compile::current(); ! int alias_idx = C->get_alias_index(n->as_Mem()->adr_type()); assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || // oop will be recorded in oop map if load crosses safepoint n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || LoadNode::is_immutable_value(n->in(MemNode::Address))), "raw memory operations should have control edge"); --- 2251,2261 ---- } } #ifdef ASSERT if( n->is_Mem() ) { ! int alias_idx = get_alias_index(n->as_Mem()->adr_type()); assert( n->in(0) != NULL || alias_idx != Compile::AliasIdxRaw || // oop will be recorded in oop map if load crosses safepoint n->is_Load() && (n->as_Load()->bottom_type()->isa_oopptr() || LoadNode::is_immutable_value(n->in(MemNode::Address))), "raw memory operations should have control edge");
*** 2211,2221 **** case Op_CmpD3: frc.inc_double_count(); break; case Op_Opaque1: // Remove Opaque Nodes before matching case Op_Opaque2: // Remove Opaque Nodes before matching ! n->subsume_by(n->in(1)); break; case Op_CallStaticJava: case Op_CallJava: case Op_CallDynamicJava: frc.inc_java_call_count(); // Count java call site; --- 2300,2310 ---- case Op_CmpD3: frc.inc_double_count(); break; case Op_Opaque1: // Remove Opaque Nodes before matching case Op_Opaque2: // Remove Opaque Nodes before matching ! n->subsume_by(n->in(1), this); break; case Op_CallStaticJava: case Op_CallJava: case Op_CallDynamicJava: frc.inc_java_call_count(); // Count java call site;
*** 2335,2346 **** Node* nn = NULL; int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass; // Look for existing ConN node of the same exact type. ! Compile* C = Compile::current(); ! Node* r = C->root(); uint cnt = r->outcnt(); for (uint i = 0; i < cnt; i++) { Node* m = r->raw_out(i); if (m!= NULL && m->Opcode() == op && m->bottom_type()->make_ptr() == t) { --- 2424,2434 ---- Node* nn = NULL; int op = t->isa_oopptr() ? Op_ConN : Op_ConNKlass; // Look for existing ConN node of the same exact type. ! Node* r = root(); uint cnt = r->outcnt(); for (uint i = 0; i < cnt; i++) { Node* m = r->raw_out(i); if (m!= NULL && m->Opcode() == op && m->bottom_type()->make_ptr() == t) {
*** 2350,2367 **** } if (nn != NULL) { // Decode a narrow oop to match address // [R12 + narrow_oop_reg<<3 + offset] if (t->isa_oopptr()) { ! nn = new (C) DecodeNNode(nn, t); } else { ! nn = new (C) DecodeNKlassNode(nn, t); } n->set_req(AddPNode::Base, nn); n->set_req(AddPNode::Address, nn); if (addp->outcnt() == 0) { ! addp->disconnect_inputs(NULL); } } } } #endif --- 2438,2455 ---- } if (nn != NULL) { // Decode a narrow oop to match address // [R12 + narrow_oop_reg<<3 + offset] if (t->isa_oopptr()) { ! nn = new (this) DecodeNNode(nn, t); } else { ! nn = new (this) DecodeNKlassNode(nn, t); } n->set_req(AddPNode::Base, nn); n->set_req(AddPNode::Address, nn); if (addp->outcnt() == 0) { ! addp->disconnect_inputs(NULL, this); } } } } #endif
*** 2369,2379 **** } #ifdef _LP64 case Op_CastPP: if (n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) { - Compile* C = Compile::current(); Node* in1 = n->in(1); const Type* t = n->bottom_type(); Node* new_in1 = in1->clone(); new_in1->as_DecodeN()->set_type(t); --- 2457,2466 ----
*** 2398,2410 **** // corresponds to use it as value in implicit_null_check(). // new_in1->set_req(0, n->in(0)); } ! n->subsume_by(new_in1); if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL); } } break; case Op_CmpP: --- 2485,2497 ---- // corresponds to use it as value in implicit_null_check(). // new_in1->set_req(0, n->in(0)); } ! n->subsume_by(new_in1, this); if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL, this); } } break; case Op_CmpP:
*** 2417,2427 **** in2 = in1; in1 = n->in(2); } assert(in1->is_DecodeNarrowPtr(), "sanity"); - Compile* C = Compile::current(); Node* new_in2 = NULL; if (in2->is_DecodeNarrowPtr()) { assert(in2->Opcode() == in1->Opcode(), "must be same node type"); new_in2 = in2->in(1); } else if (in2->Opcode() == Op_ConP) { --- 2504,2513 ----
*** 2430,2440 **** assert(in1->is_DecodeN(), "compare klass to null?"); // Don't convert CmpP null check into CmpN if compressed // oops implicit null check is not generated. // This will allow to generate normal oop implicit null check. if (Matcher::gen_narrow_oop_implicit_null_checks()) ! new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); // // This transformation together with CastPP transformation above // will generated code for implicit NULL checks for compressed oops. // // The original code after Optimize() --- 2516,2526 ---- assert(in1->is_DecodeN(), "compare klass to null?"); // Don't convert CmpP null check into CmpN if compressed // oops implicit null check is not generated. // This will allow to generate normal oop implicit null check. if (Matcher::gen_narrow_oop_implicit_null_checks()) ! new_in2 = ConNode::make(this, TypeNarrowOop::NULL_PTR); // // This transformation together with CastPP transformation above // will generated code for implicit NULL checks for compressed oops. // // The original code after Optimize()
*** 2469,2491 **** // decode_not_null narrow_oop_reg, base_reg // Load [base_reg + offset], val_reg // NullCheck base_reg // } else if (t->isa_oopptr()) { ! new_in2 = ConNode::make(C, t->make_narrowoop()); } else if (t->isa_klassptr()) { ! new_in2 = ConNode::make(C, t->make_narrowklass()); } } if (new_in2 != NULL) { ! Node* cmpN = new (C) CmpNNode(in1->in(1), new_in2); ! n->subsume_by( cmpN ); if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL); } if (in2->outcnt() == 0) { ! in2->disconnect_inputs(NULL); } } } break; --- 2555,2577 ---- // decode_not_null narrow_oop_reg, base_reg // Load [base_reg + offset], val_reg // NullCheck base_reg // } else if (t->isa_oopptr()) { ! new_in2 = ConNode::make(this, t->make_narrowoop()); } else if (t->isa_klassptr()) { ! new_in2 = ConNode::make(this, t->make_narrowklass()); } } if (new_in2 != NULL) { ! Node* cmpN = new (this) CmpNNode(in1->in(1), new_in2); ! n->subsume_by(cmpN, this); if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL, this); } if (in2->outcnt() == 0) { ! in2->disconnect_inputs(NULL, this); } } } break;
*** 2499,2523 **** case Op_EncodeP: case Op_EncodePKlass: { Node* in1 = n->in(1); if (in1->is_DecodeNarrowPtr()) { ! n->subsume_by(in1->in(1)); } else if (in1->Opcode() == Op_ConP) { - Compile* C = Compile::current(); const Type* t = in1->bottom_type(); if (t == TypePtr::NULL_PTR) { assert(t->isa_oopptr(), "null klass?"); ! n->subsume_by(ConNode::make(C, TypeNarrowOop::NULL_PTR)); } else if (t->isa_oopptr()) { ! n->subsume_by(ConNode::make(C, t->make_narrowoop())); } else if (t->isa_klassptr()) { ! n->subsume_by(ConNode::make(C, t->make_narrowklass())); } } if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL); } break; } case Op_Proj: { --- 2585,2608 ---- case Op_EncodeP: case Op_EncodePKlass: { Node* in1 = n->in(1); if (in1->is_DecodeNarrowPtr()) { ! n->subsume_by(in1->in(1), this); } else if (in1->Opcode() == Op_ConP) { const Type* t = in1->bottom_type(); if (t == TypePtr::NULL_PTR) { assert(t->isa_oopptr(), "null klass?"); ! n->subsume_by(ConNode::make(this, TypeNarrowOop::NULL_PTR), this); } else if (t->isa_oopptr()) { ! n->subsume_by(ConNode::make(this, t->make_narrowoop()), this); } else if (t->isa_klassptr()) { ! n->subsume_by(ConNode::make(this, t->make_narrowklass()), this); } } if (in1->outcnt() == 0) { ! in1->disconnect_inputs(NULL, this); } break; } case Op_Proj: {
*** 2536,2546 **** proj = use; break; } } assert(proj != NULL, "must be found"); ! p->subsume_by(proj); } } break; } --- 2621,2631 ---- proj = use; break; } } assert(proj != NULL, "must be found"); ! p->subsume_by(proj, this); } } break; }
*** 2556,2566 **** assert(m != NULL, ""); if (unique_in != m) unique_in = NULL; } if (unique_in != NULL) { ! n->subsume_by(unique_in); } } break; #endif --- 2641,2651 ---- assert(m != NULL, ""); if (unique_in != m) unique_in = NULL; } if (unique_in != NULL) { ! n->subsume_by(unique_in, this); } } break; #endif
*** 2569,2588 **** if (UseDivMod) { // Check if a%b and a/b both exist Node* d = n->find_similar(Op_DivI); if (d) { // Replace them with a fused divmod if supported - Compile* C = Compile::current(); if (Matcher::has_match_rule(Op_DivModI)) { ! DivModINode* divmod = DivModINode::make(C, n); ! d->subsume_by(divmod->div_proj()); ! n->subsume_by(divmod->mod_proj()); } else { // replace a%b with a-((a/b)*b) ! Node* mult = new (C) MulINode(d, d->in(2)); ! Node* sub = new (C) SubINode(d->in(1), mult); ! n->subsume_by( sub ); } } } break; --- 2654,2672 ---- if (UseDivMod) { // Check if a%b and a/b both exist Node* d = n->find_similar(Op_DivI); if (d) { // Replace them with a fused divmod if supported if (Matcher::has_match_rule(Op_DivModI)) { ! DivModINode* divmod = DivModINode::make(this, n); ! d->subsume_by(divmod->div_proj(), this); ! n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) ! Node* mult = new (this) MulINode(d, d->in(2)); ! Node* sub = new (this) SubINode(d->in(1), mult); ! n->subsume_by(sub, this); } } } break;
*** 2590,2609 **** if (UseDivMod) { // Check if a%b and a/b both exist Node* d = n->find_similar(Op_DivL); if (d) { // Replace them with a fused divmod if supported - Compile* C = Compile::current(); if (Matcher::has_match_rule(Op_DivModL)) { ! DivModLNode* divmod = DivModLNode::make(C, n); ! d->subsume_by(divmod->div_proj()); ! n->subsume_by(divmod->mod_proj()); } else { // replace a%b with a-((a/b)*b) ! Node* mult = new (C) MulLNode(d, d->in(2)); ! Node* sub = new (C) SubLNode(d->in(1), mult); ! n->subsume_by( sub ); } } } break; --- 2674,2692 ---- if (UseDivMod) { // Check if a%b and a/b both exist Node* d = n->find_similar(Op_DivL); if (d) { // Replace them with a fused divmod if supported if (Matcher::has_match_rule(Op_DivModL)) { ! DivModLNode* divmod = DivModLNode::make(this, n); ! d->subsume_by(divmod->div_proj(), this); ! n->subsume_by(divmod->mod_proj(), this); } else { // replace a%b with a-((a/b)*b) ! Node* mult = new (this) MulLNode(d, d->in(2)); ! Node* sub = new (this) SubLNode(d->in(1), mult); ! n->subsume_by(sub, this); } } } break;
*** 2618,2629 **** case Op_PackL: case Op_PackD: if (n->req()-1 > 2) { // Replace many operand PackNodes with a binary tree for matching PackNode* p = (PackNode*) n; ! Node* btp = p->binary_tree_pack(Compile::current(), 1, n->req()); ! n->subsume_by(btp); } break; case Op_Loop: case Op_CountedLoop: if (n->as_Loop()->is_inner_loop()) { --- 2701,2712 ---- case Op_PackL: case Op_PackD: if (n->req()-1 > 2) { // Replace many operand PackNodes with a binary tree for matching PackNode* p = (PackNode*) n; ! Node* btp = p->binary_tree_pack(this, 1, n->req()); ! n->subsume_by(btp, this); } break; case Op_Loop: case Op_CountedLoop: if (n->as_Loop()->is_inner_loop()) {
*** 2643,2664 **** juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); const TypeInt* t = in2->find_int_type(); if (t != NULL && t->is_con()) { juint shift = t->get_con(); if (shift > mask) { // Unsigned cmp ! Compile* C = Compile::current(); ! n->set_req(2, ConNode::make(C, TypeInt::make(shift & mask))); } } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { ! Compile* C = Compile::current(); ! Node* shift = new (C) AndINode(in2, ConNode::make(C, TypeInt::make(mask))); n->set_req(2, shift); } } if (in2->outcnt() == 0) { // Remove dead node ! in2->disconnect_inputs(NULL); } } break; default: assert( !n->is_Call(), "" ); --- 2726,2745 ---- juint mask = (n->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1); const TypeInt* t = in2->find_int_type(); if (t != NULL && t->is_con()) { juint shift = t->get_con(); if (shift > mask) { // Unsigned cmp ! n->set_req(2, ConNode::make(this, TypeInt::make(shift & mask))); } } else { if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) { ! Node* shift = new (this) AndINode(in2, ConNode::make(this, TypeInt::make(mask))); n->set_req(2, shift); } } if (in2->outcnt() == 0) { // Remove dead node ! in2->disconnect_inputs(NULL, this); } } break; default: assert( !n->is_Call(), "" );
*** 2672,2682 **** } //------------------------------final_graph_reshaping_walk--------------------- // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), // requires that the walk visits a node's inputs before visiting the node. ! static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) { ResourceArea *area = Thread::current()->resource_area(); Unique_Node_List sfpt(area); frc._visited.set(root->_idx); // first, mark node as visited uint cnt = root->req(); --- 2753,2763 ---- } //------------------------------final_graph_reshaping_walk--------------------- // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), // requires that the walk visits a node's inputs before visiting the node. ! void Compile::final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &frc ) { ResourceArea *area = Thread::current()->resource_area(); Unique_Node_List sfpt(area); frc._visited.set(root->_idx); // first, mark node as visited uint cnt = root->req();
*** 2739,2749 **** } if (safe_to_skip) { n->set_req(j, in->in(1)); } if (in->outcnt() == 0) { ! in->disconnect_inputs(NULL); } } } } } --- 2820,2830 ---- } if (safe_to_skip) { n->set_req(j, in->in(1)); } if (in->outcnt() == 0) { ! in->disconnect_inputs(NULL, this); } } } } }
*** 3012,3040 **** } _root = NULL; // flush the graph, too } Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) ! : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false) { if (dolog) { C = Compile::current(); _log = C->log(); } else { C = NULL; _log = NULL; } if (_log != NULL) { ! _log->begin_head("phase name='%s' nodes='%d'", name, C->unique()); _log->stamp(); _log->end_head(); } } Compile::TracePhase::~TracePhase() { if (_log != NULL) { ! _log->done("phase nodes='%d'", C->unique()); } } //============================================================================= // Two Constant's are equal when the type and the value are equal. --- 3093,3141 ---- } _root = NULL; // flush the graph, too } Compile::TracePhase::TracePhase(const char* name, elapsedTimer* accumulator, bool dolog) ! : TraceTime(NULL, accumulator, false NOT_PRODUCT( || TimeCompiler ), false), ! _phase_name(name), _dolog(dolog) { if (dolog) { C = Compile::current(); _log = C->log(); } else { C = NULL; _log = NULL; } if (_log != NULL) { ! _log->begin_head("phase name='%s' nodes='%d' live='%d'", _phase_name, C->unique(), C->live_nodes()); _log->stamp(); _log->end_head(); } } Compile::TracePhase::~TracePhase() { + + C = Compile::current(); + if (_dolog) { + _log = C->log(); + } else { + _log = NULL; + } + + #ifdef ASSERT + if (PrintIdealNodeCount) { + tty->print_cr("phase name='%s' nodes='%d' live='%d' live_graph_walk='%d'", + _phase_name, C->unique(), C->live_nodes(), C->count_live_nodes_by_graph_walk()); + } + + if (VerifyIdealNodeCount) { + Compile::current()->print_missing_nodes(); + } + #endif + if (_log != NULL) { ! _log->done("phase name='%s' nodes='%d' live='%d' ", _phase_name, C->unique(), C->live_nodes()); } } //============================================================================= // Two Constant's are equal when the type and the value are equal.
src/share/vm/opto/compile.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File