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) {