comparison src/share/vm/opto/block.hpp @ 12071:adb9a7d94cb5

8023003: Cleanup the public interface to PhaseCFG Summary: public methods that don't need to be public should be private. Reviewed-by: kvn, twisti
author adlertz
date Fri, 16 Aug 2013 10:23:55 +0200
parents d1034bd8cefc
children 650868c062a9
comparison
equal deleted inserted replaced
12070:afbe18ae0905 12071:adb9a7d94cb5
346 //------------------------------PhaseCFG--------------------------------------- 346 //------------------------------PhaseCFG---------------------------------------
347 // Build an array of Basic Block pointers, one per Node. 347 // Build an array of Basic Block pointers, one per Node.
348 class PhaseCFG : public Phase { 348 class PhaseCFG : public Phase {
349 friend class VMStructs; 349 friend class VMStructs;
350 private: 350 private:
351
352 // Root of whole program
353 RootNode* _root;
354
355 // The block containing the root node
356 Block* _root_block;
357
358 // List of basic blocks that are created during CFG creation
359 Block_List _blocks;
360
361 // Count of basic blocks
362 uint _number_of_blocks;
363
351 // Arena for the blocks to be stored in 364 // Arena for the blocks to be stored in
352 Arena* _block_arena; 365 Arena* _block_arena;
353 366
367 // The matcher for this compilation
368 Matcher& _matcher;
369
354 // Map nodes to owning basic block 370 // Map nodes to owning basic block
355 Block_Array _node_to_block_mapping; 371 Block_Array _node_to_block_mapping;
356 372
373 // Loop from the root
374 CFGLoop* _root_loop;
375
376 // Outmost loop frequency
377 float _outer_loop_frequency;
378
379 // Per node latency estimation, valid only during GCM
380 GrowableArray<uint>* _node_latency;
381
357 // Build a proper looking cfg. Return count of basic blocks 382 // Build a proper looking cfg. Return count of basic blocks
358 uint build_cfg(); 383 uint build_cfg();
359 384
360 // Perform DFS search. 385 // Build the dominator tree so that we know where we can move instructions
386 void build_dominator_tree();
387
388 // Estimate block frequencies based on IfNode probabilities, so that we know where we want to move instructions
389 void estimate_block_frequency();
390
391 // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
392 // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
393 // Move nodes to ensure correctness from GVN and also try to move nodes out of loops.
394 void global_code_motion();
395
396 // Schedule Nodes early in their basic blocks.
397 bool schedule_early(VectorSet &visited, Node_List &roots);
398
399 // For each node, find the latest block it can be scheduled into
400 // and then select the cheapest block between the latest and earliest
401 // block to place the node.
402 void schedule_late(VectorSet &visited, Node_List &stack);
403
404 // Compute the (backwards) latency of a node from a single use
405 int latency_from_use(Node *n, const Node *def, Node *use);
406
407 // Compute the (backwards) latency of a node from the uses of this instruction
408 void partial_latency_of_defs(Node *n);
409
410 // Compute the instruction global latency with a backwards walk
411 void compute_latencies_backwards(VectorSet &visited, Node_List &stack);
412
413 // Pick a block between early and late that is a cheaper alternative
414 // to late. Helper for schedule_late.
415 Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
416
417 // Perform a Depth First Search (DFS).
361 // Setup 'vertex' as DFS to vertex mapping. 418 // Setup 'vertex' as DFS to vertex mapping.
362 // Setup 'semi' as vertex to DFS mapping. 419 // Setup 'semi' as vertex to DFS mapping.
363 // Set 'parent' to DFS parent. 420 // Set 'parent' to DFS parent.
364 uint DFS( Tarjan *tarjan ); 421 uint do_DFS(Tarjan* tarjan, uint rpo_counter);
365 422
366 // Helper function to insert a node into a block 423 // Helper function to insert a node into a block
367 void schedule_node_into_block( Node *n, Block *b ); 424 void schedule_node_into_block( Node *n, Block *b );
368 425
369 void replace_block_proj_ctrl( Node *n ); 426 void replace_block_proj_ctrl( Node *n );
370 427
371 // Set the basic block for pinned Nodes 428 // Set the basic block for pinned Nodes
372 void schedule_pinned_nodes( VectorSet &visited ); 429 void schedule_pinned_nodes( VectorSet &visited );
373 430
374 // I'll need a few machine-specific GotoNodes. Clone from this one. 431 // I'll need a few machine-specific GotoNodes. Clone from this one.
375 MachNode *_goto; 432 // Used when building the CFG and creating end nodes for blocks.
433 MachNode* _goto;
376 434
377 Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false); 435 Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
378 void verify_anti_dependences(Block* LCA, Node* load) { 436 void verify_anti_dependences(Block* LCA, Node* load) {
379 assert(LCA == get_block_for_node(load), "should already be scheduled"); 437 assert(LCA == get_block_for_node(load), "should already be scheduled");
380 insert_anti_dependences(LCA, load, true); 438 insert_anti_dependences(LCA, load, true);
381 } 439 }
382 440
383 public:
384 PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher);
385
386 uint _num_blocks; // Count of basic blocks
387 Block_List _blocks; // List of basic blocks
388 RootNode *_root; // Root of whole program
389 Block *_broot; // Basic block of root
390 uint _rpo_ctr;
391 CFGLoop* _root_loop;
392 float _outer_loop_freq; // Outmost loop frequency
393
394
395 // set which block this node should reside in
396 void map_node_to_block(const Node* node, Block* block) {
397 _node_to_block_mapping.map(node->_idx, block);
398 }
399
400 // removes the mapping from a node to a block
401 void unmap_node_from_block(const Node* node) {
402 _node_to_block_mapping.map(node->_idx, NULL);
403 }
404
405 // get the block in which this node resides
406 Block* get_block_for_node(const Node* node) const {
407 return _node_to_block_mapping[node->_idx];
408 }
409
410 // does this node reside in a block; return true
411 bool has_block(const Node* node) const {
412 return (_node_to_block_mapping.lookup(node->_idx) != NULL);
413 }
414
415 // Per node latency estimation, valid only during GCM
416 GrowableArray<uint> *_node_latency;
417
418 #ifndef PRODUCT
419 bool _trace_opto_pipelining; // tracing flag
420 #endif
421
422 #ifdef ASSERT
423 Unique_Node_List _raw_oops;
424 #endif
425
426 // Build dominators
427 void Dominators();
428
429 // Estimate block frequencies based on IfNode probabilities
430 void Estimate_Block_Frequency();
431
432 // Global Code Motion. See Click's PLDI95 paper. Place Nodes in specific
433 // basic blocks; i.e. _node_to_block_mapping now maps _idx for all Nodes to some Block.
434 void GlobalCodeMotion( Matcher &m, uint unique, Node_List &proj_list );
435
436 // Compute the (backwards) latency of a node from the uses
437 void latency_from_uses(Node *n);
438
439 // Compute the (backwards) latency of a node from a single use
440 int latency_from_use(Node *n, const Node *def, Node *use);
441
442 // Compute the (backwards) latency of a node from the uses of this instruction
443 void partial_latency_of_defs(Node *n);
444
445 // Schedule Nodes early in their basic blocks.
446 bool schedule_early(VectorSet &visited, Node_List &roots);
447
448 // For each node, find the latest block it can be scheduled into
449 // and then select the cheapest block between the latest and earliest
450 // block to place the node.
451 void schedule_late(VectorSet &visited, Node_List &stack);
452
453 // Pick a block between early and late that is a cheaper alternative
454 // to late. Helper for schedule_late.
455 Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
456
457 // Compute the instruction global latency with a backwards walk
458 void ComputeLatenciesBackwards(VectorSet &visited, Node_List &stack);
459
460 // Set loop alignment
461 void set_loop_alignment();
462
463 // Remove empty basic blocks
464 void remove_empty();
465 void fixup_flow();
466 bool move_to_next(Block* bx, uint b_index); 441 bool move_to_next(Block* bx, uint b_index);
467 void move_to_end(Block* bx, uint b_index); 442 void move_to_end(Block* bx, uint b_index);
443
468 void insert_goto_at(uint block_no, uint succ_no); 444 void insert_goto_at(uint block_no, uint succ_no);
469 445
470 // Check for NeverBranch at block end. This needs to become a GOTO to the 446 // Check for NeverBranch at block end. This needs to become a GOTO to the
471 // true target. NeverBranch are treated as a conditional branch that always 447 // true target. NeverBranch are treated as a conditional branch that always
472 // goes the same direction for most of the optimizer and are used to give a 448 // goes the same direction for most of the optimizer and are used to give a
474 // into Goto's so that when you enter the infinite loop you indeed hang. 450 // into Goto's so that when you enter the infinite loop you indeed hang.
475 void convert_NeverBranch_to_Goto(Block *b); 451 void convert_NeverBranch_to_Goto(Block *b);
476 452
477 CFGLoop* create_loop_tree(); 453 CFGLoop* create_loop_tree();
478 454
479 // Insert a node into a block, and update the _bbs 455 #ifndef PRODUCT
480 void insert( Block *b, uint idx, Node *n ) { 456 bool _trace_opto_pipelining; // tracing flag
457 #endif
458
459 public:
460 PhaseCFG(Arena* arena, RootNode* root, Matcher& matcher);
461
462 void set_latency_for_node(Node* node, int latency) {
463 _node_latency->at_put_grow(node->_idx, latency);
464 }
465
466 uint get_latency_for_node(Node* node) {
467 return _node_latency->at_grow(node->_idx);
468 }
469
470 // Get the outer most frequency
471 float get_outer_loop_frequency() const {
472 return _outer_loop_frequency;
473 }
474
475 // Get the root node of the CFG
476 RootNode* get_root_node() const {
477 return _root;
478 }
479
480 // Get the block of the root node
481 Block* get_root_block() const {
482 return _root_block;
483 }
484
485 // Add a block at a position and moves the later ones one step
486 void add_block_at(uint pos, Block* block) {
487 _blocks.insert(pos, block);
488 _number_of_blocks++;
489 }
490
491 // Adds a block to the top of the block list
492 void add_block(Block* block) {
493 _blocks.push(block);
494 _number_of_blocks++;
495 }
496
497 // Clear the list of blocks
498 void clear_blocks() {
499 _blocks.reset();
500 _number_of_blocks = 0;
501 }
502
503 // Get the block at position pos in _blocks
504 Block* get_block(uint pos) const {
505 return _blocks[pos];
506 }
507
508 // Number of blocks
509 uint number_of_blocks() const {
510 return _number_of_blocks;
511 }
512
513 // set which block this node should reside in
514 void map_node_to_block(const Node* node, Block* block) {
515 _node_to_block_mapping.map(node->_idx, block);
516 }
517
518 // removes the mapping from a node to a block
519 void unmap_node_from_block(const Node* node) {
520 _node_to_block_mapping.map(node->_idx, NULL);
521 }
522
523 // get the block in which this node resides
524 Block* get_block_for_node(const Node* node) const {
525 return _node_to_block_mapping[node->_idx];
526 }
527
528 // does this node reside in a block; return true
529 bool has_block(const Node* node) const {
530 return (_node_to_block_mapping.lookup(node->_idx) != NULL);
531 }
532
533 #ifdef ASSERT
534 Unique_Node_List _raw_oops;
535 #endif
536
537 // Do global code motion by first building dominator tree and estimate block frequency
538 // Returns true on success
539 bool do_global_code_motion();
540
541 // Compute the (backwards) latency of a node from the uses
542 void latency_from_uses(Node *n);
543
544 // Set loop alignment
545 void set_loop_alignment();
546
547 // Remove empty basic blocks
548 void remove_empty_blocks();
549 void fixup_flow();
550
551 // Insert a node into a block at index and map the node to the block
552 void insert(Block *b, uint idx, Node *n) {
481 b->_nodes.insert( idx, n ); 553 b->_nodes.insert( idx, n );
482 map_node_to_block(n, b); 554 map_node_to_block(n, b);
483 } 555 }
484 556
485 #ifndef PRODUCT 557 #ifndef PRODUCT