Mercurial > hg > graal-compiler
comparison src/share/vm/opto/escape.cpp @ 6795:7eca5de9e0b6
7023898: Intrinsify AtomicLongFieldUpdater.getAndIncrement()
Summary: use shorter instruction sequences for atomic add and atomic exchange when possible.
Reviewed-by: kvn, jrose
author | roland |
---|---|
date | Thu, 20 Sep 2012 16:49:17 +0200 |
parents | 6c5b7a6becc8 |
children | 8e47bac5643a |
comparison
equal
deleted
inserted
replaced
6794:8ae8f9dd7099 | 6795:7eca5de9e0b6 |
---|---|
280 #endif | 280 #endif |
281 } | 281 } |
282 return has_non_escaping_obj; | 282 return has_non_escaping_obj; |
283 } | 283 } |
284 | 284 |
285 // Utility function for nodes that load an object | |
286 void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { | |
287 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because | |
288 // ThreadLocal has RawPtr type. | |
289 const Type* t = _igvn->type(n); | |
290 if (t->make_ptr() != NULL) { | |
291 Node* adr = n->in(MemNode::Address); | |
292 #ifdef ASSERT | |
293 if (!adr->is_AddP()) { | |
294 assert(_igvn->type(adr)->isa_rawptr(), "sanity"); | |
295 } else { | |
296 assert((ptnode_adr(adr->_idx) == NULL || | |
297 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity"); | |
298 } | |
299 #endif | |
300 add_local_var_and_edge(n, PointsToNode::NoEscape, | |
301 adr, delayed_worklist); | |
302 } | |
303 } | |
304 | |
285 // Populate Connection Graph with PointsTo nodes and create simple | 305 // Populate Connection Graph with PointsTo nodes and create simple |
286 // connection graph edges. | 306 // connection graph edges. |
287 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { | 307 void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) { |
288 assert(!_verify, "this method sould not be called for verification"); | 308 assert(!_verify, "this method sould not be called for verification"); |
289 PhaseGVN* igvn = _igvn; | 309 PhaseGVN* igvn = _igvn; |
385 break; | 405 break; |
386 } | 406 } |
387 case Op_LoadP: | 407 case Op_LoadP: |
388 case Op_LoadN: | 408 case Op_LoadN: |
389 case Op_LoadPLocked: { | 409 case Op_LoadPLocked: { |
390 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because | 410 add_objload_to_connection_graph(n, delayed_worklist); |
391 // ThreadLocal has RawPrt type. | |
392 const Type* t = igvn->type(n); | |
393 if (t->make_ptr() != NULL) { | |
394 Node* adr = n->in(MemNode::Address); | |
395 #ifdef ASSERT | |
396 if (!adr->is_AddP()) { | |
397 assert(igvn->type(adr)->isa_rawptr(), "sanity"); | |
398 } else { | |
399 assert((ptnode_adr(adr->_idx) == NULL || | |
400 ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity"); | |
401 } | |
402 #endif | |
403 add_local_var_and_edge(n, PointsToNode::NoEscape, | |
404 adr, delayed_worklist); | |
405 } | |
406 break; | 411 break; |
407 } | 412 } |
408 case Op_Parm: { | 413 case Op_Parm: { |
409 map_ideal_node(n, phantom_obj); | 414 map_ideal_node(n, phantom_obj); |
410 break; | 415 break; |
415 map_ideal_node(n, phantom_obj); // Result is unknown | 420 map_ideal_node(n, phantom_obj); // Result is unknown |
416 break; | 421 break; |
417 } | 422 } |
418 case Op_Phi: { | 423 case Op_Phi: { |
419 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because | 424 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because |
420 // ThreadLocal has RawPrt type. | 425 // ThreadLocal has RawPtr type. |
421 const Type* t = n->as_Phi()->type(); | 426 const Type* t = n->as_Phi()->type(); |
422 if (t->make_ptr() != NULL) { | 427 if (t->make_ptr() != NULL) { |
423 add_local_var(n, PointsToNode::NoEscape); | 428 add_local_var(n, PointsToNode::NoEscape); |
424 // Do not add edges during first iteration because some could be | 429 // Do not add edges during first iteration because some could be |
425 // not defined yet. | 430 // not defined yet. |
443 // Treat Return value as LocalVar with GlobalEscape escape state. | 448 // Treat Return value as LocalVar with GlobalEscape escape state. |
444 add_local_var_and_edge(n, PointsToNode::GlobalEscape, | 449 add_local_var_and_edge(n, PointsToNode::GlobalEscape, |
445 n->in(TypeFunc::Parms), delayed_worklist); | 450 n->in(TypeFunc::Parms), delayed_worklist); |
446 } | 451 } |
447 break; | 452 break; |
453 } | |
454 case Op_GetAndSetP: | |
455 case Op_GetAndSetN: { | |
456 add_objload_to_connection_graph(n, delayed_worklist); | |
457 // fallthrough | |
448 } | 458 } |
449 case Op_StoreP: | 459 case Op_StoreP: |
450 case Op_StoreN: | 460 case Op_StoreN: |
451 case Op_StorePConditional: | 461 case Op_StorePConditional: |
452 case Op_CompareAndSwapP: | 462 case Op_CompareAndSwapP: |
583 } | 593 } |
584 case Op_LoadP: | 594 case Op_LoadP: |
585 case Op_LoadN: | 595 case Op_LoadN: |
586 case Op_LoadPLocked: { | 596 case Op_LoadPLocked: { |
587 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because | 597 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because |
588 // ThreadLocal has RawPrt type. | 598 // ThreadLocal has RawPtr type. |
589 const Type* t = _igvn->type(n); | 599 const Type* t = _igvn->type(n); |
590 if (t->make_ptr() != NULL) { | 600 if (t->make_ptr() != NULL) { |
591 Node* adr = n->in(MemNode::Address); | 601 Node* adr = n->in(MemNode::Address); |
592 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); | 602 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); |
593 break; | 603 break; |
594 } | 604 } |
595 ELSE_FAIL("Op_LoadP"); | 605 ELSE_FAIL("Op_LoadP"); |
596 } | 606 } |
597 case Op_Phi: { | 607 case Op_Phi: { |
598 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because | 608 // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because |
599 // ThreadLocal has RawPrt type. | 609 // ThreadLocal has RawPtr type. |
600 const Type* t = n->as_Phi()->type(); | 610 const Type* t = n->as_Phi()->type(); |
601 if (t->make_ptr() != NULL) { | 611 if (t->make_ptr() != NULL) { |
602 for (uint i = 1; i < n->req(); i++) { | 612 for (uint i = 1; i < n->req(); i++) { |
603 Node* in = n->in(i); | 613 Node* in = n->in(i); |
604 if (in == NULL) | 614 if (in == NULL) |
636 } | 646 } |
637 case Op_StoreP: | 647 case Op_StoreP: |
638 case Op_StoreN: | 648 case Op_StoreN: |
639 case Op_StorePConditional: | 649 case Op_StorePConditional: |
640 case Op_CompareAndSwapP: | 650 case Op_CompareAndSwapP: |
641 case Op_CompareAndSwapN: { | 651 case Op_CompareAndSwapN: |
652 case Op_GetAndSetP: | |
653 case Op_GetAndSetN: { | |
642 Node* adr = n->in(MemNode::Address); | 654 Node* adr = n->in(MemNode::Address); |
655 if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) { | |
656 const Type* t = _igvn->type(n); | |
657 if (t->make_ptr() != NULL) { | |
658 add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL); | |
659 } | |
660 } | |
643 const Type *adr_type = _igvn->type(adr); | 661 const Type *adr_type = _igvn->type(adr); |
644 adr_type = adr_type->make_ptr(); | 662 adr_type = adr_type->make_ptr(); |
645 if (adr_type->isa_oopptr() || | 663 if (adr_type->isa_oopptr() || |
646 (opcode == Op_StoreP || opcode == Op_StoreN) && | 664 (opcode == Op_StoreP || opcode == Op_StoreN) && |
647 (adr_type == TypeRawPtr::NOTNULL && | 665 (adr_type == TypeRawPtr::NOTNULL && |