Mercurial > hg > truffle
comparison src/share/vm/opto/macro.cpp @ 4115:1bd45abaa507
6890673: Eliminate allocations immediately after EA
Summary: Try to eliminate allocations and related locks immediately after escape analysis.
Reviewed-by: never
author | kvn |
---|---|
date | Wed, 16 Nov 2011 09:13:57 -0800 |
parents | a92cdbac8b9e |
children | 069ab3f976d3 |
comparison
equal
deleted
inserted
replaced
4114:6729bbc1fcd6 | 4115:1bd45abaa507 |
---|---|
79 if (old_in != NULL && old_in->is_SafePointScalarObject()) { | 79 if (old_in != NULL && old_in->is_SafePointScalarObject()) { |
80 SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); | 80 SafePointScalarObjectNode* old_sosn = old_in->as_SafePointScalarObject(); |
81 uint old_unique = C->unique(); | 81 uint old_unique = C->unique(); |
82 Node* new_in = old_sosn->clone(jvms_adj, sosn_map); | 82 Node* new_in = old_sosn->clone(jvms_adj, sosn_map); |
83 if (old_unique != C->unique()) { | 83 if (old_unique != C->unique()) { |
84 new_in->set_req(0, newcall->in(0)); // reset control edge | 84 new_in->set_req(0, C->root()); // reset control edge |
85 new_in = transform_later(new_in); // Register new node. | 85 new_in = transform_later(new_in); // Register new node. |
86 } | 86 } |
87 old_in = new_in; | 87 old_in = new_in; |
88 } | 88 } |
89 newcall->add_req(old_in); | 89 newcall->add_req(old_in); |
563 Node* res = alloc->result_cast(); | 563 Node* res = alloc->result_cast(); |
564 const TypeOopPtr* res_type = NULL; | 564 const TypeOopPtr* res_type = NULL; |
565 if (res == NULL) { | 565 if (res == NULL) { |
566 // All users were eliminated. | 566 // All users were eliminated. |
567 } else if (!res->is_CheckCastPP()) { | 567 } else if (!res->is_CheckCastPP()) { |
568 alloc->_is_scalar_replaceable = false; // don't try again | |
569 NOT_PRODUCT(fail_eliminate = "Allocation does not have unique CheckCastPP";) | 568 NOT_PRODUCT(fail_eliminate = "Allocation does not have unique CheckCastPP";) |
570 can_eliminate = false; | 569 can_eliminate = false; |
571 } else { | 570 } else { |
572 res_type = _igvn.type(res)->isa_oopptr(); | 571 res_type = _igvn.type(res)->isa_oopptr(); |
573 if (res_type == NULL) { | 572 if (res_type == NULL) { |
717 SafePointScalarObjectNode* sobj = new (C, 1) SafePointScalarObjectNode(res_type, | 716 SafePointScalarObjectNode* sobj = new (C, 1) SafePointScalarObjectNode(res_type, |
718 #ifdef ASSERT | 717 #ifdef ASSERT |
719 alloc, | 718 alloc, |
720 #endif | 719 #endif |
721 first_ind, nfields); | 720 first_ind, nfields); |
722 sobj->init_req(0, sfpt->in(TypeFunc::Control)); | 721 sobj->init_req(0, C->root()); |
723 transform_later(sobj); | 722 transform_later(sobj); |
724 | 723 |
725 // Scan object's fields adding an input to the safepoint for each field. | 724 // Scan object's fields adding an input to the safepoint for each field. |
726 for (int j = 0; j < nfields; j++) { | 725 for (int j = 0; j < nfields; j++) { |
727 intptr_t offset; | 726 intptr_t offset; |
760 | 759 |
761 const TypeOopPtr *field_addr_type = res_type->add_offset(offset)->isa_oopptr(); | 760 const TypeOopPtr *field_addr_type = res_type->add_offset(offset)->isa_oopptr(); |
762 | 761 |
763 Node *field_val = value_from_mem(mem, basic_elem_type, field_type, field_addr_type, alloc); | 762 Node *field_val = value_from_mem(mem, basic_elem_type, field_type, field_addr_type, alloc); |
764 if (field_val == NULL) { | 763 if (field_val == NULL) { |
765 // we weren't able to find a value for this field, | 764 // We weren't able to find a value for this field, |
766 // give up on eliminating this allocation | 765 // give up on eliminating this allocation. |
767 alloc->_is_scalar_replaceable = false; // don't try again | 766 |
768 // remove any extra entries we added to the safepoint | 767 // Remove any extra entries we added to the safepoint. |
769 uint last = sfpt->req() - 1; | 768 uint last = sfpt->req() - 1; |
770 for (int k = 0; k < j; k++) { | 769 for (int k = 0; k < j; k++) { |
771 sfpt->del_req(last--); | 770 sfpt->del_req(last--); |
772 } | 771 } |
773 // rollback processed safepoints | 772 // rollback processed safepoints |
1802 } | 1801 } |
1803 | 1802 |
1804 #ifndef PRODUCT | 1803 #ifndef PRODUCT |
1805 if (PrintEliminateLocks) { | 1804 if (PrintEliminateLocks) { |
1806 if (alock->is_Lock()) { | 1805 if (alock->is_Lock()) { |
1807 tty->print_cr("++++ Eliminating: %d Lock", alock->_idx); | 1806 tty->print_cr("++++ Eliminated: %d Lock", alock->_idx); |
1808 } else { | 1807 } else { |
1809 tty->print_cr("++++ Eliminating: %d Unlock", alock->_idx); | 1808 tty->print_cr("++++ Eliminated: %d Unlock", alock->_idx); |
1810 } | 1809 } |
1811 } | 1810 } |
1812 #endif | 1811 #endif |
1813 | 1812 |
1814 Node* mem = alock->in(TypeFunc::Memory); | 1813 Node* mem = alock->in(TypeFunc::Memory); |
2163 mem_phi->init_req(2, mem); | 2162 mem_phi->init_req(2, mem); |
2164 transform_later(mem_phi); | 2163 transform_later(mem_phi); |
2165 _igvn.replace_node(_memproj_fallthrough, mem_phi); | 2164 _igvn.replace_node(_memproj_fallthrough, mem_phi); |
2166 } | 2165 } |
2167 | 2166 |
2168 //------------------------------expand_macro_nodes---------------------- | 2167 //---------------------------eliminate_macro_nodes---------------------- |
2169 // Returns true if a failure occurred. | 2168 // Eliminate scalar replaced allocations and associated locks. |
2170 bool PhaseMacroExpand::expand_macro_nodes() { | 2169 void PhaseMacroExpand::eliminate_macro_nodes() { |
2171 if (C->macro_count() == 0) | 2170 if (C->macro_count() == 0) |
2172 return false; | 2171 return; |
2172 | |
2173 // First, attempt to eliminate locks | 2173 // First, attempt to eliminate locks |
2174 int cnt = C->macro_count(); | 2174 int cnt = C->macro_count(); |
2175 for (int i=0; i < cnt; i++) { | 2175 for (int i=0; i < cnt; i++) { |
2176 Node *n = C->macro_node(i); | 2176 Node *n = C->macro_node(i); |
2177 if (n->is_AbstractLock()) { // Lock and Unlock nodes | 2177 if (n->is_AbstractLock()) { // Lock and Unlock nodes |
2187 Node * n = C->macro_node(i-1); | 2187 Node * n = C->macro_node(i-1); |
2188 bool success = false; | 2188 bool success = false; |
2189 debug_only(int old_macro_count = C->macro_count();); | 2189 debug_only(int old_macro_count = C->macro_count();); |
2190 if (n->is_AbstractLock()) { | 2190 if (n->is_AbstractLock()) { |
2191 success = eliminate_locking_node(n->as_AbstractLock()); | 2191 success = eliminate_locking_node(n->as_AbstractLock()); |
2192 } else if (n->Opcode() == Op_LoopLimit) { | |
2193 // Remove it from macro list and put on IGVN worklist to optimize. | |
2194 C->remove_macro_node(n); | |
2195 _igvn._worklist.push(n); | |
2196 success = true; | |
2197 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | |
2198 _igvn.replace_node(n, n->in(1)); | |
2199 success = true; | |
2200 } | 2192 } |
2201 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | 2193 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); |
2202 progress = progress || success; | 2194 progress = progress || success; |
2203 } | 2195 } |
2204 } | 2196 } |
2218 case Node::Class_Lock: | 2210 case Node::Class_Lock: |
2219 case Node::Class_Unlock: | 2211 case Node::Class_Unlock: |
2220 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); | 2212 assert(!n->as_AbstractLock()->is_eliminated(), "sanity"); |
2221 break; | 2213 break; |
2222 default: | 2214 default: |
2223 assert(false, "unknown node type in macro list"); | 2215 assert(n->Opcode() == Op_LoopLimit || |
2216 n->Opcode() == Op_Opaque1 || | |
2217 n->Opcode() == Op_Opaque2, "unknown node type in macro list"); | |
2224 } | 2218 } |
2225 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | 2219 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); |
2226 progress = progress || success; | 2220 progress = progress || success; |
2227 } | 2221 } |
2228 } | 2222 } |
2223 } | |
2224 | |
2225 //------------------------------expand_macro_nodes---------------------- | |
2226 // Returns true if a failure occurred. | |
2227 bool PhaseMacroExpand::expand_macro_nodes() { | |
2228 // Last attempt to eliminate macro nodes. | |
2229 eliminate_macro_nodes(); | |
2230 | |
2229 // Make sure expansion will not cause node limit to be exceeded. | 2231 // Make sure expansion will not cause node limit to be exceeded. |
2230 // Worst case is a macro node gets expanded into about 50 nodes. | 2232 // Worst case is a macro node gets expanded into about 50 nodes. |
2231 // Allow 50% more for optimization. | 2233 // Allow 50% more for optimization. |
2232 if (C->check_node_count(C->macro_count() * 75, "out of nodes before macro expansion" ) ) | 2234 if (C->check_node_count(C->macro_count() * 75, "out of nodes before macro expansion" ) ) |
2233 return true; | 2235 return true; |
2236 | |
2237 // Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations. | |
2238 bool progress = true; | |
2239 while (progress) { | |
2240 progress = false; | |
2241 for (int i = C->macro_count(); i > 0; i--) { | |
2242 Node * n = C->macro_node(i-1); | |
2243 bool success = false; | |
2244 debug_only(int old_macro_count = C->macro_count();); | |
2245 if (n->Opcode() == Op_LoopLimit) { | |
2246 // Remove it from macro list and put on IGVN worklist to optimize. | |
2247 C->remove_macro_node(n); | |
2248 _igvn._worklist.push(n); | |
2249 success = true; | |
2250 } else if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) { | |
2251 _igvn.replace_node(n, n->in(1)); | |
2252 success = true; | |
2253 } | |
2254 assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); | |
2255 progress = progress || success; | |
2256 } | |
2257 } | |
2234 | 2258 |
2235 // expand "macro" nodes | 2259 // expand "macro" nodes |
2236 // nodes are removed from the macro list as they are processed | 2260 // nodes are removed from the macro list as they are processed |
2237 while (C->macro_count() > 0) { | 2261 while (C->macro_count() > 0) { |
2238 int macro_count = C->macro_count(); | 2262 int macro_count = C->macro_count(); |
2263 if (C->failing()) return true; | 2287 if (C->failing()) return true; |
2264 } | 2288 } |
2265 | 2289 |
2266 _igvn.set_delay_transform(false); | 2290 _igvn.set_delay_transform(false); |
2267 _igvn.optimize(); | 2291 _igvn.optimize(); |
2292 if (C->failing()) return true; | |
2268 return false; | 2293 return false; |
2269 } | 2294 } |