From ce7b251bc5a17ae04be57a7fb1db22e86adac282 Mon Sep 17 00:00:00 2001
From: Kugan Vivekanandarajah <kugan.vivekanandarajah@linaro.org>
Date: Tue, 21 Jun 2016 12:42:44 +1000
Subject: [PATCH 3/6] Refactor vrp

---
 gcc/tree-ssanames.h |  5 ---
 gcc/tree-vrp.c      | 93 +++++++++++++++++------------------------------------
 gcc/tree-vrp.h      | 65 +++++++++++++++++++++++++++++++++++++
 gcc/tree.h          | 31 ++++++++++++++++++
 4 files changed, 125 insertions(+), 69 deletions(-)
 create mode 100644 gcc/tree-vrp.h

diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h
index c81b1a1..8e66ce6 100644
--- a/gcc/tree-ssanames.h
+++ b/gcc/tree-ssanames.h
@@ -62,11 +62,6 @@ struct GTY ((variable_size)) range_info_def {
 #define num_ssa_names (vec_safe_length (cfun->gimple_df->ssa_names))
 #define ssa_name(i) ((*cfun->gimple_df->ssa_names)[(i)])
 
-
-/* Type of value ranges.  See value_range_d In tree-vrp.c for a
-   description of these types.  */
-enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
-
 /* Sets the value range to SSA.  */
 extern void set_range_info (tree, enum value_range_type, const wide_int_ref &,
 			    const wide_int_ref &);
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 23c12b5..8c87c06 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -58,32 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "omp-low.h"
 #include "target.h"
 #include "case-cfn-macros.h"
-
-/* Range of values that can be associated with an SSA_NAME after VRP
-   has executed.  */
-struct value_range
-{
-  /* Lattice value represented by this range.  */
-  enum value_range_type type;
-
-  /* Minimum and maximum values represented by this range.  These
-     values should be interpreted as follows:
-
-	- If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
-	  be NULL.
-
-	- If TYPE == VR_RANGE then MIN holds the minimum value and
-	  MAX holds the maximum value of the range [MIN, MAX].
-
-	- If TYPE == ANTI_RANGE the variable is known to NOT
-	  take any values in the range [MIN, MAX].  */
-  tree min;
-  tree max;
-
-  /* Set of SSA names whose value ranges are equivalent to this one.
-     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
-  bitmap equiv;
-};
+#include "tree-vrp.h"
 
 #define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
 
@@ -103,8 +78,6 @@ live_on_edge (edge e, tree name)
 /* Local functions.  */
 static int compare_values (tree val1, tree val2);
 static int compare_values_warnv (tree val1, tree val2, bool *);
-static void vrp_meet (value_range *, value_range *);
-static void vrp_intersect_ranges (value_range *, value_range *);
 static tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
 						     tree, tree, bool, bool *,
 						     bool *);
@@ -351,21 +324,9 @@ set_value_range_to_undefined (value_range *vr)
 }
 
 
-/* Set value range VR to VR_VARYING.  */
-
-static inline void
-set_value_range_to_varying (value_range *vr)
-{
-  vr->type = VR_VARYING;
-  vr->min = vr->max = NULL_TREE;
-  if (vr->equiv)
-    bitmap_clear (vr->equiv);
-}
-
-
 /* Set value range VR to {T, MIN, MAX, EQUIV}.  */
 
-static void
+void
 set_value_range (value_range *vr, enum value_range_type t, tree min,
 		 tree max, bitmap equiv)
 {
@@ -660,7 +621,7 @@ abs_extent_range (value_range *vr, tree min, tree max)
    If we have no values ranges recorded (ie, VRP is not running), then
    return NULL.  Otherwise create an empty range if none existed for VAR.  */
 
-static value_range *
+value_range *
 get_value_range (const_tree var)
 {
   static const value_range vr_const_varying
@@ -717,6 +678,19 @@ get_value_range (const_tree var)
   return vr;
 }
 
+/* Update the value range VR to VAR.  */
+
+void change_value_range (const_tree var, value_range *vr)
+{
+  unsigned ver = SSA_NAME_VERSION (var);
+
+  if (!vr_value)
+    return;
+
+  if (ver < num_vr_values)
+      vr_value[ver] = vr;
+}
+
 /* Return true, if VAL1 and VAL2 are equal values for VRP purposes.  */
 
 static inline bool
@@ -751,7 +725,7 @@ vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
    this function.  Do not call update_value_range when NEW_VR
    is the range object associated with another SSA name.  */
 
-static inline bool
+bool
 update_value_range (const_tree var, value_range *new_vr)
 {
   value_range *old_vr;
@@ -867,15 +841,6 @@ range_int_cst_singleton_p (value_range *vr)
 	  && tree_int_cst_equal (vr->min, vr->max));
 }
 
