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

src/share/vm/opto/block.cpp

Print this page

        

*** 219,229 **** } //------------------------------is_uncommon------------------------------------ // True if block is low enough frequency or guarded by a test which // mostly does not go here. ! bool Block::is_uncommon( Block_Array &bbs ) const { // Initial blocks must never be moved, so are never uncommon. if (head()->is_Root() || head()->is_Start()) return false; // Check for way-low freq if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; --- 219,229 ---- } //------------------------------is_uncommon------------------------------------ // True if block is low enough frequency or guarded by a test which // mostly does not go here. ! bool Block::is_uncommon(PhaseCFG* cfg) const { // Initial blocks must never be moved, so are never uncommon. if (head()->is_Root() || head()->is_Start()) return false; // Check for way-low freq if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true;
*** 236,246 **** uint uncommon_preds = 0; uint freq_preds = 0; uint uncommon_for_freq_preds = 0; for( uint i=1; i<num_preds(); i++ ) { ! Block* guard = bbs[pred(i)->_idx]; // Check to see if this block follows its guard 1 time out of 10000 // or less. // // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which // we intend to be "uncommon", such as slow-path TLE allocation, --- 236,246 ---- uint uncommon_preds = 0; uint freq_preds = 0; uint uncommon_for_freq_preds = 0; for( uint i=1; i<num_preds(); i++ ) { ! Block* guard = cfg->get_block_for_node(pred(i)); // Check to see if this block follows its guard 1 time out of 10000 // or less. // // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which // we intend to be "uncommon", such as slow-path TLE allocation,
*** 283,305 **** orig->dump_bidx(orig, st); st->print(")"); } } ! void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const { if (is_connector()) { for (uint i=1; i<num_preds(); i++) { ! Block *p = ((*bbs)[pred(i)->_idx]); ! p->dump_pred(bbs, orig, st); } } else { dump_bidx(orig, st); st->print(" "); } } ! void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { // Print the basic block dump_bidx(this, st); st->print(": #\t"); // Print the incoming CFG edges and the outgoing CFG edges --- 283,305 ---- orig->dump_bidx(orig, st); st->print(")"); } } ! void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const { if (is_connector()) { for (uint i=1; i<num_preds(); i++) { ! Block *p = cfg->get_block_for_node(pred(i)); ! p->dump_pred(cfg, orig, st); } } else { dump_bidx(orig, st); st->print(" "); } } ! void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { // Print the basic block dump_bidx(this, st); st->print(": #\t"); // Print the incoming CFG edges and the outgoing CFG edges
*** 309,338 **** } st->print("<- "); if( head()->is_block_start() ) { for (uint i=1; i<num_preds(); i++) { Node *s = pred(i); ! if (bbs) { ! Block *p = (*bbs)[s->_idx]; ! p->dump_pred(bbs, p, st); } else { while (!s->is_block_start()) s = s->in(0); st->print("N%d ", s->_idx ); } } ! } else st->print("BLOCK HEAD IS JUNK "); // Print loop, if any const Block *bhead = this; // Head of self-loop Node *bh = bhead->head(); ! if( bbs && bh->is_Loop() && !head()->is_Root() ) { LoopNode *loop = bh->as_Loop(); ! const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; while (bx->is_connector()) { ! bx = (*bbs)[bx->pred(1)->_idx]; } st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); // Dump any loop-specific bits, especially for CountedLoops. loop->dump_spec(st); } else if (has_loop_alignment()) { --- 309,340 ---- } st->print("<- "); if( head()->is_block_start() ) { for (uint i=1; i<num_preds(); i++) { Node *s = pred(i); ! if (cfg != NULL) { ! Block *p = cfg->get_block_for_node(s); ! p->dump_pred(cfg, p, st); } else { while (!s->is_block_start()) s = s->in(0); st->print("N%d ", s->_idx ); } } ! } else { st->print("BLOCK HEAD IS JUNK "); + } // Print loop, if any const Block *bhead = this; // Head of self-loop Node *bh = bhead->head(); ! ! if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) { LoopNode *loop = bh->as_Loop(); ! const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl)); while (bx->is_connector()) { ! bx = cfg->get_block_for_node(bx->pred(1)); } st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); // Dump any loop-specific bits, especially for CountedLoops. loop->dump_spec(st); } else if (has_loop_alignment()) {
*** 347,394 **** st->print(" FHRP Index: %d",_fhrp_index); } st->print_cr(""); } ! void Block::dump() const { dump(NULL); } ! void Block::dump( const Block_Array *bbs ) const { ! dump_head(bbs); ! uint cnt = _nodes.size(); ! for( uint i=0; i<cnt; i++ ) _nodes[i]->dump(); tty->print("\n"); } #endif //============================================================================= //------------------------------PhaseCFG--------------------------------------- ! PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : ! Phase(CFG), ! _bbs(a), ! _root(r), ! _node_latency(NULL) #ifndef PRODUCT ! , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif #ifdef ASSERT ! , _raw_oops(a) #endif { ResourceMark rm; // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, // then Match it into a machine-specific Node. Then clone the machine // Node on demand. Node *x = new (C) GotoNode(NULL); x->init_req(0, x); ! _goto = m.match_tree(x); assert(_goto != NULL, ""); _goto->set_req(0,_goto); // Build the CFG in Reverse Post Order _num_blocks = build_cfg(); ! _broot = _bbs[_root->_idx]; } //------------------------------build_cfg-------------------------------------- // Build a proper looking CFG. Make every block begin with either a StartNode // or a RegionNode. Make every block end with either a Goto, If or Return. --- 349,399 ---- st->print(" FHRP Index: %d",_fhrp_index); } st->print_cr(""); } ! void Block::dump() const { ! dump(NULL); ! } ! void Block::dump(const PhaseCFG* cfg) const { ! dump_head(cfg); ! for (uint i=0; i< _nodes.size(); i++) { _nodes[i]->dump(); + } tty->print("\n"); } #endif //============================================================================= //------------------------------PhaseCFG--------------------------------------- ! PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher) ! : Phase(CFG) ! , _block_arena(arena) ! , _node_to_block_mapping(arena) ! , _root(root) ! , _node_latency(NULL) #ifndef PRODUCT ! , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) #endif #ifdef ASSERT ! , _raw_oops(arena) #endif { ResourceMark rm; // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, // then Match it into a machine-specific Node. Then clone the machine // Node on demand. Node *x = new (C) GotoNode(NULL); x->init_req(0, x); ! _goto = matcher.match_tree(x); assert(_goto != NULL, ""); _goto->set_req(0,_goto); // Build the CFG in Reverse Post Order _num_blocks = build_cfg(); ! _broot = get_block_for_node(_root); } //------------------------------build_cfg-------------------------------------- // Build a proper looking CFG. Make every block begin with either a StartNode // or a RegionNode. Make every block end with either a Goto, If or Return.
*** 438,450 **** p = r; } // 'p' now points to the start of this basic block // Put self in array of basic blocks ! Block *bb = new (_bbs._arena) Block(_bbs._arena,p); ! _bbs.map(p->_idx,bb); ! _bbs.map(x->_idx,bb); if( x != p ) { // Only for root is x == p bb->_nodes.push((Node*)x); } // Now handle predecessors ++sum; // Count 1 for self block --- 443,455 ---- p = r; } // 'p' now points to the start of this basic block // Put self in array of basic blocks ! Block *bb = new (_block_arena) Block(_block_arena, p); ! map_node_to_block(p, bb); ! map_node_to_block(x, bb); if( x != p ) { // Only for root is x == p bb->_nodes.push((Node*)x); } // Now handle predecessors ++sum; // Count 1 for self block
*** 471,490 **** } else { // Post-processing visited nodes nstack.pop(); // remove node from stack // Check if it the fist node pushed on stack at the beginning. if (idx == 0) break; // end of the build // Find predecessor basic block ! Block *pb = _bbs[x->_idx]; // Insert into nodes array, if not already there ! if( !_bbs.lookup(proj->_idx) ) { assert( x != proj, "" ); // Map basic block of projection ! _bbs.map(proj->_idx,pb); pb->_nodes.push(proj); } // Insert self as a child of my predecessor block ! pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]); assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), "too many control users, not a CFG?" ); } } // Return number of basic blocks for all children and self --- 476,495 ---- } else { // Post-processing visited nodes nstack.pop(); // remove node from stack // Check if it the fist node pushed on stack at the beginning. if (idx == 0) break; // end of the build // Find predecessor basic block ! Block *pb = get_block_for_node(x); // Insert into nodes array, if not already there ! if (!has_block(proj)) { assert( x != proj, "" ); // Map basic block of projection ! map_node_to_block(proj, pb); pb->_nodes.push(proj); } // Insert self as a child of my predecessor block ! pb->_succs.map(pb->_num_succs++, get_block_for_node(np)); assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), "too many control users, not a CFG?" ); } } // Return number of basic blocks for all children and self
*** 509,527 **** ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); // create region for basic block RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); // setup corresponding basic block ! Block* block = new (_bbs._arena) Block(_bbs._arena, region); ! _bbs.map(region->_idx, block); C->regalloc()->set_bad(region->_idx); // add a goto node Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, region); // add it to the basic block block->_nodes.push(gto); ! _bbs.map(gto->_idx, block); C->regalloc()->set_bad(gto->_idx); // hook up successor block block->_succs.map(block->_num_succs++, out); // remap successor's predecessors if necessary for (uint i = 1; i < out->num_preds(); i++) { --- 514,532 ---- ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); // create region for basic block RegionNode* region = new (C) RegionNode(2); region->init_req(1, proj); // setup corresponding basic block ! Block* block = new (_block_arena) Block(_block_arena, region); ! map_node_to_block(region, block); C->regalloc()->set_bad(region->_idx); // add a goto node Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, region); // add it to the basic block block->_nodes.push(gto); ! map_node_to_block(gto, block); C->regalloc()->set_bad(gto->_idx); // hook up successor block block->_succs.map(block->_num_succs++, out); // remap successor's predecessors if necessary for (uint i = 1; i < out->num_preds(); i++) {
*** 568,578 **** Block *succ = b->_succs[idx]; Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, b->head()); Node *bp = b->_nodes[end_idx]; b->_nodes.map(end_idx,gto); // Slam over NeverBranch ! _bbs.map(gto->_idx, b); C->regalloc()->set_bad(gto->_idx); b->_nodes.pop(); // Yank projections b->_nodes.pop(); // Yank projections b->_succs.map(0,succ); // Map only successor b->_num_succs = 1; --- 573,583 ---- Block *succ = b->_succs[idx]; Node* gto = _goto->clone(); // get a new goto node gto->set_req(0, b->head()); Node *bp = b->_nodes[end_idx]; b->_nodes.map(end_idx,gto); // Slam over NeverBranch ! map_node_to_block(gto, b); C->regalloc()->set_bad(gto->_idx); b->_nodes.pop(); // Yank projections b->_nodes.pop(); // Yank projections b->_succs.map(0,succ); // Map only successor b->_num_succs = 1;
*** 611,621 **** assert(_blocks[bx_index] == bx, "block not found"); // If the previous block conditionally falls into bx, return false, // because moving bx will create an extra jump. for(uint k = 1; k < bx->num_preds(); k++ ) { ! Block* pred = _bbs[bx->pred(k)->_idx]; if (pred == _blocks[bx_index-1]) { if (pred->_num_succs != 1) { return false; } } --- 616,626 ---- assert(_blocks[bx_index] == bx, "block not found"); // If the previous block conditionally falls into bx, return false, // because moving bx will create an extra jump. for(uint k = 1; k < bx->num_preds(); k++ ) { ! Block* pred = get_block_for_node(bx->pred(k)); if (pred == _blocks[bx_index-1]) { if (pred->_num_succs != 1) { return false; } }
*** 680,690 **** if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch ) convert_NeverBranch_to_Goto(b); // Look for uncommon blocks and move to end. if (!C->do_freq_based_layout()) { ! if( b->is_uncommon(_bbs) ) { move_to_end(b, i); last--; // No longer check for being uncommon! if( no_flip_branch(b) ) { // Fall-thru case must follow? b = _blocks[i]; // Find the fall-thru block move_to_end(b, i); --- 685,695 ---- if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch ) convert_NeverBranch_to_Goto(b); // Look for uncommon blocks and move to end. if (!C->do_freq_based_layout()) { ! if (b->is_uncommon(this)) { move_to_end(b, i); last--; // No longer check for being uncommon! if( no_flip_branch(b) ) { // Fall-thru case must follow? b = _blocks[i]; // Find the fall-thru block move_to_end(b, i);
*** 868,899 **** p = p->in(0); // Move control forward assert( !p->is_block_proj() || p->is_Root(), "not a CFG" ); } while( !p->is_block_start() ); // Recursively visit ! for( uint i=1; i<p->req(); i++ ) ! _dump_cfg(p->in(i),visited); // Dump the block ! _bbs[p->_idx]->dump(&_bbs); } void PhaseCFG::dump( ) const { tty->print("\n--- CFG --- %d BBs\n",_num_blocks); ! if( _blocks.size() ) { // Did we do basic-block layout? ! for( uint i=0; i<_num_blocks; i++ ) ! _blocks[i]->dump(&_bbs); } else { // Else do it with a DFS ! VectorSet visited(_bbs._arena); _dump_cfg(_root,visited); } } void PhaseCFG::dump_headers() { for( uint i = 0; i < _num_blocks; i++ ) { ! if( _blocks[i] == NULL ) continue; ! _blocks[i]->dump_head(&_bbs); } } void PhaseCFG::verify( ) const { #ifdef ASSERT --- 873,907 ---- p = p->in(0); // Move control forward assert( !p->is_block_proj() || p->is_Root(), "not a CFG" ); } while( !p->is_block_start() ); // Recursively visit ! for (uint i = 1; i < p->req(); i++) { ! _dump_cfg(p->in(i), visited); ! } // Dump the block ! get_block_for_node(p)->dump(this); } void PhaseCFG::dump( ) const { tty->print("\n--- CFG --- %d BBs\n",_num_blocks); ! if (_blocks.size()) { // Did we do basic-block layout? ! for (uint i = 0; i < _num_blocks; i++) { ! _blocks[i]->dump(this); ! } } else { // Else do it with a DFS ! VectorSet visited(_block_arena); _dump_cfg(_root,visited); } } void PhaseCFG::dump_headers() { for( uint i = 0; i < _num_blocks; i++ ) { ! if (_blocks[i]) { ! _blocks[i]->dump_head(this); ! } } } void PhaseCFG::verify( ) const { #ifdef ASSERT
*** 902,927 **** Block *b = _blocks[i]; uint cnt = b->_nodes.size(); uint j; for (j = 0; j < cnt; j++) { Node *n = b->_nodes[j]; ! assert( _bbs[n->_idx] == b, "" ); if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { assert(j == 1 || b->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block"); } for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); if (def && def != n) { ! assert(_bbs[def->_idx] || def->is_Con(), ! "must have block; constants for debug info ok"); // Verify that instructions in the block is in correct order. // Uses must follow their definition if they are at the same block. // Mostly done to check that MachSpillCopy nodes are placed correctly // when CreateEx node is moved in build_ifg_physical(). ! if (_bbs[def->_idx] == b && !(b->head()->is_Loop() && n->is_Phi()) && // See (+++) comment in reg_split.cpp !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) { bool is_loop = false; if (n->is_Phi()) { --- 910,934 ---- Block *b = _blocks[i]; uint cnt = b->_nodes.size(); uint j; for (j = 0; j < cnt; j++) { Node *n = b->_nodes[j]; ! assert(get_block_for_node(n) == b, ""); if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) { assert(j == 1 || b->_nodes[j-1]->is_Phi(), "CreateEx must be first instruction in block"); } for (uint k = 0; k < n->req(); k++) { Node *def = n->in(k); if (def && def != n) { ! assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok"); // Verify that instructions in the block is in correct order. // Uses must follow their definition if they are at the same block. // Mostly done to check that MachSpillCopy nodes are placed correctly // when CreateEx node is moved in build_ifg_physical(). ! if (get_block_for_node(def) == b && !(b->head()->is_Loop() && n->is_Phi()) && // See (+++) comment in reg_split.cpp !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) { bool is_loop = false; if (n->is_Phi()) {
src/share/vm/opto/block.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File