* gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer)
authorJeff Law <law@redhat.com>
Wed, 22 Nov 2017 20:31:14 +0000 (13:31 -0700)
committerJeff Law <law@gcc.gnu.org>
Wed, 22 Nov 2017 20:31:14 +0000 (13:31 -0700)
Initialize vr_values.
(evrp_range_analyzer::try_find_new_range): Call methods attached to
vr_values via vr_values class instance rather than delegators.
(evrp_range_analyzer::record_ranges_from_phis): Likewise.
(evrp_range_analyzer::record_ranges_from_stmt): Likewise.
(evrp_range_analyzer::push_value_range): Likewise.
(evrp_range_analyzer::pop_value_range): Likewise.
* gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove
most delegators.  Those remaining are exposed as public interfaces.
Make vr_values a pointer and private.
(evrp_range_analyzer::~evrp_range_analyzer): Delete the attached
vr_values.
(evrp_range_analyzer::get_vr_value): New method.
* gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN.
(evrp_folder::evrp_folder): New ctor to initialize vr_values.
(class evrp_dom_walker): Attach evrp_folder class, initialize
it in the ctor.  Remove temporary delegators.
(evrp_dom_walker::before_dom_children): Call methods in attached
evrp_range_analyzer class via class instance pointer.  Use
free value_range_constant_singleton to remove need for
op_with_constant_singleton_value delegator method.  Do not
create a vrp_prop class instance for every call!  Narrow
scope of a couple variables.
(evrp_dom_walker::cleanup): Call methods in attached
evrp_range_analyzer class via class instance pointer.
* vr-values.h (class vr_values): Privatize many methods and
data members.

From-SVN: r255074

gcc/ChangeLog
gcc/gimple-ssa-evrp-analyze.c
gcc/gimple-ssa-evrp-analyze.h
gcc/gimple-ssa-evrp.c
gcc/vr-values.h

index 50f5a73..4ecf5bc 100644 (file)
@@ -1,3 +1,34 @@
+2017-11-22  Jeff Law  <law@redhat.com>
+
+       * gimple-ssa-evrp-analyze.c (evrp_range_analyzer::evrp_range_analyzer)
+       Initialize vr_values.
+       (evrp_range_analyzer::try_find_new_range): Call methods attached to
+       vr_values via vr_values class instance rather than delegators.
+       (evrp_range_analyzer::record_ranges_from_phis): Likewise.
+       (evrp_range_analyzer::record_ranges_from_stmt): Likewise.
+       (evrp_range_analyzer::push_value_range): Likewise.
+       (evrp_range_analyzer::pop_value_range): Likewise.
+       * gimple-ssa-evrp-analyze.h (class evrp_range_analyzer): Remove
+       most delegators.  Those remaining are exposed as public interfaces.
+       Make vr_values a pointer and private.
+       (evrp_range_analyzer::~evrp_range_analyzer): Delete the attached
+       vr_values.
+       (evrp_range_analyzer::get_vr_value): New method.
+       * gimple-ssa-evrp.c (class evrp_folder): Use DISABLE_COPY_AND_ASSIGN.
+       (evrp_folder::evrp_folder): New ctor to initialize vr_values.
+       (class evrp_dom_walker): Attach evrp_folder class, initialize
+       it in the ctor.  Remove temporary delegators.
+       (evrp_dom_walker::before_dom_children): Call methods in attached
+       evrp_range_analyzer class via class instance pointer.  Use
+       free value_range_constant_singleton to remove need for
+       op_with_constant_singleton_value delegator method.  Do not
+       create a vrp_prop class instance for every call!  Narrow
+       scope of a couple variables.
+       (evrp_dom_walker::cleanup): Call methods in attached
+       evrp_range_analyzer class via class instance pointer.
+       * vr-values.h (class vr_values): Privatize many methods and
+       data members.
+
 2017-11-22  Richard Sandiford  <richard.sandiford@linaro.org>
 
        * tree.def (REDUC_MAX_EXPR, REDUC_MIN_EXPR, REDUC_PLUS_EXPR): Delete.
