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

src/share/vm/opto/compile.cpp

Print this page

        

*** 1965,1974 **** --- 1965,1975 ---- // Clone shared simple arguments to uncommon calls, item (1). if( n->outcnt() > 1 && !n->is_Proj() && nop != Op_CreateEx && nop != Op_CheckCastPP && + nop != Op_DecodeN && !n->is_Mem() ) { Node *x = n->clone(); call->set_req( TypeFunc::Parms, x ); } }
*** 2073,2096 **** #ifdef _LP64 case Op_CmpP: // Do this transformation here to preserve CmpPNode::sub() and // other TypePtr related Ideal optimizations (for example, ptr nullness). ! if( n->in(1)->is_DecodeN() ) { Compile* C = Compile::current(); ! Node* in2 = NULL; ! if( n->in(2)->is_DecodeN() ) { ! in2 = n->in(2)->in(1); ! } else if ( n->in(2)->Opcode() == Op_ConP ) { ! const Type* t = n->in(2)->bottom_type(); if (t == TypePtr::NULL_PTR) { - Node *in1 = n->in(1); if (Matcher::clone_shift_expressions) { // x86, ARM and friends can handle 2 adds in addressing mode. // Decode a narrow oop and do implicit NULL check in address // [R12 + narrow_oop_reg<<3 + offset] ! in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } else { // Don't replace CmpP(o ,null) if 'o' is used in AddP // to generate implicit NULL check on Sparc where // narrow oops can't be used in address. uint i = 0; --- 2074,2104 ---- #ifdef _LP64 case Op_CmpP: // Do this transformation here to preserve CmpPNode::sub() and // other TypePtr related Ideal optimizations (for example, ptr nullness). ! if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) { ! Node* in1 = n->in(1); ! Node* in2 = n->in(2); ! if (!in1->is_DecodeN()) { ! in2 = in1; ! in1 = n->in(2); ! } ! assert(in1->is_DecodeN(), "sanity"); ! Compile* C = Compile::current(); ! Node* new_in2 = NULL; ! if (in2->is_DecodeN()) { ! new_in2 = in2->in(1); ! } else if (in2->Opcode() == Op_ConP) { ! const Type* t = in2->bottom_type(); if (t == TypePtr::NULL_PTR) { if (Matcher::clone_shift_expressions) { // x86, ARM and friends can handle 2 adds in addressing mode. // Decode a narrow oop and do implicit NULL check in address // [R12 + narrow_oop_reg<<3 + offset] ! new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } else { // Don't replace CmpP(o ,null) if 'o' is used in AddP // to generate implicit NULL check on Sparc where // narrow oops can't be used in address. uint i = 0;
*** 2097,2118 **** for (; i < in1->outcnt(); i++) { if (in1->raw_out(i)->is_AddP()) break; } if (i >= in1->outcnt()) { ! in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } } } else if (t->isa_oopptr()) { ! in2 = ConNode::make(C, t->make_narrowoop()); } } ! if( in2 != NULL ) { ! Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2); n->subsume_by( cmpN ); } } break; #endif case Op_ModI: if (UseDivMod) { --- 2105,2132 ---- for (; i < in1->outcnt(); i++) { if (in1->raw_out(i)->is_AddP()) break; } if (i >= in1->outcnt()) { ! new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); } } } else if (t->isa_oopptr()) { ! new_in2 = ConNode::make(C, t->make_narrowoop()); } } ! if (new_in2 != NULL) { ! Node* cmpN = new (C, 3) 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; #endif case Op_ModI: if (UseDivMod) {
*** 2212,2221 **** --- 2226,2238 ---- //------------------------------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 &fpu ) { + ResourceArea *area = Thread::current()->resource_area(); + Unique_Node_List sfpt(area); + fpu._visited.set(root->_idx); // first, mark node as visited uint cnt = root->req(); Node *n = root; uint i = 0; while (true) {
*** 2222,2231 **** --- 2239,2250 ---- if (i < cnt) { // Place all non-visited non-null inputs onto stack Node* m = n->in(i); ++i; if (m != NULL && !fpu._visited.test_set(m->_idx)) { + if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) + sfpt.push(m); cnt = m->req(); nstack.push(n, i); // put on stack parent and next input's index n = m; i = 0; }
*** 2238,2247 **** --- 2257,2301 ---- cnt = n->req(); i = nstack.index(); nstack.pop(); // Shift to the next node on stack } } + + // Go over safepoints nodes to skip DecodeN nodes for debug edges. + // It could be done for an uncommon traps or any safepoints/calls + // if the DecodeN node is referenced only in a debug info. + while (sfpt.size() > 0) { + n = sfpt.pop(); + JVMState *jvms = n->as_SafePoint()->jvms(); + assert(jvms != NULL, "sanity"); + int start = jvms->debug_start(); + int end = n->req(); + bool is_uncommon = (n->is_CallStaticJava() && + n->as_CallStaticJava()->uncommon_trap_request() != 0); + for (int j = start; j < end; j++) { + Node* in = n->in(j); + if (in->is_DecodeN()) { + bool safe_to_skip = true; + if (!is_uncommon ) { + // Is it safe to skip? + for (uint i = 0; i < in->outcnt(); i++) { + Node* u = in->raw_out(i); + if (!u->is_SafePoint() || + u->is_Call() && u->as_Call()->has_non_debug_use(n)) { + safe_to_skip = false; + } + } + } + if (safe_to_skip) { + n->set_req(j, in->in(1)); + } + if (in->outcnt() == 0) { + in->disconnect_inputs(NULL); + } + } + } + } } //------------------------------final_graph_reshaping-------------------------- // Final Graph Reshaping. //
src/share/vm/opto/compile.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File