comparison src/share/vm/opto/compile.cpp @ 1080:7c57aead6d3e

6892658: C2 should optimize some stringbuilder patterns Reviewed-by: kvn, twisti
author never
date Thu, 12 Nov 2009 09:24:21 -0800
parents cd18bd5e667c
children f96a1a986f7b
comparison
equal deleted inserted replaced
1078:8e7adf982378 1080:7c57aead6d3e
220 } 220 }
221 221
222 bool Compile::valid_bundle_info(const Node *n) { 222 bool Compile::valid_bundle_info(const Node *n) {
223 return (_node_bundling_limit > n->_idx); 223 return (_node_bundling_limit > n->_idx);
224 } 224 }
225
226
227 void Compile::gvn_replace_by(Node* n, Node* nn) {
228 for (DUIterator_Last imin, i = n->last_outs(imin); i >= imin; ) {
229 Node* use = n->last_out(i);
230 bool is_in_table = initial_gvn()->hash_delete(use);
231 uint uses_found = 0;
232 for (uint j = 0; j < use->len(); j++) {
233 if (use->in(j) == n) {
234 if (j < use->req())
235 use->set_req(j, nn);
236 else
237 use->set_prec(j, nn);
238 uses_found++;
239 }
240 }
241 if (is_in_table) {
242 // reinsert into table
243 initial_gvn()->hash_find_insert(use);
244 }
245 record_for_igvn(use);
246 i -= uses_found; // we deleted 1 or more copies of this edge
247 }
248 }
249
250
225 251
226 252
227 // Identify all nodes that are reachable from below, useful. 253 // Identify all nodes that are reachable from below, useful.
228 // Use breadth-first pass that records state in a Unique_Node_List, 254 // Use breadth-first pass that records state in a Unique_Node_List,
229 // recursive traversal is slower. 255 // recursive traversal is slower.
551 // Any exceptions that escape from this call must be rethrown 577 // Any exceptions that escape from this call must be rethrown
552 // to whatever caller is dynamically above us on the stack. 578 // to whatever caller is dynamically above us on the stack.
553 // This is done by a special, unique RethrowNode bound to root. 579 // This is done by a special, unique RethrowNode bound to root.
554 rethrow_exceptions(kit.transfer_exceptions_into_jvms()); 580 rethrow_exceptions(kit.transfer_exceptions_into_jvms());
555 } 581 }
582
583 if (!failing() && has_stringbuilder()) {
584 {
585 // remove useless nodes to make the usage analysis simpler
586 ResourceMark rm;
587 PhaseRemoveUseless pru(initial_gvn(), &for_igvn);
588 }
589
590 {
591 ResourceMark rm;
592 print_method("Before StringOpts", 3);
593 PhaseStringOpts pso(initial_gvn(), &for_igvn);
594 print_method("After StringOpts", 3);
595 }
596
597 // now inline anything that we skipped the first time around
598 while (_late_inlines.length() > 0) {
599 CallGenerator* cg = _late_inlines.pop();
600 cg->do_late_inline();
601 }
602 }
603 assert(_late_inlines.length() == 0, "should have been processed");
556 604
557 print_method("Before RemoveUseless", 3); 605 print_method("Before RemoveUseless", 3);
558 606
559 // Remove clutter produced by parsing. 607 // Remove clutter produced by parsing.
560 if (!failing()) { 608 if (!failing()) {
818 env()->set_dependencies(new Dependencies(env())); 866 env()->set_dependencies(new Dependencies(env()));
819 867
820 _fixed_slots = 0; 868 _fixed_slots = 0;
821 set_has_split_ifs(false); 869 set_has_split_ifs(false);
822 set_has_loops(has_method() && method()->has_loops()); // first approximation 870 set_has_loops(has_method() && method()->has_loops()); // first approximation
871 set_has_stringbuilder(false);
823 _deopt_happens = true; // start out assuming the worst 872 _deopt_happens = true; // start out assuming the worst
824 _trap_can_recompile = false; // no traps emitted yet 873 _trap_can_recompile = false; // no traps emitted yet
825 _major_progress = true; // start out assuming good things will happen 874 _major_progress = true; // start out assuming good things will happen
826 set_has_unsafe_access(false); 875 set_has_unsafe_access(false);
827 Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist)); 876 Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
2238 in1->disconnect_inputs(NULL); 2287 in1->disconnect_inputs(NULL);
2239 } 2288 }
2240 break; 2289 break;
2241 } 2290 }
2242 2291
2292 case Op_Proj: {
2293 if (OptimizeStringConcat) {
2294 ProjNode* p = n->as_Proj();
2295 if (p->_is_io_use) {
2296 // Separate projections were used for the exception path which
2297 // are normally removed by a late inline. If it wasn't inlined
2298 // then they will hang around and should just be replaced with
2299 // the original one.
2300 Node* proj = NULL;
2301 // Replace with just one
2302 for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) {
2303 Node *use = i.get();
2304 if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) {
2305 proj = use;
2306 break;
2307 }
2308 }
2309 assert(p != NULL, "must be found");
2310 p->subsume_by(proj);
2311 }
2312 }
2313 break;
2314 }
2315
2243 case Op_Phi: 2316 case Op_Phi:
2244 if (n->as_Phi()->bottom_type()->isa_narrowoop()) { 2317 if (n->as_Phi()->bottom_type()->isa_narrowoop()) {
2245 // The EncodeP optimization may create Phi with the same edges 2318 // The EncodeP optimization may create Phi with the same edges
2246 // for all paths. It is not handled well by Register Allocator. 2319 // for all paths. It is not handled well by Register Allocator.
2247 Node* unique_in = n->in(1); 2320 Node* unique_in = n->in(1);