Mercurial > hg > graal-compiler
comparison src/share/vm/opto/postaloc.cpp @ 12071:adb9a7d94cb5
8023003: Cleanup the public interface to PhaseCFG
Summary: public methods that don't need to be public should be private.
Reviewed-by: kvn, twisti
author | adlertz |
---|---|
date | Fri, 16 Aug 2013 10:23:55 +0200 |
parents | d1034bd8cefc |
children | 650868c062a9 |
comparison
equal
deleted
inserted
replaced
12070:afbe18ae0905 | 12071:adb9a7d94cb5 |
---|---|
403 NOT_PRODUCT( Compile::TracePhase t3("postAllocCopyRemoval", &_t_postAllocCopyRemoval, TimeCompiler); ) | 403 NOT_PRODUCT( Compile::TracePhase t3("postAllocCopyRemoval", &_t_postAllocCopyRemoval, TimeCompiler); ) |
404 ResourceMark rm; | 404 ResourceMark rm; |
405 | 405 |
406 // Need a mapping from basic block Node_Lists. We need a Node_List to | 406 // Need a mapping from basic block Node_Lists. We need a Node_List to |
407 // map from register number to value-producing Node. | 407 // map from register number to value-producing Node. |
408 Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1); | 408 Node_List **blk2value = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1); |
409 memset( blk2value, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) ); | 409 memset(blk2value, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1)); |
410 // Need a mapping from basic block Node_Lists. We need a Node_List to | 410 // Need a mapping from basic block Node_Lists. We need a Node_List to |
411 // map from register number to register-defining Node. | 411 // map from register number to register-defining Node. |
412 Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg._num_blocks+1); | 412 Node_List **blk2regnd = NEW_RESOURCE_ARRAY( Node_List *, _cfg.number_of_blocks() + 1); |
413 memset( blk2regnd, 0, sizeof(Node_List*)*(_cfg._num_blocks+1) ); | 413 memset(blk2regnd, 0, sizeof(Node_List*) * (_cfg.number_of_blocks() + 1)); |
414 | 414 |
415 // We keep unused Node_Lists on a free_list to avoid wasting | 415 // We keep unused Node_Lists on a free_list to avoid wasting |
416 // memory. | 416 // memory. |
417 GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16); | 417 GrowableArray<Node_List*> free_list = GrowableArray<Node_List*>(16); |
418 | 418 |
419 // For all blocks | 419 // For all blocks |
420 for( uint i = 0; i < _cfg._num_blocks; i++ ) { | 420 for (uint i = 0; i < _cfg.number_of_blocks(); i++) { |
421 uint j; | 421 uint j; |
422 Block *b = _cfg._blocks[i]; | 422 Block* block = _cfg.get_block(i); |
423 | 423 |
424 // Count of Phis in block | 424 // Count of Phis in block |
425 uint phi_dex; | 425 uint phi_dex; |
426 for( phi_dex = 1; phi_dex < b->_nodes.size(); phi_dex++ ) { | 426 for (phi_dex = 1; phi_dex < block->_nodes.size(); phi_dex++) { |
427 Node *phi = b->_nodes[phi_dex]; | 427 Node* phi = block->_nodes[phi_dex]; |
428 if( !phi->is_Phi() ) | 428 if (!phi->is_Phi()) { |
429 break; | 429 break; |
430 } | |
430 } | 431 } |
431 | 432 |
432 // If any predecessor has not been visited, we do not know the state | 433 // If any predecessor has not been visited, we do not know the state |
433 // of registers at the start. Check for this, while updating copies | 434 // of registers at the start. Check for this, while updating copies |
434 // along Phi input edges | 435 // along Phi input edges |
435 bool missing_some_inputs = false; | 436 bool missing_some_inputs = false; |
436 Block *freed = NULL; | 437 Block *freed = NULL; |
437 for( j = 1; j < b->num_preds(); j++ ) { | 438 for (j = 1; j < block->num_preds(); j++) { |
438 Block *pb = _cfg.get_block_for_node(b->pred(j)); | 439 Block* pb = _cfg.get_block_for_node(block->pred(j)); |
439 // Remove copies along phi edges | 440 // Remove copies along phi edges |
440 for( uint k=1; k<phi_dex; k++ ) | 441 for (uint k = 1; k < phi_dex; k++) { |
441 elide_copy( b->_nodes[k], j, b, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false ); | 442 elide_copy(block->_nodes[k], j, block, *blk2value[pb->_pre_order], *blk2regnd[pb->_pre_order], false); |
442 if( blk2value[pb->_pre_order] ) { // Have a mapping on this edge? | 443 } |
444 if (blk2value[pb->_pre_order]) { // Have a mapping on this edge? | |
443 // See if this predecessor's mappings have been used by everybody | 445 // See if this predecessor's mappings have been used by everybody |
444 // who wants them. If so, free 'em. | 446 // who wants them. If so, free 'em. |
445 uint k; | 447 uint k; |
446 for( k=0; k<pb->_num_succs; k++ ) { | 448 for (k = 0; k < pb->_num_succs; k++) { |
447 Block *pbsucc = pb->_succs[k]; | 449 Block* pbsucc = pb->_succs[k]; |
448 if( !blk2value[pbsucc->_pre_order] && pbsucc != b ) | 450 if (!blk2value[pbsucc->_pre_order] && pbsucc != block) { |
449 break; // Found a future user | 451 break; // Found a future user |
450 } | 452 } |
451 if( k >= pb->_num_succs ) { // No more uses, free! | 453 } |
454 if (k >= pb->_num_succs) { // No more uses, free! | |
452 freed = pb; // Record last block freed | 455 freed = pb; // Record last block freed |
453 free_list.push(blk2value[pb->_pre_order]); | 456 free_list.push(blk2value[pb->_pre_order]); |
454 free_list.push(blk2regnd[pb->_pre_order]); | 457 free_list.push(blk2regnd[pb->_pre_order]); |
455 } | 458 } |
456 } else { // This block has unvisited (loopback) inputs | 459 } else { // This block has unvisited (loopback) inputs |
465 Node_List &value = *(free_list.is_empty() ? new Node_List() : free_list.pop()); | 468 Node_List &value = *(free_list.is_empty() ? new Node_List() : free_list.pop()); |
466 assert( !freed || blk2value[freed->_pre_order] == &value, "" ); | 469 assert( !freed || blk2value[freed->_pre_order] == &value, "" ); |
467 value.map(_max_reg,NULL); | 470 value.map(_max_reg,NULL); |
468 regnd.map(_max_reg,NULL); | 471 regnd.map(_max_reg,NULL); |
469 // Set mappings as OUR mappings | 472 // Set mappings as OUR mappings |
470 blk2value[b->_pre_order] = &value; | 473 blk2value[block->_pre_order] = &value; |
471 blk2regnd[b->_pre_order] = ®nd; | 474 blk2regnd[block->_pre_order] = ®nd; |
472 | 475 |
473 // Initialize value & regnd for this block | 476 // Initialize value & regnd for this block |
474 if( missing_some_inputs ) { | 477 if (missing_some_inputs) { |
475 // Some predecessor has not yet been visited; zap map to empty | 478 // Some predecessor has not yet been visited; zap map to empty |
476 for( uint k = 0; k < (uint)_max_reg; k++ ) { | 479 for (uint k = 0; k < (uint)_max_reg; k++) { |
477 value.map(k,NULL); | 480 value.map(k,NULL); |
478 regnd.map(k,NULL); | 481 regnd.map(k,NULL); |
479 } | 482 } |
480 } else { | 483 } else { |
481 if( !freed ) { // Didn't get a freebie prior block | 484 if( !freed ) { // Didn't get a freebie prior block |
482 // Must clone some data | 485 // Must clone some data |
483 freed = _cfg.get_block_for_node(b->pred(1)); | 486 freed = _cfg.get_block_for_node(block->pred(1)); |
484 Node_List &f_value = *blk2value[freed->_pre_order]; | 487 Node_List &f_value = *blk2value[freed->_pre_order]; |
485 Node_List &f_regnd = *blk2regnd[freed->_pre_order]; | 488 Node_List &f_regnd = *blk2regnd[freed->_pre_order]; |
486 for( uint k = 0; k < (uint)_max_reg; k++ ) { | 489 for( uint k = 0; k < (uint)_max_reg; k++ ) { |
487 value.map(k,f_value[k]); | 490 value.map(k,f_value[k]); |
488 regnd.map(k,f_regnd[k]); | 491 regnd.map(k,f_regnd[k]); |
489 } | 492 } |
490 } | 493 } |
491 // Merge all inputs together, setting to NULL any conflicts. | 494 // Merge all inputs together, setting to NULL any conflicts. |
492 for( j = 1; j < b->num_preds(); j++ ) { | 495 for (j = 1; j < block->num_preds(); j++) { |
493 Block *pb = _cfg.get_block_for_node(b->pred(j)); | 496 Block* pb = _cfg.get_block_for_node(block->pred(j)); |
494 if( pb == freed ) continue; // Did self already via freelist | 497 if (pb == freed) { |
498 continue; // Did self already via freelist | |
499 } | |
495 Node_List &p_regnd = *blk2regnd[pb->_pre_order]; | 500 Node_List &p_regnd = *blk2regnd[pb->_pre_order]; |
496 for( uint k = 0; k < (uint)_max_reg; k++ ) { | 501 for( uint k = 0; k < (uint)_max_reg; k++ ) { |
497 if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs? | 502 if( regnd[k] != p_regnd[k] ) { // Conflict on reaching defs? |
498 value.map(k,NULL); // Then no value handy | 503 value.map(k,NULL); // Then no value handy |
499 regnd.map(k,NULL); | 504 regnd.map(k,NULL); |
501 } | 506 } |
502 } | 507 } |
503 } | 508 } |
504 | 509 |
505 // For all Phi's | 510 // For all Phi's |
506 for( j = 1; j < phi_dex; j++ ) { | 511 for (j = 1; j < phi_dex; j++) { |
507 uint k; | 512 uint k; |
508 Node *phi = b->_nodes[j]; | 513 Node *phi = block->_nodes[j]; |
509 uint pidx = _lrg_map.live_range_id(phi); | 514 uint pidx = _lrg_map.live_range_id(phi); |
510 OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg(); | 515 OptoReg::Name preg = lrgs(_lrg_map.live_range_id(phi)).reg(); |
511 | 516 |
512 // Remove copies remaining on edges. Check for junk phi. | 517 // Remove copies remaining on edges. Check for junk phi. |
513 Node *u = NULL; | 518 Node *u = NULL; |
514 for (k = 1; k < phi->req(); k++) { | 519 for (k = 1; k < phi->req(); k++) { |
515 Node *x = phi->in(k); | 520 Node *x = phi->in(k); |
516 if( phi != x && u != x ) // Found a different input | 521 if( phi != x && u != x ) // Found a different input |
517 u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input | 522 u = u ? NodeSentinel : x; // Capture unique input, or NodeSentinel for 2nd input |
518 } | 523 } |
519 if( u != NodeSentinel ) { // Junk Phi. Remove | 524 if (u != NodeSentinel) { // Junk Phi. Remove |
520 b->_nodes.remove(j--); | 525 block->_nodes.remove(j--); |
521 phi_dex--; | 526 phi_dex--; |
522 _cfg.unmap_node_from_block(phi); | 527 _cfg.unmap_node_from_block(phi); |
523 phi->replace_by(u); | 528 phi->replace_by(u); |
524 phi->disconnect_inputs(NULL, C); | 529 phi->disconnect_inputs(NULL, C); |
525 continue; | 530 continue; |
545 } | 550 } |
546 } | 551 } |
547 } | 552 } |
548 | 553 |
549 // For all remaining instructions | 554 // For all remaining instructions |
550 for( j = phi_dex; j < b->_nodes.size(); j++ ) { | 555 for (j = phi_dex; j < block->_nodes.size(); j++) { |
551 Node *n = b->_nodes[j]; | 556 Node* n = block->_nodes[j]; |
552 | 557 |
553 if( n->outcnt() == 0 && // Dead? | 558 if(n->outcnt() == 0 && // Dead? |
554 n != C->top() && // (ignore TOP, it has no du info) | 559 n != C->top() && // (ignore TOP, it has no du info) |
555 !n->is_Proj() ) { // fat-proj kills | 560 !n->is_Proj() ) { // fat-proj kills |
556 j -= yank_if_dead(n,b,&value,®nd); | 561 j -= yank_if_dead(n, block, &value, ®nd); |
557 continue; | 562 continue; |
558 } | 563 } |
559 | 564 |
560 // Improve reaching-def info. Occasionally post-alloc's liveness gives | 565 // Improve reaching-def info. Occasionally post-alloc's liveness gives |
561 // up (at loop backedges, because we aren't doing a full flow pass). | 566 // up (at loop backedges, because we aren't doing a full flow pass). |
596 } | 601 } |
597 | 602 |
598 const uint two_adr = n->is_Mach() ? n->as_Mach()->two_adr() : 0; | 603 const uint two_adr = n->is_Mach() ? n->as_Mach()->two_adr() : 0; |
599 | 604 |
600 // Remove copies along input edges | 605 // Remove copies along input edges |
601 for( k = 1; k < n->req(); k++ ) | 606 for (k = 1; k < n->req(); k++) { |
602 j -= elide_copy( n, k, b, value, regnd, two_adr!=k ); | 607 j -= elide_copy(n, k, block, value, regnd, two_adr != k); |
608 } | |
603 | 609 |
604 // Unallocated Nodes define no registers | 610 // Unallocated Nodes define no registers |
605 uint lidx = _lrg_map.live_range_id(n); | 611 uint lidx = _lrg_map.live_range_id(n); |
606 if (!lidx) { | 612 if (!lidx) { |
607 continue; | 613 continue; |
628 if (n_regs == 1) { | 634 if (n_regs == 1) { |
629 // If Node 'n' does not change the value mapped by the register, | 635 // If Node 'n' does not change the value mapped by the register, |
630 // then 'n' is a useless copy. Do not update the register->node | 636 // then 'n' is a useless copy. Do not update the register->node |
631 // mapping so 'n' will go dead. | 637 // mapping so 'n' will go dead. |
632 if( value[nreg] != val ) { | 638 if( value[nreg] != val ) { |
633 if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) { | 639 if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, OptoReg::Bad)) { |
634 j -= replace_and_yank_if_dead(n, nreg, b, value, regnd); | 640 j -= replace_and_yank_if_dead(n, nreg, block, value, regnd); |
635 } else { | 641 } else { |
636 // Update the mapping: record new Node defined by the register | 642 // Update the mapping: record new Node defined by the register |
637 regnd.map(nreg,n); | 643 regnd.map(nreg,n); |
638 // Update mapping for defined *value*, which is the defined | 644 // Update mapping for defined *value*, which is the defined |
639 // Node after skipping all copies. | 645 // Node after skipping all copies. |
640 value.map(nreg,val); | 646 value.map(nreg,val); |
641 } | 647 } |
642 } else if( !may_be_copy_of_callee(n) ) { | 648 } else if( !may_be_copy_of_callee(n) ) { |
643 assert( n->is_Copy(), "" ); | 649 assert(n->is_Copy(), ""); |
644 j -= replace_and_yank_if_dead(n, nreg, b, value, regnd); | 650 j -= replace_and_yank_if_dead(n, nreg, block, value, regnd); |
645 } | 651 } |
646 } else if (RegMask::is_vector(n_ideal_reg)) { | 652 } else if (RegMask::is_vector(n_ideal_reg)) { |
647 // If Node 'n' does not change the value mapped by the register, | 653 // If Node 'n' does not change the value mapped by the register, |
648 // then 'n' is a useless copy. Do not update the register->node | 654 // then 'n' is a useless copy. Do not update the register->node |
649 // mapping so 'n' will go dead. | 655 // mapping so 'n' will go dead. |
658 regnd.map(nreg_lo, n ); | 664 regnd.map(nreg_lo, n ); |
659 value.map(nreg_lo,val); | 665 value.map(nreg_lo,val); |
660 } | 666 } |
661 } else if (n->is_Copy()) { | 667 } else if (n->is_Copy()) { |
662 // Note: vector can't be constant and can't be copy of calee. | 668 // Note: vector can't be constant and can't be copy of calee. |
663 j -= replace_and_yank_if_dead(n, nreg, b, value, regnd); | 669 j -= replace_and_yank_if_dead(n, nreg, block, value, regnd); |
664 } | 670 } |
665 } else { | 671 } else { |
666 // If the value occupies a register pair, record same info | 672 // If the value occupies a register pair, record same info |
667 // in both registers. | 673 // in both registers. |
668 OptoReg::Name nreg_lo = OptoReg::add(nreg,-1); | 674 OptoReg::Name nreg_lo = OptoReg::add(nreg,-1); |
672 // Find the actual other value | 678 // Find the actual other value |
673 RegMask tmp = lrgs(lidx).mask(); | 679 RegMask tmp = lrgs(lidx).mask(); |
674 tmp.Remove(nreg); | 680 tmp.Remove(nreg); |
675 nreg_lo = tmp.find_first_elem(); | 681 nreg_lo = tmp.find_first_elem(); |
676 } | 682 } |
677 if( value[nreg] != val || value[nreg_lo] != val ) { | 683 if (value[nreg] != val || value[nreg_lo] != val) { |
678 if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) { | 684 if (eliminate_copy_of_constant(val, n, block, value, regnd, nreg, nreg_lo)) { |
679 j -= replace_and_yank_if_dead(n, nreg, b, value, regnd); | 685 j -= replace_and_yank_if_dead(n, nreg, block, value, regnd); |
680 } else { | 686 } else { |
681 regnd.map(nreg , n ); | 687 regnd.map(nreg , n ); |
682 regnd.map(nreg_lo, n ); | 688 regnd.map(nreg_lo, n ); |
683 value.map(nreg ,val); | 689 value.map(nreg ,val); |
684 value.map(nreg_lo,val); | 690 value.map(nreg_lo,val); |
685 } | 691 } |
686 } else if( !may_be_copy_of_callee(n) ) { | 692 } else if (!may_be_copy_of_callee(n)) { |
687 assert( n->is_Copy(), "" ); | 693 assert(n->is_Copy(), ""); |
688 j -= replace_and_yank_if_dead(n, nreg, b, value, regnd); | 694 j -= replace_and_yank_if_dead(n, nreg, block, value, regnd); |
689 } | 695 } |
690 } | 696 } |
691 | 697 |
692 // Fat projections kill many registers | 698 // Fat projections kill many registers |
693 if( n_ideal_reg == MachProjNode::fat_proj ) { | 699 if( n_ideal_reg == MachProjNode::fat_proj ) { |