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() ) {