comparison src/share/vm/opto/macro.cpp @ 66:6dbf1a175d6b

6672848: (Escape Analysis) improve lock elimination with EA Summary: Remove lock/unlock MemBar nodes and specify locks in debug info for deoptimization. Reviewed-by: never
author kvn
date Fri, 14 Mar 2008 16:40:42 -0700
parents eac007780a58
children a8880a78d355
comparison
equal deleted inserted replaced
65:99269dbf4ba8 66:6dbf1a175d6b
826 // eliminate the node without expanding it. 826 // eliminate the node without expanding it.
827 // 827 //
828 // Note: The membar's associated with the lock/unlock are currently not 828 // Note: The membar's associated with the lock/unlock are currently not
829 // eliminated. This should be investigated as a future enhancement. 829 // eliminated. This should be investigated as a future enhancement.
830 // 830 //
831 void PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { 831 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) {
832 Node* mem = alock->in(TypeFunc::Memory); 832
833 if (!alock->is_eliminated()) {
834 return false;
835 }
836 // Mark the box lock as eliminated if all correspondent locks are eliminated
837 // to construct correct debug info.
838 BoxLockNode* box = alock->box_node()->as_BoxLock();
839 if (!box->is_eliminated()) {
840 bool eliminate = true;
841 for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) {
842 Node *lck = box->fast_out(i);
843 if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) {
844 eliminate = false;
845 break;
846 }
847 }
848 if (eliminate)
849 box->set_eliminated();
850 }
851
852 #ifndef PRODUCT
853 if (PrintEliminateLocks) {
854 if (alock->is_Lock()) {
855 tty->print_cr("++++ Eliminating: %d Lock", alock->_idx);
856 } else {
857 tty->print_cr("++++ Eliminating: %d Unlock", alock->_idx);
858 }
859 }
860 #endif
861
862 Node* mem = alock->in(TypeFunc::Memory);
863 Node* ctrl = alock->in(TypeFunc::Control);
864
865 extract_call_projections(alock);
866 // There are 2 projections from the lock. The lock node will
867 // be deleted when its last use is subsumed below.
868 assert(alock->outcnt() == 2 &&
869 _fallthroughproj != NULL &&
870 _memproj_fallthrough != NULL,
871 "Unexpected projections from Lock/Unlock");
872
873 Node* fallthroughproj = _fallthroughproj;
874 Node* memproj_fallthrough = _memproj_fallthrough;
833 875
834 // The memory projection from a lock/unlock is RawMem 876 // The memory projection from a lock/unlock is RawMem
835 // The input to a Lock is merged memory, so extract its RawMem input 877 // The input to a Lock is merged memory, so extract its RawMem input
836 // (unless the MergeMem has been optimized away.) 878 // (unless the MergeMem has been optimized away.)
837 if (alock->is_Lock()) { 879 if (alock->is_Lock()) {
838 if (mem->is_MergeMem()) 880 // Seach for MemBarAcquire node and delete it also.
839 mem = mem->as_MergeMem()->in(Compile::AliasIdxRaw); 881 MemBarNode* membar = fallthroughproj->unique_ctrl_out()->as_MemBar();
840 } 882 assert(membar != NULL && membar->Opcode() == Op_MemBarAcquire, "");
841 883 Node* ctrlproj = membar->proj_out(TypeFunc::Control);
842 extract_call_projections(alock); 884 Node* memproj = membar->proj_out(TypeFunc::Memory);
843 // There are 2 projections from the lock. The lock node will 885 _igvn.hash_delete(ctrlproj);
844 // be deleted when its last use is subsumed below. 886 _igvn.subsume_node(ctrlproj, fallthroughproj);
845 assert(alock->outcnt() == 2 && _fallthroughproj != NULL && 887 _igvn.hash_delete(memproj);
846 _memproj_fallthrough != NULL, "Unexpected projections from Lock/Unlock"); 888 _igvn.subsume_node(memproj, memproj_fallthrough);
847 _igvn.hash_delete(_fallthroughproj); 889 }
848 _igvn.subsume_node(_fallthroughproj, alock->in(TypeFunc::Control)); 890
849 _igvn.hash_delete(_memproj_fallthrough); 891 // Seach for MemBarRelease node and delete it also.
850 _igvn.subsume_node(_memproj_fallthrough, mem); 892 if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() &&
851 return; 893 ctrl->in(0)->is_MemBar()) {
894 MemBarNode* membar = ctrl->in(0)->as_MemBar();
895 assert(membar->Opcode() == Op_MemBarRelease &&
896 mem->is_Proj() && membar == mem->in(0), "");
897 _igvn.hash_delete(fallthroughproj);
898 _igvn.subsume_node(fallthroughproj, ctrl);
899 _igvn.hash_delete(memproj_fallthrough);
900 _igvn.subsume_node(memproj_fallthrough, mem);
901 fallthroughproj = ctrl;
902 memproj_fallthrough = mem;
903 ctrl = membar->in(TypeFunc::Control);
904 mem = membar->in(TypeFunc::Memory);
905 }
906
907 _igvn.hash_delete(fallthroughproj);
908 _igvn.subsume_node(fallthroughproj, ctrl);
909 _igvn.hash_delete(memproj_fallthrough);
910 _igvn.subsume_node(memproj_fallthrough, mem);
911 return true;
852 } 912 }
853 913
854 914
855 //------------------------------expand_lock_node---------------------- 915 //------------------------------expand_lock_node----------------------
856 void PhaseMacroExpand::expand_lock_node(LockNode *lock) { 916 void PhaseMacroExpand::expand_lock_node(LockNode *lock) {
917
918 if (eliminate_locking_node(lock)) {
919 return;
920 }
857 921
858 Node* ctrl = lock->in(TypeFunc::Control); 922 Node* ctrl = lock->in(TypeFunc::Control);
859 Node* mem = lock->in(TypeFunc::Memory); 923 Node* mem = lock->in(TypeFunc::Memory);
860 Node* obj = lock->obj_node(); 924 Node* obj = lock->obj_node();
861 Node* box = lock->box_node(); 925 Node* box = lock->box_node();
862 Node *flock = lock->fastlock_node(); 926 Node* flock = lock->fastlock_node();
863
864 if (lock->is_eliminated()) {
865 eliminate_locking_node(lock);
866 return;
867 }
868 927
869 // Make the merge point 928 // Make the merge point
870 Node *region = new (C, 3) RegionNode(3); 929 Node *region = new (C, 3) RegionNode(3);
871 930
872 Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne)); 931 Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne));
911 } 970 }
912 971
913 //------------------------------expand_unlock_node---------------------- 972 //------------------------------expand_unlock_node----------------------
914 void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) { 973 void PhaseMacroExpand::expand_unlock_node(UnlockNode *unlock) {
915 974
916 Node *ctrl = unlock->in(TypeFunc::Control); 975 if (eliminate_locking_node(unlock)) {
976 return;
977 }
978
979 Node* ctrl = unlock->in(TypeFunc::Control);
917 Node* mem = unlock->in(TypeFunc::Memory); 980 Node* mem = unlock->in(TypeFunc::Memory);
918 Node* obj = unlock->obj_node(); 981 Node* obj = unlock->obj_node();
919 Node* box = unlock->box_node(); 982 Node* box = unlock->box_node();
920
921
922 if (unlock->is_eliminated()) {
923 eliminate_locking_node(unlock);
924 return;
925 }
926 983
927 // No need for a null check on unlock 984 // No need for a null check on unlock
928 985
929 // Make the merge point 986 // Make the merge point
930 RegionNode *region = new (C, 3) RegionNode(3); 987 RegionNode *region = new (C, 3) RegionNode(3);