Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/output.cpp @ 3853:11211f7cb5a0
7079317: Incorrect branch's destination block in PrintoOptoAssembly output
Summary: save/restore label and block in scratch_emit_size()
Reviewed-by: never
author | kvn |
---|---|
date | Tue, 16 Aug 2011 11:53:57 -0700 |
parents | 95134e034042 |
children | 739a9abbbd4b |
comparison
equal
deleted
inserted
replaced
3852:fdb992d83a87 | 3853:11211f7cb5a0 |
---|---|
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; |
420 } | 420 } |
421 } | 421 } |
422 if (mach->may_be_short_branch()) { | 422 if (mach->may_be_short_branch()) { |
423 if (!nj->is_Branch()) { | 423 if (!nj->is_MachBranch()) { |
424 #ifndef PRODUCT | 424 #ifndef PRODUCT |
425 nj->dump(3); | 425 nj->dump(3); |
426 #endif | 426 #endif |
427 Unimplemented(); | 427 Unimplemented(); |
428 } | 428 } |
471 Block *b = _cfg->_blocks[i]; | 471 Block *b = _cfg->_blocks[i]; |
472 int idx = jmp_nidx[i]; | 472 int idx = jmp_nidx[i]; |
473 MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach(); | 473 MachNode* mach = (idx == -1) ? NULL: b->_nodes[idx]->as_Mach(); |
474 if (mach != NULL && mach->may_be_short_branch()) { | 474 if (mach != NULL && mach->may_be_short_branch()) { |
475 #ifdef ASSERT | 475 #ifdef ASSERT |
476 assert(jmp_size[i] > 0 && mach->is_Branch(), "sanity"); | 476 assert(jmp_size[i] > 0 && mach->is_MachBranch(), "sanity"); |
477 int j; | 477 int j; |
478 // Find the branch; ignore trailing NOPs. | 478 // Find the branch; ignore trailing NOPs. |
479 for (j = b->_nodes.size()-1; j>=0; j--) { | 479 for (j = b->_nodes.size()-1; j>=0; j--) { |
480 Node* n = b->_nodes[j]; | 480 Node* n = b->_nodes[j]; |
481 if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) | 481 if (!n->is_Mach() || n->as_Mach()->ideal_Opcode() != Op_Con) |
498 if (needs_padding && offset <= 0) | 498 if (needs_padding && offset <= 0) |
499 offset -= nop_size; | 499 offset -= nop_size; |
500 | 500 |
501 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { | 501 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { |
502 // We've got a winner. Replace this branch. | 502 // We've got a winner. Replace this branch. |
503 MachNode* replacement = mach->short_branch_version(this); | 503 MachNode* replacement = mach->as_MachBranch()->short_branch_version(this); |
504 | 504 |
505 // Update the jmp_size. | 505 // Update the jmp_size. |
506 int new_size = replacement->size(_regalloc); | 506 int new_size = replacement->size(_regalloc); |
507 int diff = br_size - new_size; | 507 int diff = br_size - new_size; |
508 assert(diff >= (int)nop_size, "short_branch size should be smaller"); | 508 assert(diff >= (int)nop_size, "short_branch size should be smaller"); |
668 if (needs_padding && offset <= 0) | 668 if (needs_padding && offset <= 0) |
669 offset -= nop_size; | 669 offset -= nop_size; |
670 | 670 |
671 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { | 671 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { |
672 // We've got a winner. Replace this branch. | 672 // We've got a winner. Replace this branch. |
673 MachNode* replacement = mach->short_branch_version(this); | 673 MachNode* replacement = mach->as_MachBranch()->short_branch_version(this); |
674 | 674 |
675 // Update the jmp_size. | 675 // Update the jmp_size. |
676 int new_size = replacement->size(_regalloc); | 676 int new_size = replacement->size(_regalloc); |
677 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); | 677 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); |
678 // Conservatively take into accound padding between | 678 // Conservatively take into accound padding between |
1523 else if( mach->is_MachNullCheck() ) { | 1523 else if( mach->is_MachNullCheck() ) { |
1524 inct_starts[inct_cnt++] = previous_offset; | 1524 inct_starts[inct_cnt++] = previous_offset; |
1525 } | 1525 } |
1526 | 1526 |
1527 // If this is a branch, then fill in the label with the target BB's label | 1527 // If this is a branch, then fill in the label with the target BB's label |
1528 else if (mach->is_Branch()) { | 1528 else if (mach->is_MachBranch()) { |
1529 | 1529 // This requires the TRUE branch target be in succs[0] |
1530 if (mach->ideal_Opcode() == Op_Jump) { | 1530 uint block_num = b->non_connector_successor(0)->_pre_order; |
1531 for (uint h = 0; h < b->_num_succs; h++) { | 1531 mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); |
1532 Block* succs_block = b->_succs[h]; | 1532 } else if (mach->ideal_Opcode() == Op_Jump) { |
1533 for (uint j = 1; j < succs_block->num_preds(); j++) { | 1533 for (uint h = 0; h < b->_num_succs; h++) { |
1534 Node* jpn = succs_block->pred(j); | 1534 Block* succs_block = b->_succs[h]; |
1535 if (jpn->is_JumpProj() && jpn->in(0) == mach) { | 1535 for (uint j = 1; j < succs_block->num_preds(); j++) { |
1536 uint block_num = succs_block->non_connector()->_pre_order; | 1536 Node* jpn = succs_block->pred(j); |
1537 Label *blkLabel = &blk_labels[block_num]; | 1537 if (jpn->is_JumpProj() && jpn->in(0) == mach) { |
1538 mach->add_case_label(jpn->as_JumpProj()->proj_no(), blkLabel); | 1538 uint block_num = succs_block->non_connector()->_pre_order; |
1539 } | 1539 Label *blkLabel = &blk_labels[block_num]; |
1540 mach->add_case_label(jpn->as_JumpProj()->proj_no(), blkLabel); | |
1540 } | 1541 } |
1541 } | 1542 } |
1542 } else { | |
1543 // For Branchs | |
1544 // This requires the TRUE branch target be in succs[0] | |
1545 uint block_num = b->non_connector_successor(0)->_pre_order; | |
1546 mach->label_set( &blk_labels[block_num], block_num ); | |
1547 } | 1543 } |
1548 } | 1544 } |
1549 | 1545 |
1550 #ifdef ASSERT | 1546 #ifdef ASSERT |
1551 // Check that oop-store precedes the card-mark | 1547 // Check that oop-store precedes the card-mark |
2227 // branch, OR a conditionally executed instruction if | 2223 // branch, OR a conditionally executed instruction if |
2228 // the branch is taken. In practice, this means that | 2224 // the branch is taken. In practice, this means that |
2229 // the first instruction at the branch target is | 2225 // the first instruction at the branch target is |
2230 // copied to the delay slot, and the branch goes to | 2226 // copied to the delay slot, and the branch goes to |
2231 // the instruction after that at the branch target | 2227 // the instruction after that at the branch target |
2232 if ( n->is_Mach() && n->is_Branch() ) { | 2228 if ( n->is_MachBranch() ) { |
2233 | 2229 |
2234 assert( !n->is_MachNullCheck(), "should not look for delay slot for Null Check" ); | 2230 assert( !n->is_MachNullCheck(), "should not look for delay slot for Null Check" ); |
2235 assert( !n->is_Catch(), "should not look for delay slot for Catch" ); | 2231 assert( !n->is_Catch(), "should not look for delay slot for Catch" ); |
2236 | 2232 |
2237 #ifndef PRODUCT | 2233 #ifndef PRODUCT |
2888 } | 2884 } |
2889 | 2885 |
2890 // Kill projections on a branch should appear to occur on the | 2886 // Kill projections on a branch should appear to occur on the |
2891 // branch, not afterwards, so grab the masks from the projections | 2887 // branch, not afterwards, so grab the masks from the projections |
2892 // and process them. | 2888 // and process them. |
2893 if (n->is_Branch()) { | 2889 if (n->is_MachBranch() || n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_Jump) { |
2894 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { | 2890 for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) { |
2895 Node* use = n->fast_out(i); | 2891 Node* use = n->fast_out(i); |
2896 if (use->is_Proj()) { | 2892 if (use->is_Proj()) { |
2897 RegMask rm = use->out_RegMask();// Make local copy | 2893 RegMask rm = use->out_RegMask();// Make local copy |
2898 while( rm.is_NotEmpty() ) { | 2894 while( rm.is_NotEmpty() ) { |