index 9e58183..c387779 100644 (file)
@@ -53,6 +53,7 @@ evrp_range_analyzer::evrp_range_analyzer () : stack (10)
       FOR_EACH_EDGE (e, ei, bb->preds)
         e->flags |= EDGE_EXECUTABLE;
     }
+  vr_values = new class vr_values;
 }
 
 void
@@ -73,8 +74,8 @@ evrp_range_analyzer::try_find_new_range (tree name,
   value_range *old_vr = get_value_range (name);
 
   /* Discover VR when condition is true.  */
-  extract_range_for_var_from_comparison_expr (name, code, op,
-                                             limit, &vr);
+  vr_values->extract_range_for_var_from_comparison_expr (name, code, op,
+                                                        limit, &vr);
   /* If we found any usable VR, set the VR to ssa_name and create a
      PUSH old value in the stack with the old VR.  */
   if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
@@ -83,7 +84,7 @@ evrp_range_analyzer::try_find_new_range (tree name,
          && vrp_operand_equal_p (old_vr->min, vr.min)
          && vrp_operand_equal_p (old_vr->max, vr.max))
        return NULL;
-      value_range *new_vr = vr_values.vrp_value_range_pool.allocate ();
+      value_range *new_vr = vr_values->vrp_value_range_pool.allocate ();
       *new_vr = vr;
       return new_vr;
     }
@@ -167,7 +168,7 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
       value_range vr_result = VR_INITIALIZER;
       bool interesting = stmt_interesting_for_vrp (phi);
       if (!has_unvisited_preds && interesting)
-       extract_range_from_phi_node (phi, &vr_result);
+       vr_values->extract_range_from_phi_node (phi, &vr_result);
       else
        {
          set_value_range_to_varying (&vr_result);
@@ -179,9 +180,9 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
          if (interesting
              && (l = loop_containing_stmt (phi))
              && l->header == gimple_bb (phi))
-         adjust_range_with_scev (&vr_result, l, phi, lhs);
+         vr_values->adjust_range_with_scev (&vr_result, l, phi, lhs);
        }
-      update_value_range (lhs, &vr_result);
+      vr_values->update_value_range (lhs, &vr_result);
 
       /* Set the SSA with the value range.  */
       if (INTEGRAL_TYPE_P (TREE_TYPE (lhs)))
@@ -216,11 +217,11 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
     {
       edge taken_edge;
       value_range vr = VR_INITIALIZER;
-      extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
+      vr_values->extract_range_from_stmt (stmt, &taken_edge, &output, &vr);
       if (output
          && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE))
        {
-         update_value_range (output, &vr);
+         vr_values->update_value_range (output, &vr);
 
          /* Set the SSA with the value range.  */
          if (INTEGRAL_TYPE_P (TREE_TYPE (output)))
@@ -240,10 +241,10 @@ evrp_range_analyzer::record_ranges_from_stmt (gimple *stmt)
            set_ptr_nonnull (output);
        }
       else
-       set_defs_to_varying (stmt);
+       vr_values->set_defs_to_varying (stmt);
     }
   else
-    set_defs_to_varying (stmt);
+    vr_values->set_defs_to_varying (stmt);
 
   /* See if we can derive a range for any of STMT's operands.  */
   tree op;
@@ -319,7 +320,7 @@ evrp_range_analyzer::push_value_range (tree var, value_range *vr)
       fprintf (dump_file, "\n");
     }
   stack.safe_push (std::make_pair (var, get_value_range (var)));
-  set_vr_value (var, vr);
+  vr_values->set_vr_value (var, vr);
 }
 
 /* Pop the Value Range from the vrp_stack and update VAR with it.  */
@@ -337,7 +338,7 @@ evrp_range_analyzer::pop_value_range (tree var)
       dump_value_range (dump_file, vr);
       fprintf (dump_file, "\n");
     }
-  set_vr_value (var, vr);
+  vr_values->set_vr_value (var, vr);
   stack.pop ();
   return vr;
 }
