< prev index next >

src/share/vm/opto/block.hpp

Print this page




  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_OPTO_BLOCK_HPP
  26 #define SHARE_VM_OPTO_BLOCK_HPP
  27 
  28 #include "opto/multnode.hpp"
  29 #include "opto/node.hpp"
  30 #include "opto/phase.hpp"
  31 
  32 // Optimization - Graph Style
  33 
  34 class Block;
  35 class CFGLoop;
  36 class MachCallNode;
  37 class Matcher;
  38 class RootNode;
  39 class VectorSet;

  40 struct Tarjan;
  41 
  42 //------------------------------Block_Array------------------------------------
  43 // Map dense integer indices to Blocks.  Uses classic doubling-array trick.
  44 // Abstractly provides an infinite array of Block*'s, initialized to NULL.
  45 // Note that the constructor just zeros things, and since I use Arena
  46 // allocation I do not need a destructor to reclaim storage.
  47 class Block_Array : public ResourceObj {
  48   friend class VMStructs;
  49   uint _size;                   // allocated size, as opposed to formal limit
  50   debug_only(uint _limit;)      // limit to formal domain
  51   Arena *_arena;                // Arena to allocate in
  52 protected:
  53   Block **_blocks;
  54   void grow( uint i );          // Grow array node to fit
  55 
  56 public:
  57   Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) {
  58     debug_only(_limit=0);
  59     _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize );


 366 // Build an array of Basic Block pointers, one per Node.
 367 class PhaseCFG : public Phase {
 368   friend class VMStructs;
 369  private:
 370 
 371   // Root of whole program
 372   RootNode* _root;
 373 
 374   // The block containing the root node
 375   Block* _root_block;
 376 
 377   // List of basic blocks that are created during CFG creation
 378   Block_List _blocks;
 379 
 380   // Count of basic blocks
 381   uint _number_of_blocks;
 382 
 383   // Arena for the blocks to be stored in
 384   Arena* _block_arena;
 385 






 386   // The matcher for this compilation
 387   Matcher& _matcher;
 388 
 389   // Map nodes to owning basic block
 390   Block_Array _node_to_block_mapping;
 391 
 392   // Loop from the root
 393   CFGLoop* _root_loop;
 394 
 395   // Outmost loop frequency
 396   double _outer_loop_frequency;
 397 
 398   // Per node latency estimation, valid only during GCM
 399   GrowableArray<uint>* _node_latency;
 400 
 401   // Build a proper looking cfg.  Return count of basic blocks
 402   uint build_cfg();
 403 
 404   // Build the dominator tree so that we know where we can move instructions
 405   void build_dominator_tree();


 416   bool schedule_early(VectorSet &visited, Node_List &roots);
 417 
 418   // For each node, find the latest block it can be scheduled into
 419   // and then select the cheapest block between the latest and earliest
 420   // block to place the node.
 421   void schedule_late(VectorSet &visited, Node_List &stack);
 422 
 423   // Compute the (backwards) latency of a node from a single use
 424   int latency_from_use(Node *n, const Node *def, Node *use);
 425 
 426   // Compute the (backwards) latency of a node from the uses of this instruction
 427   void partial_latency_of_defs(Node *n);
 428 
 429   // Compute the instruction global latency with a backwards walk
 430   void compute_latencies_backwards(VectorSet &visited, Node_List &stack);
 431 
 432   // Pick a block between early and late that is a cheaper alternative
 433   // to late. Helper for schedule_late.
 434   Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
 435 
 436   bool schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call);
 437   void set_next_call(Block* block, Node* n, VectorSet& next_call);
 438   void needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call);
 439 
 440   // Perform basic-block local scheduling
 441   Node* select(Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, VectorSet& next_call, uint sched_slot);


 442 
 443   // Schedule a call next in the block
 444   uint sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray<int>& ready_cnt, MachCallNode* mcall, VectorSet& next_call);
 445 
 446   // Cleanup if any code lands between a Call and his Catch
 447   void call_catch_cleanup(Block* block);
 448 
 449   Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx);
 450   void  catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx);
 451 
 452   // Detect implicit-null-check opportunities.  Basically, find NULL checks
 453   // with suitable memory ops nearby.  Use the memory op to do the NULL check.
 454   // I can generate a memory op if there is not one nearby.
 455   void implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons);
 456 
 457   // Perform a Depth First Search (DFS).
 458   // Setup 'vertex' as DFS to vertex mapping.
 459   // Setup 'semi' as vertex to DFS mapping.
 460   // Set 'parent' to DFS parent.
 461   uint do_DFS(Tarjan* tarjan, uint rpo_counter);




  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #ifndef SHARE_VM_OPTO_BLOCK_HPP
  26 #define SHARE_VM_OPTO_BLOCK_HPP
  27 
  28 #include "opto/multnode.hpp"
  29 #include "opto/node.hpp"
  30 #include "opto/phase.hpp"
  31 
  32 // Optimization - Graph Style
  33 
  34 class Block;
  35 class CFGLoop;
  36 class MachCallNode;
  37 class Matcher;
  38 class RootNode;
  39 class VectorSet;
  40 class PhaseChaitin;
  41 struct Tarjan;
  42 
  43 //------------------------------Block_Array------------------------------------
  44 // Map dense integer indices to Blocks.  Uses classic doubling-array trick.
  45 // Abstractly provides an infinite array of Block*'s, initialized to NULL.
  46 // Note that the constructor just zeros things, and since I use Arena
  47 // allocation I do not need a destructor to reclaim storage.
  48 class Block_Array : public ResourceObj {
  49   friend class VMStructs;
  50   uint _size;                   // allocated size, as opposed to formal limit
  51   debug_only(uint _limit;)      // limit to formal domain
  52   Arena *_arena;                // Arena to allocate in
  53 protected:
  54   Block **_blocks;
  55   void grow( uint i );          // Grow array node to fit
  56 
  57 public:
  58   Block_Array(Arena *a) : _arena(a), _size(OptoBlockListSize) {
  59     debug_only(_limit=0);
  60     _blocks = NEW_ARENA_ARRAY( a, Block *, OptoBlockListSize );


 367 // Build an array of Basic Block pointers, one per Node.
 368 class PhaseCFG : public Phase {
 369   friend class VMStructs;
 370  private:
 371 
 372   // Root of whole program
 373   RootNode* _root;
 374 
 375   // The block containing the root node
 376   Block* _root_block;
 377 
 378   // List of basic blocks that are created during CFG creation
 379   Block_List _blocks;
 380 
 381   // Count of basic blocks
 382   uint _number_of_blocks;
 383 
 384   // Arena for the blocks to be stored in
 385   Arena* _block_arena;
 386 
 387   // Info used for scheduling
 388   PhaseChaitin* _regalloc;
 389 
 390   // Register pressure heuristic used?
 391   bool _scheduling_for_pressure;
 392 
 393   // The matcher for this compilation
 394   Matcher& _matcher;
 395 
 396   // Map nodes to owning basic block
 397   Block_Array _node_to_block_mapping;
 398 
 399   // Loop from the root
 400   CFGLoop* _root_loop;
 401 
 402   // Outmost loop frequency
 403   double _outer_loop_frequency;
 404 
 405   // Per node latency estimation, valid only during GCM
 406   GrowableArray<uint>* _node_latency;
 407 
 408   // Build a proper looking cfg.  Return count of basic blocks
 409   uint build_cfg();
 410 
 411   // Build the dominator tree so that we know where we can move instructions
 412   void build_dominator_tree();


 423   bool schedule_early(VectorSet &visited, Node_List &roots);
 424 
 425   // For each node, find the latest block it can be scheduled into
 426   // and then select the cheapest block between the latest and earliest
 427   // block to place the node.
 428   void schedule_late(VectorSet &visited, Node_List &stack);
 429 
 430   // Compute the (backwards) latency of a node from a single use
 431   int latency_from_use(Node *n, const Node *def, Node *use);
 432 
 433   // Compute the (backwards) latency of a node from the uses of this instruction
 434   void partial_latency_of_defs(Node *n);
 435 
 436   // Compute the instruction global latency with a backwards walk
 437   void compute_latencies_backwards(VectorSet &visited, Node_List &stack);
 438 
 439   // Pick a block between early and late that is a cheaper alternative
 440   // to late. Helper for schedule_late.
 441   Block* hoist_to_cheaper_block(Block* LCA, Block* early, Node* self);
 442 
 443   bool schedule_local(Block* block, GrowableArray<int>& ready_cnt, VectorSet& next_call, intptr_t* recacl_pressure_nodes);
 444   void set_next_call(Block* block, Node* n, VectorSet& next_call);
 445   void needed_for_next_call(Block* block, Node* this_call, VectorSet& next_call);
 446 
 447   // Perform basic-block local scheduling
 448   Node* select(Block* block, Node_List& worklist, GrowableArray<int>& ready_cnt, VectorSet& next_call, uint sched_slot,
 449                intptr_t* recacl_pressure_nodes);
 450   void adjust_register_pressure(Node* n, Block* block, intptr_t *recalc_pressure_nodes, bool finalize_mode);
 451 
 452   // Schedule a call next in the block
 453   uint sched_call(Block* block, uint node_cnt, Node_List& worklist, GrowableArray<int>& ready_cnt, MachCallNode* mcall, VectorSet& next_call);
 454 
 455   // Cleanup if any code lands between a Call and his Catch
 456   void call_catch_cleanup(Block* block);
 457 
 458   Node* catch_cleanup_find_cloned_def(Block* use_blk, Node* def, Block* def_blk, int n_clone_idx);
 459   void  catch_cleanup_inter_block(Node *use, Block *use_blk, Node *def, Block *def_blk, int n_clone_idx);
 460 
 461   // Detect implicit-null-check opportunities.  Basically, find NULL checks
 462   // with suitable memory ops nearby.  Use the memory op to do the NULL check.
 463   // I can generate a memory op if there is not one nearby.
 464   void implicit_null_check(Block* block, Node *proj, Node *val, int allowed_reasons);
 465 
 466   // Perform a Depth First Search (DFS).
 467   // Setup 'vertex' as DFS to vertex mapping.
 468   // Setup 'semi' as vertex to DFS mapping.
 469   // Set 'parent' to DFS parent.
 470   uint do_DFS(Tarjan* tarjan, uint rpo_counter);


< prev index next >