Mercurial > hg > truffle
comparison src/share/vm/opto/macro.cpp @ 10278:6f3fd5150b67
6934604: enable parts of EliminateAutoBox by default
Summary: Resurrected autobox elimination code and enabled part of it by default.
Reviewed-by: roland, twisti
author | kvn |
---|---|
date | Wed, 08 May 2013 15:08:01 -0700 |
parents | 8651f608fea4 |
children | 70120f47d403 |
comparison
equal
deleted
inserted
replaced
10277:aabf54ccedb1 | 10278:6f3fd5150b67 |
---|---|
664 tty->print("Scalar "); | 664 tty->print("Scalar "); |
665 if (res == NULL) | 665 if (res == NULL) |
666 alloc->dump(); | 666 alloc->dump(); |
667 else | 667 else |
668 res->dump(); | 668 res->dump(); |
669 } else { | 669 } else if (alloc->_is_scalar_replaceable) { |
670 tty->print("NotScalar (%s)", fail_eliminate); | 670 tty->print("NotScalar (%s)", fail_eliminate); |
671 if (res == NULL) | 671 if (res == NULL) |
672 alloc->dump(); | 672 alloc->dump(); |
673 else | 673 else |
674 res->dump(); | 674 res->dump(); |
843 jvms->set_endoff(sfpt->req()); | 843 jvms->set_endoff(sfpt->req()); |
844 // Now make a pass over the debug information replacing any references | 844 // Now make a pass over the debug information replacing any references |
845 // to the allocated object with "sobj" | 845 // to the allocated object with "sobj" |
846 int start = jvms->debug_start(); | 846 int start = jvms->debug_start(); |
847 int end = jvms->debug_end(); | 847 int end = jvms->debug_end(); |
848 for (int i = start; i < end; i++) { | 848 sfpt->replace_edges_in_range(res, sobj, start, end); |
849 if (sfpt->in(i) == res) { | |
850 sfpt->set_req(i, sobj); | |
851 } | |
852 } | |
853 safepoints_done.append_if_missing(sfpt); // keep it for rollback | 849 safepoints_done.append_if_missing(sfpt); // keep it for rollback |
854 } | 850 } |
855 return true; | 851 return true; |
856 } | 852 } |
857 | 853 |
858 // Process users of eliminated allocation. | 854 // Process users of eliminated allocation. |
859 void PhaseMacroExpand::process_users_of_allocation(AllocateNode *alloc) { | 855 void PhaseMacroExpand::process_users_of_allocation(CallNode *alloc) { |
860 Node* res = alloc->result_cast(); | 856 Node* res = alloc->result_cast(); |
861 if (res != NULL) { | 857 if (res != NULL) { |
862 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) { | 858 for (DUIterator_Last jmin, j = res->last_outs(jmin); j >= jmin; ) { |
863 Node *use = res->last_out(j); | 859 Node *use = res->last_out(j); |
864 uint oc1 = res->outcnt(); | 860 uint oc1 = res->outcnt(); |
897 | 893 |
898 // | 894 // |
899 // Process other users of allocation's projections | 895 // Process other users of allocation's projections |
900 // | 896 // |
901 if (_resproj != NULL && _resproj->outcnt() != 0) { | 897 if (_resproj != NULL && _resproj->outcnt() != 0) { |
898 // First disconnect stores captured by Initialize node. | |
899 // If Initialize node is eliminated first in the following code, | |
900 // it will kill such stores and DUIterator_Last will assert. | |
901 for (DUIterator_Fast jmax, j = _resproj->fast_outs(jmax); j < jmax; j++) { | |
902 Node *use = _resproj->fast_out(j); | |
903 if (use->is_AddP()) { | |
904 // raw memory addresses used only by the initialization | |
905 _igvn.replace_node(use, C->top()); | |
906 --j; --jmax; | |
907 } | |
908 } | |
902 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) { | 909 for (DUIterator_Last jmin, j = _resproj->last_outs(jmin); j >= jmin; ) { |
903 Node *use = _resproj->last_out(j); | 910 Node *use = _resproj->last_out(j); |
904 uint oc1 = _resproj->outcnt(); | 911 uint oc1 = _resproj->outcnt(); |
905 if (use->is_Initialize()) { | 912 if (use->is_Initialize()) { |
906 // Eliminate Initialize node. | 913 // Eliminate Initialize node. |
921 assert(mem == _memproj_fallthrough, "allocation memory projection"); | 928 assert(mem == _memproj_fallthrough, "allocation memory projection"); |
922 } | 929 } |
923 #endif | 930 #endif |
924 _igvn.replace_node(mem_proj, mem); | 931 _igvn.replace_node(mem_proj, mem); |
925 } | 932 } |
926 } else if (use->is_AddP()) { | |
927 // raw memory addresses used only by the initialization | |
928 _igvn.replace_node(use, C->top()); | |
929 } else { | 933 } else { |
930 assert(false, "only Initialize or AddP expected"); | 934 assert(false, "only Initialize or AddP expected"); |
931 } | 935 } |
932 j -= (oc1 - _resproj->outcnt()); | 936 j -= (oc1 - _resproj->outcnt()); |
933 } | 937 } |
951 _igvn.replace_node(_catchallcatchproj, C->top()); | 955 _igvn.replace_node(_catchallcatchproj, C->top()); |
952 } | 956 } |
953 } | 957 } |
954 | 958 |
955 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { | 959 bool PhaseMacroExpand::eliminate_allocate_node(AllocateNode *alloc) { |
956 | 960 if (!EliminateAllocations || !alloc->_is_non_escaping) { |
957 if (!EliminateAllocations || !alloc->_is_scalar_replaceable) { | 961 return false; |
962 } | |
963 Node* klass = alloc->in(AllocateNode::KlassNode); | |
964 const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr(); | |
965 Node* res = alloc->result_cast(); | |
966 // Eliminate boxing allocations which are not used | |
967 // regardless scalar replacable status. | |
968 bool boxing_alloc = C->eliminate_boxing() && | |
969 tklass->klass()->is_instance_klass() && | |
970 tklass->klass()->as_instance_klass()->is_box_klass(); | |
971 if (!alloc->_is_scalar_replaceable && (!boxing_alloc || (res != NULL))) { | |
958 return false; | 972 return false; |
959 } | 973 } |
960 | 974 |
961 extract_call_projections(alloc); | 975 extract_call_projections(alloc); |
962 | 976 |
963 GrowableArray <SafePointNode *> safepoints; | 977 GrowableArray <SafePointNode *> safepoints; |
964 if (!can_eliminate_allocation(alloc, safepoints)) { | 978 if (!can_eliminate_allocation(alloc, safepoints)) { |
965 return false; | 979 return false; |
966 } | 980 } |
967 | 981 |
982 if (!alloc->_is_scalar_replaceable) { | |
983 assert(res == NULL, "sanity"); | |
984 // We can only eliminate allocation if all debug info references | |
985 // are already replaced with SafePointScalarObject because | |
986 // we can't search for a fields value without instance_id. | |
987 if (safepoints.length() > 0) { | |
988 return false; | |
989 } | |
990 } | |
991 | |
968 if (!scalar_replacement(alloc, safepoints)) { | 992 if (!scalar_replacement(alloc, safepoints)) { |
969 return false; | 993 return false; |
970 } | 994 } |
971 | 995 |
972 CompileLog* log = C->log(); | 996 CompileLog* log = C->log(); |
973 if (log != NULL) { | 997 if (log != NULL) { |
974 Node* klass = alloc->in(AllocateNode::KlassNode); | |
975 const TypeKlassPtr* tklass = _igvn.type(klass)->is_klassptr(); | |
976 log->head("eliminate_allocation type='%d'", | 998 log->head("eliminate_allocation type='%d'", |
977 log->identify(tklass->klass())); | 999 log->identify(tklass->klass())); |
978 JVMState* p = alloc->jvms(); | 1000 JVMState* p = alloc->jvms(); |
979 while (p != NULL) { | 1001 while (p != NULL) { |
980 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); | 1002 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); |
995 #endif | 1017 #endif |
996 | 1018 |
997 return true; | 1019 return true; |
998 } | 1020 } |
999 | 1021 |
1022 bool PhaseMacroExpand::eliminate_boxing_node(CallStaticJavaNode *boxing) { | |
1023 // EA should remove all uses of non-escaping boxing node. | |
1024 if (!C->eliminate_boxing() || boxing->proj_out(TypeFunc::Parms) != NULL) { | |
1025 return false; | |
1026 } | |
1027 | |
1028 extract_call_projections(boxing); | |
1029 | |
1030 const TypeTuple* r = boxing->tf()->range(); | |
1031 assert(r->cnt() > TypeFunc::Parms, "sanity"); | |
1032 const TypeInstPtr* t = r->field_at(TypeFunc::Parms)->isa_instptr(); | |
1033 assert(t != NULL, "sanity"); | |
1034 | |
1035 CompileLog* log = C->log(); | |
1036 if (log != NULL) { | |
1037 log->head("eliminate_boxing type='%d'", | |
1038 log->identify(t->klass())); | |
1039 JVMState* p = boxing->jvms(); | |
1040 while (p != NULL) { | |
1041 log->elem("jvms bci='%d' method='%d'", p->bci(), log->identify(p->method())); | |
1042 p = p->caller(); | |
1043 } | |
1044 log->tail("eliminate_boxing"); | |
1045 } | |
1046 | |
1047 process_users_of_allocation(boxing); | |
1048 | |
1049 #ifndef PRODUCT | |
1050 if (PrintEliminateAllocations) { | |
1051 tty->print("++++ Eliminated: %d ", boxing->_idx); | |
1052 boxing->method()->print_short_name(tty); | |
1053 tty->cr(); | |
1054 } | |
1055 #endif | |
1056 | |
1057 return true; | |
1058 } | |
1000 | 1059 |
1001 //---------------------------set_eden_pointers------------------------- | 1060 //---------------------------set_eden_pointers------------------------- |
1002 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { | 1061 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) { |
1003 if (UseTLAB) { // Private allocation: load from TLS | 1062 if (UseTLAB) { // Private allocation: load from TLS |
1004 Node* thread = transform_later(new (C) ThreadLocalNode()); | 1063 Node* thread = transform_later(new (C) ThreadLocalNode()); |
2382 switch (n->class_id()) { | 2441 switch (n->class_id()) { |
2383 case Node::Class_Allocate: | 2442 case Node::Class_Allocate: |
2384 case Node::Class_AllocateArray: | 2443 case Node::Class_AllocateArray: |
2385 success = eliminate_allocate_node(n->as_Allocate()); | 2444 success = eliminate_allocate_node(n->as_Allocate()); |
2386 break; | 2445 break; |
2446 case Node::Class_CallStaticJava: | |
2447 success = eliminate_boxing_node(n->as_CallStaticJava()); | |
2448 break; | |
2387 case Node::Class_Lock: | 2449 case Node::Class_Lock: |
2388 case Node::Class_Unlock: | 2450 case Node::Class_Unlock: |
2389 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); | 2451 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
2390 break; | 2452 break; |
2391 default: | 2453 default: |
2418 for (int i = C->macro_count(); i > 0; i--) { | 2480 for (int i = C->macro_count(); i > 0; i--) { |
2419 Node * n = C->macro_node(i-1); | 2481 Node * n = C->macro_node(i-1); |
2420 bool success = false; | 2482 bool success = false; |
2421 debug_only(int old_macro_count = C->macro_count();); | 2483 debug_only(int old_macro_count = C->macro_count();); |
2422 if (n->Opcode() == Op_LoopLimit) { | 2484 if (n->Opcode() == Op_LoopLimit) { |
2485 // Remove it from macro list and put on IGVN worklist to optimize. | |
2486 C->remove_macro_node(n); | |
2487 _igvn._worklist.push(n); | |
2488 success = true; | |
2489 } else if (n->Opcode() == Op_CallStaticJava) { | |
2423 // Remove it from macro list and put on IGVN worklist to optimize. | 2490 // Remove it from macro list and put on IGVN worklist to optimize. |
2424 C->remove_macro_node(n); | 2491 C->remove_macro_node(n); |
2425 _igvn._worklist.push(n); | 2492 _igvn._worklist.push(n); |
2426 success = true; | 2493 success = true; |
2427 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | 2494 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { |