Mercurial > hg > truffle
comparison src/share/vm/opto/output.cpp @ 14509:b3e1a903b6e8
8035283: Second phase of branch shortening doesn't account for loop alignment
Summary: added missing check for loop padding case.
Reviewed-by: kvn, jrose
author | iveresov |
---|---|
date | Wed, 26 Feb 2014 16:45:15 -0800 |
parents | abec000618bf |
children | d8041d695d19 |
comparison
equal
deleted
inserted
replaced
14508:78112be27ba0 | 14509:b3e1a903b6e8 |
---|---|
342 uint nblocks = _cfg->number_of_blocks(); | 342 uint nblocks = _cfg->number_of_blocks(); |
343 | 343 |
344 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); | 344 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); |
345 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); | 345 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); |
346 int* jmp_nidx = NEW_RESOURCE_ARRAY(int ,nblocks); | 346 int* jmp_nidx = NEW_RESOURCE_ARRAY(int ,nblocks); |
347 | |
348 // Collect worst case block paddings | |
349 int* block_worst_case_pad = NEW_RESOURCE_ARRAY(int, nblocks); | |
350 memset(block_worst_case_pad, 0, nblocks * sizeof(int)); | |
351 | |
347 DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); ) | 352 DEBUG_ONLY( uint *jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); ) |
348 DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); ) | 353 DEBUG_ONLY( uint *jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); ) |
349 | 354 |
350 bool has_short_branch_candidate = false; | 355 bool has_short_branch_candidate = false; |
351 | 356 |
458 } | 463 } |
459 if (last_avoid_back_to_back_adr == blk_starts[i]+blk_size) { | 464 if (last_avoid_back_to_back_adr == blk_starts[i]+blk_size) { |
460 last_avoid_back_to_back_adr += max_loop_pad; | 465 last_avoid_back_to_back_adr += max_loop_pad; |
461 } | 466 } |
462 blk_size += max_loop_pad; | 467 blk_size += max_loop_pad; |
468 block_worst_case_pad[i + 1] = max_loop_pad; | |
463 } | 469 } |
464 } | 470 } |
465 | 471 |
466 // Save block size; update total method size | 472 // Save block size; update total method size |
467 blk_starts[i+1] = blk_starts[i]+blk_size; | 473 blk_starts[i+1] = blk_starts[i]+blk_size; |
497 uint bnum = block->non_connector_successor(0)->_pre_order; | 503 uint bnum = block->non_connector_successor(0)->_pre_order; |
498 int offset = blk_starts[bnum] - br_offs; | 504 int offset = blk_starts[bnum] - br_offs; |
499 if (bnum > i) { // adjust following block's offset | 505 if (bnum > i) { // adjust following block's offset |
500 offset -= adjust_block_start; | 506 offset -= adjust_block_start; |
501 } | 507 } |
508 | |
509 // This block can be a loop header, account for the padding | |
510 // in the previous block. | |
511 int block_padding = block_worst_case_pad[i]; | |
512 assert(i == 0 || block_padding == 0 || br_offs >= block_padding, "Should have at least a padding on top"); | |
502 // In the following code a nop could be inserted before | 513 // In the following code a nop could be inserted before |
503 // the branch which will increase the backward distance. | 514 // the branch which will increase the backward distance. |
504 bool needs_padding = ((uint)br_offs == last_may_be_short_branch_adr); | 515 bool needs_padding = ((uint)(br_offs - block_padding) == last_may_be_short_branch_adr); |
516 assert(!needs_padding || jmp_offset[i] == 0, "padding only branches at the beginning of block"); | |
517 | |
505 if (needs_padding && offset <= 0) | 518 if (needs_padding && offset <= 0) |
506 offset -= nop_size; | 519 offset -= nop_size; |
507 | 520 |
508 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { | 521 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { |
509 // We've got a winner. Replace this branch. | 522 // We've got a winner. Replace this branch. |