< prev index next >

src/hotspot/share/opto/loopnode.hpp

Print this page
*** 41,10 ***
--- 41,11 ---
  class Node;
  class OuterStripMinedLoopEndNode;
  class PredicateBlock;
  class PathFrequency;
  class PhaseIdealLoop;
+ class UnswitchCandidate;
  class LoopSelector;
  class UnswitchedLoopSelector;
  class VectorSet;
  class VSharedData;
  class Invariance;

*** 83,11 ***
           LoopNestLongOuterLoop = 1<<16,
           MultiversionFastLoop         = 1<<17,
           MultiversionSlowLoop         = 2<<17,
           MultiversionDelayedSlowLoop  = 3<<17,
           MultiversionFlagsMask        = 3<<17,
!        };
    char _unswitch_count;
    enum { _unswitch_max=3 };
  
    // Expected trip count from profile data
    float _profile_trip_cnt;
--- 84,11 ---
           LoopNestLongOuterLoop = 1<<16,
           MultiversionFastLoop         = 1<<17,
           MultiversionSlowLoop         = 2<<17,
           MultiversionDelayedSlowLoop  = 3<<17,
           MultiversionFlagsMask        = 3<<17,
!          FlatArrays            = 1<<18};
    char _unswitch_count;
    enum { _unswitch_max=3 };
  
    // Expected trip count from profile data
    float _profile_trip_cnt;

*** 106,10 ***
--- 107,11 ---
    bool is_strip_mined() const { return _loop_flags & StripMined; }
    bool is_profile_trip_failed() const { return _loop_flags & ProfileTripFailed; }
    bool is_subword_loop() const { return _loop_flags & SubwordLoop; }
    bool is_loop_nest_inner_loop() const { return _loop_flags & LoopNestInnerLoop; }
    bool is_loop_nest_outer_loop() const { return _loop_flags & LoopNestLongOuterLoop; }
+   bool is_flat_arrays() const { return _loop_flags & FlatArrays; }
  
    void mark_partial_peel_failed() { _loop_flags |= PartialPeelFailed; }
    void mark_was_slp() { _loop_flags |= WasSlpAnalyzed; }
    void mark_passed_slp() { _loop_flags |= PassedSlpAnalysis; }
    void mark_do_unroll_only() { _loop_flags |= DoUnrollOnly; }

*** 119,10 ***
--- 121,11 ---
    void clear_strip_mined() { _loop_flags &= ~StripMined; }
    void mark_profile_trip_failed() { _loop_flags |= ProfileTripFailed; }
    void mark_subword_loop() { _loop_flags |= SubwordLoop; }
    void mark_loop_nest_inner_loop() { _loop_flags |= LoopNestInnerLoop; }
    void mark_loop_nest_outer_loop() { _loop_flags |= LoopNestLongOuterLoop; }
