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