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
@@ -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 &);
@@ -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);
new file mode 100644
@@ -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);
+}
+
@@ -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