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

src/share/vm/opto/block.cpp

Print this page




 356 #endif
 357 
 358 PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
 359 : Phase(CFG)
 360 , _block_arena(arena)
 361 , _root(root)
 362 , _matcher(matcher)
 363 , _node_to_block_mapping(arena)
 364 , _node_latency(NULL)
 365 #ifndef PRODUCT
 366 , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
 367 #endif
 368 #ifdef ASSERT
 369 , _raw_oops(arena)
 370 #endif
 371 {
 372   ResourceMark rm;
 373   // I'll need a few machine-specific GotoNodes.  Make an Ideal GotoNode,
 374   // then Match it into a machine-specific Node.  Then clone the machine
 375   // Node on demand.
 376   Node *x = new (C) GotoNode(NULL);
 377   x->init_req(0, x);
 378   _goto = matcher.match_tree(x);
 379   assert(_goto != NULL, "");
 380   _goto->set_req(0,_goto);
 381 
 382   // Build the CFG in Reverse Post Order
 383   _number_of_blocks = build_cfg();
 384   _root_block = get_block_for_node(_root);
 385 }
 386 
 387 // Build a proper looking CFG.  Make every block begin with either a StartNode
 388 // or a RegionNode.  Make every block end with either a Goto, If or Return.
 389 // The RootNode both starts and ends it's own block.  Do this with a recursive
 390 // backwards walk over the control edges.
 391 uint PhaseCFG::build_cfg() {
 392   Arena *a = Thread::current()->resource_area();
 393   VectorSet visited(a);
 394 
 395   // Allocate stack with enough space to avoid frequent realloc
 396   Node_Stack nstack(a, C->unique() >> 1);


 409     Node *proj = np->in(idx);
 410     const Node *x = proj->is_block_proj();
 411     // Does the block end with a proper block-ending Node?  One of Return,
 412     // If or Goto? (This check should be done for visited nodes also).
 413     if (x == NULL) {                    // Does not end right...
 414       Node *g = _goto->clone(); // Force it to end in a Goto
 415       g->set_req(0, proj);
 416       np->set_req(idx, g);
 417       x = proj = g;
 418     }
 419     if (!visited.test_set(x->_idx)) { // Visit this block once
 420       // Skip any control-pinned middle'in stuff
 421       Node *p = proj;
 422       do {
 423         proj = p;                   // Update pointer to last Control
 424         p = p->in(0);               // Move control forward
 425       } while( !p->is_block_proj() &&
 426                !p->is_block_start() );
 427       // Make the block begin with one of Region or StartNode.
 428       if( !p->is_block_start() ) {
 429         RegionNode *r = new (C) RegionNode( 2 );
 430         r->init_req(1, p);         // Insert RegionNode in the way
 431         proj->set_req(0, r);        // Insert RegionNode in the way
 432         p = r;
 433       }
 434       // 'p' now points to the start of this basic block
 435 
 436       // Put self in array of basic blocks
 437       Block *bb = new (_block_arena) Block(_block_arena, p);
 438       map_node_to_block(p, bb);
 439       map_node_to_block(x, bb);
 440       if( x != p ) {                // Only for root is x == p
 441         bb->push_node((Node*)x);
 442       }
 443       // Now handle predecessors
 444       ++sum;                        // Count 1 for self block
 445       uint cnt = bb->num_preds();
 446       for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors
 447         Node *prevproj = p->in(i);  // Get prior input
 448         assert( !prevproj->is_Con(), "dead input not removed" );
 449         // Check to see if p->in(i) is a "control-dependent" CFG edge -


 484   // Return number of basic blocks for all children and self
 485   return sum;
 486 }
 487 
 488 // Inserts a goto & corresponding basic block between
 489 // block[block_no] and its succ_no'th successor block
 490 void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
 491   // get block with block_no
 492   assert(block_no < number_of_blocks(), "illegal block number");
 493   Block* in  = get_block(block_no);
 494   // get successor block succ_no
 495   assert(succ_no < in->_num_succs, "illegal successor number");
 496   Block* out = in->_succs[succ_no];
 497   // Compute frequency of the new block. Do this before inserting
 498   // new block in case succ_prob() needs to infer the probability from
 499   // surrounding blocks.
 500   float freq = in->_freq * in->succ_prob(succ_no);
 501   // get ProjNode corresponding to the succ_no'th successor of the in block
 502   ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj();
 503   // create region for basic block
 504   RegionNode* region = new (C) RegionNode(2);
 505   region->init_req(1, proj);
 506   // setup corresponding basic block
 507   Block* block = new (_block_arena) Block(_block_arena, region);
 508   map_node_to_block(region, block);
 509   C->regalloc()->set_bad(region->_idx);
 510   // add a goto node
 511   Node* gto = _goto->clone(); // get a new goto node
 512   gto->set_req(0, region);
 513   // add it to the basic block
 514   block->push_node(gto);
 515   map_node_to_block(gto, block);
 516   C->regalloc()->set_bad(gto->_idx);
 517   // hook up successor block
 518   block->_succs.map(block->_num_succs++, out);
 519   // remap successor's predecessors if necessary
 520   for (uint i = 1; i < out->num_preds(); i++) {
 521     if (out->pred(i) == proj) out->head()->set_req(i, gto);
 522   }
 523   // remap predecessor's successor to new block
 524   in->_succs.map(succ_no, block);




 356 #endif
 357 
 358 PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher)
 359 : Phase(CFG)
 360 , _block_arena(arena)
 361 , _root(root)
 362 , _matcher(matcher)
 363 , _node_to_block_mapping(arena)
 364 , _node_latency(NULL)
 365 #ifndef PRODUCT
 366 , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining"))
 367 #endif
 368 #ifdef ASSERT
 369 , _raw_oops(arena)
 370 #endif
 371 {
 372   ResourceMark rm;
 373   // I'll need a few machine-specific GotoNodes.  Make an Ideal GotoNode,
 374   // then Match it into a machine-specific Node.  Then clone the machine
 375   // Node on demand.
 376   Node *x = new GotoNode(NULL);
 377   x->init_req(0, x);
 378   _goto = matcher.match_tree(x);
 379   assert(_goto != NULL, "");
 380   _goto->set_req(0,_goto);
 381 
 382   // Build the CFG in Reverse Post Order
 383   _number_of_blocks = build_cfg();
 384   _root_block = get_block_for_node(_root);
 385 }
 386 
 387 // Build a proper looking CFG.  Make every block begin with either a StartNode
 388 // or a RegionNode.  Make every block end with either a Goto, If or Return.
 389 // The RootNode both starts and ends it's own block.  Do this with a recursive
 390 // backwards walk over the control edges.
 391 uint PhaseCFG::build_cfg() {
 392   Arena *a = Thread::current()->resource_area();
 393   VectorSet visited(a);
 394 
 395   // Allocate stack with enough space to avoid frequent realloc
 396   Node_Stack nstack(a, C->unique() >> 1);


 409     Node *proj = np->in(idx);
 410     const Node *x = proj->is_block_proj();
 411     // Does the block end with a proper block-ending Node?  One of Return,
 412     // If or Goto? (This check should be done for visited nodes also).
 413     if (x == NULL) {                    // Does not end right...
 414       Node *g = _goto->clone(); // Force it to end in a Goto
 415       g->set_req(0, proj);
 416       np->set_req(idx, g);
 417       x = proj = g;
 418     }
 419     if (!visited.test_set(x->_idx)) { // Visit this block once
 420       // Skip any control-pinned middle'in stuff
 421       Node *p = proj;
 422       do {
 423         proj = p;                   // Update pointer to last Control
 424         p = p->in(0);               // Move control forward
 425       } while( !p->is_block_proj() &&
 426                !p->is_block_start() );
 427       // Make the block begin with one of Region or StartNode.
 428       if( !p->is_block_start() ) {
 429         RegionNode *r = new RegionNode( 2 );
 430         r->init_req(1, p);         // Insert RegionNode in the way
 431         proj->set_req(0, r);        // Insert RegionNode in the way
 432         p = r;
 433       }
 434       // 'p' now points to the start of this basic block
 435 
 436       // Put self in array of basic blocks
 437       Block *bb = new (_block_arena) Block(_block_arena, p);
 438       map_node_to_block(p, bb);
 439       map_node_to_block(x, bb);
 440       if( x != p ) {                // Only for root is x == p
 441         bb->push_node((Node*)x);
 442       }
 443       // Now handle predecessors
 444       ++sum;                        // Count 1 for self block
 445       uint cnt = bb->num_preds();
 446       for (int i = (cnt - 1); i > 0; i-- ) { // For all predecessors
 447         Node *prevproj = p->in(i);  // Get prior input
 448         assert( !prevproj->is_Con(), "dead input not removed" );
 449         // Check to see if p->in(i) is a "control-dependent" CFG edge -


 484   // Return number of basic blocks for all children and self
 485   return sum;
 486 }
 487 
 488 // Inserts a goto & corresponding basic block between
 489 // block[block_no] and its succ_no'th successor block
 490 void PhaseCFG::insert_goto_at(uint block_no, uint succ_no) {
 491   // get block with block_no
 492   assert(block_no < number_of_blocks(), "illegal block number");
 493   Block* in  = get_block(block_no);
 494   // get successor block succ_no
 495   assert(succ_no < in->_num_succs, "illegal successor number");
 496   Block* out = in->_succs[succ_no];
 497   // Compute frequency of the new block. Do this before inserting
 498   // new block in case succ_prob() needs to infer the probability from
 499   // surrounding blocks.
 500   float freq = in->_freq * in->succ_prob(succ_no);
 501   // get ProjNode corresponding to the succ_no'th successor of the in block
 502   ProjNode* proj = in->get_node(in->number_of_nodes() - in->_num_succs + succ_no)->as_Proj();
 503   // create region for basic block
 504   RegionNode* region = new RegionNode(2);
 505   region->init_req(1, proj);
 506   // setup corresponding basic block
 507   Block* block = new (_block_arena) Block(_block_arena, region);
 508   map_node_to_block(region, block);
 509   C->regalloc()->set_bad(region->_idx);
 510   // add a goto node
 511   Node* gto = _goto->clone(); // get a new goto node
 512   gto->set_req(0, region);
 513   // add it to the basic block
 514   block->push_node(gto);
 515   map_node_to_block(gto, block);
 516   C->regalloc()->set_bad(gto->_idx);
 517   // hook up successor block
 518   block->_succs.map(block->_num_succs++, out);
 519   // remap successor's predecessors if necessary
 520   for (uint i = 1; i < out->num_preds(); i++) {
 521     if (out->pred(i) == proj) out->head()->set_req(i, gto);
 522   }
 523   // remap predecessor's successor to new block
 524   in->_succs.map(succ_no, block);


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