Mercurial > hg > graal-compiler
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); |