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);
|