Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/output.cpp @ 3857:739a9abbbd4b
7080431: VM asserts if specified size(x) in .ad is larger than emitted size
Summary: Move code from finalize_offsets_and_shorten() to fill_buffer() to restore previous behavior.
Reviewed-by: never
author | kvn |
---|---|
date | Thu, 18 Aug 2011 11:49:33 -0700 |
parents | 11211f7cb5a0 |
children | 04b9a2566eec e9a5e0a812c8 |
comparison
equal
deleted
inserted
replaced
3856:bd87c0dcaba5 | 3857:739a9abbbd4b |
---|---|
153 } | 153 } |
154 } | 154 } |
155 #endif | 155 #endif |
156 | 156 |
157 if (failing()) return; | 157 if (failing()) return; |
158 | |
159 finalize_offsets_and_shorten(blk_starts); | |
160 | 158 |
161 BuildOopMaps(); | 159 BuildOopMaps(); |
162 | 160 |
163 if (failing()) return; | 161 if (failing()) return; |
164 | 162 |
384 // Sum all instruction sizes to compute block size | 382 // Sum all instruction sizes to compute block size |
385 uint last_inst = b->_nodes.size(); | 383 uint last_inst = b->_nodes.size(); |
386 uint blk_size = 0; | 384 uint blk_size = 0; |
387 for (uint j = 0; j < last_inst; j++) { | 385 for (uint j = 0; j < last_inst; j++) { |
388 Node* nj = b->_nodes[j]; | 386 Node* nj = b->_nodes[j]; |
389 uint inst_size = nj->size(_regalloc); | |
390 // Handle machine instruction nodes | 387 // Handle machine instruction nodes |
391 if (nj->is_Mach()) { | 388 if (nj->is_Mach()) { |
392 MachNode *mach = nj->as_Mach(); | 389 MachNode *mach = nj->as_Mach(); |
393 blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding | 390 blk_size += (mach->alignment_required() - 1) * relocInfo::addr_unit(); // assume worst case padding |
394 reloc_size += mach->reloc(); | 391 reloc_size += mach->reloc(); |
426 #endif | 423 #endif |
427 Unimplemented(); | 424 Unimplemented(); |
428 } | 425 } |
429 assert(jmp_nidx[i] == -1, "block should have only one branch"); | 426 assert(jmp_nidx[i] == -1, "block should have only one branch"); |
430 jmp_offset[i] = blk_size; | 427 jmp_offset[i] = blk_size; |
431 jmp_size[i] = inst_size; | 428 jmp_size[i] = nj->size(_regalloc); |
432 jmp_nidx[i] = j; | 429 jmp_nidx[i] = j; |
433 has_short_branch_candidate = true; | 430 has_short_branch_candidate = true; |
434 } | 431 } |
435 } | 432 } |
436 blk_size += inst_size; | 433 blk_size += nj->size(_regalloc); |
437 // Remember end of call offset | 434 // Remember end of call offset |
438 if (nj->is_MachCall() && !nj->is_MachCallLeaf()) { | 435 if (nj->is_MachCall() && !nj->is_MachCallLeaf()) { |
439 last_call_adr = blk_starts[i]+blk_size; | 436 last_call_adr = blk_starts[i]+blk_size; |
440 } | 437 } |
441 // Remember end of avoid_back_to_back offset | 438 // Remember end of avoid_back_to_back offset |
547 assert(_matcher->is_short_branch_offset(jmp_rule[i], br_size, offset), "Displacement too large for short jmp"); | 544 assert(_matcher->is_short_branch_offset(jmp_rule[i], br_size, offset), "Displacement too large for short jmp"); |
548 } | 545 } |
549 } | 546 } |
550 #endif | 547 #endif |
551 | 548 |
552 // Step 3, compute the offsets of all blocks, will be done in finalize_offsets_and_shorten() | 549 // Step 3, compute the offsets of all blocks, will be done in fill_buffer() |
553 // after ScheduleAndBundle(). | 550 // after ScheduleAndBundle(). |
554 | 551 |
555 // ------------------ | 552 // ------------------ |
556 // Compute size for code buffer | 553 // Compute size for code buffer |
557 code_size = blk_starts[nblocks]; | 554 code_size = blk_starts[nblocks]; |
562 // Adjust reloc_size to number of record of relocation info | 559 // Adjust reloc_size to number of record of relocation info |
563 // Min is 2 bytes, max is probably 6 or 8, with a tax up to 25% for | 560 // Min is 2 bytes, max is probably 6 or 8, with a tax up to 25% for |
564 // a relocation index. | 561 // a relocation index. |
565 // The CodeBuffer will expand the locs array if this estimate is too low. | 562 // The CodeBuffer will expand the locs array if this estimate is too low. |
566 reloc_size *= 10 / sizeof(relocInfo); | 563 reloc_size *= 10 / sizeof(relocInfo); |
567 } | |
568 | |
569 //----------------------finalize_offsets_and_shorten------------------------- | |
570 void Compile::finalize_offsets_and_shorten(uint* blk_starts) { | |
571 // blk_starts[] contains offsets calculated during short branches processing, | |
572 // offsets should not be increased during following steps. | |
573 | |
574 // Compute the size of first NumberOfLoopInstrToAlign instructions at head | |
575 // of a loop. It is used to determine the padding for loop alignment. | |
576 compute_loop_first_inst_sizes(); | |
577 | |
578 uint nblocks = _cfg->_num_blocks; | |
579 #ifdef ASSERT | |
580 uint* jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); | |
581 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); | |
582 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); | |
583 uint* jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); | |
584 #endif | |
585 | |
586 // Inserts nops where needed and do final short branches replacement. | |
587 uint nop_size = (new (this) MachNopNode())->size(_regalloc); | |
588 uint last_call_adr = max_uint; | |
589 uint last_avoid_back_to_back_adr = max_uint; | |
590 | |
591 assert(blk_starts[0] == 0, "sanity"); | |
592 uint current_offset = 0; | |
593 uint block_alignment_padding = 0; | |
594 | |
595 for (uint i=0; i < nblocks; i++) { // For all blocks | |
596 Block *b = _cfg->_blocks[i]; | |
597 | |
598 #ifdef ASSERT | |
599 jmp_target[i] = 0; | |
600 jmp_offset[i] = 0; | |
601 jmp_size[i] = 0; | |
602 jmp_rule[i] = 0; | |
603 #endif | |
604 | |
605 // Maximum alignment was added before loop block during | |
606 // Step One, as result padding for nodes was not added. | |
607 // Take this into account for block's size change check | |
608 // and allow increase block's size by the difference | |
609 // of maximum and actual alignment paddings. | |
610 DEBUG_ONLY( uint orig_blk_size = blk_starts[i+1] - blk_starts[i] + block_alignment_padding; ) | |
611 uint blk_offset = current_offset; | |
612 | |
613 uint last_inst = b->_nodes.size(); | |
614 for (uint j = 0; j<last_inst; j++) { | |
615 Node* nj = b->_nodes[j]; | |
616 | |
617 if (valid_bundle_info(nj) && | |
618 node_bundling(nj)->used_in_unconditional_delay()) { | |
619 continue; // Skip instruction in delay slot | |
620 } | |
621 | |
622 uint inst_size = nj->size(_regalloc); | |
623 if (nj->is_Mach()) { | |
624 MachNode *mach = nj->as_Mach(); | |
625 int padding = mach->compute_padding(current_offset); | |
626 | |
627 // If call/safepoint are adjacent insert a nop (5010568) | |
628 if (padding == 0 && nj->is_MachSafePoint() && !nj->is_MachCall() && | |
629 current_offset == last_call_adr) { | |
630 padding = nop_size; | |
631 } | |
632 | |
633 // Inserted a nop between "avoid back to back" instructions. | |
634 if (padding == 0 && mach->avoid_back_to_back() && | |
635 current_offset == last_avoid_back_to_back_adr) { | |
636 padding = nop_size; | |
637 } | |
638 | |
639 if (padding > 0) { | |
640 assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); | |
641 int nops_cnt = padding / nop_size; | |
642 MachNode *nop = new (this) MachNopNode(nops_cnt); | |
643 b->_nodes.insert(j++, nop); | |
644 _cfg->_bbs.map(nop->_idx, b); | |
645 last_inst++; | |
646 current_offset += padding; | |
647 } | |
648 | |
649 // Try to replace long branch if delay slot is not used, | |
650 // it is mostly for back branches since forward branch's | |
651 // distance is not updated yet. | |
652 bool delay_slot_is_used = valid_bundle_info(nj) && | |
653 node_bundling(nj)->use_unconditional_delay(); | |
654 if (!delay_slot_is_used && mach->may_be_short_branch()) { | |
655 int br_size = inst_size; | |
656 | |
657 // This requires the TRUE branch target be in succs[0] | |
658 uint bnum = b->non_connector_successor(0)->_pre_order; | |
659 int offset = blk_starts[bnum] - current_offset; | |
660 if (bnum >= i) { | |
661 // Current and following block's offset are not | |
662 // finilized yet, adjust distance. | |
663 offset -= (blk_starts[i] - blk_offset); | |
664 } | |
665 // In the following code a nop could be inserted before | |
666 // the branch which will increase the backward distance. | |
667 bool needs_padding = (current_offset == last_avoid_back_to_back_adr); | |
668 if (needs_padding && offset <= 0) | |
669 offset -= nop_size; | |
670 | |
671 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { | |
672 // We've got a winner. Replace this branch. | |
673 MachNode* replacement = mach->as_MachBranch()->short_branch_version(this); | |
674 | |
675 // Update the jmp_size. | |
676 int new_size = replacement->size(_regalloc); | |
677 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); | |
678 // Conservatively take into accound padding between | |
679 // avoid_back_to_back branches. Previous branch could be | |
680 // converted into avoid_back_to_back branch during next | |
681 // rounds. | |
682 if (needs_padding && replacement->avoid_back_to_back()) { | |
683 MachNode *nop = new (this) MachNopNode(); | |
684 b->_nodes.insert(j++, nop); | |
685 _cfg->_bbs.map(nop->_idx, b); | |
686 last_inst++; | |
687 current_offset += nop_size; | |
688 } | |
689 inst_size = new_size; | |
690 b->_nodes.map(j, replacement); | |
691 mach->subsume_by(replacement); | |
692 nj = replacement; | |
693 #ifdef ASSERT | |
694 jmp_target[i] = bnum; | |
695 jmp_offset[i] = current_offset - blk_offset; | |
696 jmp_size[i] = new_size; | |
697 jmp_rule[i] = mach->rule(); | |
698 #endif | |
699 } | |
700 } | |
701 } | |
702 current_offset += inst_size; | |
703 | |
704 // Remember end of call offset | |
705 if (nj->is_MachCall() && !nj->is_MachCallLeaf()) { | |
706 last_call_adr = current_offset; | |
707 } | |
708 // Remember end of avoid_back_to_back offset | |
709 if (nj->is_Mach() && nj->as_Mach()->avoid_back_to_back()) { | |
710 last_avoid_back_to_back_adr = current_offset; | |
711 } | |
712 } | |
713 assert(blk_offset <= blk_starts[i], "shouldn't increase distance"); | |
714 blk_starts[i] = blk_offset; | |
715 | |
716 // When the next block is the top of a loop, we may insert pad NOP | |
717 // instructions. | |
718 if (i < nblocks-1) { | |
719 Block *nb = _cfg->_blocks[i+1]; | |
720 int padding = nb->alignment_padding(current_offset); | |
721 if (padding > 0) { | |
722 assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); | |
723 int nops_cnt = padding / nop_size; | |
724 MachNode *nop = new (this) MachNopNode(nops_cnt); | |
725 b->_nodes.insert(b->_nodes.size(), nop); | |
726 _cfg->_bbs.map(nop->_idx, b); | |
727 current_offset += padding; | |
728 } | |
729 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); | |
730 assert(max_loop_pad >= padding, "sanity"); | |
731 block_alignment_padding = max_loop_pad - padding; | |
732 } | |
733 assert(orig_blk_size >= (current_offset - blk_offset), "shouldn't increase block size"); | |
734 } | |
735 blk_starts[nblocks] = current_offset; | |
736 | |
737 #ifdef ASSERT | |
738 for (uint i = 0; i < nblocks; i++) { // For all blocks | |
739 if (jmp_target[i] != 0) { | |
740 int br_size = jmp_size[i]; | |
741 int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_offset[i]); | |
742 if (!_matcher->is_short_branch_offset(jmp_rule[i], br_size, offset)) { | |
743 tty->print_cr("target (%d) - jmp_offset(%d) = offset (%d), jump_size(%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_offset[i], offset, br_size, i, jmp_target[i]); | |
744 } | |
745 assert(_matcher->is_short_branch_offset(jmp_rule[i], br_size, offset), "Displacement too large for short jmp"); | |
746 } | |
747 } | |
748 #endif | |
749 } | 564 } |
750 | 565 |
751 //------------------------------FillLocArray----------------------------------- | 566 //------------------------------FillLocArray----------------------------------- |
752 // Create a bit of debug info and append it to the array. The mapping is from | 567 // Create a bit of debug info and append it to the array. The mapping is from |
753 // Java local or expression stack to constant, register or stack-slot. For | 568 // Java local or expression stack to constant, register or stack-slot. For |
1348 return cb; | 1163 return cb; |
1349 } | 1164 } |
1350 | 1165 |
1351 //------------------------------fill_buffer------------------------------------ | 1166 //------------------------------fill_buffer------------------------------------ |
1352 void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { | 1167 void Compile::fill_buffer(CodeBuffer* cb, uint* blk_starts) { |
1168 // blk_starts[] contains offsets calculated during short branches processing, | |
1169 // offsets should not be increased during following steps. | |
1170 | |
1171 // Compute the size of first NumberOfLoopInstrToAlign instructions at head | |
1172 // of a loop. It is used to determine the padding for loop alignment. | |
1173 compute_loop_first_inst_sizes(); | |
1353 | 1174 |
1354 // Create oopmap set. | 1175 // Create oopmap set. |
1355 _oop_map_set = new OopMapSet(); | 1176 _oop_map_set = new OopMapSet(); |
1356 | 1177 |
1357 // !!!!! This preserves old handling of oopmaps for now | 1178 // !!!!! This preserves old handling of oopmaps for now |
1358 debug_info()->set_oopmaps(_oop_map_set); | 1179 debug_info()->set_oopmaps(_oop_map_set); |
1359 | 1180 |
1181 uint nblocks = _cfg->_num_blocks; | |
1360 // Count and start of implicit null check instructions | 1182 // Count and start of implicit null check instructions |
1361 uint inct_cnt = 0; | 1183 uint inct_cnt = 0; |
1362 uint *inct_starts = NEW_RESOURCE_ARRAY(uint, _cfg->_num_blocks+1); | 1184 uint *inct_starts = NEW_RESOURCE_ARRAY(uint, nblocks+1); |
1363 | 1185 |
1364 // Count and start of calls | 1186 // Count and start of calls |
1365 uint *call_returns = NEW_RESOURCE_ARRAY(uint, _cfg->_num_blocks+1); | 1187 uint *call_returns = NEW_RESOURCE_ARRAY(uint, nblocks+1); |
1366 | 1188 |
1367 uint return_offset = 0; | 1189 uint return_offset = 0; |
1368 int nop_size = (new (this) MachNopNode())->size(_regalloc); | 1190 int nop_size = (new (this) MachNopNode())->size(_regalloc); |
1369 | 1191 |
1370 int previous_offset = 0; | 1192 int previous_offset = 0; |
1371 int current_offset = 0; | 1193 int current_offset = 0; |
1372 #ifdef ASSERT | |
1373 int last_call_offset = -1; | 1194 int last_call_offset = -1; |
1374 int last_avoid_back_to_back_offset = -1; | 1195 int last_avoid_back_to_back_offset = -1; |
1375 #endif | 1196 #ifdef ASSERT |
1197 int block_alignment_padding = 0; | |
1198 | |
1199 uint* jmp_target = NEW_RESOURCE_ARRAY(uint,nblocks); | |
1200 uint* jmp_offset = NEW_RESOURCE_ARRAY(uint,nblocks); | |
1201 uint* jmp_size = NEW_RESOURCE_ARRAY(uint,nblocks); | |
1202 uint* jmp_rule = NEW_RESOURCE_ARRAY(uint,nblocks); | |
1203 #endif | |
1204 | |
1376 // Create an array of unused labels, one for each basic block, if printing is enabled | 1205 // Create an array of unused labels, one for each basic block, if printing is enabled |
1377 #ifndef PRODUCT | 1206 #ifndef PRODUCT |
1378 int *node_offsets = NULL; | 1207 int *node_offsets = NULL; |
1379 uint node_offset_limit = unique(); | 1208 uint node_offset_limit = unique(); |
1380 | 1209 |
1388 if (has_mach_constant_base_node()) { | 1217 if (has_mach_constant_base_node()) { |
1389 constant_table().emit(*cb); | 1218 constant_table().emit(*cb); |
1390 } | 1219 } |
1391 | 1220 |
1392 // Create an array of labels, one for each basic block | 1221 // Create an array of labels, one for each basic block |
1393 Label *blk_labels = NEW_RESOURCE_ARRAY(Label, _cfg->_num_blocks+1); | 1222 Label *blk_labels = NEW_RESOURCE_ARRAY(Label, nblocks+1); |
1394 for (uint i=0; i <= _cfg->_num_blocks; i++) { | 1223 for (uint i=0; i <= nblocks; i++) { |
1395 blk_labels[i].init(); | 1224 blk_labels[i].init(); |
1396 } | 1225 } |
1397 | 1226 |
1398 // ------------------ | 1227 // ------------------ |
1399 // Now fill in the code buffer | 1228 // Now fill in the code buffer |
1400 Node *delay_slot = NULL; | 1229 Node *delay_slot = NULL; |
1401 | 1230 |
1402 for (uint i=0; i < _cfg->_num_blocks; i++) { | 1231 for (uint i=0; i < nblocks; i++) { |
1403 guarantee(blk_starts[i] == (uint)cb->insts_size(),"should not change size"); | 1232 guarantee(blk_starts[i] >= (uint)cb->insts_size(),"should not increase size"); |
1404 | 1233 |
1405 Block *b = _cfg->_blocks[i]; | 1234 Block *b = _cfg->_blocks[i]; |
1406 | 1235 |
1407 Node *head = b->head(); | 1236 Node *head = b->head(); |
1408 | 1237 |
1416 if (!b->is_connector()) { | 1245 if (!b->is_connector()) { |
1417 stringStream st; | 1246 stringStream st; |
1418 b->dump_head(&_cfg->_bbs, &st); | 1247 b->dump_head(&_cfg->_bbs, &st); |
1419 MacroAssembler(cb).block_comment(st.as_string()); | 1248 MacroAssembler(cb).block_comment(st.as_string()); |
1420 } | 1249 } |
1421 #endif | 1250 jmp_target[i] = 0; |
1251 jmp_offset[i] = 0; | |
1252 jmp_size[i] = 0; | |
1253 jmp_rule[i] = 0; | |
1254 | |
1255 // Maximum alignment padding for loop block was used | |
1256 // during first round of branches shortening, as result | |
1257 // padding for nodes (sfpt after call) was not added. | |
1258 // Take this into account for block's size change check | |
1259 // and allow increase block's size by the difference | |
1260 // of maximum and actual alignment paddings. | |
1261 int orig_blk_size = blk_starts[i+1] - blk_starts[i] + block_alignment_padding; | |
1262 #endif | |
1263 int blk_offset = current_offset; | |
1422 | 1264 |
1423 // Define the label at the beginning of the basic block | 1265 // Define the label at the beginning of the basic block |
1424 MacroAssembler(cb).bind(blk_labels[b->_pre_order]); | 1266 MacroAssembler(cb).bind(blk_labels[b->_pre_order]); |
1425 | 1267 |
1426 uint last_inst = b->_nodes.size(); | 1268 uint last_inst = b->_nodes.size(); |
1462 if (is_sfn || is_mcall || mach->alignment_required() != 1) { | 1304 if (is_sfn || is_mcall || mach->alignment_required() != 1) { |
1463 cb->flush_bundle(true); | 1305 cb->flush_bundle(true); |
1464 current_offset = cb->insts_size(); | 1306 current_offset = cb->insts_size(); |
1465 } | 1307 } |
1466 | 1308 |
1467 #ifdef ASSERT | |
1468 // A padding may be needed again since a previous instruction | 1309 // A padding may be needed again since a previous instruction |
1469 // could be moved to delay slot. | 1310 // could be moved to delay slot. |
1470 | 1311 |
1471 // align the instruction if necessary | 1312 // align the instruction if necessary |
1472 int padding = mach->compute_padding(current_offset); | 1313 int padding = mach->compute_padding(current_offset); |
1478 if (padding == 0 && mach->avoid_back_to_back() && | 1319 if (padding == 0 && mach->avoid_back_to_back() && |
1479 current_offset == last_avoid_back_to_back_offset) { | 1320 current_offset == last_avoid_back_to_back_offset) { |
1480 // Avoid back to back some instructions. | 1321 // Avoid back to back some instructions. |
1481 padding = nop_size; | 1322 padding = nop_size; |
1482 } | 1323 } |
1483 assert(padding == 0, "padding should be added already"); | 1324 |
1484 #endif | 1325 if(padding > 0) { |
1326 assert((padding % nop_size) == 0, "padding is not a multiple of NOP size"); | |
1327 int nops_cnt = padding / nop_size; | |
1328 MachNode *nop = new (this) MachNopNode(nops_cnt); | |
1329 b->_nodes.insert(j++, nop); | |
1330 last_inst++; | |
1331 _cfg->_bbs.map( nop->_idx, b ); | |
1332 nop->emit(*cb, _regalloc); | |
1333 cb->flush_bundle(true); | |
1334 current_offset = cb->insts_size(); | |
1335 } | |
1336 | |
1485 // Remember the start of the last call in a basic block | 1337 // Remember the start of the last call in a basic block |
1486 if (is_mcall) { | 1338 if (is_mcall) { |
1487 MachCallNode *mcall = mach->as_MachCall(); | 1339 MachCallNode *mcall = mach->as_MachCall(); |
1488 | 1340 |
1489 // This destination address is NOT PC-relative | 1341 // This destination address is NOT PC-relative |
1526 | 1378 |
1527 // If this is a branch, then fill in the label with the target BB's label | 1379 // If this is a branch, then fill in the label with the target BB's label |
1528 else if (mach->is_MachBranch()) { | 1380 else if (mach->is_MachBranch()) { |
1529 // This requires the TRUE branch target be in succs[0] | 1381 // This requires the TRUE branch target be in succs[0] |
1530 uint block_num = b->non_connector_successor(0)->_pre_order; | 1382 uint block_num = b->non_connector_successor(0)->_pre_order; |
1383 | |
1384 // Try to replace long branch if delay slot is not used, | |
1385 // it is mostly for back branches since forward branch's | |
1386 // distance is not updated yet. | |
1387 bool delay_slot_is_used = valid_bundle_info(n) && | |
1388 node_bundling(n)->use_unconditional_delay(); | |
1389 if (!delay_slot_is_used && mach->may_be_short_branch()) { | |
1390 assert(delay_slot == NULL, "not expecting delay slot node"); | |
1391 int br_size = n->size(_regalloc); | |
1392 int offset = blk_starts[block_num] - current_offset; | |
1393 if (block_num >= i) { | |
1394 // Current and following block's offset are not | |
1395 // finilized yet, adjust distance by the difference | |
1396 // between calculated and final offsets of current block. | |
1397 offset -= (blk_starts[i] - blk_offset); | |
1398 } | |
1399 // In the following code a nop could be inserted before | |
1400 // the branch which will increase the backward distance. | |
1401 bool needs_padding = (current_offset == last_avoid_back_to_back_offset); | |
1402 if (needs_padding && offset <= 0) | |
1403 offset -= nop_size; | |
1404 | |
1405 if (_matcher->is_short_branch_offset(mach->rule(), br_size, offset)) { | |
1406 // We've got a winner. Replace this branch. | |
1407 MachNode* replacement = mach->as_MachBranch()->short_branch_version(this); | |
1408 | |
1409 // Update the jmp_size. | |
1410 int new_size = replacement->size(_regalloc); | |
1411 assert((br_size - new_size) >= (int)nop_size, "short_branch size should be smaller"); | |
1412 // Insert padding between avoid_back_to_back branches. | |
1413 if (needs_padding && replacement->avoid_back_to_back()) { | |
1414 MachNode *nop = new (this) MachNopNode(); | |
1415 b->_nodes.insert(j++, nop); | |
1416 _cfg->_bbs.map(nop->_idx, b); | |
1417 last_inst++; | |
1418 nop->emit(*cb, _regalloc); | |
1419 cb->flush_bundle(true); | |
1420 current_offset = cb->insts_size(); | |
1421 } | |
1422 #ifdef ASSERT | |
1423 jmp_target[i] = block_num; | |
1424 jmp_offset[i] = current_offset - blk_offset; | |
1425 jmp_size[i] = new_size; | |
1426 jmp_rule[i] = mach->rule(); | |
1427 #endif | |
1428 b->_nodes.map(j, replacement); | |
1429 mach->subsume_by(replacement); | |
1430 n = replacement; | |
1431 mach = replacement; | |
1432 } | |
1433 } | |
1531 mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); | 1434 mach->as_MachBranch()->label_set( &blk_labels[block_num], block_num ); |
1532 } else if (mach->ideal_Opcode() == Op_Jump) { | 1435 } else if (mach->ideal_Opcode() == Op_Jump) { |
1533 for (uint h = 0; h < b->_num_succs; h++) { | 1436 for (uint h = 0; h < b->_num_succs; h++) { |
1534 Block* succs_block = b->_succs[h]; | 1437 Block* succs_block = b->_succs[h]; |
1535 for (uint j = 1; j < succs_block->num_preds(); j++) { | 1438 for (uint j = 1; j < succs_block->num_preds(); j++) { |
1589 DEBUG_ONLY( uint instr_offset = cb->insts_size(); ) | 1492 DEBUG_ONLY( uint instr_offset = cb->insts_size(); ) |
1590 n->emit(*cb, _regalloc); | 1493 n->emit(*cb, _regalloc); |
1591 current_offset = cb->insts_size(); | 1494 current_offset = cb->insts_size(); |
1592 | 1495 |
1593 #ifdef ASSERT | 1496 #ifdef ASSERT |
1594 if (n->size(_regalloc) != (current_offset-instr_offset)) { | 1497 if (n->size(_regalloc) < (current_offset-instr_offset)) { |
1595 n->dump(); | 1498 n->dump(); |
1596 assert(n->size(_regalloc) == (current_offset-instr_offset), "wrong size of mach node"); | 1499 assert(false, "wrong size of mach node"); |
1597 } | 1500 } |
1598 #endif | 1501 #endif |
1599 non_safepoints.observe_instruction(n, current_offset); | 1502 non_safepoints.observe_instruction(n, current_offset); |
1600 | 1503 |
1601 #ifdef ASSERT | |
1602 // mcall is last "call" that can be a safepoint | 1504 // mcall is last "call" that can be a safepoint |
1603 // record it so we can see if a poll will directly follow it | 1505 // record it so we can see if a poll will directly follow it |
1604 // in which case we'll need a pad to make the PcDesc sites unique | 1506 // in which case we'll need a pad to make the PcDesc sites unique |
1605 // see 5010568. This can be slightly inaccurate but conservative | 1507 // see 5010568. This can be slightly inaccurate but conservative |
1606 // in the case that return address is not actually at current_offset. | 1508 // in the case that return address is not actually at current_offset. |
1612 | 1514 |
1613 if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) { | 1515 if (n->is_Mach() && n->as_Mach()->avoid_back_to_back()) { |
1614 // Avoid back to back some instructions. | 1516 // Avoid back to back some instructions. |
1615 last_avoid_back_to_back_offset = current_offset; | 1517 last_avoid_back_to_back_offset = current_offset; |
1616 } | 1518 } |
1617 #endif | |
1618 | 1519 |
1619 // See if this instruction has a delay slot | 1520 // See if this instruction has a delay slot |
1620 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { | 1521 if (valid_bundle_info(n) && node_bundling(n)->use_unconditional_delay()) { |
1621 assert(delay_slot != NULL, "expecting delay slot node"); | 1522 assert(delay_slot != NULL, "expecting delay slot node"); |
1622 | 1523 |
1655 // Don't reuse it | 1556 // Don't reuse it |
1656 delay_slot = NULL; | 1557 delay_slot = NULL; |
1657 } | 1558 } |
1658 | 1559 |
1659 } // End for all instructions in block | 1560 } // End for all instructions in block |
1660 #ifdef ASSERT | 1561 assert((uint)blk_offset <= blk_starts[i], "shouldn't increase distance"); |
1562 blk_starts[i] = blk_offset; | |
1563 | |
1661 // If the next block is the top of a loop, pad this block out to align | 1564 // If the next block is the top of a loop, pad this block out to align |
1662 // the loop top a little. Helps prevent pipe stalls at loop back branches. | 1565 // the loop top a little. Helps prevent pipe stalls at loop back branches. |
1663 if (i < _cfg->_num_blocks-1) { | 1566 if (i < nblocks-1) { |
1664 Block *nb = _cfg->_blocks[i+1]; | 1567 Block *nb = _cfg->_blocks[i+1]; |
1665 uint padding = nb->alignment_padding(current_offset); | 1568 int padding = nb->alignment_padding(current_offset); |
1666 assert(padding == 0, "alignment should be added already"); | 1569 if( padding > 0 ) { |
1667 } | 1570 MachNode *nop = new (this) MachNopNode(padding / nop_size); |
1668 #endif | 1571 b->_nodes.insert( b->_nodes.size(), nop ); |
1572 _cfg->_bbs.map( nop->_idx, b ); | |
1573 nop->emit(*cb, _regalloc); | |
1574 current_offset = cb->insts_size(); | |
1575 } | |
1576 #ifdef ASSERT | |
1577 int max_loop_pad = nb->code_alignment()-relocInfo::addr_unit(); | |
1578 block_alignment_padding = (max_loop_pad - padding); | |
1579 assert(block_alignment_padding >= 0, "sanity"); | |
1580 #endif | |
1581 } | |
1582 // Verify that the distance for generated before forward | |
1583 // short branches is still valid. | |
1584 assert(orig_blk_size >= (current_offset - blk_offset), "shouldn't increase block size"); | |
1585 | |
1669 } // End of for all blocks | 1586 } // End of for all blocks |
1587 blk_starts[nblocks] = current_offset; | |
1670 | 1588 |
1671 non_safepoints.flush_at_end(); | 1589 non_safepoints.flush_at_end(); |
1672 | 1590 |
1673 // Offset too large? | 1591 // Offset too large? |
1674 if (failing()) return; | 1592 if (failing()) return; |
1675 | 1593 |
1676 // Define a pseudo-label at the end of the code | 1594 // Define a pseudo-label at the end of the code |
1677 MacroAssembler(cb).bind( blk_labels[_cfg->_num_blocks] ); | 1595 MacroAssembler(cb).bind( blk_labels[nblocks] ); |
1678 | 1596 |
1679 // Compute the size of the first block | 1597 // Compute the size of the first block |
1680 _first_block_size = blk_labels[1].loc_pos() - blk_labels[0].loc_pos(); | 1598 _first_block_size = blk_labels[1].loc_pos() - blk_labels[0].loc_pos(); |
1681 | 1599 |
1682 assert(cb->insts_size() < 500000, "method is unreasonably large"); | 1600 assert(cb->insts_size() < 500000, "method is unreasonably large"); |
1601 | |
1602 #ifdef ASSERT | |
1603 for (uint i = 0; i < nblocks; i++) { // For all blocks | |
1604 if (jmp_target[i] != 0) { | |
1605 int br_size = jmp_size[i]; | |
1606 int offset = blk_starts[jmp_target[i]]-(blk_starts[i] + jmp_offset[i]); | |
1607 if (!_matcher->is_short_branch_offset(jmp_rule[i], br_size, offset)) { | |
1608 tty->print_cr("target (%d) - jmp_offset(%d) = offset (%d), jump_size(%d), jmp_block B%d, target_block B%d", blk_starts[jmp_target[i]], blk_starts[i] + jmp_offset[i], offset, br_size, i, jmp_target[i]); | |
1609 assert(false, "Displacement too large for short jmp"); | |
1610 } | |
1611 } | |
1612 } | |
1613 #endif | |
1683 | 1614 |
1684 // ------------------ | 1615 // ------------------ |
1685 | 1616 |
1686 #ifndef PRODUCT | 1617 #ifndef PRODUCT |
1687 // Information on the size of the method, without the extraneous code | 1618 // Information on the size of the method, without the extraneous code |