index 2e6c609..6376780 100644 (file)
@@ -24,16 +24,45 @@ class evrp_range_analyzer
 {
  public:
   evrp_range_analyzer (void);
-  ~evrp_range_analyzer (void) { stack.release (); }
+  ~evrp_range_analyzer (void)
+  {
+    delete vr_values;
+    stack.release ();
+  }
 
   void enter (basic_block);
   void leave (basic_block);
   void record_ranges_from_stmt (gimple *);
 
-  class vr_values vr_values;
+  /* Main interface to retrieve range information.  */
+  value_range *get_value_range (const_tree op)
+    { return vr_values->get_value_range (op); }
+
+  /* Dump all the current value ranges.  This is primarily
+     a debugging interface.  */
+  void dump_all_value_ranges (FILE *fp)
+    { vr_values->dump_all_value_ranges (fp); }
+
+  /* A bit of a wart.  This should ideally go away.  */
+  void vrp_visit_cond_stmt (gcond *cond, edge *e)
+    { return vr_values->vrp_visit_cond_stmt (cond, e); }
+
+  /* Get the underlying vr_values class instance.  If TRANSFER is
+     true, then we are transferring ownership.  Else we keep ownership.
+
+     This should be converted to a unique_ptr.  */
+  class vr_values *get_vr_values (bool transfer)
+    {
+      class vr_values *x = vr_values;
+      if (transfer)
+       vr_values = NULL;
+      return x;
+    }
 
  private:
   DISABLE_COPY_AND_ASSIGN (evrp_range_analyzer);
+  class vr_values *vr_values;
+
   void push_value_range (tree var, value_range *vr);
   value_range *pop_value_range (tree var);
   value_range *try_find_new_range (tree, tree op, tree_code code, tree limit);
@@ -42,30 +71,6 @@ class evrp_range_analyzer
 
   /* STACK holds the old VR.  */
   auto_vec<std::pair <tree, value_range*> > stack;
-
-  /* Temporary delegators.  */
-  value_range *get_value_range (const_tree op)
-    { return vr_values.get_value_range (op); }
-  bool update_value_range (const_tree op, value_range *vr)
-    { return vr_values.update_value_range (op, vr); }
-  void extract_range_from_phi_node (gphi *phi, value_range *vr)
-    { vr_values.extract_range_from_phi_node (phi, vr); }
-  void adjust_range_with_scev (value_range *vr, struct loop *loop,
-                               gimple *stmt, tree var)
-    { vr_values.adjust_range_with_scev (vr, loop, stmt, var); }
-  void extract_range_from_stmt (gimple *stmt, edge *taken_edge_p,
-                                tree *output_p, value_range *vr)
-    { vr_values.extract_range_from_stmt (stmt, taken_edge_p, output_p, vr); }
-  void set_defs_to_varying (gimple *stmt)
-    { return vr_values.set_defs_to_varying (stmt); }
-  void set_vr_value (tree name, value_range *vr)
-    { vr_values.set_vr_value (name, vr); }
-  void extract_range_for_var_from_comparison_expr (tree var,
-                                                  enum tree_code cond_code,
-                                                  tree op, tree limit,
-                                                  value_range *vr_p)
-    { vr_values.extract_range_for_var_from_comparison_expr (var, cond_code,
-                                                           op, limit, vr_p); }
 };
 
 #endif /* GCC_GIMPLE_SSA_EVRP_ANALYZE_H */
index 27a983d..a554cf9 100644 (file)
@@ -46,8 +46,11 @@ class evrp_folder : public substitute_and_fold_engine
 {
  public:
   tree get_value (tree) FINAL OVERRIDE;
-
+  evrp_folder (class vr_values *vr_values_) : vr_values (vr_values_) { }
   class vr_values *vr_values;
+
+ private:
+  DISABLE_COPY_AND_ASSIGN (evrp_folder);
 };
 
 tree
