//------------------------------set_next_call---------------------------------- void Block::set_next_call( Node *n, VectorSet &next_call, Block_Array &bbs ) { if( next_call.test_set(n->_idx) ) return; for( uint i=0; i<n->len(); i++ ) { Node *m = n->in(i); if( !m ) continue; // must see all nodes in block that precede call if( bbs[m->_idx] == this ) set_next_call( m, next_call, bbs ); } }
//------------------------------set_next_call---------------------------------- void PhaseCFG::set_next_call(Block* block, Node* n, VectorSet& next_call) { if( next_call.test_set(n->_idx) ) return; for( uint i=0; i<n->len(); i++ ) { Node *m = n->in(i); if( !m ) continue; // must see all nodes in block that precede call if (get_block_for_node(m) == block) { set_next_call(block, m, next_call); } } }
//------------------------------needed_for_next_call--------------------------- // Set the flag 'next_call' for each Node that is needed for the next call to // be scheduled. This flag lets me bias scheduling so Nodes needed for the // next subroutine call get priority - basically it moves things NOT needed // for the next call till after the call. This prevents me from trying to // carry lots of stuff live across a call. void Block::needed_for_next_call(Node *this_call, VectorSet &next_call, Block_Array &bbs) { // Find the next control-defining Node in this block Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); if( bbs[m->_idx] == this && // Local-block user m != this_call && // Not self-start node m->is_Call() ) call = m; break; } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call set_next_call(call, next_call, bbs); }
//------------------------------needed_for_next_call--------------------------- // Set the flag 'next_call' for each Node that is needed for the next call to // be scheduled. This flag lets me bias scheduling so Nodes needed for the // next subroutine call get priority - basically it moves things NOT needed // for the next call till after the call. This prevents me from trying to // carry lots of stuff live across a call. void PhaseCFG::needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call) { // Find the next control-defining Node in this block Node* call = NULL; for (DUIterator_Fast imax, i = this_call->fast_outs(imax); i < imax; i++) { Node* m = this_call->fast_out(i); if (get_block_for_node(m) == block && // Local-block user m != this_call && // Not self-start node m->is_MachCall()) { call = m; break; } } if (call == NULL) return; // No next call (e.g., block end is near) // Set next-call for all inputs to this call set_next_call(block, call, next_call); }