< prev index next >

src/share/vm/opto/lcm.cpp

Print this page
rev 6874 : 8059780: SPECjvm2008-MPEG performance regressions on x64 platforms
Summary: Back-out 8052081 changes made in lcm.cpp.
Reviewed-by: iveresov, roland


 467 
 468   uint choice  = 0; // Bigger is most important
 469   uint latency = 0; // Bigger is scheduled first
 470   uint score   = 0; // Bigger is better
 471   int idx = -1;     // Index in worklist
 472   int cand_cnt = 0; // Candidate count
 473 
 474   for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
 475     // Order in worklist is used to break ties.
 476     // See caller for how this is used to delay scheduling
 477     // of induction variable increments to after the other
 478     // uses of the phi are scheduled.
 479     Node *n = worklist[i];      // Get Node on worklist
 480 
 481     int iop = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : 0;
 482     if( n->is_Proj() ||         // Projections always win
 483         n->Opcode()== Op_Con || // So does constant 'Top'
 484         iop == Op_CreateEx ||   // Create-exception must start block
 485         iop == Op_CheckCastPP
 486         ) {
 487       // select the node n
 488       // remove n from worklist and retain the order of remaining nodes
 489       worklist.remove((uint)i);
 490       return n;
 491     }
 492 
 493     // Final call in a block must be adjacent to 'catch'
 494     Node *e = block->end();
 495     if( e->is_Catch() && e->in(0)->in(0) == n )
 496       continue;
 497 
 498     // Memory op for an implicit null check has to be at the end of the block
 499     if( e->is_MachNullCheck() && e->in(1) == n )
 500       continue;
 501 
 502     // Schedule IV increment last.
 503     if (e->is_Mach() && e->as_Mach()->ideal_Opcode() == Op_CountedLoopEnd &&
 504         e->in(1)->in(1) == n && n->is_iteratively_computed())
 505       continue;
 506 
 507     uint n_choice  = 2;
 508 
 509     // See if this instruction is consumed by a branch. If so, then (as the


 555 
 556     // Keep best latency found
 557     cand_cnt++;
 558     if (choice < n_choice ||
 559         (choice == n_choice &&
 560          ((StressLCM && Compile::randomized_select(cand_cnt)) ||
 561           (!StressLCM &&
 562            (latency < n_latency ||
 563             (latency == n_latency &&
 564              (score < n_score))))))) {
 565       choice  = n_choice;
 566       latency = n_latency;
 567       score   = n_score;
 568       idx     = i;               // Also keep index in worklist
 569     }
 570   } // End of for all ready nodes in worklist
 571 
 572   assert(idx >= 0, "index should be set");
 573   Node *n = worklist[(uint)idx];      // Get the winner
 574 
 575   // select the node n
 576   // remove n from worklist and retain the order of remaining nodes
 577   worklist.remove((uint)idx);
 578   return n;
 579 }
 580 
 581 
 582 //------------------------------set_next_call----------------------------------
 583 void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) {
 584   if( next_call.test_set(n->_idx) ) return;
 585   for( uint i=0; i<n->len(); i++ ) {
 586     Node *m = n->in(i);
 587     if( !m ) continue;  // must see all nodes in block that precede call
 588     if (get_block_for_node(m) == block) {
 589       set_next_call(block, m, next_call);
 590     }
 591   }
 592 }
 593 
 594 //------------------------------needed_for_next_call---------------------------
 595 // Set the flag 'next_call' for each Node that is needed for the next call to
 596 // be scheduled.  This flag lets me bias scheduling so Nodes needed for the
 597 // next subroutine call get priority - basically it moves things NOT needed




 467 
 468   uint choice  = 0; // Bigger is most important
 469   uint latency = 0; // Bigger is scheduled first
 470   uint score   = 0; // Bigger is better
 471   int idx = -1;     // Index in worklist
 472   int cand_cnt = 0; // Candidate count
 473 
 474   for( uint i=0; i<cnt; i++ ) { // Inspect entire worklist
 475     // Order in worklist is used to break ties.
 476     // See caller for how this is used to delay scheduling
 477     // of induction variable increments to after the other
 478     // uses of the phi are scheduled.
 479     Node *n = worklist[i];      // Get Node on worklist
 480 
 481     int iop = n->is_Mach() ? n->as_Mach()->ideal_Opcode() : 0;
 482     if( n->is_Proj() ||         // Projections always win
 483         n->Opcode()== Op_Con || // So does constant 'Top'
 484         iop == Op_CreateEx ||   // Create-exception must start block
 485         iop == Op_CheckCastPP
 486         ) {
 487       worklist.map(i,worklist.pop());


 488       return n;
 489     }
 490 
 491     // Final call in a block must be adjacent to 'catch'
 492     Node *e = block->end();
 493     if( e->is_Catch() && e->in(0)->in(0) == n )
 494       continue;
 495 
 496     // Memory op for an implicit null check has to be at the end of the block
 497     if( e->is_MachNullCheck() && e->in(1) == n )
 498       continue;
 499 
 500     // Schedule IV increment last.
 501     if (e->is_Mach() && e->as_Mach()->ideal_Opcode() == Op_CountedLoopEnd &&
 502         e->in(1)->in(1) == n && n->is_iteratively_computed())
 503       continue;
 504 
 505     uint n_choice  = 2;
 506 
 507     // See if this instruction is consumed by a branch. If so, then (as the


 553 
 554     // Keep best latency found
 555     cand_cnt++;
 556     if (choice < n_choice ||
 557         (choice == n_choice &&
 558          ((StressLCM && Compile::randomized_select(cand_cnt)) ||
 559           (!StressLCM &&
 560            (latency < n_latency ||
 561             (latency == n_latency &&
 562              (score < n_score))))))) {
 563       choice  = n_choice;
 564       latency = n_latency;
 565       score   = n_score;
 566       idx     = i;               // Also keep index in worklist
 567     }
 568   } // End of for all ready nodes in worklist
 569 
 570   assert(idx >= 0, "index should be set");
 571   Node *n = worklist[(uint)idx];      // Get the winner
 572 
 573   worklist.map((uint)idx, worklist.pop());     // Compress worklist


 574   return n;
 575 }
 576 
 577 
 578 //------------------------------set_next_call----------------------------------
 579 void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) {
 580   if( next_call.test_set(n->_idx) ) return;
 581   for( uint i=0; i<n->len(); i++ ) {
 582     Node *m = n->in(i);
 583     if( !m ) continue;  // must see all nodes in block that precede call
 584     if (get_block_for_node(m) == block) {
 585       set_next_call(block, m, next_call);
 586     }
 587   }
 588 }
 589 
 590 //------------------------------needed_for_next_call---------------------------
 591 // Set the flag 'next_call' for each Node that is needed for the next call to
 592 // be scheduled.  This flag lets me bias scheduling so Nodes needed for the
 593 // next subroutine call get priority - basically it moves things NOT needed


< prev index next >