Commit 97ecc8d5 by Aldy Hernandez Committed by Aldy Hernandez

Add type to VR_VARYING.

From-SVN: r274561
parent e3cfbeaf
2019-08-16 Aldy Hernandez <aldyh@redhat.com>
* gimple-ssa-evrp-analyze.c (record_ranges_from_phis): Skip PHIs
for which we can't represent a range.
* ipa-cp.c (ipcp_vr_lattice::set_to_bottom): Pass type to
set_varying.
* tree-ssa-threadedge.c (record_temporary_equivalences_from_phis):
Set VR_UNDEFINED if type is not supported.
* tree-ssanames.c (get_range_info): Pass type to set_varying.
* tree-vrp.c (value_range_base::check): Assert that a varying has
min/max set.
(value_range_base::equal_p): Early bail for undefines.
(value_range_base::set_varying): Accept a type.
(value_range::set_varying): Same.
(value_range_base::type): VARYING can have a type, while UNDEFINE
is typeless.
(value_range_base::dump): Print type for VARYING nodes.
(value_range_base::set): Add type to VARYING.
(extract_range_from_multiplicative_op): Pass type to set_varying.
(extract_range_from_binary_expr): Same.
(value_range_base::intersect_helper): Same.
(value_range_base::union_helper): Same.
(value_range_base::normalize_symbolics): Same.
(determine_value_range_1): Same.
* tree-vrp.h (class value_range_base): Add type to set_varying.
Add prototype for dump(void).
Add prototype for supports_type_p.
(class value_range): Add type to set_varying.
Add prototype for dump(void).
* vr-values.c (set_value_range_to_truthvalue): Pass type to
set_varying.
(vr_values::get_lattice_entry): Set varying even if propagation
finished.
Pass type to set_varying.
(vr_values::get_value_range): Remove vr_const_varying.
Reallocate the lattice if needed.
(vr_values::update_value_range): Pass type to set_varying.
(vr_values::extract_range_for_var_from_comparison_expr): Same.
(vr_values::extract_range_from_binary_expr): Same.
(vr_values::extract_range_from_unary_expr): Same.
(vr_values::extract_range_from_cond_expr): Same.
(vr_values::check_for_binary_op_overflow): Same.
(vr_values::extract_range_basic): Same.
(vr_values::extract_range_from_assignment): Same.
(vr_values::vr_values): Increase size of num_vr_values.
(vr_values::extract_range_from_phi_node): Pass type to
set_varying.
2019-08-15 H.J. Lu <hongjiu.lu@intel.com> 2019-08-15 H.J. Lu <hongjiu.lu@intel.com>
PR target/90878 PR target/90878
......
...@@ -254,13 +254,18 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb) ...@@ -254,13 +254,18 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
if (virtual_operand_p (lhs)) if (virtual_operand_p (lhs))
continue; continue;
/* Skips floats and other things we can't represent in a
range. */
if (!value_range_base::supports_type_p (TREE_TYPE (lhs)))
continue;
value_range vr_result; value_range vr_result;
bool interesting = stmt_interesting_for_vrp (phi); bool interesting = stmt_interesting_for_vrp (phi);
if (!has_unvisited_preds && interesting) if (!has_unvisited_preds && interesting)
vr_values->extract_range_from_phi_node (phi, &vr_result); vr_values->extract_range_from_phi_node (phi, &vr_result);
else else
{ {
vr_result.set_varying (); vr_result.set_varying (TREE_TYPE (lhs));
/* When we have an unvisited executable predecessor we can't /* When we have an unvisited executable predecessor we can't
use PHI arg ranges which may be still UNDEFINED but have use PHI arg ranges which may be still UNDEFINED but have
to use VARYING for them. But we can still resort to to use VARYING for them. But we can still resort to
......
...@@ -977,7 +977,12 @@ ipcp_vr_lattice::set_to_bottom () ...@@ -977,7 +977,12 @@ ipcp_vr_lattice::set_to_bottom ()
{ {
if (m_vr.varying_p ()) if (m_vr.varying_p ())
return false; return false;
m_vr.set_varying (); /* ?? We create all sorts of VARYING ranges for floats, structures,
and other types which we cannot handle as ranges. We should
probably avoid handling them throughout the pass, but it's easier
to create a sensible VARYING here and let the lattice
propagate. */
m_vr.set_varying (integer_type_node);
return true; return true;
} }
......
...@@ -183,7 +183,7 @@ record_temporary_equivalences_from_phis (edge e, ...@@ -183,7 +183,7 @@ record_temporary_equivalences_from_phis (edge e,
else if (TREE_CODE (src) == INTEGER_CST) else if (TREE_CODE (src) == INTEGER_CST)
new_vr->set (src); new_vr->set (src);
else else
new_vr->set_varying (); new_vr->set_varying (TREE_TYPE (src));
/* This is a temporary range for DST, so push it. */ /* This is a temporary range for DST, so push it. */
evrp_range_analyzer->push_value_range (dst, new_vr); evrp_range_analyzer->push_value_range (dst, new_vr);
......
...@@ -440,14 +440,16 @@ get_range_info (const_tree name, value_range_base &vr) ...@@ -440,14 +440,16 @@ get_range_info (const_tree name, value_range_base &vr)
wide_int wmin, wmax; wide_int wmin, wmax;
enum value_range_kind kind = get_range_info (name, &wmin, &wmax); enum value_range_kind kind = get_range_info (name, &wmin, &wmax);
if (kind == VR_VARYING || kind == VR_UNDEFINED) if (kind == VR_VARYING)
min = max = NULL; vr.set_varying (TREE_TYPE (name));
else if (kind == VR_UNDEFINED)
vr.set_undefined ();
else else
{ {
min = wide_int_to_tree (TREE_TYPE (name), wmin); min = wide_int_to_tree (TREE_TYPE (name), wmin);
max = wide_int_to_tree (TREE_TYPE (name), wmax); max = wide_int_to_tree (TREE_TYPE (name), wmax);
vr.set (kind, min, max);
} }
vr.set (kind, min, max);
return kind; return kind;
} }
......
...@@ -58,7 +58,7 @@ public: ...@@ -58,7 +58,7 @@ public:
bool constant_p () const; bool constant_p () const;
bool undefined_p () const; bool undefined_p () const;
bool varying_p () const; bool varying_p () const;
void set_varying (); void set_varying (tree type);
void set_undefined (); void set_undefined ();
void union_ (const value_range_base *); void union_ (const value_range_base *);
...@@ -75,7 +75,9 @@ public: ...@@ -75,7 +75,9 @@ public:
bool nonzero_p () const; bool nonzero_p () const;
bool singleton_p (tree *result = NULL) const; bool singleton_p (tree *result = NULL) const;
void dump (FILE *) const; void dump (FILE *) const;
void dump () const;
static bool supports_type_p (tree);
value_range_base normalize_symbolics () const; value_range_base normalize_symbolics () const;
protected: protected:
...@@ -135,7 +137,7 @@ class GTY((user)) value_range : public value_range_base ...@@ -135,7 +137,7 @@ class GTY((user)) value_range : public value_range_base
/* Types of value ranges. */ /* Types of value ranges. */
void set_undefined (); void set_undefined ();
void set_varying (); void set_varying (tree);
/* Equivalence bitmap methods. */ /* Equivalence bitmap methods. */
bitmap equiv () const; bitmap equiv () const;
...@@ -145,6 +147,7 @@ class GTY((user)) value_range : public value_range_base ...@@ -145,6 +147,7 @@ class GTY((user)) value_range : public value_range_base
/* Misc methods. */ /* Misc methods. */
void deep_copy (const value_range *); void deep_copy (const value_range *);
void dump (FILE *) const; void dump (FILE *) const;
void dump () const;
private: private:
/* Deep-copies bitmap argument. */ /* Deep-copies bitmap argument. */
...@@ -254,6 +257,17 @@ struct assert_info ...@@ -254,6 +257,17 @@ struct assert_info
tree expr; tree expr;
}; };
// Return true if TYPE is a valid type for value_range to operate on.
// Otherwise return FALSE.
inline bool
value_range_base::supports_type_p (tree type)
{
if (type && (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type)))
return type;
return NULL;
}
extern void register_edge_assert_for (tree, edge, enum tree_code, extern void register_edge_assert_for (tree, edge, enum tree_code,
tree, tree, vec<assert_info> &); tree, tree, vec<assert_info> &);
extern bool stmt_interesting_for_vrp (gimple *); extern bool stmt_interesting_for_vrp (gimple *);
......
...@@ -64,7 +64,7 @@ static inline void ...@@ -64,7 +64,7 @@ static inline void
set_value_range_to_truthvalue (value_range *vr, tree type) set_value_range_to_truthvalue (value_range *vr, tree type)
{ {
if (TYPE_PRECISION (type) == 1) if (TYPE_PRECISION (type) == 1)
vr->set_varying (); vr->set_varying (type);
else else
vr->update (VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1)); vr->update (VR_RANGE, build_int_cst (type, 0), build_int_cst (type, 1));
} }
...@@ -89,12 +89,16 @@ vr_values::get_lattice_entry (const_tree var) ...@@ -89,12 +89,16 @@ vr_values::get_lattice_entry (const_tree var)
if (vr) if (vr)
return vr; return vr;
/* After propagation finished do not allocate new value-ranges. */
if (values_propagated)
return NULL;
/* Create a default value range. */ /* Create a default value range. */
vr_value[ver] = vr = vrp_value_range_pool.allocate (); vr_value[ver] = vr = vrp_value_range_pool.allocate ();
/* After propagation finished return varying. */
if (values_propagated)
{
vr->set_varying (TREE_TYPE (var));
return vr;
}
vr->set_undefined (); vr->set_undefined ();
/* If VAR is a default definition of a parameter, the variable can /* If VAR is a default definition of a parameter, the variable can
...@@ -118,10 +122,10 @@ vr_values::get_lattice_entry (const_tree var) ...@@ -118,10 +122,10 @@ vr_values::get_lattice_entry (const_tree var)
{ {
get_range_info (var, *vr); get_range_info (var, *vr);
if (vr->undefined_p ()) if (vr->undefined_p ())
vr->set_varying (); vr->set_varying (TREE_TYPE (sym));
} }
else else
vr->set_varying (); vr->set_varying (TREE_TYPE (sym));
} }
else if (TREE_CODE (sym) == RESULT_DECL else if (TREE_CODE (sym) == RESULT_DECL
&& DECL_BY_REFERENCE (sym)) && DECL_BY_REFERENCE (sym))
...@@ -142,15 +146,25 @@ vr_values::get_lattice_entry (const_tree var) ...@@ -142,15 +146,25 @@ vr_values::get_lattice_entry (const_tree var)
const value_range * const value_range *
vr_values::get_value_range (const_tree var) vr_values::get_value_range (const_tree var)
{ {
static const value_range vr_const_varying (VR_VARYING, NULL, NULL);
/* If we have no recorded ranges, then return NULL. */ /* If we have no recorded ranges, then return NULL. */
if (!vr_value) if (!vr_value)
return NULL; return NULL;
value_range *vr = get_lattice_entry (var); value_range *vr = get_lattice_entry (var);
/* Reallocate the lattice if needed. */
if (!vr) if (!vr)
return &vr_const_varying; {
unsigned int old_sz = num_vr_values;
num_vr_values = num_ssa_names + num_ssa_names / 10;
vr_value = XRESIZEVEC (value_range *, vr_value, num_vr_values);
for ( ; old_sz < num_vr_values; old_sz++)
vr_value [old_sz] = NULL;
/* Now that the lattice has been resized, we should never fail. */
vr = get_lattice_entry (var);
gcc_assert (vr);
}
return vr; return vr;
} }
...@@ -162,7 +176,7 @@ vr_values::set_def_to_varying (const_tree def) ...@@ -162,7 +176,7 @@ vr_values::set_def_to_varying (const_tree def)
{ {
value_range *vr = get_lattice_entry (def); value_range *vr = get_lattice_entry (def);
if (vr) if (vr)
vr->set_varying (); vr->set_varying (TREE_TYPE (def));
} }
/* Set value-ranges of all SSA names defined by STMT to varying. */ /* Set value-ranges of all SSA names defined by STMT to varying. */
...@@ -220,13 +234,13 @@ vr_values::update_value_range (const_tree var, value_range *new_vr) ...@@ -220,13 +234,13 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
called, if we are anyway, keep it VARYING. */ called, if we are anyway, keep it VARYING. */
if (old_vr->varying_p ()) if (old_vr->varying_p ())
{ {
new_vr->set_varying (); new_vr->set_varying (new_vr->type ());
is_new = false; is_new = false;
} }
else if (new_vr->undefined_p ()) else if (new_vr->undefined_p ())
{ {
old_vr->set_varying (); old_vr->set_varying (TREE_TYPE (var));
new_vr->set_varying (); new_vr->set_varying (TREE_TYPE (var));
return true; return true;
} }
else else
...@@ -457,7 +471,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, ...@@ -457,7 +471,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR) if ((POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
|| limit == var) || limit == var)
{ {
vr_p->set_varying (); vr_p->set_varying (type);
return; return;
} }
...@@ -617,7 +631,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, ...@@ -617,7 +631,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
all should be optimized away above us. */ all should be optimized away above us. */
if (cond_code == LT_EXPR if (cond_code == LT_EXPR
&& compare_values (max, min) == 0) && compare_values (max, min) == 0)
vr_p->set_varying (); vr_p->set_varying (TREE_TYPE (min));
else else
{ {
/* For LT_EXPR, we create the range [MIN, MAX - 1]. */ /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
...@@ -657,7 +671,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var, ...@@ -657,7 +671,7 @@ vr_values::extract_range_for_var_from_comparison_expr (tree var,
all should be optimized away above us. */ all should be optimized away above us. */
if (cond_code == GT_EXPR if (cond_code == GT_EXPR
&& compare_values (min, max) == 0) && compare_values (min, max) == 0)
vr_p->set_varying (); vr_p->set_varying (TREE_TYPE (min));
else else
{ {
/* For GT_EXPR, we create the range [MIN + 1, MAX]. */ /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
...@@ -765,14 +779,14 @@ vr_values::extract_range_from_binary_expr (value_range *vr, ...@@ -765,14 +779,14 @@ vr_values::extract_range_from_binary_expr (value_range *vr,
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
vr0.set (op0); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *(get_value_range (op1)); vr1 = *(get_value_range (op1));
else if (is_gimple_min_invariant (op1)) else if (is_gimple_min_invariant (op1))
vr1.set (op1); vr1.set (op1);
else else
vr1.set_varying (); vr1.set_varying (TREE_TYPE (op1));
/* If one argument is varying, we can sometimes still deduce a /* If one argument is varying, we can sometimes still deduce a
range for the output: any + [3, +INF] is in [MIN+3, +INF]. */ range for the output: any + [3, +INF] is in [MIN+3, +INF]. */
...@@ -913,7 +927,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code, ...@@ -913,7 +927,7 @@ vr_values::extract_range_from_unary_expr (value_range *vr, enum tree_code code,
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
vr0.set (op0); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying (type);
::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0)); ::extract_range_from_unary_expr (vr, code, type, &vr0, TREE_TYPE (op0));
} }
...@@ -935,7 +949,7 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt) ...@@ -935,7 +949,7 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
else if (is_gimple_min_invariant (op0)) else if (is_gimple_min_invariant (op0))
tem0.set (op0); tem0.set (op0);
else else
tem0.set_varying (); tem0.set_varying (TREE_TYPE (op0));
tree op1 = gimple_assign_rhs3 (stmt); tree op1 = gimple_assign_rhs3 (stmt);
value_range tem1; value_range tem1;
...@@ -945,7 +959,7 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt) ...@@ -945,7 +959,7 @@ vr_values::extract_range_from_cond_expr (value_range *vr, gassign *stmt)
else if (is_gimple_min_invariant (op1)) else if (is_gimple_min_invariant (op1))
tem1.set (op1); tem1.set (op1);
else else
tem1.set_varying (); tem1.set_varying (TREE_TYPE (op1));
/* The resulting value range is the union of the operand ranges */ /* The resulting value range is the union of the operand ranges */
vr->deep_copy (vr0); vr->deep_copy (vr0);
...@@ -997,14 +1011,14 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type, ...@@ -997,14 +1011,14 @@ vr_values::check_for_binary_op_overflow (enum tree_code subcode, tree type,
else if (TREE_CODE (op0) == INTEGER_CST) else if (TREE_CODE (op0) == INTEGER_CST)
vr0.set (op0); vr0.set (op0);
else else
vr0.set_varying (); vr0.set_varying (TREE_TYPE (op0));
if (TREE_CODE (op1) == SSA_NAME) if (TREE_CODE (op1) == SSA_NAME)
vr1 = *get_value_range (op1); vr1 = *get_value_range (op1);
else if (TREE_CODE (op1) == INTEGER_CST) else if (TREE_CODE (op1) == INTEGER_CST)
vr1.set (op1); vr1.set (op1);
else else
vr1.set_varying (); vr1.set_varying (TREE_TYPE (op1));
tree vr0min = vr0.min (), vr0max = vr0.max (); tree vr0min = vr0.min (), vr0max = vr0.max ();
tree vr1min = vr1.min (), vr1max = vr1.max (); tree vr1min = vr1.min (), vr1max = vr1.max ();
...@@ -1332,7 +1346,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1332,7 +1346,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
if (vr->kind () == VR_RANGE if (vr->kind () == VR_RANGE
&& (vr->min () == vr->max () && (vr->min () == vr->max ()
|| operand_equal_p (vr->min (), vr->max (), 0))) || operand_equal_p (vr->min (), vr->max (), 0)))
vr->set_varying (); vr->set_varying (vr->type ());
return; return;
} }
} }
...@@ -1388,7 +1402,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1388,7 +1402,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
vr->set (build_int_cst (type, ovf)); vr->set (build_int_cst (type, ovf));
else if (TYPE_PRECISION (type) == 1 else if (TYPE_PRECISION (type) == 1
&& !TYPE_UNSIGNED (type)) && !TYPE_UNSIGNED (type))
vr->set_varying (); vr->set_varying (type);
else else
vr->set (VR_RANGE, build_int_cst (type, 0), vr->set (VR_RANGE, build_int_cst (type, 0),
build_int_cst (type, 1)); build_int_cst (type, 1));
...@@ -1433,7 +1447,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt) ...@@ -1433,7 +1447,7 @@ vr_values::extract_range_basic (value_range *vr, gimple *stmt)
vr->equiv_clear (); vr->equiv_clear ();
} }
else else
vr->set_varying (); vr->set_varying (type);
} }
...@@ -1469,7 +1483,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt) ...@@ -1469,7 +1483,7 @@ vr_values::extract_range_from_assignment (value_range *vr, gassign *stmt)
&& is_gimple_min_invariant (gimple_assign_rhs1 (stmt))) && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
vr->set (gimple_assign_rhs1 (stmt)); vr->set (gimple_assign_rhs1 (stmt));
else else
vr->set_varying (); vr->set_varying (TREE_TYPE (gimple_assign_lhs (stmt)));
if (vr->varying_p ()) if (vr->varying_p ())
extract_range_basic (vr, stmt); extract_range_basic (vr, stmt);
...@@ -1938,7 +1952,7 @@ vr_values::dump_all_value_ranges (FILE *file) ...@@ -1938,7 +1952,7 @@ vr_values::dump_all_value_ranges (FILE *file)
vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges") vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
{ {
values_propagated = false; values_propagated = false;
num_vr_values = num_ssa_names; num_vr_values = num_ssa_names * 2;
vr_value = XCNEWVEC (value_range *, num_vr_values); vr_value = XCNEWVEC (value_range *, num_vr_values);
vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names); vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
bitmap_obstack_initialize (&vrp_equiv_obstack); bitmap_obstack_initialize (&vrp_equiv_obstack);
...@@ -2875,7 +2889,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2875,7 +2889,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
vr_arg_tem.set (vr_arg_->kind (), vr_arg_->min (), vr_arg_tem.set (vr_arg_->kind (), vr_arg_->min (),
vr_arg_->max (), NULL); vr_arg_->max (), NULL);
if (vr_arg_tem.symbolic_p ()) if (vr_arg_tem.symbolic_p ())
vr_arg_tem.set_varying (); vr_arg_tem.set_varying (TREE_TYPE (arg));
} }
else else
vr_arg = vr_arg_; vr_arg = vr_arg_;
...@@ -2997,7 +3011,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result) ...@@ -2997,7 +3011,7 @@ vr_values::extract_range_from_phi_node (gphi *phi, value_range *vr_result)
goto update_range; goto update_range;
varying: varying:
vr_result->set_varying (); vr_result->set_varying (TREE_TYPE (lhs));
scev_check: scev_check:
/* If this is a loop PHI node SCEV may known more about its value-range. /* If this is a loop PHI node SCEV may known more about its value-range.
...@@ -3018,7 +3032,7 @@ infinite_check: ...@@ -3018,7 +3032,7 @@ infinite_check:
|| compare_values (vr_result->min (), vr_result->max ()) > 0)) || compare_values (vr_result->min (), vr_result->max ()) > 0))
; ;
else else
vr_result->set_varying (); vr_result->set_varying (TREE_TYPE (lhs));
/* If the new range is different than the previous value, keep /* If the new range is different than the previous value, keep
iterating. */ iterating. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment