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
|