@@ -63,7 +66,9 @@ evrp_folder::get_value (tree op)
 class evrp_dom_walker : public dom_walker
 {
 public:
-  evrp_dom_walker () : dom_walker (CDI_DOMINATORS)
+  evrp_dom_walker ()
+    : dom_walker (CDI_DOMINATORS),
+      evrp_folder (evrp_range_analyzer.get_vr_values (false))
     {
       need_eh_cleanup = BITMAP_ALLOC (NULL);
     }
@@ -82,14 +87,7 @@ public:
   auto_vec<gimple *> stmts_to_remove;
 
   class evrp_range_analyzer evrp_range_analyzer;
-
-  /* Temporary delegators.  */
-  value_range *get_value_range (const_tree op)
-    { return evrp_range_analyzer.vr_values.get_value_range (op); }
-  tree op_with_constant_singleton_value_range (tree op)
-    { return evrp_range_analyzer.vr_values.op_with_constant_singleton_value_range (op); }
-  void vrp_visit_cond_stmt (gcond *cond, edge *e)
-    { evrp_range_analyzer.vr_values.vrp_visit_cond_stmt (cond, e); }
+  class evrp_folder evrp_folder;
 };
 
 edge
@@ -108,8 +106,9 @@ evrp_dom_walker::before_dom_children (basic_block bb)
       if (virtual_operand_p (lhs))
        continue;
 
+      value_range *vr = evrp_range_analyzer.get_value_range (lhs);
       /* Mark PHIs whose lhs we fully propagate for removal.  */
