src/share/vm/opto/buildOopMap.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File JDK-8022284 Sdiff src/share/vm/opto

src/share/vm/opto/buildOopMap.cpp

Print this page




 409   }
 410 #endif
 411 
 412   return omap;
 413 }
 414 
 415 //------------------------------do_liveness------------------------------------
 416 // Compute backwards liveness on registers
 417 static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *worklist, int max_reg_ints, Arena *A, Dict *safehash ) {
 418   int *live = NEW_ARENA_ARRAY(A, int, (cfg->_num_blocks+1) * max_reg_ints);
 419   int *tmp_live = &live[cfg->_num_blocks * max_reg_ints];
 420   Node *root = cfg->C->root();
 421   // On CISC platforms, get the node representing the stack pointer  that regalloc
 422   // used for spills
 423   Node *fp = NodeSentinel;
 424   if (UseCISCSpill && root->req() > 1) {
 425     fp = root->in(1)->in(TypeFunc::FramePtr);
 426   }
 427   memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) );
 428   // Push preds onto worklist
 429   for( uint i=1; i<root->req(); i++ )
 430     worklist->push(cfg->_bbs[root->in(i)->_idx]);


 431 
 432   // ZKM.jar includes tiny infinite loops which are unreached from below.
 433   // If we missed any blocks, we'll retry here after pushing all missed
 434   // blocks on the worklist.  Normally this outer loop never trips more
 435   // than once.
 436   while( 1 ) {
 437 
 438     while( worklist->size() ) { // Standard worklist algorithm
 439       Block *b = worklist->rpop();
 440 
 441       // Copy first successor into my tmp_live space
 442       int s0num = b->_succs[0]->_pre_order;
 443       int *t = &live[s0num*max_reg_ints];
 444       for( int i=0; i<max_reg_ints; i++ )
 445         tmp_live[i] = t[i];
 446 
 447       // OR in the remaining live registers
 448       for( uint j=1; j<b->_num_succs; j++ ) {
 449         uint sjnum = b->_succs[j]->_pre_order;
 450         int *t = &live[sjnum*max_reg_ints];
 451         for( int i=0; i<max_reg_ints; i++ )
 452           tmp_live[i] |= t[i];
 453       }
 454 
 455       // Now walk tmp_live up the block backwards, computing live
 456       for( int k=b->_nodes.size()-1; k>=0; k-- ) {


 520           int *n_live = NEW_ARENA_ARRAY(A, int, max_reg_ints);
 521           for( int l=0; l<max_reg_ints; l++ )
 522             n_live[l] = tmp_live[l];
 523           safehash->Insert(n,n_live);
 524         }
 525 
 526       }
 527 
 528       // Now at block top, see if we have any changes.  If so, propagate
 529       // to prior blocks.
 530       int *old_live = &live[b->_pre_order*max_reg_ints];
 531       int l;
 532       for( l=0; l<max_reg_ints; l++ )
 533         if( tmp_live[l] != old_live[l] )
 534           break;
 535       if( l<max_reg_ints ) {     // Change!
 536         // Copy in new value
 537         for( l=0; l<max_reg_ints; l++ )
 538           old_live[l] = tmp_live[l];
 539         // Push preds onto worklist
 540         for( l=1; l<(int)b->num_preds(); l++ )
 541           worklist->push(cfg->_bbs[b->pred(l)->_idx]);


 542       }
 543     }
 544 
 545     // Scan for any missing safepoints.  Happens to infinite loops
 546     // ala ZKM.jar
 547     uint i;
 548     for( i=1; i<cfg->_num_blocks; i++ ) {
 549       Block *b = cfg->_blocks[i];
 550       uint j;
 551       for( j=1; j<b->_nodes.size(); j++ )
 552         if( b->_nodes[j]->jvms() &&
 553             (*safehash)[b->_nodes[j]] == NULL )
 554            break;
 555       if( j<b->_nodes.size() ) break;
 556     }
 557     if( i == cfg->_num_blocks )
 558       break;                    // Got 'em all
 559 #ifndef PRODUCT
 560     if( PrintOpto && Verbose )
 561       tty->print_cr("retripping live calc");


 612     // Scan for a block with all predecessors visited, or any randoms slob
 613     // otherwise.  All-preds-visited order allows me to recycle OopFlow
 614     // structures rapidly and cut down on the memory footprint.
 615     // Note: not all predecessors might be visited yet (must happen for
 616     // irreducible loops).  This is OK, since every live value must have the
 617     // SAME reaching def for the block, so any reaching def is OK.
 618     uint i;
 619 
 620     Block *b = worklist.pop();
 621     // Ignore root block
 622     if( b == _cfg->_broot ) continue;
 623     // Block is already done?  Happens if block has several predecessors,
 624     // he can get on the worklist more than once.
 625     if( flows[b->_pre_order] ) continue;
 626 
 627     // If this block has a visited predecessor AND that predecessor has this
 628     // last block as his only undone child, we can move the OopFlow from the
 629     // pred to this block.  Otherwise we have to grab a new OopFlow.
 630     OopFlow *flow = NULL;       // Flag for finding optimized flow
 631     Block *pred = (Block*)0xdeadbeef;
 632     uint j;
 633     // Scan this block's preds to find a done predecessor
 634     for( j=1; j<b->num_preds(); j++ ) {
 635       Block *p = _cfg->_bbs[b->pred(j)->_idx];
 636       OopFlow *p_flow = flows[p->_pre_order];
 637       if( p_flow ) {            // Predecessor is done
 638         assert( p_flow->_b == p, "cross check" );
 639         pred = p;               // Record some predecessor
 640         // If all successors of p are done except for 'b', then we can carry
 641         // p_flow forward to 'b' without copying, otherwise we have to draw
 642         // from the free_list and clone data.
 643         uint k;
 644         for( k=0; k<p->_num_succs; k++ )
 645           if( !flows[p->_succs[k]->_pre_order] &&
 646               p->_succs[k] != b )
 647             break;
 648 
 649         // Either carry-forward the now-unused OopFlow for b's use
 650         // or draw a new one from the free list
 651         if( k==p->_num_succs ) {
 652           flow = p_flow;
 653           break;                // Found an ideal pred, use him
 654         }
 655       }




 409   }
 410 #endif
 411 
 412   return omap;
 413 }
 414 
 415 //------------------------------do_liveness------------------------------------
 416 // Compute backwards liveness on registers
 417 static void do_liveness( PhaseRegAlloc *regalloc, PhaseCFG *cfg, Block_List *worklist, int max_reg_ints, Arena *A, Dict *safehash ) {
 418   int *live = NEW_ARENA_ARRAY(A, int, (cfg->_num_blocks+1) * max_reg_ints);
 419   int *tmp_live = &live[cfg->_num_blocks * max_reg_ints];
 420   Node *root = cfg->C->root();
 421   // On CISC platforms, get the node representing the stack pointer  that regalloc
 422   // used for spills
 423   Node *fp = NodeSentinel;
 424   if (UseCISCSpill && root->req() > 1) {
 425     fp = root->in(1)->in(TypeFunc::FramePtr);
 426   }
 427   memset( live, 0, cfg->_num_blocks * (max_reg_ints<<LogBytesPerInt) );
 428   // Push preds onto worklist
 429   for (uint i = 1; i < root->req(); i++) {
 430     Block* block = cfg->get_block_for_node(root->in(i));
 431     worklist->push(block);
 432   }
 433 
 434   // ZKM.jar includes tiny infinite loops which are unreached from below.
 435   // If we missed any blocks, we'll retry here after pushing all missed
 436   // blocks on the worklist.  Normally this outer loop never trips more
 437   // than once.
 438   while (1) {
 439 
 440     while( worklist->size() ) { // Standard worklist algorithm
 441       Block *b = worklist->rpop();
 442 
 443       // Copy first successor into my tmp_live space
 444       int s0num = b->_succs[0]->_pre_order;
 445       int *t = &live[s0num*max_reg_ints];
 446       for( int i=0; i<max_reg_ints; i++ )
 447         tmp_live[i] = t[i];
 448 
 449       // OR in the remaining live registers
 450       for( uint j=1; j<b->_num_succs; j++ ) {
 451         uint sjnum = b->_succs[j]->_pre_order;
 452         int *t = &live[sjnum*max_reg_ints];
 453         for( int i=0; i<max_reg_ints; i++ )
 454           tmp_live[i] |= t[i];
 455       }
 456 
 457       // Now walk tmp_live up the block backwards, computing live
 458       for( int k=b->_nodes.size()-1; k>=0; k-- ) {


 522           int *n_live = NEW_ARENA_ARRAY(A, int, max_reg_ints);
 523           for( int l=0; l<max_reg_ints; l++ )
 524             n_live[l] = tmp_live[l];
 525           safehash->Insert(n,n_live);
 526         }
 527 
 528       }
 529 
 530       // Now at block top, see if we have any changes.  If so, propagate
 531       // to prior blocks.
 532       int *old_live = &live[b->_pre_order*max_reg_ints];
 533       int l;
 534       for( l=0; l<max_reg_ints; l++ )
 535         if( tmp_live[l] != old_live[l] )
 536           break;
 537       if( l<max_reg_ints ) {     // Change!
 538         // Copy in new value
 539         for( l=0; l<max_reg_ints; l++ )
 540           old_live[l] = tmp_live[l];
 541         // Push preds onto worklist
 542         for (l = 1; l < (int)b->num_preds(); l++) {
 543           Block* block = cfg->get_block_for_node(b->pred(l));
 544           worklist->push(block);
 545         }
 546       }
 547     }
 548 
 549     // Scan for any missing safepoints.  Happens to infinite loops
 550     // ala ZKM.jar
 551     uint i;
 552     for( i=1; i<cfg->_num_blocks; i++ ) {
 553       Block *b = cfg->_blocks[i];
 554       uint j;
 555       for( j=1; j<b->_nodes.size(); j++ )
 556         if( b->_nodes[j]->jvms() &&
 557             (*safehash)[b->_nodes[j]] == NULL )
 558            break;
 559       if( j<b->_nodes.size() ) break;
 560     }
 561     if( i == cfg->_num_blocks )
 562       break;                    // Got 'em all
 563 #ifndef PRODUCT
 564     if( PrintOpto && Verbose )
 565       tty->print_cr("retripping live calc");


 616     // Scan for a block with all predecessors visited, or any randoms slob
 617     // otherwise.  All-preds-visited order allows me to recycle OopFlow
 618     // structures rapidly and cut down on the memory footprint.
 619     // Note: not all predecessors might be visited yet (must happen for
 620     // irreducible loops).  This is OK, since every live value must have the
 621     // SAME reaching def for the block, so any reaching def is OK.
 622     uint i;
 623 
 624     Block *b = worklist.pop();
 625     // Ignore root block
 626     if( b == _cfg->_broot ) continue;
 627     // Block is already done?  Happens if block has several predecessors,
 628     // he can get on the worklist more than once.
 629     if( flows[b->_pre_order] ) continue;
 630 
 631     // If this block has a visited predecessor AND that predecessor has this
 632     // last block as his only undone child, we can move the OopFlow from the
 633     // pred to this block.  Otherwise we have to grab a new OopFlow.
 634     OopFlow *flow = NULL;       // Flag for finding optimized flow
 635     Block *pred = (Block*)0xdeadbeef;

 636     // Scan this block's preds to find a done predecessor
 637     for (uint j = 1; j < b->num_preds(); j++) {
 638       Block* p = _cfg->get_block_for_node(b->pred(j));
 639       OopFlow *p_flow = flows[p->_pre_order];
 640       if( p_flow ) {            // Predecessor is done
 641         assert( p_flow->_b == p, "cross check" );
 642         pred = p;               // Record some predecessor
 643         // If all successors of p are done except for 'b', then we can carry
 644         // p_flow forward to 'b' without copying, otherwise we have to draw
 645         // from the free_list and clone data.
 646         uint k;
 647         for( k=0; k<p->_num_succs; k++ )
 648           if( !flows[p->_succs[k]->_pre_order] &&
 649               p->_succs[k] != b )
 650             break;
 651 
 652         // Either carry-forward the now-unused OopFlow for b's use
 653         // or draw a new one from the free list
 654         if( k==p->_num_succs ) {
 655           flow = p_flow;
 656           break;                // Found an ideal pred, use him
 657         }
 658       }


src/share/vm/opto/buildOopMap.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File