324 tty->print_cr("Merge candidate of length %d exceeds argument limit", arguments_appended);
325 }
326 #endif
327 return nullptr;
328 }
329 }
330 result->set_allocation(other->_begin);
331 for (uint i = 0; i < _constructors.size(); i++) {
332 result->add_constructor(_constructors.at(i));
333 }
334 for (uint i = 0; i < other->_constructors.size(); i++) {
335 result->add_constructor(other->_constructors.at(i));
336 }
337 result->_multiple = true;
338 return result;
339 }
340
341
342 void StringConcat::eliminate_call(CallNode* call) {
343 Compile* C = _stringopts->C;
344 CallProjections projs;
345 call->extract_projections(&projs, false);
346 if (projs.fallthrough_catchproj != nullptr) {
347 C->gvn_replace_by(projs.fallthrough_catchproj, call->in(TypeFunc::Control));
348 }
349 if (projs.fallthrough_memproj != nullptr) {
350 C->gvn_replace_by(projs.fallthrough_memproj, call->in(TypeFunc::Memory));
351 }
352 if (projs.catchall_memproj != nullptr) {
353 C->gvn_replace_by(projs.catchall_memproj, C->top());
354 }
355 if (projs.fallthrough_ioproj != nullptr) {
356 C->gvn_replace_by(projs.fallthrough_ioproj, call->in(TypeFunc::I_O));
357 }
358 if (projs.catchall_ioproj != nullptr) {
359 C->gvn_replace_by(projs.catchall_ioproj, C->top());
360 }
361 if (projs.catchall_catchproj != nullptr) {
362 // EA can't cope with the partially collapsed graph this
363 // creates so put it on the worklist to be collapsed later.
364 for (SimpleDUIterator i(projs.catchall_catchproj); i.has_next(); i.next()) {
365 Node *use = i.get();
366 int opc = use->Opcode();
367 if (opc == Op_CreateEx || opc == Op_Region) {
368 _stringopts->record_dead_node(use);
369 }
370 }
371 C->gvn_replace_by(projs.catchall_catchproj, C->top());
372 }
373 if (projs.resproj != nullptr) {
374 C->gvn_replace_by(projs.resproj, C->top());
375 }
376 C->gvn_replace_by(call, C->top());
377 }
378
379 void StringConcat::eliminate_initialize(InitializeNode* init) {
380 Compile* C = _stringopts->C;
381
382 // Eliminate Initialize node.
383 assert(init->outcnt() <= 2, "only a control and memory projection expected");
384 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
385 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
386 if (ctrl_proj != nullptr) {
387 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
388 }
389 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
390 if (mem_proj != nullptr) {
391 Node *mem = init->in(TypeFunc::Memory);
392 C->gvn_replace_by(mem_proj, mem);
393 }
394 C->gvn_replace_by(init, C->top());
1139 }
1140 }
1141
1142 Node* last_result = nullptr;
1143 while (worklist.size() > 0) {
1144 Node* result = worklist.pop();
1145 if (_stringopts->_visited.test_set(result->_idx))
1146 continue;
1147 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
1148 Node *use = i.get();
1149 if (ctrl_path.member(use)) {
1150 // already checked this
1151 continue;
1152 }
1153 int opc = use->Opcode();
1154 if (opc == Op_CmpP || opc == Op_Node) {
1155 ctrl_path.push(use);
1156 continue;
1157 }
1158 if (opc == Op_CastPP || opc == Op_CheckCastPP) {
1159 for (SimpleDUIterator j(use); j.has_next(); j.next()) {
1160 worklist.push(j.get());
1161 }
1162 worklist.push(use->in(1));
1163 ctrl_path.push(use);
1164 continue;
1165 }
1166 #ifndef PRODUCT
1167 if (PrintOptimizeStringConcat) {
1168 if (result != last_result) {
1169 last_result = result;
1170 tty->print_cr("extra uses for result:");
1171 last_result->dump();
1172 }
1173 use->dump();
1174 }
1175 #endif
1176 fail = true;
1177 break;
1178 }
|
324 tty->print_cr("Merge candidate of length %d exceeds argument limit", arguments_appended);
325 }
326 #endif
327 return nullptr;
328 }
329 }
330 result->set_allocation(other->_begin);
331 for (uint i = 0; i < _constructors.size(); i++) {
332 result->add_constructor(_constructors.at(i));
333 }
334 for (uint i = 0; i < other->_constructors.size(); i++) {
335 result->add_constructor(other->_constructors.at(i));
336 }
337 result->_multiple = true;
338 return result;
339 }
340
341
342 void StringConcat::eliminate_call(CallNode* call) {
343 Compile* C = _stringopts->C;
344 CallProjections* projs = call->extract_projections(false);
345 if (projs->fallthrough_catchproj != nullptr) {
346 C->gvn_replace_by(projs->fallthrough_catchproj, call->in(TypeFunc::Control));
347 }
348 if (projs->fallthrough_memproj != nullptr) {
349 C->gvn_replace_by(projs->fallthrough_memproj, call->in(TypeFunc::Memory));
350 }
351 if (projs->catchall_memproj != nullptr) {
352 C->gvn_replace_by(projs->catchall_memproj, C->top());
353 }
354 if (projs->fallthrough_ioproj != nullptr) {
355 C->gvn_replace_by(projs->fallthrough_ioproj, call->in(TypeFunc::I_O));
356 }
357 if (projs->catchall_ioproj != nullptr) {
358 C->gvn_replace_by(projs->catchall_ioproj, C->top());
359 }
360 if (projs->catchall_catchproj != nullptr) {
361 // EA can't cope with the partially collapsed graph this
362 // creates so put it on the worklist to be collapsed later.
363 for (SimpleDUIterator i(projs->catchall_catchproj); i.has_next(); i.next()) {
364 Node *use = i.get();
365 int opc = use->Opcode();
366 if (opc == Op_CreateEx || opc == Op_Region) {
367 _stringopts->record_dead_node(use);
368 }
369 }
370 C->gvn_replace_by(projs->catchall_catchproj, C->top());
371 }
372 if (projs->resproj[0] != nullptr) {
373 assert(projs->nb_resproj == 1, "unexpected number of results");
374 C->gvn_replace_by(projs->resproj[0], C->top());
375 }
376 C->gvn_replace_by(call, C->top());
377 }
378
379 void StringConcat::eliminate_initialize(InitializeNode* init) {
380 Compile* C = _stringopts->C;
381
382 // Eliminate Initialize node.
383 assert(init->outcnt() <= 2, "only a control and memory projection expected");
384 assert(init->req() <= InitializeNode::RawStores, "no pending inits");
385 Node *ctrl_proj = init->proj_out_or_null(TypeFunc::Control);
386 if (ctrl_proj != nullptr) {
387 C->gvn_replace_by(ctrl_proj, init->in(TypeFunc::Control));
388 }
389 Node *mem_proj = init->proj_out_or_null(TypeFunc::Memory);
390 if (mem_proj != nullptr) {
391 Node *mem = init->in(TypeFunc::Memory);
392 C->gvn_replace_by(mem_proj, mem);
393 }
394 C->gvn_replace_by(init, C->top());
1139 }
1140 }
1141
1142 Node* last_result = nullptr;
1143 while (worklist.size() > 0) {
1144 Node* result = worklist.pop();
1145 if (_stringopts->_visited.test_set(result->_idx))
1146 continue;
1147 for (SimpleDUIterator i(result); i.has_next(); i.next()) {
1148 Node *use = i.get();
1149 if (ctrl_path.member(use)) {
1150 // already checked this
1151 continue;
1152 }
1153 int opc = use->Opcode();
1154 if (opc == Op_CmpP || opc == Op_Node) {
1155 ctrl_path.push(use);
1156 continue;
1157 }
1158 if (opc == Op_CastPP || opc == Op_CheckCastPP) {
1159 if (opc == Op_CheckCastPP) {
1160 worklist.push(use);
1161 }
1162 for (SimpleDUIterator j(use); j.has_next(); j.next()) {
1163 worklist.push(j.get());
1164 }
1165 worklist.push(use->in(1));
1166 ctrl_path.push(use);
1167 continue;
1168 }
1169 #ifndef PRODUCT
1170 if (PrintOptimizeStringConcat) {
1171 if (result != last_result) {
1172 last_result = result;
1173 tty->print_cr("extra uses for result:");
1174 last_result->dump();
1175 }
1176 use->dump();
1177 }
1178 #endif
1179 fail = true;
1180 break;
1181 }
|