comparison src/share/vm/opto/output.cpp @ 17877:17b2fbdb6637

8038297: Avoid placing CTI immediately following cbcond instruction on T4 Summary: Insert a nop between cbcond and CTI Reviewed-by: kvn, twisti
author iveresov
date Thu, 10 Apr 2014 23:15:13 -0700
parents a433eb716ce1
children 0bf37f737702
comparison
equal deleted inserted replaced
17875:cb1b723cbca8 17877:17b2fbdb6637
409 // check for all offsets inside this block. 409 // check for all offsets inside this block.
410 if (last_call_adr >= blk_starts[i]) { 410 if (last_call_adr >= blk_starts[i]) {
411 blk_size += nop_size; 411 blk_size += nop_size;
412 } 412 }
413 } 413 }
414 if (mach->avoid_back_to_back()) { 414 if (mach->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
415 // Nop is inserted between "avoid back to back" instructions. 415 // Nop is inserted between "avoid back to back" instructions.
416 // ScheduleAndBundle() can rearrange nodes in a block, 416 // ScheduleAndBundle() can rearrange nodes in a block,
417 // check for all offsets inside this block. 417 // check for all offsets inside this block.
418 if (last_avoid_back_to_back_adr >= blk_starts[i]) { 418 if (last_avoid_back_to_back_adr >= blk_starts[i]) {
419 blk_size += nop_size; 419 blk_size += nop_size;
437 // Remember end of call offset 437 // Remember end of call offset
438 if (nj->is_MachCall() && !nj->is_MachCallLeaf()) { 438 if (nj->is_MachCall() && !nj->is_MachCallLeaf()) {
439 last_call_adr = blk_starts[i]+blk_size; 439 last_call_adr = blk_starts[i]+blk_size;
440 } 440 }
441 // Remember end of avoid_back_to_back offset 441 // Remember end of avoid_back_to_back offset
442 if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back()) { 442 if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
443 last_avoid_back_to_back_adr = blk_starts[i]+blk_size; 443 last_avoid_back_to_back_adr = blk_starts[i]+blk_size;
444 } 444 }
445 } 445 }
446 446
447 // When the next block starts a loop, we may insert pad NOP 447 // When the next block starts a loop, we may insert pad NOP
523 523
524 // Update the jmp_size. 524 // Update the jmp_size.
525 int new_size = replacement->size(_regalloc); 525 int new_size = replacement->size(_regalloc);
526 int diff = br_size - new_size; 526 int diff = br_size - new_size;
527 assert(diff >= (int)nop_size, "short_branch size should be smaller"); 527 assert(diff >= (int)nop_size, "short_branch size should be smaller");
528 // Conservatively take into accound padding between 528 // Conservatively take into account padding between
529 // avoid_back_to_back branches. Previous branch could be 529 // avoid_back_to_back branches. Previous branch could be
530 // converted into avoid_back_to_back branch during next 530 // converted into avoid_back_to_back branch during next
531 // rounds. 531 // rounds.
532 if (needs_padding && replacement->avoid_back_to_back()) { 532 if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
533 jmp_offset[i] += nop_size; 533 jmp_offset[i] += nop_size;
534 diff -= nop_size; 534 diff -= nop_size;
535 } 535 }
536 adjust_block_start += diff; 536 adjust_block_start += diff;
537 block->map_node(replacement, idx); 537 block->map_node(replacement, idx);
546 // The jump distance is not short, try again during next iteration. 546 // The jump distance is not short, try again during next iteration.
547 has_short_branch_candidate = true; 547 has_short_branch_candidate = true;
548 } 548 }
549 } // (mach->may_be_short_branch()) 549 } // (mach->may_be_short_branch())
550 if (mach != NULL && (mach->may_be_short_branch() || 550 if (mach != NULL && (mach->may_be_short_branch() ||
551 mach->avoid_back_to_back())) { 551 mach->avoid_back_to_back(MachNode::AVOID_AFTER))) {
552 last_may_be_short_branch_adr = blk_starts[i] + jmp_offset[i] + jmp_size[i]; 552 last_may_be_short_branch_adr = blk_starts[i] + jmp_offset[i] + jmp_size[i];
553 } 553 }
554 blk_starts[i+1] -= adjust_block_start; 554 blk_starts[i+1] -= adjust_block_start;
555 } 555 }
556 } 556 }
1311 // Make sure safepoint node for polling is distinct from a call's 1311 // Make sure safepoint node for polling is distinct from a call's
1312 // return by adding a nop if needed. 1312 // return by adding a nop if needed.
1313 if (is_sfn && !is_mcall && padding == 0 && current_offset == last_call_offset) { 1313 if (is_sfn && !is_mcall && padding == 0 && current_offset == last_call_offset) {
1314 padding = nop_size; 1314 padding = nop_size;
1315 } 1315 }
1316 if (padding == 0 && mach->avoid_back_to_back() && 1316 if (padding == 0 && mach->avoid_back_to_back(MachNode::AVOID_BEFORE) &&
1317 current_offset == last_avoid_back_to_back_offset) { 1317 current_offset == last_avoid_back_to_back_offset) {
1318 // Avoid back to back some instructions. 1318 // Avoid back to back some instructions.
1319 padding = nop_size; 1319 padding = nop_size;
1320 } 1320 }
1321 1321
1405 1405
1406 // Update the jmp_size. 1406 // Update the jmp_size.
1407 int new_size = replacement->size(_regalloc); 1407 int new_size = replacement->size(_regalloc);
1408 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); 1408 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller");
1409 // Insert padding between avoid_back_to_back branches. 1409 // Insert padding between avoid_back_to_back branches.
1410 if (needs_padding && replacement->avoid_back_to_back()) { 1410 if (needs_padding && replacement->avoid_back_to_back(MachNode::AVOID_BEFORE)) {
1411 MachNode *nop = new (this) MachNopNode(); 1411 MachNode *nop = new (this) MachNopNode();
1412 block->insert_node(nop, j++); 1412 block->insert_node(nop, j++);
1413 _cfg->map_node_to_block(nop, block); 1413 _cfg->map_node_to_block(nop, block);
1414 last_inst++; 1414 last_inst++;
1415 nop->emit(*cb, _regalloc); 1415 nop->emit(*cb, _regalloc);
1513 1513
1514 if (is_mcall) { 1514 if (is_mcall) {
1515 last_call_offset = current_offset; 1515 last_call_offset = current_offset;
1516 } 1516 }
1517 1517
1518 if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) { 1518 if (n->is_Mach() && n->as_Mach()->avoid_back_to_back(MachNode::AVOID_AFTER)) {
1519 // Avoid back to back some instructions. 1519 // Avoid back to back some instructions.
1520 last_avoid_back_to_back_offset = current_offset; 1520 last_avoid_back_to_back_offset = current_offset;
1521 } 1521 }
1522 1522
1523 // See if this instruction has a delay slot 1523 // See if this instruction has a delay slot