345 Node *use = i.get();
346 int opc = use->Opcode();
347 if (opc == Op_CreateEx || opc == Op_Region) {
348 _stringopts->record_dead_node(use);
349 }
350 }
351 C->gvn_replace_by(projs.catchall_catchproj, C->top());
352 }
353 if (projs.resproj != NULL) {
354 C->gvn_replace_by(projs.resproj, C->top());
355 }
356 C->gvn_replace_by(call, C->top());
357 }
358
359 void StringConcat::eliminate_initialize(InitializeNode* init) {
360 Compile* C = _stringopts->C;
361
362 // Eliminate Initialize node.
363 assert(init->outcnt() <= 2, "only a control and memory projection expected");
364 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
365 Node *ctrl_proj = init->proj_out(TypeFunc::Control);
366 if (ctrl_proj != NULL) {
367 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
368 }
369 Node *mem_proj = init->proj_out(TypeFunc::Memory);
370 if (mem_proj != NULL) {
371 Node *mem = init->in(TypeFunc::Memory);
372 C->gvn_replace_by(mem_proj, mem);
373 }
374 C->gvn_replace_by(init, C->top());
375 init->disconnect_inputs(NULL, C);
376 }
377
378 Node_List PhaseStringOpts::collect_toString_calls() {
379 Node_List string_calls;
380 Node_List worklist;
381
382 _visited.Clear();
383
384 // Prime the worklist
385 for (uint i = 1; i < C->root()->len(); i++) {
386 Node* n = C->root()->in(i);
387 if (n != NULL && !_visited.test_set(n->_idx)) {
388 worklist.push(n);
389 }
874 Unique_Node_List ctrl_path;
875
876 assert(_control.contains(_begin), "missing");
877 assert(_control.contains(_end), "missing");
878
879 // Collect the nodes that we know about and will eliminate into ctrl_path
880 for (uint i = 0; i < _control.size(); i++) {
881 // Push the call and it's control projection
882 Node* n = _control.at(i);
883 if (n->is_Allocate()) {
884 AllocateNode* an = n->as_Allocate();
885 InitializeNode* init = an->initialization();
886 ctrl_path.push(init);
887 ctrl_path.push(init->as_Multi()->proj_out(0));
888 }
889 if (n->is_Call()) {
890 CallNode* cn = n->as_Call();
891 ctrl_path.push(cn);
892 ctrl_path.push(cn->proj_out(0));
893 ctrl_path.push(cn->proj_out(0)->unique_out());
894 Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0);
895 if (catchproj != NULL) {
896 ctrl_path.push(catchproj);
897 }
898 } else {
899 ShouldNotReachHere();
900 }
901 }
902
903 // Skip backwards through the control checking for unexpected control flow
904 Node* ptr = _end;
905 bool fail = false;
906 while (ptr != _begin) {
907 if (ptr->is_Call() && ctrl_path.member(ptr)) {
908 ptr = ptr->in(0);
909 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
910 ptr = ptr->in(0)->in(0)->in(0);
911 assert(ctrl_path.member(ptr), "should be a known piece of control");
912 } else if (ptr->is_IfTrue()) {
913 IfNode* iff = ptr->in(0)->as_If();
914 BoolNode* b = iff->in(1)->isa_Bool();
1018 #ifndef PRODUCT
1019 if (PrintOptimizeStringConcat) {
1020 ptr->dump();
1021 }
1022 #endif
1023 ptr = ptr->in(0);
1024 }
1025 }
1026 #ifndef PRODUCT
1027 if (PrintOptimizeStringConcat && fail) {
1028 tty->cr();
1029 }
1030 #endif
1031 if (fail) return !fail;
1032
1033 // Validate that all these results produced are contained within
1034 // this cluster of objects. First collect all the results produced
1035 // by calls in the region.
1036 _stringopts->_visited.Clear();
1037 Node_List worklist;
1038 Node* final_result = _end->proj_out(TypeFunc::Parms);
1039 for (uint i = 0; i < _control.size(); i++) {
1040 CallNode* cnode = _control.at(i)->isa_Call();
1041 if (cnode != NULL) {
1042 _stringopts->_visited.test_set(cnode->_idx);
1043 }
1044 Node* result = cnode != NULL ? cnode->proj_out(TypeFunc::Parms) : NULL;
1045 if (result != NULL && result != final_result) {
1046 worklist.push(result);
1047 }
1048 }
1049
1050 Node* last_result = NULL;
1051 while (worklist.size() > 0) {
1052 Node* result = worklist.pop();
1053 if (_stringopts->_visited.test_set(result->_idx))
1054 continue;
1055 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
1056 Node *use = i.get();
1057 if (ctrl_path.member(use)) {
1058 // already checked this
1059 continue;
1060 }
1061 int opc = use->Opcode();
1062 if (opc == Op_CmpP || opc == Op_Node) {
1063 ctrl_path.push(use);
1064 continue;
|
345 Node *use = i.get();
346 int opc = use->Opcode();
347 if (opc == Op_CreateEx || opc == Op_Region) {
348 _stringopts->record_dead_node(use);
349 }
350 }
351 C->gvn_replace_by(projs.catchall_catchproj, C->top());
352 }
353 if (projs.resproj != NULL) {
354 C->gvn_replace_by(projs.resproj, C->top());
355 }
356 C->gvn_replace_by(call, C->top());
357 }
358
359 void StringConcat::eliminate_initialize(InitializeNode* init) {
360 Compile* C = _stringopts->C;
361
362 // Eliminate Initialize node.
363 assert(init->outcnt() <= 2, "only a control and memory projection expected");
364 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
365 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
366 if (ctrl_proj != NULL) {
367 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
368 }
369 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
370 if (mem_proj != NULL) {
371 Node *mem = init->in(TypeFunc::Memory);
372 C->gvn_replace_by(mem_proj, mem);
373 }
374 C->gvn_replace_by(init, C->top());
375 init->disconnect_inputs(NULL, C);
376 }
377
378 Node_List PhaseStringOpts::collect_toString_calls() {
379 Node_List string_calls;
380 Node_List worklist;
381
382 _visited.Clear();
383
384 // Prime the worklist
385 for (uint i = 1; i < C->root()->len(); i++) {
386 Node* n = C->root()->in(i);
387 if (n != NULL && !_visited.test_set(n->_idx)) {
388 worklist.push(n);
389 }
874 Unique_Node_List ctrl_path;
875
876 assert(_control.contains(_begin), "missing");
877 assert(_control.contains(_end), "missing");
878
879 // Collect the nodes that we know about and will eliminate into ctrl_path
880 for (uint i = 0; i < _control.size(); i++) {
881 // Push the call and it's control projection
882 Node* n = _control.at(i);
883 if (n->is_Allocate()) {
884 AllocateNode* an = n->as_Allocate();
885 InitializeNode* init = an->initialization();
886 ctrl_path.push(init);
887 ctrl_path.push(init->as_Multi()->proj_out(0));
888 }
889 if (n->is_Call()) {
890 CallNode* cn = n->as_Call();
891 ctrl_path.push(cn);
892 ctrl_path.push(cn->proj_out(0));
893 ctrl_path.push(cn->proj_out(0)->unique_out());
894 Node* catchproj = cn->proj_out(0)->unique_out()->as_Catch()->proj_out_or_null(0);
895 if (catchproj != NULL) {
896 ctrl_path.push(catchproj);
897 }
898 } else {
899 ShouldNotReachHere();
900 }
901 }
902
903 // Skip backwards through the control checking for unexpected control flow
904 Node* ptr = _end;
905 bool fail = false;
906 while (ptr != _begin) {
907 if (ptr->is_Call() && ctrl_path.member(ptr)) {
908 ptr = ptr->in(0);
909 } else if (ptr->is_CatchProj() && ctrl_path.member(ptr)) {
910 ptr = ptr->in(0)->in(0)->in(0);
911 assert(ctrl_path.member(ptr), "should be a known piece of control");
912 } else if (ptr->is_IfTrue()) {
913 IfNode* iff = ptr->in(0)->as_If();
914 BoolNode* b = iff->in(1)->isa_Bool();
1018 #ifndef PRODUCT
1019 if (PrintOptimizeStringConcat) {
1020 ptr->dump();
1021 }
1022 #endif
1023 ptr = ptr->in(0);
1024 }
1025 }
1026 #ifndef PRODUCT
1027 if (PrintOptimizeStringConcat && fail) {
1028 tty->cr();
1029 }
1030 #endif
1031 if (fail) return !fail;
1032
1033 // Validate that all these results produced are contained within
1034 // this cluster of objects. First collect all the results produced
1035 // by calls in the region.
1036 _stringopts->_visited.Clear();
1037 Node_List worklist;
1038 Node* final_result = _end->proj_out_or_null(TypeFunc::Parms);
1039 for (uint i = 0; i < _control.size(); i++) {
1040 CallNode* cnode = _control.at(i)->isa_Call();
1041 if (cnode != NULL) {
1042 _stringopts->_visited.test_set(cnode->_idx);
1043 }
1044 Node* result = cnode != NULL ? cnode->proj_out_or_null(TypeFunc::Parms) : NULL;
1045 if (result != NULL && result != final_result) {
1046 worklist.push(result);
1047 }
1048 }
1049
1050 Node* last_result = NULL;
1051 while (worklist.size() > 0) {
1052 Node* result = worklist.pop();
1053 if (_stringopts->_visited.test_set(result->_idx))
1054 continue;
1055 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
1056 Node *use = i.get();
1057 if (ctrl_path.member(use)) {
1058 // already checked this
1059 continue;
1060 }
1061 int opc = use->Opcode();
1062 if (opc == Op_CmpP || opc == Op_Node) {
1063 ctrl_path.push(use);
1064 continue;
|