Mercurial > hg > truffle
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 |