+   void mark_flat_arrays() { _loop_flags |= FlatArrays; }
  
    int unswitch_max() { return _unswitch_max; }
    int unswitch_count() { return _unswitch_count; }
  
    void set_unswitch_count(int val) {

*** 720,10 ***
--- 723,11 ---
    bool policy_peel_only( PhaseIdealLoop *phase ) const;
  
    // Return TRUE or FALSE if the loop should be unswitched -- clone
    // loop with an invariant test
    bool policy_unswitching( PhaseIdealLoop *phase ) const;
+   bool no_unswitch_candidate() const;
  
    // Micro-benchmark spamming.  Remove empty loops.
    bool do_remove_empty_loop( PhaseIdealLoop *phase );
  
    // Convert one iteration loop into normal code.

*** 1471,25 ***
    // Clone loop with an invariant test (that does not exit) and
    // insert a clone of the test that selects which version to
    // execute.
    void do_unswitching(IdealLoopTree* loop, Node_List& old_new);
  
!   IfNode* find_unswitch_candidate(const IdealLoopTree* loop) const;
  
   private:
    static bool has_control_dependencies_from_predicates(LoopNode* head);
    static void revert_to_normal_loop(const LoopNode* loop_head);
  
    void hoist_invariant_check_casts(const IdealLoopTree* loop, const Node_List& old_new,
!                                    const UnswitchedLoopSelector& unswitched_loop_selector);
    void add_unswitched_loop_version_bodies_to_igvn(IdealLoopTree* loop, const Node_List& old_new);
    static void increment_unswitch_counts(LoopNode* original_head, LoopNode* new_head);
    void remove_unswitch_candidate_from_loops(const Node_List& old_new, const UnswitchedLoopSelector& unswitched_loop_selector);
  #ifndef PRODUCT
    static void trace_loop_unswitching_count(IdealLoopTree* loop, LoopNode* original_head);
    static void trace_loop_unswitching_impossible(const LoopNode* original_head);
    static void trace_loop_unswitching_result(const UnswitchedLoopSelector& unswitched_loop_selector,
                                              const LoopNode* original_head, const LoopNode* new_head);
    static void trace_loop_multiversioning_result(const LoopSelector& loop_selector,
                                                  const LoopNode* original_head, const LoopNode* new_head);
  #endif
  
--- 1475,27 ---
    // Clone loop with an invariant test (that does not exit) and
    // insert a clone of the test that selects which version to
    // execute.
    void do_unswitching(IdealLoopTree* loop, Node_List& old_new);
  
!   IfNode* find_unswitch_candidates(const IdealLoopTree* loop, Node_List& flat_array_checks) const;
+   IfNode* find_unswitch_candidate_from_idoms(const IdealLoopTree* loop) const;
  
   private:
    static bool has_control_dependencies_from_predicates(LoopNode* head);
    static void revert_to_normal_loop(const LoopNode* loop_head);
  
    void hoist_invariant_check_casts(const IdealLoopTree* loop, const Node_List& old_new,
!                                    const UnswitchCandidate& unswitch_candidate, const IfNode* loop_selector);
    void add_unswitched_loop_version_bodies_to_igvn(IdealLoopTree* loop, const Node_List& old_new);
    static void increment_unswitch_counts(LoopNode* original_head, LoopNode* new_head);
    void remove_unswitch_candidate_from_loops(const Node_List& old_new, const UnswitchedLoopSelector& unswitched_loop_selector);
  #ifndef PRODUCT
    static void trace_loop_unswitching_count(IdealLoopTree* loop, LoopNode* original_head);
    static void trace_loop_unswitching_impossible(const LoopNode* original_head);
    static void trace_loop_unswitching_result(const UnswitchedLoopSelector& unswitched_loop_selector,
+                                             const UnswitchCandidate& unswitch_candidate,
                                              const LoopNode* original_head, const LoopNode* new_head);
    static void trace_loop_multiversioning_result(const LoopSelector& loop_selector,
                                                  const LoopNode* original_head, const LoopNode* new_head);
  #endif
  

*** 1627,11 ***
--- 1633,13 ---
    bool split_up( Node *n, Node *blk1, Node *blk2 );
  
    Node* place_outside_loop(Node* useblock, IdealLoopTree* loop) const;
    Node* try_move_store_before_loop(Node* n, Node *n_ctrl);
    void try_move_store_after_loop(Node* n);
+   void move_flat_array_check_out_of_loop(Node* n);
    bool identical_backtoback_ifs(Node *n);
+   bool flat_array_element_type_check(Node *n);
    bool can_split_if(Node *n_ctrl);
    bool cannot_split_division(const Node* n, const Node* region) const;
    static bool is_divisor_loop_phi(const Node* divisor, const Node* loop);
    bool loop_phi_backedge_type_contains_zero(const Node* phi_divisor, const Type* zero) const;
  

*** 1817,10 ***
--- 1825,12 ---
  
    bool can_move_to_inner_loop(Node* n, LoopNode* n_loop, Node* x);
  
    void pin_array_access_nodes_dependent_on(Node* ctrl);
  
+   void collect_flat_array_checks(const IdealLoopTree* loop, Node_List& flat_array_checks) const;
+ 
    Node* ensure_node_and_inputs_are_above_pre_end(CountedLoopEndNode* pre_end, Node* node);
  
    ConINode* intcon(jint i);
  
    ConLNode* longcon(jlong i);
< prev index next >