src/share/vm/opto/loopnode.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/share/vm/opto

src/share/vm/opto/loopnode.hpp

Print this page
rev 8571 : 8080289: Intermediate writes in a loop not eliminated by optimizer
Summary: Move Stores out of loop (after or before) when possible
Reviewed-by:


 343   uint8_t _irreducible:1,       // True if irreducible
 344           _has_call:1,          // True if has call safepoint
 345           _has_sfpt:1,          // True if has non-call safepoint
 346           _rce_candidate:1;     // True if candidate for range check elimination
 347 
 348   Node_List* _safepts;          // List of safepoints in this loop
 349   Node_List* _required_safept;  // A inner loop cannot delete these safepts;
 350   bool  _allow_optimizations;   // Allow loop optimizations
 351 
 352   IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail )
 353     : _parent(0), _next(0), _child(0),
 354       _head(head), _tail(tail),
 355       _phase(phase),
 356       _safepts(NULL),
 357       _required_safept(NULL),
 358       _allow_optimizations(true),
 359       _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
 360   { }
 361 
 362   // Is 'l' a member of 'this'?
 363   int is_member( const IdealLoopTree *l ) const; // Test for nested membership
 364 
 365   // Set loop nesting depth.  Accumulate has_call bits.
 366   int set_nest( uint depth );
 367 
 368   // Split out multiple fall-in edges from the loop header.  Move them to a
 369   // private RegionNode before the loop.  This becomes the loop landing pad.
 370   void split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt );
 371 
 372   // Split out the outermost loop from this shared header.
 373   void split_outer_loop( PhaseIdealLoop *phase );
 374 
 375   // Merge all the backedges from the shared header into a private Region.
 376   // Feed that region as the one backedge to this loop.
 377   void merge_many_backedges( PhaseIdealLoop *phase );
 378 
 379   // Split shared headers and insert loop landing pads.
 380   // Insert a LoopNode to replace the RegionNode.
 381   // Returns TRUE if loop tree is structurally changed.
 382   bool beautify_loops( PhaseIdealLoop *phase );
 383 


1040   // Conversion of fill/copy patterns into intrisic versions
1041   bool do_intrinsify_fill();
1042   bool intrinsify_fill(IdealLoopTree* lpt);
1043   bool match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& store_value,
1044                        Node*& shift, Node*& offset);
1045 
1046 private:
1047   // Return a type based on condition control flow
1048   const TypeInt* filtered_type( Node *n, Node* n_ctrl);
1049   const TypeInt* filtered_type( Node *n ) { return filtered_type(n, NULL); }
1050  // Helpers for filtered type
1051   const TypeInt* filtered_type_from_dominators( Node* val, Node *val_ctrl);
1052 
1053   // Helper functions
1054   Node *spinup( Node *iff, Node *new_false, Node *new_true, Node *region, Node *phi, small_cache *cache );
1055   Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true );
1056   void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true );
1057   bool split_up( Node *n, Node *blk1, Node *blk2 );
1058   void sink_use( Node *use, Node *post_loop );
1059   Node *place_near_use( Node *useblock ) const;