-/* Return true if value range VR involves at least one symbol.  */
-
-static inline bool
-symbolic_range_p (value_range *vr)
-{
-  return (!is_gimple_min_invariant (vr->min)
-          || !is_gimple_min_invariant (vr->max));
-}
-
 /* Return the single symbol (an SSA_NAME) contained in T if any, or NULL_TREE
    otherwise.  We only handle additive operations and set NEG to true if the
    symbol is negated and INV to the invariant part, if any.  */
@@ -1461,7 +1426,7 @@ op_with_boolean_value_range_p (tree op)
 /* Extract value range information from an ASSERT_EXPR EXPR and store
    it in *VR_P.  */
 
-static void
+void
 extract_range_from_assert (value_range *vr_p, tree expr)
 {
   tree var, cond, limit, min, max, type;
@@ -4600,7 +4565,6 @@ compare_range_with_value (enum tree_code comp, value_range *vr, tree val,
 
 /* Debugging dumps.  */
 
-void dump_value_range (FILE *, value_range *);
 void debug_value_range (value_range *);
 void dump_all_value_ranges (FILE *);
 void debug_all_value_ranges (void);
@@ -6828,7 +6792,7 @@ remove_range_assertions (void)
 
 /* Return true if STMT is interesting for VRP.  */
 
-static bool
+bool
 stmt_interesting_for_vrp (gimple *stmt)
 {
   if (gimple_code (stmt) == GIMPLE_PHI)
@@ -6876,7 +6840,7 @@ stmt_interesting_for_vrp (gimple *stmt)
 
 /* Initialize local data structures for VRP.  */
 
-static void
+void
 vrp_initialize (void)
 {
   basic_block bb;
@@ -7862,7 +7826,7 @@ vrp_visit_switch_stmt (gswitch *stmt, edge *taken_edge_p)
 
    If STMT produces a varying value, return SSA_PROP_VARYING.  */
 
-static enum ssa_prop_result
+enum ssa_prop_result
 vrp_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
 {
   tree def;
@@ -8493,7 +8457,7 @@ vrp_intersect_ranges_1 (value_range *vr0, value_range *vr1)
     bitmap_copy (vr0->equiv, vr1->equiv);
 }
 
-static void
+void
 vrp_intersect_ranges (value_range *vr0, value_range *vr1)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -8590,7 +8554,7 @@ vrp_meet_1 (value_range *vr0, value_range *vr1)
     bitmap_clear (vr0->equiv);
 }
 
-static void
+void
 vrp_meet (value_range *vr0, value_range *vr1)
 {
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -8615,7 +8579,7 @@ vrp_meet (value_range *vr0, value_range *vr1)
    edges.  If a valid value range can be derived from all the incoming
    value ranges, set a new range for the LHS of PHI.  */
 
-static enum ssa_prop_result
+enum ssa_prop_result
 vrp_visit_phi_node (gphi *phi)
 {
   size_t i;
@@ -10164,8 +10128,8 @@ finalize_jump_threads (void)
 
 /* Traverse all the blocks folding conditionals with known ranges.  */
 
-static void
-vrp_finalize (bool warn_array_bounds_p)
+void
+vrp_finalize (bool jump_thread_p, bool warn_array_bounds_p)
 {
   size_t i;
 
@@ -10206,7 +10170,8 @@ vrp_finalize (bool warn_array_bounds_p)
 
   /* We must identify jump threading opportunities before we release
      the datastructures built by VRP.  */
-  identify_jump_threads ();
+  if (jump_thread_p)
+    identify_jump_threads ();
 
   /* Free allocated memory.  */
   for (i = 0; i < num_vr_values; i++)
@@ -10295,7 +10260,7 @@ execute_vrp (bool warn_array_bounds_p)
 
   vrp_initialize ();
   ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
-  vrp_finalize (warn_array_bounds_p);
+  vrp_finalize (true, warn_array_bounds_p);
 
   free_numbers_of_iterations_estimates (cfun);
 
diff --git a/gcc/tree-vrp.h b/gcc/tree-vrp.h
new file mode 100644
index 0000000..bcefaa7
--- /dev/null
+++ b/gcc/tree-vrp.h
@@ -0,0 +1,65 @@
+/* Support routines for Value Range Propagation (VRP).
+   Copyright (C) Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "tree-ssa-operands.h"
+#include "gimple.h"
+#include "tree-ssa-propagate.h"
+
+#define VR_INITIALIZER { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL }
+
+extern void vrp_initialize (void);
+extern void vrp_finalize (bool update, bool warn_array_bounds_p);
+extern void vrp_intersect_ranges (value_range *vr0, value_range *vr1);
+extern void vrp_meet (value_range *vr0, value_range *vr1);
+extern enum ssa_prop_result vrp_visit_stmt (gimple *stmt,
+					    edge *taken_edge_p,
+					    tree *output_p);
+extern enum ssa_prop_result vrp_visit_phi_node (gphi *phi);
+extern bool stmt_interesting_for_vrp (gimple *stmt);
+
+extern void extract_range_from_assert (value_range *vr_p, tree expr);
+extern bool update_value_range (const_tree var, value_range *vr);
+extern value_range *get_value_range (const_tree var);
+extern void set_value_range (value_range *vr, enum value_range_type t,
+			     tree min, tree max, bitmap equiv);
+extern void change_value_range (const_tree var, value_range *new_vr);
+
+extern void dump_value_range (FILE *, value_range *);
+
+/* Return true if value range VR involves at least one symbol.  */
+
+inline bool
+symbolic_range_p (value_range *vr)
+{
+  return (!is_gimple_min_invariant (vr->min)
+	  || !is_gimple_min_invariant (vr->max));
+}
+
+/* Set value range VR to VR_VARYING.  */
+
+inline void
+set_value_range_to_varying (value_range *vr)
+{
+  vr->type = VR_VARYING;
+  vr->min = vr->max = NULL_TREE;
+  if (vr->equiv)
+    bitmap_clear (vr->equiv);
+}
+
diff --git a/gcc/tree.h b/gcc/tree.h
index 90413fc..8fc4f4f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -230,6 +230,37 @@ as_internal_fn (combined_fn code)
 
 #define TREE_CODE_LENGTH(CODE)	tree_code_length[(int) (CODE)]
 
+/* Type of value ranges.  See value_range_d In tree-vrp.c for a
+   description of these types.  */
+enum value_range_type { VR_UNDEFINED, VR_RANGE,
+			VR_ANTI_RANGE, VR_VARYING, VR_LAST };
+
+/* Range of values that can be associated with an SSA_NAME after VRP
+   has executed.  */
+struct GTY(()) value_range
+{
+  /* Lattice value represented by this range.  */
+  enum value_range_type type;
+
+  /* Minimum and maximum values represented by this range.  These
+     values should be interpreted as follows:
+
+	- If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
+	  be NULL.
+
+	- If TYPE == VR_RANGE then MIN holds the minimum value and
+	  MAX holds the maximum value of the range [MIN, MAX].
+
+	- If TYPE == ANTI_RANGE the variable is known to NOT
+	  take any values in the range [MIN, MAX].  */
+  tree min;
+  tree max;
+
+  /* Set of SSA names whose value ranges are equivalent to this one.
+     This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
+  bitmap equiv;
+};
+
 
 /* Helper macros for math builtins.  */
 
-- 
1.9.1

