Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/compile.cpp @ 333:7484fa4b8825
Merge
author | rasbold |
---|---|
date | Mon, 15 Sep 2008 09:58:26 -0700 |
parents | 93befa083681 cecd8eb4e0ca |
children | 194b8e3a2fc4 |
comparison
equal
deleted
inserted
replaced
329:0ba3ec980ae5 | 333:7484fa4b8825 |
---|---|
1965 // Clone shared simple arguments to uncommon calls, item (1). | 1965 // Clone shared simple arguments to uncommon calls, item (1). |
1966 if( n->outcnt() > 1 && | 1966 if( n->outcnt() > 1 && |
1967 !n->is_Proj() && | 1967 !n->is_Proj() && |
1968 nop != Op_CreateEx && | 1968 nop != Op_CreateEx && |
1969 nop != Op_CheckCastPP && | 1969 nop != Op_CheckCastPP && |
1970 nop != Op_DecodeN && | |
1970 !n->is_Mem() ) { | 1971 !n->is_Mem() ) { |
1971 Node *x = n->clone(); | 1972 Node *x = n->clone(); |
1972 call->set_req( TypeFunc::Parms, x ); | 1973 call->set_req( TypeFunc::Parms, x ); |
1973 } | 1974 } |
1974 } | 1975 } |
2073 | 2074 |
2074 #ifdef _LP64 | 2075 #ifdef _LP64 |
2075 case Op_CmpP: | 2076 case Op_CmpP: |
2076 // Do this transformation here to preserve CmpPNode::sub() and | 2077 // Do this transformation here to preserve CmpPNode::sub() and |
2077 // other TypePtr related Ideal optimizations (for example, ptr nullness). | 2078 // other TypePtr related Ideal optimizations (for example, ptr nullness). |
2078 if( n->in(1)->is_DecodeN() ) { | 2079 if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) { |
2080 Node* in1 = n->in(1); | |
2081 Node* in2 = n->in(2); | |
2082 if (!in1->is_DecodeN()) { | |
2083 in2 = in1; | |
2084 in1 = n->in(2); | |
2085 } | |
2086 assert(in1->is_DecodeN(), "sanity"); | |
2087 | |
2079 Compile* C = Compile::current(); | 2088 Compile* C = Compile::current(); |
2080 Node* in2 = NULL; | 2089 Node* new_in2 = NULL; |
2081 if( n->in(2)->is_DecodeN() ) { | 2090 if (in2->is_DecodeN()) { |
2082 in2 = n->in(2)->in(1); | 2091 new_in2 = in2->in(1); |
2083 } else if ( n->in(2)->Opcode() == Op_ConP ) { | 2092 } else if (in2->Opcode() == Op_ConP) { |
2084 const Type* t = n->in(2)->bottom_type(); | 2093 const Type* t = in2->bottom_type(); |
2085 if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) { | 2094 if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) { |
2086 Node *in1 = n->in(1); | |
2087 if (Matcher::clone_shift_expressions) { | 2095 if (Matcher::clone_shift_expressions) { |
2088 // x86, ARM and friends can handle 2 adds in addressing mode. | 2096 // x86, ARM and friends can handle 2 adds in addressing mode. |
2089 // Decode a narrow oop and do implicit NULL check in address | 2097 // Decode a narrow oop and do implicit NULL check in address |
2090 // [R12 + narrow_oop_reg<<3 + offset] | 2098 // [R12 + narrow_oop_reg<<3 + offset] |
2091 in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); | 2099 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
2092 } else { | 2100 } else { |
2093 // Don't replace CmpP(o ,null) if 'o' is used in AddP | 2101 // Don't replace CmpP(o ,null) if 'o' is used in AddP |
2094 // to generate implicit NULL check on Sparc where | 2102 // to generate implicit NULL check on Sparc where |
2095 // narrow oops can't be used in address. | 2103 // narrow oops can't be used in address. |
2096 uint i = 0; | 2104 uint i = 0; |
2097 for (; i < in1->outcnt(); i++) { | 2105 for (; i < in1->outcnt(); i++) { |
2098 if (in1->raw_out(i)->is_AddP()) | 2106 if (in1->raw_out(i)->is_AddP()) |
2099 break; | 2107 break; |
2100 } | 2108 } |
2101 if (i >= in1->outcnt()) { | 2109 if (i >= in1->outcnt()) { |
2102 in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); | 2110 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); |
2103 } | 2111 } |
2104 } | 2112 } |
2105 } else if (t->isa_oopptr()) { | 2113 } else if (t->isa_oopptr()) { |
2106 in2 = ConNode::make(C, t->make_narrowoop()); | 2114 new_in2 = ConNode::make(C, t->make_narrowoop()); |
2107 } | 2115 } |
2108 } | 2116 } |
2109 if( in2 != NULL ) { | 2117 if (new_in2 != NULL) { |
2110 Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2); | 2118 Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2); |
2111 n->subsume_by( cmpN ); | 2119 n->subsume_by( cmpN ); |
2120 if (in1->outcnt() == 0) { | |
2121 in1->disconnect_inputs(NULL); | |
2122 } | |
2123 if (in2->outcnt() == 0) { | |
2124 in2->disconnect_inputs(NULL); | |
2125 } | |
2112 } | 2126 } |
2113 } | 2127 } |
2114 break; | 2128 break; |
2115 #endif | 2129 #endif |
2116 | 2130 |
2212 | 2226 |
2213 //------------------------------final_graph_reshaping_walk--------------------- | 2227 //------------------------------final_graph_reshaping_walk--------------------- |
2214 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), | 2228 // Replacing Opaque nodes with their input in final_graph_reshaping_impl(), |
2215 // requires that the walk visits a node's inputs before visiting the node. | 2229 // requires that the walk visits a node's inputs before visiting the node. |
2216 static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) { | 2230 static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) { |
2231 ResourceArea *area = Thread::current()->resource_area(); | |
2232 Unique_Node_List sfpt(area); | |
2233 | |
2217 fpu._visited.set(root->_idx); // first, mark node as visited | 2234 fpu._visited.set(root->_idx); // first, mark node as visited |
2218 uint cnt = root->req(); | 2235 uint cnt = root->req(); |
2219 Node *n = root; | 2236 Node *n = root; |
2220 uint i = 0; | 2237 uint i = 0; |
2221 while (true) { | 2238 while (true) { |
2222 if (i < cnt) { | 2239 if (i < cnt) { |
2223 // Place all non-visited non-null inputs onto stack | 2240 // Place all non-visited non-null inputs onto stack |
2224 Node* m = n->in(i); | 2241 Node* m = n->in(i); |
2225 ++i; | 2242 ++i; |
2226 if (m != NULL && !fpu._visited.test_set(m->_idx)) { | 2243 if (m != NULL && !fpu._visited.test_set(m->_idx)) { |
2244 if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL) | |
2245 sfpt.push(m); | |
2227 cnt = m->req(); | 2246 cnt = m->req(); |
2228 nstack.push(n, i); // put on stack parent and next input's index | 2247 nstack.push(n, i); // put on stack parent and next input's index |
2229 n = m; | 2248 n = m; |
2230 i = 0; | 2249 i = 0; |
2231 } | 2250 } |
2236 break; // finished | 2255 break; // finished |
2237 n = nstack.node(); // Get node from stack | 2256 n = nstack.node(); // Get node from stack |
2238 cnt = n->req(); | 2257 cnt = n->req(); |
2239 i = nstack.index(); | 2258 i = nstack.index(); |
2240 nstack.pop(); // Shift to the next node on stack | 2259 nstack.pop(); // Shift to the next node on stack |
2260 } | |
2261 } | |
2262 | |
2263 // Go over safepoints nodes to skip DecodeN nodes for debug edges. | |
2264 // It could be done for an uncommon traps or any safepoints/calls | |
2265 // if the DecodeN node is referenced only in a debug info. | |
2266 while (sfpt.size() > 0) { | |
2267 n = sfpt.pop(); | |
2268 JVMState *jvms = n->as_SafePoint()->jvms(); | |
2269 assert(jvms != NULL, "sanity"); | |
2270 int start = jvms->debug_start(); | |
2271 int end = n->req(); | |
2272 bool is_uncommon = (n->is_CallStaticJava() && | |
2273 n->as_CallStaticJava()->uncommon_trap_request() != 0); | |
2274 for (int j = start; j < end; j++) { | |
2275 Node* in = n->in(j); | |
2276 if (in->is_DecodeN()) { | |
2277 bool safe_to_skip = true; | |
2278 if (!is_uncommon ) { | |
2279 // Is it safe to skip? | |
2280 for (uint i = 0; i < in->outcnt(); i++) { | |
2281 Node* u = in->raw_out(i); | |
2282 if (!u->is_SafePoint() || | |
2283 u->is_Call() && u->as_Call()->has_non_debug_use(n)) { | |
2284 safe_to_skip = false; | |
2285 } | |
2286 } | |
2287 } | |
2288 if (safe_to_skip) { | |
2289 n->set_req(j, in->in(1)); | |
2290 } | |
2291 if (in->outcnt() == 0) { | |
2292 in->disconnect_inputs(NULL); | |
2293 } | |
2294 } | |
2241 } | 2295 } |
2242 } | 2296 } |
2243 } | 2297 } |
2244 | 2298 |
2245 //------------------------------final_graph_reshaping-------------------------- | 2299 //------------------------------final_graph_reshaping-------------------------- |