1060 
1061   bool _created_loop_node;
1062 public:
1063   void set_created_loop_node() { _created_loop_node = true; }
1064   bool created_loop_node()     { return _created_loop_node; }
1065   void register_new_node( Node *n, Node *blk );
1066 
1067 #ifdef ASSERT
1068   void dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA);
1069 #endif
1070 
1071 #ifndef PRODUCT
1072   void dump( ) const;
1073   void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
1074   void rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const;
1075   void verify() const;          // Major slow  :-)
1076   void verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const;
1077   IdealLoopTree *get_loop_idx(Node* n) const {
1078     // Dead nodes have no loop, so return the top level loop instead
1079     return _nodes[n->_idx] ? (IdealLoopTree*)_nodes[n->_idx] : _ltree_root;




 343   uint8_t _irreducible:1,       // True if irreducible
 344           _has_call:1,          // True if has call safepoint
 345           _has_sfpt:1,          // True if has non-call safepoint
 346           _rce_candidate:1;     // True if candidate for range check elimination
 347 
 348   Node_List* _safepts;          // List of safepoints in this loop
 349   Node_List* _required_safept;  // A inner loop cannot delete these safepts;
 350   bool  _allow_optimizations;   // Allow loop optimizations
 351 
 352   IdealLoopTree( PhaseIdealLoop* phase, Node *head, Node *tail )
 353     : _parent(0), _next(0), _child(0),
 354       _head(head), _tail(tail),
 355       _phase(phase),
 356       _safepts(NULL),
 357       _required_safept(NULL),
 358       _allow_optimizations(true),
 359       _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
 360   { }
 361 
 362   // Is 'l' a member of 'this'?
 363   bool is_member(const IdealLoopTree *l) const; // Test for nested membership
 364 
 365   // Set loop nesting depth.  Accumulate has_call bits.
 366   int set_nest( uint depth );
 367 
 368   // Split out multiple fall-in edges from the loop header.  Move them to a
 369   // private RegionNode before the loop.  This becomes the loop landing pad.
 370   void split_fall_in( PhaseIdealLoop *phase, int fall_in_cnt );
 371 
 372   // Split out the outermost loop from this shared header.
 373   void split_outer_loop( PhaseIdealLoop *phase );
 374 
 375   // Merge all the backedges from the shared header into a private Region.
 376   // Feed that region as the one backedge to this loop.
 377   void merge_many_backedges( PhaseIdealLoop *phase );
 378 
 379   // Split shared headers and insert loop landing pads.
 380   // Insert a LoopNode to replace the RegionNode.
 381   // Returns TRUE if loop tree is structurally changed.
 382   bool beautify_loops( PhaseIdealLoop *phase );
 383 


1040   // Conversion of fill/copy patterns into intrisic versions
1041   bool do_intrinsify_fill();
1042   bool intrinsify_fill(IdealLoopTree* lpt);
1043   bool match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& store_value,
1044                        Node*& shift, Node*& offset);
1045 
1046 private:
1047   // Return a type based on condition control flow
1048   const TypeInt* filtered_type( Node *n, Node* n_ctrl);
1049   const TypeInt* filtered_type( Node *n ) { return filtered_type(n, NULL); }
1050  // Helpers for filtered type
1051   const TypeInt* filtered_type_from_dominators( Node* val, Node *val_ctrl);
1052 
1053   // Helper functions
1054   Node *spinup( Node *iff, Node *new_false, Node *new_true, Node *region, Node *phi, small_cache *cache );
1055   Node *find_use_block( Node *use, Node *def, Node *old_false, Node *new_false, Node *old_true, Node *new_true );
1056   void handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true );
1057   bool split_up( Node *n, Node *blk1, Node *blk2 );
1058   void sink_use( Node *use, Node *post_loop );
1059   Node *place_near_use( Node *useblock ) const;
1060   Node* try_move_store_before_loop(Node* n, Node *n_ctrl);
1061   void try_move_store_after_loop(Node* n);
1062 
1063   bool _created_loop_node;
1064 public:
1065   void set_created_loop_node() { _created_loop_node = true; }
1066   bool created_loop_node()     { return _created_loop_node; }
1067   void register_new_node( Node *n, Node *blk );
1068 
1069 #ifdef ASSERT
1070   void dump_bad_graph(const char* msg, Node* n, Node* early, Node* LCA);
1071 #endif
1072 
1073 #ifndef PRODUCT
1074   void dump( ) const;
1075   void dump( IdealLoopTree *loop, uint rpo_idx, Node_List &rpo_list ) const;
1076   void rpo( Node *start, Node_Stack &stk, VectorSet &visited, Node_List &rpo_list ) const;
1077   void verify() const;          // Major slow  :-)
1078   void verify_compare( Node *n, const PhaseIdealLoop *loop_verify, VectorSet &visited ) const;
1079   IdealLoopTree *get_loop_idx(Node* n) const {
1080     // Dead nodes have no loop, so return the top level loop instead
1081     return _nodes[n->_idx] ? (IdealLoopTree*)_nodes[n->_idx] : _ltree_root;


src/share/vm/opto/loopnode.hpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File