comparison src/share/vm/opto/compile.cpp @ 1575:3657cb01ffc5

6954029: Improve implicit null check generation with compressed oops Summary: Hoist DecodeN instruction above null check Reviewed-by: never, twisti
author kvn
date Wed, 02 Jun 2010 09:49:32 -0700
parents b4776199210f
children e9ff18c4ace7
comparison
equal deleted inserted replaced
1574:1eb493f33423 1575:3657cb01ffc5
2174 break; 2174 break;
2175 } 2175 }
2176 2176
2177 #ifdef _LP64 2177 #ifdef _LP64
2178 case Op_CastPP: 2178 case Op_CastPP:
2179 if (n->in(1)->is_DecodeN() && Universe::narrow_oop_use_implicit_null_checks()) { 2179 if (n->in(1)->is_DecodeN() && Matcher::gen_narrow_oop_implicit_null_checks()) {
2180 Compile* C = Compile::current(); 2180 Compile* C = Compile::current();
2181 Node* in1 = n->in(1); 2181 Node* in1 = n->in(1);
2182 const Type* t = n->bottom_type(); 2182 const Type* t = n->bottom_type();
2183 Node* new_in1 = in1->clone(); 2183 Node* new_in1 = in1->clone();
2184 new_in1->as_DecodeN()->set_type(t); 2184 new_in1->as_DecodeN()->set_type(t);
2185 2185
2186 if (!Matcher::clone_shift_expressions) { 2186 if (!Matcher::narrow_oop_use_complex_address()) {
2187 // 2187 //
2188 // x86, ARM and friends can handle 2 adds in addressing mode 2188 // x86, ARM and friends can handle 2 adds in addressing mode
2189 // and Matcher can fold a DecodeN node into address by using 2189 // and Matcher can fold a DecodeN node into address by using
2190 // a narrow oop directly and do implicit NULL check in address: 2190 // a narrow oop directly and do implicit NULL check in address:
2191 // 2191 //
2229 Node* new_in2 = NULL; 2229 Node* new_in2 = NULL;
2230 if (in2->is_DecodeN()) { 2230 if (in2->is_DecodeN()) {
2231 new_in2 = in2->in(1); 2231 new_in2 = in2->in(1);
2232 } else if (in2->Opcode() == Op_ConP) { 2232 } else if (in2->Opcode() == Op_ConP) {
2233 const Type* t = in2->bottom_type(); 2233 const Type* t = in2->bottom_type();
2234 if (t == TypePtr::NULL_PTR && Universe::narrow_oop_use_implicit_null_checks()) { 2234 if (t == TypePtr::NULL_PTR) {
2235 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR); 2235 // Don't convert CmpP null check into CmpN if compressed
2236 // oops implicit null check is not generated.
2237 // This will allow to generate normal oop implicit null check.
2238 if (Matcher::gen_narrow_oop_implicit_null_checks())
2239 new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
2236 // 2240 //
2237 // This transformation together with CastPP transformation above 2241 // This transformation together with CastPP transformation above
2238 // will generated code for implicit NULL checks for compressed oops. 2242 // will generated code for implicit NULL checks for compressed oops.
2239 // 2243 //
2240 // The original code after Optimize() 2244 // The original code after Optimize()
2287 } 2291 }
2288 break; 2292 break;
2289 2293
2290 case Op_DecodeN: 2294 case Op_DecodeN:
2291 assert(!n->in(1)->is_EncodeP(), "should be optimized out"); 2295 assert(!n->in(1)->is_EncodeP(), "should be optimized out");
2292 // DecodeN could be pinned on Sparc where it can't be fold into 2296 // DecodeN could be pinned when it can't be fold into
2293 // an address expression, see the code for Op_CastPP above. 2297 // an address expression, see the code for Op_CastPP above.
2294 assert(n->in(0) == NULL || !Matcher::clone_shift_expressions, "no control except on sparc"); 2298 assert(n->in(0) == NULL || !Matcher::narrow_oop_use_complex_address(), "no control");
2295 break; 2299 break;
2296 2300
2297 case Op_EncodeP: { 2301 case Op_EncodeP: {
2298 Node* in1 = n->in(1); 2302 Node* in1 = n->in(1);
2299 if (in1->is_DecodeN()) { 2303 if (in1->is_DecodeN()) {
2493 cnt = n->req(); 2497 cnt = n->req();
2494 i = nstack.index(); 2498 i = nstack.index();
2495 nstack.pop(); // Shift to the next node on stack 2499 nstack.pop(); // Shift to the next node on stack
2496 } 2500 }
2497 } 2501 }
2502
2503 // Skip next transformation if compressed oops are not used.
2504 if (!UseCompressedOops || !Matcher::gen_narrow_oop_implicit_null_checks())
2505 return;
2498 2506
2499 // Go over safepoints nodes to skip DecodeN nodes for debug edges. 2507 // Go over safepoints nodes to skip DecodeN nodes for debug edges.
2500 // It could be done for an uncommon traps or any safepoints/calls 2508 // It could be done for an uncommon traps or any safepoints/calls
2501 // if the DecodeN node is referenced only in a debug info. 2509 // if the DecodeN node is referenced only in a debug info.
2502 while (sfpt.size() > 0) { 2510 while (sfpt.size() > 0) {