248 void cleanup() {
249 // disconnect the hook node
250 _arguments->disconnect_inputs(NULL, _stringopts->C);
251 }
252 };
253
254
255 void StringConcat::eliminate_unneeded_control() {
256 for (uint i = 0; i < _control.size(); i++) {
257 Node* n = _control.at(i);
258 if (n->is_Allocate()) {
259 eliminate_initialize(n->as_Allocate()->initialization());
260 }
261 if (n->is_Call()) {
262 if (n != _end) {
263 eliminate_call(n->as_Call());
264 }
265 } else if (n->is_IfTrue()) {
266 Compile* C = _stringopts->C;
267 C->gvn_replace_by(n, n->in(0)->in(0));
268 C->gvn_replace_by(n->in(0), C->top());
269 }
270 }
271 }
272
273
274 StringConcat* StringConcat::merge(StringConcat* other, Node* arg) {
275 StringConcat* result = new StringConcat(_stringopts, _end);
276 for (uint x = 0; x < _control.size(); x++) {
277 Node* n = _control.at(x);
278 if (n->is_Call()) {
279 result->_control.push(n);
280 }
281 }
282 for (uint x = 0; x < other->_control.size(); x++) {
283 Node* n = other->_control.at(x);
284 if (n->is_Call()) {
285 result->_control.push(n);
286 }
287 }
288 assert(result->_control.contains(other->_end), "what?");
422 StringConcat* sc = new StringConcat(this, call);
423
424 AllocateNode* alloc = NULL;
425 InitializeNode* init = NULL;
426
427 // possible opportunity for StringBuilder fusion
428 CallStaticJavaNode* cnode = call;
429 while (cnode) {
430 Node* recv = cnode->in(TypeFunc::Parms)->uncast();
431 if (recv->is_Proj()) {
432 recv = recv->in(0);
433 }
434 cnode = recv->isa_CallStaticJava();
435 if (cnode == NULL) {
436 alloc = recv->isa_Allocate();
437 if (alloc == NULL) {
438 break;
439 }
440 // Find the constructor call
441 Node* result = alloc->result_cast();
442 if (result == NULL || !result->is_CheckCastPP()) {
443 // strange looking allocation
444 #ifndef PRODUCT
445 if (PrintOptimizeStringConcat) {
446 tty->print("giving up because allocation looks strange ");
447 alloc->jvms()->dump_spec(tty); tty->cr();
448 }
449 #endif
450 break;
451 }
452 Node* constructor = NULL;
453 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
454 CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
455 if (use != NULL &&
456 use->method() != NULL &&
457 !use->method()->is_static() &&
458 use->method()->name() == ciSymbol::object_initializer_name() &&
459 use->method()->holder() == m->holder()) {
460 // Matched the constructor.
461 ciSymbol* sig = use->method()->signature()->as_symbol();
462 if (sig == ciSymbol::void_method_signature() ||
817 tty->cr();
818 }
819 #endif
820 fail = true;
821 break;
822 } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) {
823 ptr = ptr->in(0)->in(0);
824 } else if (ptr->is_Region()) {
825 Node* copy = ptr->as_Region()->is_copy();
826 if (copy != NULL) {
827 ptr = copy;
828 continue;
829 }
830 if (ptr->req() == 3 &&
831 ptr->in(1) != NULL && ptr->in(1)->is_Proj() &&
832 ptr->in(2) != NULL && ptr->in(2)->is_Proj() &&
833 ptr->in(1)->in(0) == ptr->in(2)->in(0) &&
834 ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) {
835 // Simple diamond.
836 // XXX should check for possibly merging stores. simple data merges are ok.
837 ptr = ptr->in(1)->in(0)->in(0);
838 continue;
839 }
840 #ifndef PRODUCT
841 if (PrintOptimizeStringConcat) {
842 tty->print_cr("fusion would fail for region");
843 _begin->dump();
844 ptr->dump(2);
845 }
846 #endif
847 fail = true;
848 break;
849 } else {
850 // other unknown control
851 if (!fail) {
852 #ifndef PRODUCT
853 if (PrintOptimizeStringConcat) {
854 tty->print_cr("fusion would fail for");
855 _begin->dump();
856 }
|
248 void cleanup() {
249 // disconnect the hook node
250 _arguments->disconnect_inputs(NULL, _stringopts->C);
251 }
252 };
253
254
255 void StringConcat::eliminate_unneeded_control() {
256 for (uint i = 0; i < _control.size(); i++) {
257 Node* n = _control.at(i);
258 if (n->is_Allocate()) {
259 eliminate_initialize(n->as_Allocate()->initialization());
260 }
261 if (n->is_Call()) {
262 if (n != _end) {
263 eliminate_call(n->as_Call());
264 }
265 } else if (n->is_IfTrue()) {
266 Compile* C = _stringopts->C;
267 C->gvn_replace_by(n, n->in(0)->in(0));
268 // get rid of the other projection
269 C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top());
270 }
271 }
272 }
273
274
275 StringConcat* StringConcat::merge(StringConcat* other, Node* arg) {
276 StringConcat* result = new StringConcat(_stringopts, _end);
277 for (uint x = 0; x < _control.size(); x++) {
278 Node* n = _control.at(x);
279 if (n->is_Call()) {
280 result->_control.push(n);
281 }
282 }
283 for (uint x = 0; x < other->_control.size(); x++) {
284 Node* n = other->_control.at(x);
285 if (n->is_Call()) {
286 result->_control.push(n);
287 }
288 }
289 assert(result->_control.contains(other->_end), "what?");
423 StringConcat* sc = new StringConcat(this, call);
424
425 AllocateNode* alloc = NULL;
426 InitializeNode* init = NULL;
427
428 // possible opportunity for StringBuilder fusion
429 CallStaticJavaNode* cnode = call;
430 while (cnode) {
431 Node* recv = cnode->in(TypeFunc::Parms)->uncast();
432 if (recv->is_Proj()) {
433 recv = recv->in(0);
434 }
435 cnode = recv->isa_CallStaticJava();
436 if (cnode == NULL) {
437 alloc = recv->isa_Allocate();
438 if (alloc == NULL) {
439 break;
440 }
441 // Find the constructor call
442 Node* result = alloc->result_cast();
443 if (result == NULL || !result->is_CheckCastPP() || alloc->in(TypeFunc::Memory)->is_top()) {
444 // strange looking allocation
445 #ifndef PRODUCT
446 if (PrintOptimizeStringConcat) {
447 tty->print("giving up because allocation looks strange ");
448 alloc->jvms()->dump_spec(tty); tty->cr();
449 }
450 #endif
451 break;
452 }
453 Node* constructor = NULL;
454 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
455 CallStaticJavaNode *use = i.get()->isa_CallStaticJava();
456 if (use != NULL &&
457 use->method() != NULL &&
458 !use->method()->is_static() &&
459 use->method()->name() == ciSymbol::object_initializer_name() &&
460 use->method()->holder() == m->holder()) {
461 // Matched the constructor.
462 ciSymbol* sig = use->method()->signature()->as_symbol();
463 if (sig == ciSymbol::void_method_signature() ||
818 tty->cr();
819 }
820 #endif
821 fail = true;
822 break;
823 } else if (ptr->is_Proj() && ptr->in(0)->is_Initialize()) {
824 ptr = ptr->in(0)->in(0);
825 } else if (ptr->is_Region()) {
826 Node* copy = ptr->as_Region()->is_copy();
827 if (copy != NULL) {
828 ptr = copy;
829 continue;
830 }
831 if (ptr->req() == 3 &&
832 ptr->in(1) != NULL && ptr->in(1)->is_Proj() &&
833 ptr->in(2) != NULL && ptr->in(2)->is_Proj() &&
834 ptr->in(1)->in(0) == ptr->in(2)->in(0) &&
835 ptr->in(1)->in(0) != NULL && ptr->in(1)->in(0)->is_If()) {
836 // Simple diamond.
837 // XXX should check for possibly merging stores. simple data merges are ok.
838 // The IGVN will make this simple diamond go away when it
839 // transforms the Region. Make sure it sees it.
840 Compile::current()->record_for_igvn(ptr);
841 ptr = ptr->in(1)->in(0)->in(0);
842 continue;
843 }
844 #ifndef PRODUCT
845 if (PrintOptimizeStringConcat) {
846 tty->print_cr("fusion would fail for region");
847 _begin->dump();
848 ptr->dump(2);
849 }
850 #endif
851 fail = true;
852 break;
853 } else {
854 // other unknown control
855 if (!fail) {
856 #ifndef PRODUCT
857 if (PrintOptimizeStringConcat) {
858 tty->print_cr("fusion would fail for");
859 _begin->dump();
860 }
|