296
297 // Index of 'end' Node
298 uint end_idx() const {
299 // %%%%% add a proj after every goto
300 // so (last->is_block_proj() != last) always, then simplify this code
301 // This will not give correct end_idx for block 0 when it only contains root.
302 int last_idx = _nodes.size() - 1;
303 Node *last = _nodes[last_idx];
304 assert(last->is_block_proj() == last || last->is_block_proj() == _nodes[last_idx - _num_succs], "");
305 return (last->is_block_proj() == last) ? last_idx : (last_idx - _num_succs);
306 }
307
308 // Basic blocks have a Node which ends them. This Node determines which
309 // basic block follows this one in the program flow. This Node is either an
310 // IfNode, a GotoNode, a JmpNode, or a ReturnNode.
311 Node *end() const { return _nodes[end_idx()]; }
312
313 // Add an instruction to an existing block. It must go after the head
314 // instruction and before the end instruction.
315 void add_inst( Node *n ) { insert_node(n, end_idx()); }
316 // Find node in block
317 uint find_node( const Node *n ) const;
318 // Find and remove n from block list
319 void find_remove( const Node *n );
320
321 // Return the empty status of a block
322 enum { not_empty, empty_with_goto, completely_empty };
323 int is_Empty() const;
324
325 // Forward through connectors
326 Block* non_connector() {
327 Block* s = this;
328 while (s->is_connector()) {
329 s = s->_succs[0];
330 }
331 return s;
332 }
333
334 // Return true if b is a successor of this block
335 bool has_successor(Block* b) const {
336 for (uint i = 0; i < _num_succs; i++ ) {
337 if (non_connector_successor(i) == b) {
338 return true;
339 }
579 // Do global code motion by first building dominator tree and estimate block frequency
580 // Returns true on success
581 bool do_global_code_motion();
582
583 // Compute the (backwards) latency of a node from the uses
584 void latency_from_uses(Node *n);
585
586 // Set loop alignment
587 void set_loop_alignment();
588
589 // Remove empty basic blocks
590 void remove_empty_blocks();
591 void fixup_flow();
592
593 // Insert a node into a block at index and map the node to the block
594 void insert(Block *b, uint idx, Node *n) {
595 b->insert_node(n , idx);
596 map_node_to_block(n, b);
597 }
598
599 #ifndef PRODUCT
600 bool trace_opto_pipelining() const { return _trace_opto_pipelining; }
601
602 // Debugging print of CFG
603 void dump( ) const; // CFG only
604 void _dump_cfg( const Node *end, VectorSet &visited ) const;
605 void verify() const;
606 void dump_headers();
607 #else
608 bool trace_opto_pipelining() const { return false; }
609 #endif
610 };
611
612
613 //------------------------------UnionFind--------------------------------------
614 // Map Block indices to a block-index for a cfg-cover.
615 // Array lookup in the optimized case.
616 class UnionFind : public ResourceObj {
617 uint _cnt, _max;
618 uint* _indices;
|
296
297 // Index of 'end' Node
298 uint end_idx() const {
299 // %%%%% add a proj after every goto
300 // so (last->is_block_proj() != last) always, then simplify this code
301 // This will not give correct end_idx for block 0 when it only contains root.
302 int last_idx = _nodes.size() - 1;
303 Node *last = _nodes[last_idx];
304 assert(last->is_block_proj() == last || last->is_block_proj() == _nodes[last_idx - _num_succs], "");
305 return (last->is_block_proj() == last) ? last_idx : (last_idx - _num_succs);
306 }
307
308 // Basic blocks have a Node which ends them. This Node determines which
309 // basic block follows this one in the program flow. This Node is either an
310 // IfNode, a GotoNode, a JmpNode, or a ReturnNode.
311 Node *end() const { return _nodes[end_idx()]; }
312
313 // Add an instruction to an existing block. It must go after the head
314 // instruction and before the end instruction.
315 void add_inst( Node *n ) { insert_node(n, end_idx()); }
316 // Find node in block. Fails if node not in block.
317 uint find_node( const Node *n ) const;
318 // Find and remove n from block list
319 void find_remove( const Node *n );
320 // Check wether the node is in the block.
321 bool contains (const Node *n) const;
322
323 // Return the empty status of a block
324 enum { not_empty, empty_with_goto, completely_empty };
325 int is_Empty() const;
326
327 // Forward through connectors
328 Block* non_connector() {
329 Block* s = this;
330 while (s->is_connector()) {
331 s = s->_succs[0];
332 }
333 return s;
334 }
335
336 // Return true if b is a successor of this block
337 bool has_successor(Block* b) const {
338 for (uint i = 0; i < _num_succs; i++ ) {
339 if (non_connector_successor(i) == b) {
340 return true;
341 }
581 // Do global code motion by first building dominator tree and estimate block frequency
582 // Returns true on success
583 bool do_global_code_motion();
584
585 // Compute the (backwards) latency of a node from the uses
586 void latency_from_uses(Node *n);
587
588 // Set loop alignment
589 void set_loop_alignment();
590
591 // Remove empty basic blocks
592 void remove_empty_blocks();
593 void fixup_flow();
594
595 // Insert a node into a block at index and map the node to the block
596 void insert(Block *b, uint idx, Node *n) {
597 b->insert_node(n , idx);
598 map_node_to_block(n, b);
599 }
600
601 // Check all nodes and late expand them if necessary.
602 void LateExpand(PhaseRegAlloc* _ra);
603
604 #ifndef PRODUCT
605 bool trace_opto_pipelining() const { return _trace_opto_pipelining; }
606
607 // Debugging print of CFG
608 void dump( ) const; // CFG only
609 void _dump_cfg( const Node *end, VectorSet &visited ) const;
610 void verify() const;
611 void dump_headers();
612 #else
613 bool trace_opto_pipelining() const { return false; }
614 #endif
615 };
616
617
618 //------------------------------UnionFind--------------------------------------
619 // Map Block indices to a block-index for a cfg-cover.
620 // Array lookup in the optimized case.
621 class UnionFind : public ResourceObj {
622 uint _cnt, _max;
623 uint* _indices;
|