Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/block.cpp @ 12023:d1034bd8cefc
8022284: Hide internal data structure in PhaseCFG
Summary: Hide private node to block mapping using public interface
Reviewed-by: kvn, roland
author | adlertz |
---|---|
date | Wed, 07 Aug 2013 17:56:19 +0200 |
parents | cc32ccaaf47f |
children | adb9a7d94cb5 |
comparison
equal
deleted
inserted
replaced
12004:71526a36ebb4 | 12023:d1034bd8cefc |
---|---|
219 } | 219 } |
220 | 220 |
221 //------------------------------is_uncommon------------------------------------ | 221 //------------------------------is_uncommon------------------------------------ |
222 // True if block is low enough frequency or guarded by a test which | 222 // True if block is low enough frequency or guarded by a test which |
223 // mostly does not go here. | 223 // mostly does not go here. |
224 bool Block::is_uncommon( Block_Array &bbs ) const { | 224 bool Block::is_uncommon(PhaseCFG* cfg) const { |
225 // Initial blocks must never be moved, so are never uncommon. | 225 // Initial blocks must never be moved, so are never uncommon. |
226 if (head()->is_Root() || head()->is_Start()) return false; | 226 if (head()->is_Root() || head()->is_Start()) return false; |
227 | 227 |
228 // Check for way-low freq | 228 // Check for way-low freq |
229 if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; | 229 if( _freq < BLOCK_FREQUENCY(0.00001f) ) return true; |
236 uint uncommon_preds = 0; | 236 uint uncommon_preds = 0; |
237 uint freq_preds = 0; | 237 uint freq_preds = 0; |
238 uint uncommon_for_freq_preds = 0; | 238 uint uncommon_for_freq_preds = 0; |
239 | 239 |
240 for( uint i=1; i<num_preds(); i++ ) { | 240 for( uint i=1; i<num_preds(); i++ ) { |
241 Block* guard = bbs[pred(i)->_idx]; | 241 Block* guard = cfg->get_block_for_node(pred(i)); |
242 // Check to see if this block follows its guard 1 time out of 10000 | 242 // Check to see if this block follows its guard 1 time out of 10000 |
243 // or less. | 243 // or less. |
244 // | 244 // |
245 // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which | 245 // See list of magnitude-4 unlikely probabilities in cfgnode.hpp which |
246 // we intend to be "uncommon", such as slow-path TLE allocation, | 246 // we intend to be "uncommon", such as slow-path TLE allocation, |
283 orig->dump_bidx(orig, st); | 283 orig->dump_bidx(orig, st); |
284 st->print(")"); | 284 st->print(")"); |
285 } | 285 } |
286 } | 286 } |
287 | 287 |
288 void Block::dump_pred(const Block_Array *bbs, Block* orig, outputStream* st) const { | 288 void Block::dump_pred(const PhaseCFG* cfg, Block* orig, outputStream* st) const { |
289 if (is_connector()) { | 289 if (is_connector()) { |
290 for (uint i=1; i<num_preds(); i++) { | 290 for (uint i=1; i<num_preds(); i++) { |
291 Block *p = ((*bbs)[pred(i)->_idx]); | 291 Block *p = cfg->get_block_for_node(pred(i)); |
292 p->dump_pred(bbs, orig, st); | 292 p->dump_pred(cfg, orig, st); |
293 } | 293 } |
294 } else { | 294 } else { |
295 dump_bidx(orig, st); | 295 dump_bidx(orig, st); |
296 st->print(" "); | 296 st->print(" "); |
297 } | 297 } |
298 } | 298 } |
299 | 299 |
300 void Block::dump_head( const Block_Array *bbs, outputStream* st ) const { | 300 void Block::dump_head(const PhaseCFG* cfg, outputStream* st) const { |
301 // Print the basic block | 301 // Print the basic block |
302 dump_bidx(this, st); | 302 dump_bidx(this, st); |
303 st->print(": #\t"); | 303 st->print(": #\t"); |
304 | 304 |
305 // Print the incoming CFG edges and the outgoing CFG edges | 305 // Print the incoming CFG edges and the outgoing CFG edges |
309 } | 309 } |
310 st->print("<- "); | 310 st->print("<- "); |
311 if( head()->is_block_start() ) { | 311 if( head()->is_block_start() ) { |
312 for (uint i=1; i<num_preds(); i++) { | 312 for (uint i=1; i<num_preds(); i++) { |
313 Node *s = pred(i); | 313 Node *s = pred(i); |
314 if (bbs) { | 314 if (cfg != NULL) { |
315 Block *p = (*bbs)[s->_idx]; | 315 Block *p = cfg->get_block_for_node(s); |
316 p->dump_pred(bbs, p, st); | 316 p->dump_pred(cfg, p, st); |
317 } else { | 317 } else { |
318 while (!s->is_block_start()) | 318 while (!s->is_block_start()) |
319 s = s->in(0); | 319 s = s->in(0); |
320 st->print("N%d ", s->_idx ); | 320 st->print("N%d ", s->_idx ); |
321 } | 321 } |
322 } | 322 } |
323 } else | 323 } else { |
324 st->print("BLOCK HEAD IS JUNK "); | 324 st->print("BLOCK HEAD IS JUNK "); |
325 } | |
325 | 326 |
326 // Print loop, if any | 327 // Print loop, if any |
327 const Block *bhead = this; // Head of self-loop | 328 const Block *bhead = this; // Head of self-loop |
328 Node *bh = bhead->head(); | 329 Node *bh = bhead->head(); |
329 if( bbs && bh->is_Loop() && !head()->is_Root() ) { | 330 |
331 if ((cfg != NULL) && bh->is_Loop() && !head()->is_Root()) { | |
330 LoopNode *loop = bh->as_Loop(); | 332 LoopNode *loop = bh->as_Loop(); |
331 const Block *bx = (*bbs)[loop->in(LoopNode::LoopBackControl)->_idx]; | 333 const Block *bx = cfg->get_block_for_node(loop->in(LoopNode::LoopBackControl)); |
332 while (bx->is_connector()) { | 334 while (bx->is_connector()) { |
333 bx = (*bbs)[bx->pred(1)->_idx]; | 335 bx = cfg->get_block_for_node(bx->pred(1)); |
334 } | 336 } |
335 st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); | 337 st->print("\tLoop: B%d-B%d ", bhead->_pre_order, bx->_pre_order); |
336 // Dump any loop-specific bits, especially for CountedLoops. | 338 // Dump any loop-specific bits, especially for CountedLoops. |
337 loop->dump_spec(st); | 339 loop->dump_spec(st); |
338 } else if (has_loop_alignment()) { | 340 } else if (has_loop_alignment()) { |
347 st->print(" FHRP Index: %d",_fhrp_index); | 349 st->print(" FHRP Index: %d",_fhrp_index); |
348 } | 350 } |
349 st->print_cr(""); | 351 st->print_cr(""); |
350 } | 352 } |
351 | 353 |
352 void Block::dump() const { dump(NULL); } | 354 void Block::dump() const { |
353 | 355 dump(NULL); |
354 void Block::dump( const Block_Array *bbs ) const { | 356 } |
355 dump_head(bbs); | 357 |
356 uint cnt = _nodes.size(); | 358 void Block::dump(const PhaseCFG* cfg) const { |
357 for( uint i=0; i<cnt; i++ ) | 359 dump_head(cfg); |
360 for (uint i=0; i< _nodes.size(); i++) { | |
358 _nodes[i]->dump(); | 361 _nodes[i]->dump(); |
362 } | |
359 tty->print("\n"); | 363 tty->print("\n"); |
360 } | 364 } |
361 #endif | 365 #endif |
362 | 366 |
363 //============================================================================= | 367 //============================================================================= |
364 //------------------------------PhaseCFG--------------------------------------- | 368 //------------------------------PhaseCFG--------------------------------------- |
365 PhaseCFG::PhaseCFG( Arena *a, RootNode *r, Matcher &m ) : | 369 PhaseCFG::PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher) |
366 Phase(CFG), | 370 : Phase(CFG) |
367 _bbs(a), | 371 , _block_arena(arena) |
368 _root(r), | 372 , _node_to_block_mapping(arena) |
369 _node_latency(NULL) | 373 , _root(root) |
374 , _node_latency(NULL) | |
370 #ifndef PRODUCT | 375 #ifndef PRODUCT |
371 , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) | 376 , _trace_opto_pipelining(TraceOptoPipelining || C->method_has_option("TraceOptoPipelining")) |
372 #endif | 377 #endif |
373 #ifdef ASSERT | 378 #ifdef ASSERT |
374 , _raw_oops(a) | 379 , _raw_oops(arena) |
375 #endif | 380 #endif |
376 { | 381 { |
377 ResourceMark rm; | 382 ResourceMark rm; |
378 // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, | 383 // I'll need a few machine-specific GotoNodes. Make an Ideal GotoNode, |
379 // then Match it into a machine-specific Node. Then clone the machine | 384 // then Match it into a machine-specific Node. Then clone the machine |
380 // Node on demand. | 385 // Node on demand. |
381 Node *x = new (C) GotoNode(NULL); | 386 Node *x = new (C) GotoNode(NULL); |
382 x->init_req(0, x); | 387 x->init_req(0, x); |
383 _goto = m.match_tree(x); | 388 _goto = matcher.match_tree(x); |
384 assert(_goto != NULL, ""); | 389 assert(_goto != NULL, ""); |
385 _goto->set_req(0,_goto); | 390 _goto->set_req(0,_goto); |
386 | 391 |
387 // Build the CFG in Reverse Post Order | 392 // Build the CFG in Reverse Post Order |
388 _num_blocks = build_cfg(); | 393 _num_blocks = build_cfg(); |
389 _broot = _bbs[_root->_idx]; | 394 _broot = get_block_for_node(_root); |
390 } | 395 } |
391 | 396 |
392 //------------------------------build_cfg-------------------------------------- | 397 //------------------------------build_cfg-------------------------------------- |
393 // Build a proper looking CFG. Make every block begin with either a StartNode | 398 // Build a proper looking CFG. Make every block begin with either a StartNode |
394 // or a RegionNode. Make every block end with either a Goto, If or Return. | 399 // or a RegionNode. Make every block end with either a Goto, If or Return. |
438 p = r; | 443 p = r; |
439 } | 444 } |
440 // 'p' now points to the start of this basic block | 445 // 'p' now points to the start of this basic block |
441 | 446 |
442 // Put self in array of basic blocks | 447 // Put self in array of basic blocks |
443 Block *bb = new (_bbs._arena) Block(_bbs._arena,p); | 448 Block *bb = new (_block_arena) Block(_block_arena, p); |
444 _bbs.map(p->_idx,bb); | 449 map_node_to_block(p, bb); |
445 _bbs.map(x->_idx,bb); | 450 map_node_to_block(x, bb); |
446 if( x != p ) { // Only for root is x == p | 451 if( x != p ) { // Only for root is x == p |
447 bb->_nodes.push((Node*)x); | 452 bb->_nodes.push((Node*)x); |
448 } | 453 } |
449 // Now handle predecessors | 454 // Now handle predecessors |
450 ++sum; // Count 1 for self block | 455 ++sum; // Count 1 for self block |
471 } else { // Post-processing visited nodes | 476 } else { // Post-processing visited nodes |
472 nstack.pop(); // remove node from stack | 477 nstack.pop(); // remove node from stack |
473 // Check if it the fist node pushed on stack at the beginning. | 478 // Check if it the fist node pushed on stack at the beginning. |
474 if (idx == 0) break; // end of the build | 479 if (idx == 0) break; // end of the build |
475 // Find predecessor basic block | 480 // Find predecessor basic block |
476 Block *pb = _bbs[x->_idx]; | 481 Block *pb = get_block_for_node(x); |
477 // Insert into nodes array, if not already there | 482 // Insert into nodes array, if not already there |
478 if( !_bbs.lookup(proj->_idx) ) { | 483 if (!has_block(proj)) { |
479 assert( x != proj, "" ); | 484 assert( x != proj, "" ); |
480 // Map basic block of projection | 485 // Map basic block of projection |
481 _bbs.map(proj->_idx,pb); | 486 map_node_to_block(proj, pb); |
482 pb->_nodes.push(proj); | 487 pb->_nodes.push(proj); |
483 } | 488 } |
484 // Insert self as a child of my predecessor block | 489 // Insert self as a child of my predecessor block |
485 pb->_succs.map(pb->_num_succs++, _bbs[np->_idx]); | 490 pb->_succs.map(pb->_num_succs++, get_block_for_node(np)); |
486 assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), | 491 assert( pb->_nodes[ pb->_nodes.size() - pb->_num_succs ]->is_block_proj(), |
487 "too many control users, not a CFG?" ); | 492 "too many control users, not a CFG?" ); |
488 } | 493 } |
489 } | 494 } |
490 // Return number of basic blocks for all children and self | 495 // Return number of basic blocks for all children and self |
509 ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); | 514 ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj(); |
510 // create region for basic block | 515 // create region for basic block |
511 RegionNode* region = new (C) RegionNode(2); | 516 RegionNode* region = new (C) RegionNode(2); |
512 region->init_req(1, proj); | 517 region->init_req(1, proj); |
513 // setup corresponding basic block | 518 // setup corresponding basic block |
514 Block* block = new (_bbs._arena) Block(_bbs._arena, region); | 519 Block* block = new (_block_arena) Block(_block_arena, region); |
515 _bbs.map(region->_idx, block); | 520 map_node_to_block(region, block); |
516 C->regalloc()->set_bad(region->_idx); | 521 C->regalloc()->set_bad(region->_idx); |
517 // add a goto node | 522 // add a goto node |
518 Node* gto = _goto->clone(); // get a new goto node | 523 Node* gto = _goto->clone(); // get a new goto node |
519 gto->set_req(0, region); | 524 gto->set_req(0, region); |
520 // add it to the basic block | 525 // add it to the basic block |
521 block->_nodes.push(gto); | 526 block->_nodes.push(gto); |
522 _bbs.map(gto->_idx, block); | 527 map_node_to_block(gto, block); |
523 C->regalloc()->set_bad(gto->_idx); | 528 C->regalloc()->set_bad(gto->_idx); |
524 // hook up successor block | 529 // hook up successor block |
525 block->_succs.map(block->_num_succs++, out); | 530 block->_succs.map(block->_num_succs++, out); |
526 // remap successor's predecessors if necessary | 531 // remap successor's predecessors if necessary |
527 for (uint i = 1; i < out->num_preds(); i++) { | 532 for (uint i = 1; i < out->num_preds(); i++) { |
568 Block *succ = b->_succs[idx]; | 573 Block *succ = b->_succs[idx]; |
569 Node* gto = _goto->clone(); // get a new goto node | 574 Node* gto = _goto->clone(); // get a new goto node |
570 gto->set_req(0, b->head()); | 575 gto->set_req(0, b->head()); |
571 Node *bp = b->_nodes[end_idx]; | 576 Node *bp = b->_nodes[end_idx]; |
572 b->_nodes.map(end_idx,gto); // Slam over NeverBranch | 577 b->_nodes.map(end_idx,gto); // Slam over NeverBranch |
573 _bbs.map(gto->_idx, b); | 578 map_node_to_block(gto, b); |
574 C->regalloc()->set_bad(gto->_idx); | 579 C->regalloc()->set_bad(gto->_idx); |
575 b->_nodes.pop(); // Yank projections | 580 b->_nodes.pop(); // Yank projections |
576 b->_nodes.pop(); // Yank projections | 581 b->_nodes.pop(); // Yank projections |
577 b->_succs.map(0,succ); // Map only successor | 582 b->_succs.map(0,succ); // Map only successor |
578 b->_num_succs = 1; | 583 b->_num_succs = 1; |
611 assert(_blocks[bx_index] == bx, "block not found"); | 616 assert(_blocks[bx_index] == bx, "block not found"); |
612 | 617 |
613 // If the previous block conditionally falls into bx, return false, | 618 // If the previous block conditionally falls into bx, return false, |
614 // because moving bx will create an extra jump. | 619 // because moving bx will create an extra jump. |
615 for(uint k = 1; k < bx->num_preds(); k++ ) { | 620 for(uint k = 1; k < bx->num_preds(); k++ ) { |
616 Block* pred = _bbs[bx->pred(k)->_idx]; | 621 Block* pred = get_block_for_node(bx->pred(k)); |
617 if (pred == _blocks[bx_index-1]) { | 622 if (pred == _blocks[bx_index-1]) { |
618 if (pred->_num_succs != 1) { | 623 if (pred->_num_succs != 1) { |
619 return false; | 624 return false; |
620 } | 625 } |
621 } | 626 } |
680 if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch ) | 685 if( b->_nodes[b->end_idx()]->Opcode() == Op_NeverBranch ) |
681 convert_NeverBranch_to_Goto(b); | 686 convert_NeverBranch_to_Goto(b); |
682 | 687 |
683 // Look for uncommon blocks and move to end. | 688 // Look for uncommon blocks and move to end. |
684 if (!C->do_freq_based_layout()) { | 689 if (!C->do_freq_based_layout()) { |
685 if( b->is_uncommon(_bbs) ) { | 690 if (b->is_uncommon(this)) { |
686 move_to_end(b, i); | 691 move_to_end(b, i); |
687 last--; // No longer check for being uncommon! | 692 last--; // No longer check for being uncommon! |
688 if( no_flip_branch(b) ) { // Fall-thru case must follow? | 693 if( no_flip_branch(b) ) { // Fall-thru case must follow? |
689 b = _blocks[i]; // Find the fall-thru block | 694 b = _blocks[i]; // Find the fall-thru block |
690 move_to_end(b, i); | 695 move_to_end(b, i); |
868 p = p->in(0); // Move control forward | 873 p = p->in(0); // Move control forward |
869 assert( !p->is_block_proj() || p->is_Root(), "not a CFG" ); | 874 assert( !p->is_block_proj() || p->is_Root(), "not a CFG" ); |
870 } while( !p->is_block_start() ); | 875 } while( !p->is_block_start() ); |
871 | 876 |
872 // Recursively visit | 877 // Recursively visit |
873 for( uint i=1; i<p->req(); i++ ) | 878 for (uint i = 1; i < p->req(); i++) { |
874 _dump_cfg(p->in(i),visited); | 879 _dump_cfg(p->in(i), visited); |
880 } | |
875 | 881 |
876 // Dump the block | 882 // Dump the block |
877 _bbs[p->_idx]->dump(&_bbs); | 883 get_block_for_node(p)->dump(this); |
878 } | 884 } |
879 | 885 |
880 void PhaseCFG::dump( ) const { | 886 void PhaseCFG::dump( ) const { |
881 tty->print("\n--- CFG --- %d BBs\n",_num_blocks); | 887 tty->print("\n--- CFG --- %d BBs\n",_num_blocks); |
882 if( _blocks.size() ) { // Did we do basic-block layout? | 888 if (_blocks.size()) { // Did we do basic-block layout? |
883 for( uint i=0; i<_num_blocks; i++ ) | 889 for (uint i = 0; i < _num_blocks; i++) { |
884 _blocks[i]->dump(&_bbs); | 890 _blocks[i]->dump(this); |
891 } | |
885 } else { // Else do it with a DFS | 892 } else { // Else do it with a DFS |
886 VectorSet visited(_bbs._arena); | 893 VectorSet visited(_block_arena); |
887 _dump_cfg(_root,visited); | 894 _dump_cfg(_root,visited); |
888 } | 895 } |
889 } | 896 } |
890 | 897 |
891 void PhaseCFG::dump_headers() { | 898 void PhaseCFG::dump_headers() { |
892 for( uint i = 0; i < _num_blocks; i++ ) { | 899 for( uint i = 0; i < _num_blocks; i++ ) { |
893 if( _blocks[i] == NULL ) continue; | 900 if (_blocks[i]) { |
894 _blocks[i]->dump_head(&_bbs); | 901 _blocks[i]->dump_head(this); |
902 } | |
895 } | 903 } |
896 } | 904 } |
897 | 905 |
898 void PhaseCFG::verify( ) const { | 906 void PhaseCFG::verify( ) const { |
899 #ifdef ASSERT | 907 #ifdef ASSERT |
902 Block *b = _blocks[i]; | 910 Block *b = _blocks[i]; |
903 uint cnt = b->_nodes.size(); | 911 uint cnt = b->_nodes.size(); |
904 uint j; | 912 uint j; |
905 for (j = 0; j < cnt; j++) { | 913 for (j = 0; j < cnt; j++) { |
906 Node *n = b->_nodes[j]; | 914 Node *n = b->_nodes[j]; |
907 assert( _bbs[n->_idx] == b, "" ); | 915 assert(get_block_for_node(n) == b, ""); |
908 if (j >= 1 && n->is_Mach() && | 916 if (j >= 1 && n->is_Mach() && |
909 n->as_Mach()->ideal_Opcode() == Op_CreateEx) { | 917 n->as_Mach()->ideal_Opcode() == Op_CreateEx) { |
910 assert(j == 1 || b->_nodes[j-1]->is_Phi(), | 918 assert(j == 1 || b->_nodes[j-1]->is_Phi(), |
911 "CreateEx must be first instruction in block"); | 919 "CreateEx must be first instruction in block"); |
912 } | 920 } |
913 for (uint k = 0; k < n->req(); k++) { | 921 for (uint k = 0; k < n->req(); k++) { |
914 Node *def = n->in(k); | 922 Node *def = n->in(k); |
915 if (def && def != n) { | 923 if (def && def != n) { |
916 assert(_bbs[def->_idx] || def->is_Con(), | 924 assert(get_block_for_node(def) || def->is_Con(), "must have block; constants for debug info ok"); |
917 "must have block; constants for debug info ok"); | |
918 // Verify that instructions in the block is in correct order. | 925 // Verify that instructions in the block is in correct order. |
919 // Uses must follow their definition if they are at the same block. | 926 // Uses must follow their definition if they are at the same block. |
920 // Mostly done to check that MachSpillCopy nodes are placed correctly | 927 // Mostly done to check that MachSpillCopy nodes are placed correctly |
921 // when CreateEx node is moved in build_ifg_physical(). | 928 // when CreateEx node is moved in build_ifg_physical(). |
922 if (_bbs[def->_idx] == b && | 929 if (get_block_for_node(def) == b && |
923 !(b->head()->is_Loop() && n->is_Phi()) && | 930 !(b->head()->is_Loop() && n->is_Phi()) && |
924 // See (+++) comment in reg_split.cpp | 931 // See (+++) comment in reg_split.cpp |
925 !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) { | 932 !(n->jvms() != NULL && n->jvms()->is_monitor_use(k))) { |
926 bool is_loop = false; | 933 bool is_loop = false; |
927 if (n->is_Phi()) { | 934 if (n->is_Phi()) { |