-      tree val = op_with_constant_singleton_value_range (lhs);
+      tree val = value_range_constant_singleton (vr);
       if (val && may_propagate_copy (lhs, val))
        {
          stmts_to_remove.safe_push (phi);
@@ -139,7 +138,7 @@ evrp_dom_walker::before_dom_children (basic_block bb)
 
       if (gcond *cond = dyn_cast <gcond *> (stmt))
        {
-         vrp_visit_cond_stmt (cond, &taken_edge);
+         evrp_range_analyzer.vrp_visit_cond_stmt (cond, &taken_edge);
          if (taken_edge)
            {
              if (taken_edge->flags & EDGE_TRUE_VALUE)
@@ -153,16 +152,15 @@ evrp_dom_walker::before_dom_children (basic_block bb)
        }
       else if (stmt_interesting_for_vrp (stmt))
        {
-         value_range vr = VR_INITIALIZER;
          output = get_output_for_vrp (stmt);
          if (output)
            {
              tree val;
-             vr = *get_value_range (output);
+             value_range *vr = evrp_range_analyzer.get_value_range (output);
 
              /* Mark stmts whose output we fully propagate for removal.  */
-             if ((vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
-                 && (val = op_with_constant_singleton_value_range (output))
+             if ((vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
+                 && (val = value_range_constant_singleton (vr))
                  && may_propagate_copy (output, val)
                  && !stmt_could_throw_p (stmt)
                  && !gimple_has_side_effects (stmt))
@@ -174,8 +172,6 @@ evrp_dom_walker::before_dom_children (basic_block bb)
        }
 
       /* Try folding stmts with the VR discovered.  */
-      class evrp_folder evrp_folder;
-      evrp_folder.vr_values = &evrp_range_analyzer.vr_values;
       bool did_replace = evrp_folder.replace_uses_in (stmt);
       if (fold_stmt (&gsi, follow_single_use_edges)
          || did_replace)
@@ -222,7 +218,8 @@ evrp_dom_walker::before_dom_children (basic_block bb)
          if (TREE_CODE (arg) != SSA_NAME
              || virtual_operand_p (arg))
            continue;
-         tree val = op_with_constant_singleton_value_range (arg);
+         value_range *vr = evrp_range_analyzer.get_value_range (arg);
+         tree val = value_range_constant_singleton (vr);
          if (val && may_propagate_copy (arg, val))
            propagate_value (use_p, val);
        }
@@ -245,7 +242,7 @@ evrp_dom_walker::cleanup (void)
   if (dump_file)
     {
       fprintf (dump_file, "\nValue ranges after Early VRP:\n\n");
-      evrp_range_analyzer.vr_values.dump_all_value_ranges (dump_file);
+      evrp_range_analyzer.dump_all_value_ranges (dump_file);
       fprintf (dump_file, "\n");
     }
 
index 24f013a..9eeebed 100644 (file)
@@ -40,80 +40,81 @@ class vr_values
   vr_values (void);
   ~vr_values (void);
 
-  /* Value range array.  After propagation, VR_VALUE[I] holds the range
-     of values that SSA name N_I may take.  */
-  unsigned int num_vr_values;
-  value_range **vr_value;
-  bool values_propagated;
+  value_range *get_value_range (const_tree);
 
-  /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
-     number of executable edges we saw the last time we visited the
-     node.  */
-  int *vr_phi_edge_counts;
+  void set_vr_value (tree, value_range *);
+  void set_defs_to_varying (gimple *);
+  bool update_value_range (const_tree, value_range *);
+  tree op_with_constant_singleton_value_range (tree);
+  void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
+  tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
+  void dump_all_value_ranges (FILE *);
+
+  void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
+                                                  tree, tree, value_range *);
+  void extract_range_from_phi_node (gphi *, value_range *);
+  void extract_range_basic (value_range *, gimple *);
+  void extract_range_from_assignment (value_range *, gassign *);
+  void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
+
+  void vrp_visit_cond_stmt (gcond *, edge *);
+
+  void simplify_cond_using_ranges_2 (gcond *);
+  bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+  /* This probably belongs in the lattice rather than in here.  */
+  bool values_propagated;
 
   /* Allocation pools for tree-vrp allocations.  */
   object_allocator<value_range> vrp_value_range_pool;
-  bitmap_obstack vrp_equiv_obstack;
 
-  value_range *get_value_range (const_tree);
-  void set_vr_value (tree, value_range *);
-
-  void set_defs_to_varying (gimple *);
-  bool update_value_range (const_tree, value_range *);
+ private:
+  bitmap_obstack vrp_equiv_obstack;
   void add_equivalence (bitmap *, const_tree);
   bool vrp_stmt_computes_nonzero (gimple *);
-  tree op_with_constant_singleton_value_range (tree);
   bool op_with_boolean_value_range_p (tree);
   bool check_for_binary_op_overflow (enum tree_code, tree, tree, tree, bool *);
-  void adjust_range_with_scev (value_range *, struct loop *, gimple *, tree);
   value_range get_vr_for_comparison (int);
   tree compare_name_with_value (enum tree_code, tree, tree, bool *, bool);
   tree compare_names (enum tree_code, tree, tree, bool *);
   bool two_valued_val_range_p (tree, tree *, tree *);
-
   tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code,
                                                             tree, tree,
                                                             bool *);
   tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
                                                tree, tree, bool,
                                                bool *, bool *);
-  tree vrp_evaluate_conditional (tree_code, tree, tree, gimple *);
-
-
-  void dump_all_value_ranges (FILE *);
-
-  void extract_range_for_var_from_comparison_expr (tree, enum tree_code,
-                                                  tree, tree, value_range *);
   void extract_range_from_assert (value_range *, tree);
   void extract_range_from_ssa_name (value_range *, tree);
   void extract_range_from_binary_expr (value_range *, enum tree_code,
                                       tree, tree, tree);
   void extract_range_from_unary_expr (value_range *, enum tree_code,
                                      tree, tree);
-  void extract_range_from_phi_node (gphi *, value_range *);
   void extract_range_from_cond_expr (value_range *, gassign *);
-  void extract_range_basic (value_range *, gimple *);
-  void extract_range_from_assignment (value_range *, gassign *);
-  void extract_range_from_stmt (gimple *, edge *, tree *, value_range *);
   void extract_range_from_comparison (value_range *, enum tree_code,
                                      tree, tree, tree);
-
   void vrp_visit_assignment_or_call (gimple*, tree *, value_range *);
   void vrp_visit_switch_stmt (gswitch *, edge *);
-  void vrp_visit_cond_stmt (gcond *, edge *);
-
   bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *);
   bool simplify_cond_using_ranges_1 (gcond *);
-  void simplify_cond_using_ranges_2 (gcond *);
   bool simplify_switch_using_ranges (gswitch *);
   bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *,
                                               gimple *);
   bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *);
-  bool simplify_stmt_using_ranges (gimple_stmt_iterator *);
+
+  /* Value range array.  After propagation, VR_VALUE[I] holds the range
+     of values that SSA name N_I may take.  */
+  unsigned int num_vr_values;
+  value_range **vr_value;
+
+  /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
+     number of executable edges we saw the last time we visited the
+     node.  */
+  int *vr_phi_edge_counts;
 };
 
 #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }