1e4b17023SJohn Marino /* Support routines for Value Range Propagation (VRP).
2e4b17023SJohn Marino Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011
3e4b17023SJohn Marino Free Software Foundation, Inc.
4e4b17023SJohn Marino Contributed by Diego Novillo <dnovillo@redhat.com>.
5e4b17023SJohn Marino
6e4b17023SJohn Marino This file is part of GCC.
7e4b17023SJohn Marino
8e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
9e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
10e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
11e4b17023SJohn Marino any later version.
12e4b17023SJohn Marino
13e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
14e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
15e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16e4b17023SJohn Marino GNU General Public License for more details.
17e4b17023SJohn Marino
18e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
20e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
21e4b17023SJohn Marino
22e4b17023SJohn Marino #include "config.h"
23e4b17023SJohn Marino #include "system.h"
24e4b17023SJohn Marino #include "coretypes.h"
25e4b17023SJohn Marino #include "tm.h"
26e4b17023SJohn Marino #include "ggc.h"
27e4b17023SJohn Marino #include "flags.h"
28e4b17023SJohn Marino #include "tree.h"
29e4b17023SJohn Marino #include "basic-block.h"
30e4b17023SJohn Marino #include "tree-flow.h"
31e4b17023SJohn Marino #include "tree-pass.h"
32e4b17023SJohn Marino #include "tree-dump.h"
33e4b17023SJohn Marino #include "timevar.h"
34e4b17023SJohn Marino #include "tree-pretty-print.h"
35e4b17023SJohn Marino #include "gimple-pretty-print.h"
36e4b17023SJohn Marino #include "diagnostic-core.h"
37e4b17023SJohn Marino #include "intl.h"
38e4b17023SJohn Marino #include "cfgloop.h"
39e4b17023SJohn Marino #include "tree-scalar-evolution.h"
40e4b17023SJohn Marino #include "tree-ssa-propagate.h"
41e4b17023SJohn Marino #include "tree-chrec.h"
42e4b17023SJohn Marino #include "gimple-fold.h"
43e4b17023SJohn Marino #include "expr.h"
44e4b17023SJohn Marino #include "optabs.h"
45e4b17023SJohn Marino
46e4b17023SJohn Marino
47e4b17023SJohn Marino /* Type of value ranges. See value_range_d for a description of these
48e4b17023SJohn Marino types. */
49e4b17023SJohn Marino enum value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING };
50e4b17023SJohn Marino
51e4b17023SJohn Marino /* Range of values that can be associated with an SSA_NAME after VRP
52e4b17023SJohn Marino has executed. */
53e4b17023SJohn Marino struct value_range_d
54e4b17023SJohn Marino {
55e4b17023SJohn Marino /* Lattice value represented by this range. */
56e4b17023SJohn Marino enum value_range_type type;
57e4b17023SJohn Marino
58e4b17023SJohn Marino /* Minimum and maximum values represented by this range. These
59e4b17023SJohn Marino values should be interpreted as follows:
60e4b17023SJohn Marino
61e4b17023SJohn Marino - If TYPE is VR_UNDEFINED or VR_VARYING then MIN and MAX must
62e4b17023SJohn Marino be NULL.
63e4b17023SJohn Marino
64e4b17023SJohn Marino - If TYPE == VR_RANGE then MIN holds the minimum value and
65e4b17023SJohn Marino MAX holds the maximum value of the range [MIN, MAX].
66e4b17023SJohn Marino
67e4b17023SJohn Marino - If TYPE == ANTI_RANGE the variable is known to NOT
68e4b17023SJohn Marino take any values in the range [MIN, MAX]. */
69e4b17023SJohn Marino tree min;
70e4b17023SJohn Marino tree max;
71e4b17023SJohn Marino
72e4b17023SJohn Marino /* Set of SSA names whose value ranges are equivalent to this one.
73e4b17023SJohn Marino This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE. */
74e4b17023SJohn Marino bitmap equiv;
75e4b17023SJohn Marino };
76e4b17023SJohn Marino
77e4b17023SJohn Marino typedef struct value_range_d value_range_t;
78e4b17023SJohn Marino
79e4b17023SJohn Marino /* Set of SSA names found live during the RPO traversal of the function
80e4b17023SJohn Marino for still active basic-blocks. */
81e4b17023SJohn Marino static sbitmap *live;
82e4b17023SJohn Marino
83e4b17023SJohn Marino /* Return true if the SSA name NAME is live on the edge E. */
84e4b17023SJohn Marino
85e4b17023SJohn Marino static bool
live_on_edge(edge e,tree name)86e4b17023SJohn Marino live_on_edge (edge e, tree name)
87e4b17023SJohn Marino {
88e4b17023SJohn Marino return (live[e->dest->index]
89e4b17023SJohn Marino && TEST_BIT (live[e->dest->index], SSA_NAME_VERSION (name)));
90e4b17023SJohn Marino }
91e4b17023SJohn Marino
92e4b17023SJohn Marino /* Local functions. */
93e4b17023SJohn Marino static int compare_values (tree val1, tree val2);
94e4b17023SJohn Marino static int compare_values_warnv (tree val1, tree val2, bool *);
95e4b17023SJohn Marino static void vrp_meet (value_range_t *, value_range_t *);
96e4b17023SJohn Marino static tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code,
97e4b17023SJohn Marino tree, tree, bool, bool *,
98e4b17023SJohn Marino bool *);
99e4b17023SJohn Marino
100e4b17023SJohn Marino /* Location information for ASSERT_EXPRs. Each instance of this
101e4b17023SJohn Marino structure describes an ASSERT_EXPR for an SSA name. Since a single
102e4b17023SJohn Marino SSA name may have more than one assertion associated with it, these
103e4b17023SJohn Marino locations are kept in a linked list attached to the corresponding
104e4b17023SJohn Marino SSA name. */
105e4b17023SJohn Marino struct assert_locus_d
106e4b17023SJohn Marino {
107e4b17023SJohn Marino /* Basic block where the assertion would be inserted. */
108e4b17023SJohn Marino basic_block bb;
109e4b17023SJohn Marino
110e4b17023SJohn Marino /* Some assertions need to be inserted on an edge (e.g., assertions
111e4b17023SJohn Marino generated by COND_EXPRs). In those cases, BB will be NULL. */
112e4b17023SJohn Marino edge e;
113e4b17023SJohn Marino
114e4b17023SJohn Marino /* Pointer to the statement that generated this assertion. */
115e4b17023SJohn Marino gimple_stmt_iterator si;
116e4b17023SJohn Marino
117e4b17023SJohn Marino /* Predicate code for the ASSERT_EXPR. Must be COMPARISON_CLASS_P. */
118e4b17023SJohn Marino enum tree_code comp_code;
119e4b17023SJohn Marino
120e4b17023SJohn Marino /* Value being compared against. */
121e4b17023SJohn Marino tree val;
122e4b17023SJohn Marino
123e4b17023SJohn Marino /* Expression to compare. */
124e4b17023SJohn Marino tree expr;
125e4b17023SJohn Marino
126e4b17023SJohn Marino /* Next node in the linked list. */
127e4b17023SJohn Marino struct assert_locus_d *next;
128e4b17023SJohn Marino };
129e4b17023SJohn Marino
130e4b17023SJohn Marino typedef struct assert_locus_d *assert_locus_t;
131e4b17023SJohn Marino
132e4b17023SJohn Marino /* If bit I is present, it means that SSA name N_i has a list of
133e4b17023SJohn Marino assertions that should be inserted in the IL. */
134e4b17023SJohn Marino static bitmap need_assert_for;
135e4b17023SJohn Marino
136e4b17023SJohn Marino /* Array of locations lists where to insert assertions. ASSERTS_FOR[I]
137e4b17023SJohn Marino holds a list of ASSERT_LOCUS_T nodes that describe where
138e4b17023SJohn Marino ASSERT_EXPRs for SSA name N_I should be inserted. */
139e4b17023SJohn Marino static assert_locus_t *asserts_for;
140e4b17023SJohn Marino
141e4b17023SJohn Marino /* Value range array. After propagation, VR_VALUE[I] holds the range
142e4b17023SJohn Marino of values that SSA name N_I may take. */
143e4b17023SJohn Marino static unsigned num_vr_values;
144e4b17023SJohn Marino static value_range_t **vr_value;
145e4b17023SJohn Marino static bool values_propagated;
146e4b17023SJohn Marino
147e4b17023SJohn Marino /* For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
148e4b17023SJohn Marino number of executable edges we saw the last time we visited the
149e4b17023SJohn Marino node. */
150e4b17023SJohn Marino static int *vr_phi_edge_counts;
151e4b17023SJohn Marino
152e4b17023SJohn Marino typedef struct {
153e4b17023SJohn Marino gimple stmt;
154e4b17023SJohn Marino tree vec;
155e4b17023SJohn Marino } switch_update;
156e4b17023SJohn Marino
157e4b17023SJohn Marino static VEC (edge, heap) *to_remove_edges;
158e4b17023SJohn Marino DEF_VEC_O(switch_update);
159e4b17023SJohn Marino DEF_VEC_ALLOC_O(switch_update, heap);
VEC(switch_update,heap)160e4b17023SJohn Marino static VEC (switch_update, heap) *to_update_switch_stmts;
161e4b17023SJohn Marino
162e4b17023SJohn Marino
163e4b17023SJohn Marino /* Return the maximum value for TYPE. */
164e4b17023SJohn Marino
165e4b17023SJohn Marino static inline tree
166e4b17023SJohn Marino vrp_val_max (const_tree type)
167e4b17023SJohn Marino {
168e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (type))
169e4b17023SJohn Marino return NULL_TREE;
170e4b17023SJohn Marino
171e4b17023SJohn Marino return TYPE_MAX_VALUE (type);
172e4b17023SJohn Marino }
173e4b17023SJohn Marino
174e4b17023SJohn Marino /* Return the minimum value for TYPE. */
175e4b17023SJohn Marino
176e4b17023SJohn Marino static inline tree
vrp_val_min(const_tree type)177e4b17023SJohn Marino vrp_val_min (const_tree type)
178e4b17023SJohn Marino {
179e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (type))
180e4b17023SJohn Marino return NULL_TREE;
181e4b17023SJohn Marino
182e4b17023SJohn Marino return TYPE_MIN_VALUE (type);
183e4b17023SJohn Marino }
184e4b17023SJohn Marino
185e4b17023SJohn Marino /* Return whether VAL is equal to the maximum value of its type. This
186e4b17023SJohn Marino will be true for a positive overflow infinity. We can't do a
187e4b17023SJohn Marino simple equality comparison with TYPE_MAX_VALUE because C typedefs
188e4b17023SJohn Marino and Ada subtypes can produce types whose TYPE_MAX_VALUE is not ==
189e4b17023SJohn Marino to the integer constant with the same value in the type. */
190e4b17023SJohn Marino
191e4b17023SJohn Marino static inline bool
vrp_val_is_max(const_tree val)192e4b17023SJohn Marino vrp_val_is_max (const_tree val)
193e4b17023SJohn Marino {
194e4b17023SJohn Marino tree type_max = vrp_val_max (TREE_TYPE (val));
195e4b17023SJohn Marino return (val == type_max
196e4b17023SJohn Marino || (type_max != NULL_TREE
197e4b17023SJohn Marino && operand_equal_p (val, type_max, 0)));
198e4b17023SJohn Marino }
199e4b17023SJohn Marino
200e4b17023SJohn Marino /* Return whether VAL is equal to the minimum value of its type. This
201e4b17023SJohn Marino will be true for a negative overflow infinity. */
202e4b17023SJohn Marino
203e4b17023SJohn Marino static inline bool
vrp_val_is_min(const_tree val)204e4b17023SJohn Marino vrp_val_is_min (const_tree val)
205e4b17023SJohn Marino {
206e4b17023SJohn Marino tree type_min = vrp_val_min (TREE_TYPE (val));
207e4b17023SJohn Marino return (val == type_min
208e4b17023SJohn Marino || (type_min != NULL_TREE
209e4b17023SJohn Marino && operand_equal_p (val, type_min, 0)));
210e4b17023SJohn Marino }
211e4b17023SJohn Marino
212e4b17023SJohn Marino
213e4b17023SJohn Marino /* Return whether TYPE should use an overflow infinity distinct from
214e4b17023SJohn Marino TYPE_{MIN,MAX}_VALUE. We use an overflow infinity value to
215e4b17023SJohn Marino represent a signed overflow during VRP computations. An infinity
216e4b17023SJohn Marino is distinct from a half-range, which will go from some number to
217e4b17023SJohn Marino TYPE_{MIN,MAX}_VALUE. */
218e4b17023SJohn Marino
219e4b17023SJohn Marino static inline bool
needs_overflow_infinity(const_tree type)220e4b17023SJohn Marino needs_overflow_infinity (const_tree type)
221e4b17023SJohn Marino {
222e4b17023SJohn Marino return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
223e4b17023SJohn Marino }
224e4b17023SJohn Marino
225e4b17023SJohn Marino /* Return whether TYPE can support our overflow infinity
226e4b17023SJohn Marino representation: we use the TREE_OVERFLOW flag, which only exists
227e4b17023SJohn Marino for constants. If TYPE doesn't support this, we don't optimize
228e4b17023SJohn Marino cases which would require signed overflow--we drop them to
229e4b17023SJohn Marino VARYING. */
230e4b17023SJohn Marino
231e4b17023SJohn Marino static inline bool
supports_overflow_infinity(const_tree type)232e4b17023SJohn Marino supports_overflow_infinity (const_tree type)
233e4b17023SJohn Marino {
234e4b17023SJohn Marino tree min = vrp_val_min (type), max = vrp_val_max (type);
235e4b17023SJohn Marino #ifdef ENABLE_CHECKING
236e4b17023SJohn Marino gcc_assert (needs_overflow_infinity (type));
237e4b17023SJohn Marino #endif
238e4b17023SJohn Marino return (min != NULL_TREE
239e4b17023SJohn Marino && CONSTANT_CLASS_P (min)
240e4b17023SJohn Marino && max != NULL_TREE
241e4b17023SJohn Marino && CONSTANT_CLASS_P (max));
242e4b17023SJohn Marino }
243e4b17023SJohn Marino
244e4b17023SJohn Marino /* VAL is the maximum or minimum value of a type. Return a
245e4b17023SJohn Marino corresponding overflow infinity. */
246e4b17023SJohn Marino
247e4b17023SJohn Marino static inline tree
make_overflow_infinity(tree val)248e4b17023SJohn Marino make_overflow_infinity (tree val)
249e4b17023SJohn Marino {
250e4b17023SJohn Marino gcc_checking_assert (val != NULL_TREE && CONSTANT_CLASS_P (val));
251e4b17023SJohn Marino val = copy_node (val);
252e4b17023SJohn Marino TREE_OVERFLOW (val) = 1;
253e4b17023SJohn Marino return val;
254e4b17023SJohn Marino }
255e4b17023SJohn Marino
256e4b17023SJohn Marino /* Return a negative overflow infinity for TYPE. */
257e4b17023SJohn Marino
258e4b17023SJohn Marino static inline tree
negative_overflow_infinity(tree type)259e4b17023SJohn Marino negative_overflow_infinity (tree type)
260e4b17023SJohn Marino {
261e4b17023SJohn Marino gcc_checking_assert (supports_overflow_infinity (type));
262e4b17023SJohn Marino return make_overflow_infinity (vrp_val_min (type));
263e4b17023SJohn Marino }
264e4b17023SJohn Marino
265e4b17023SJohn Marino /* Return a positive overflow infinity for TYPE. */
266e4b17023SJohn Marino
267e4b17023SJohn Marino static inline tree
positive_overflow_infinity(tree type)268e4b17023SJohn Marino positive_overflow_infinity (tree type)
269e4b17023SJohn Marino {
270e4b17023SJohn Marino gcc_checking_assert (supports_overflow_infinity (type));
271e4b17023SJohn Marino return make_overflow_infinity (vrp_val_max (type));
272e4b17023SJohn Marino }
273e4b17023SJohn Marino
274e4b17023SJohn Marino /* Return whether VAL is a negative overflow infinity. */
275e4b17023SJohn Marino
276e4b17023SJohn Marino static inline bool
is_negative_overflow_infinity(const_tree val)277e4b17023SJohn Marino is_negative_overflow_infinity (const_tree val)
278e4b17023SJohn Marino {
279e4b17023SJohn Marino return (needs_overflow_infinity (TREE_TYPE (val))
280e4b17023SJohn Marino && CONSTANT_CLASS_P (val)
281e4b17023SJohn Marino && TREE_OVERFLOW (val)
282e4b17023SJohn Marino && vrp_val_is_min (val));
283e4b17023SJohn Marino }
284e4b17023SJohn Marino
285e4b17023SJohn Marino /* Return whether VAL is a positive overflow infinity. */
286e4b17023SJohn Marino
287e4b17023SJohn Marino static inline bool
is_positive_overflow_infinity(const_tree val)288e4b17023SJohn Marino is_positive_overflow_infinity (const_tree val)
289e4b17023SJohn Marino {
290e4b17023SJohn Marino return (needs_overflow_infinity (TREE_TYPE (val))
291e4b17023SJohn Marino && CONSTANT_CLASS_P (val)
292e4b17023SJohn Marino && TREE_OVERFLOW (val)
293e4b17023SJohn Marino && vrp_val_is_max (val));
294e4b17023SJohn Marino }
295e4b17023SJohn Marino
296e4b17023SJohn Marino /* Return whether VAL is a positive or negative overflow infinity. */
297e4b17023SJohn Marino
298e4b17023SJohn Marino static inline bool
is_overflow_infinity(const_tree val)299e4b17023SJohn Marino is_overflow_infinity (const_tree val)
300e4b17023SJohn Marino {
301e4b17023SJohn Marino return (needs_overflow_infinity (TREE_TYPE (val))
302e4b17023SJohn Marino && CONSTANT_CLASS_P (val)
303e4b17023SJohn Marino && TREE_OVERFLOW (val)
304e4b17023SJohn Marino && (vrp_val_is_min (val) || vrp_val_is_max (val)));
305e4b17023SJohn Marino }
306e4b17023SJohn Marino
307e4b17023SJohn Marino /* Return whether STMT has a constant rhs that is_overflow_infinity. */
308e4b17023SJohn Marino
309e4b17023SJohn Marino static inline bool
stmt_overflow_infinity(gimple stmt)310e4b17023SJohn Marino stmt_overflow_infinity (gimple stmt)
311e4b17023SJohn Marino {
312e4b17023SJohn Marino if (is_gimple_assign (stmt)
313e4b17023SJohn Marino && get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) ==
314e4b17023SJohn Marino GIMPLE_SINGLE_RHS)
315e4b17023SJohn Marino return is_overflow_infinity (gimple_assign_rhs1 (stmt));
316e4b17023SJohn Marino return false;
317e4b17023SJohn Marino }
318e4b17023SJohn Marino
319e4b17023SJohn Marino /* If VAL is now an overflow infinity, return VAL. Otherwise, return
320e4b17023SJohn Marino the same value with TREE_OVERFLOW clear. This can be used to avoid
321e4b17023SJohn Marino confusing a regular value with an overflow value. */
322e4b17023SJohn Marino
323e4b17023SJohn Marino static inline tree
avoid_overflow_infinity(tree val)324e4b17023SJohn Marino avoid_overflow_infinity (tree val)
325e4b17023SJohn Marino {
326e4b17023SJohn Marino if (!is_overflow_infinity (val))
327e4b17023SJohn Marino return val;
328e4b17023SJohn Marino
329e4b17023SJohn Marino if (vrp_val_is_max (val))
330e4b17023SJohn Marino return vrp_val_max (TREE_TYPE (val));
331e4b17023SJohn Marino else
332e4b17023SJohn Marino {
333e4b17023SJohn Marino gcc_checking_assert (vrp_val_is_min (val));
334e4b17023SJohn Marino return vrp_val_min (TREE_TYPE (val));
335e4b17023SJohn Marino }
336e4b17023SJohn Marino }
337e4b17023SJohn Marino
338e4b17023SJohn Marino
339e4b17023SJohn Marino /* Return true if ARG is marked with the nonnull attribute in the
340e4b17023SJohn Marino current function signature. */
341e4b17023SJohn Marino
342e4b17023SJohn Marino static bool
nonnull_arg_p(const_tree arg)343e4b17023SJohn Marino nonnull_arg_p (const_tree arg)
344e4b17023SJohn Marino {
345e4b17023SJohn Marino tree t, attrs, fntype;
346e4b17023SJohn Marino unsigned HOST_WIDE_INT arg_num;
347e4b17023SJohn Marino
348e4b17023SJohn Marino gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
349e4b17023SJohn Marino
350e4b17023SJohn Marino /* The static chain decl is always non null. */
351e4b17023SJohn Marino if (arg == cfun->static_chain_decl)
352e4b17023SJohn Marino return true;
353e4b17023SJohn Marino
354e4b17023SJohn Marino fntype = TREE_TYPE (current_function_decl);
355e4b17023SJohn Marino attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
356e4b17023SJohn Marino
357e4b17023SJohn Marino /* If "nonnull" wasn't specified, we know nothing about the argument. */
358e4b17023SJohn Marino if (attrs == NULL_TREE)
359e4b17023SJohn Marino return false;
360e4b17023SJohn Marino
361e4b17023SJohn Marino /* If "nonnull" applies to all the arguments, then ARG is non-null. */
362e4b17023SJohn Marino if (TREE_VALUE (attrs) == NULL_TREE)
363e4b17023SJohn Marino return true;
364e4b17023SJohn Marino
365e4b17023SJohn Marino /* Get the position number for ARG in the function signature. */
366e4b17023SJohn Marino for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
367e4b17023SJohn Marino t;
368e4b17023SJohn Marino t = DECL_CHAIN (t), arg_num++)
369e4b17023SJohn Marino {
370e4b17023SJohn Marino if (t == arg)
371e4b17023SJohn Marino break;
372e4b17023SJohn Marino }
373e4b17023SJohn Marino
374e4b17023SJohn Marino gcc_assert (t == arg);
375e4b17023SJohn Marino
376e4b17023SJohn Marino /* Now see if ARG_NUM is mentioned in the nonnull list. */
377e4b17023SJohn Marino for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
378e4b17023SJohn Marino {
379e4b17023SJohn Marino if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
380e4b17023SJohn Marino return true;
381e4b17023SJohn Marino }
382e4b17023SJohn Marino
383e4b17023SJohn Marino return false;
384e4b17023SJohn Marino }
385e4b17023SJohn Marino
386e4b17023SJohn Marino
387e4b17023SJohn Marino /* Set value range VR to VR_VARYING. */
388e4b17023SJohn Marino
389e4b17023SJohn Marino static inline void
set_value_range_to_varying(value_range_t * vr)390e4b17023SJohn Marino set_value_range_to_varying (value_range_t *vr)
391e4b17023SJohn Marino {
392e4b17023SJohn Marino vr->type = VR_VARYING;
393e4b17023SJohn Marino vr->min = vr->max = NULL_TREE;
394e4b17023SJohn Marino if (vr->equiv)
395e4b17023SJohn Marino bitmap_clear (vr->equiv);
396e4b17023SJohn Marino }
397e4b17023SJohn Marino
398e4b17023SJohn Marino
399e4b17023SJohn Marino /* Set value range VR to {T, MIN, MAX, EQUIV}. */
400e4b17023SJohn Marino
401e4b17023SJohn Marino static void
set_value_range(value_range_t * vr,enum value_range_type t,tree min,tree max,bitmap equiv)402e4b17023SJohn Marino set_value_range (value_range_t *vr, enum value_range_type t, tree min,
403e4b17023SJohn Marino tree max, bitmap equiv)
404e4b17023SJohn Marino {
405e4b17023SJohn Marino #if defined ENABLE_CHECKING
406e4b17023SJohn Marino /* Check the validity of the range. */
407e4b17023SJohn Marino if (t == VR_RANGE || t == VR_ANTI_RANGE)
408e4b17023SJohn Marino {
409e4b17023SJohn Marino int cmp;
410e4b17023SJohn Marino
411e4b17023SJohn Marino gcc_assert (min && max);
412e4b17023SJohn Marino
413e4b17023SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
414e4b17023SJohn Marino gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
415e4b17023SJohn Marino
416e4b17023SJohn Marino cmp = compare_values (min, max);
417e4b17023SJohn Marino gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
418e4b17023SJohn Marino
419e4b17023SJohn Marino if (needs_overflow_infinity (TREE_TYPE (min)))
420e4b17023SJohn Marino gcc_assert (!is_overflow_infinity (min)
421e4b17023SJohn Marino || !is_overflow_infinity (max));
422e4b17023SJohn Marino }
423e4b17023SJohn Marino
424e4b17023SJohn Marino if (t == VR_UNDEFINED || t == VR_VARYING)
425e4b17023SJohn Marino gcc_assert (min == NULL_TREE && max == NULL_TREE);
426e4b17023SJohn Marino
427e4b17023SJohn Marino if (t == VR_UNDEFINED || t == VR_VARYING)
428e4b17023SJohn Marino gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
429e4b17023SJohn Marino #endif
430e4b17023SJohn Marino
431e4b17023SJohn Marino vr->type = t;
432e4b17023SJohn Marino vr->min = min;
433e4b17023SJohn Marino vr->max = max;
434e4b17023SJohn Marino
435e4b17023SJohn Marino /* Since updating the equivalence set involves deep copying the
436e4b17023SJohn Marino bitmaps, only do it if absolutely necessary. */
437e4b17023SJohn Marino if (vr->equiv == NULL
438e4b17023SJohn Marino && equiv != NULL)
439e4b17023SJohn Marino vr->equiv = BITMAP_ALLOC (NULL);
440e4b17023SJohn Marino
441e4b17023SJohn Marino if (equiv != vr->equiv)
442e4b17023SJohn Marino {
443e4b17023SJohn Marino if (equiv && !bitmap_empty_p (equiv))
444e4b17023SJohn Marino bitmap_copy (vr->equiv, equiv);
445e4b17023SJohn Marino else
446e4b17023SJohn Marino bitmap_clear (vr->equiv);
447e4b17023SJohn Marino }
448e4b17023SJohn Marino }
449e4b17023SJohn Marino
450e4b17023SJohn Marino
451e4b17023SJohn Marino /* Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}.
452e4b17023SJohn Marino This means adjusting T, MIN and MAX representing the case of a
453e4b17023SJohn Marino wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
454e4b17023SJohn Marino as anti-rage ~[MAX+1, MIN-1]. Likewise for wrapping anti-ranges.
455e4b17023SJohn Marino In corner cases where MAX+1 or MIN-1 wraps this will fall back
456e4b17023SJohn Marino to varying.
457e4b17023SJohn Marino This routine exists to ease canonicalization in the case where we
458e4b17023SJohn Marino extract ranges from var + CST op limit. */
459e4b17023SJohn Marino
460e4b17023SJohn Marino static void
set_and_canonicalize_value_range(value_range_t * vr,enum value_range_type t,tree min,tree max,bitmap equiv)461e4b17023SJohn Marino set_and_canonicalize_value_range (value_range_t *vr, enum value_range_type t,
462e4b17023SJohn Marino tree min, tree max, bitmap equiv)
463e4b17023SJohn Marino {
464e4b17023SJohn Marino /* Nothing to canonicalize for symbolic or unknown or varying ranges. */
465e4b17023SJohn Marino if ((t != VR_RANGE
466e4b17023SJohn Marino && t != VR_ANTI_RANGE)
467e4b17023SJohn Marino || TREE_CODE (min) != INTEGER_CST
468e4b17023SJohn Marino || TREE_CODE (max) != INTEGER_CST)
469e4b17023SJohn Marino {
470e4b17023SJohn Marino set_value_range (vr, t, min, max, equiv);
471e4b17023SJohn Marino return;
472e4b17023SJohn Marino }
473e4b17023SJohn Marino
474e4b17023SJohn Marino /* Wrong order for min and max, to swap them and the VR type we need
475e4b17023SJohn Marino to adjust them. */
476e4b17023SJohn Marino if (tree_int_cst_lt (max, min))
477e4b17023SJohn Marino {
478e4b17023SJohn Marino tree one = build_int_cst (TREE_TYPE (min), 1);
479e4b17023SJohn Marino tree tmp = int_const_binop (PLUS_EXPR, max, one);
480e4b17023SJohn Marino max = int_const_binop (MINUS_EXPR, min, one);
481e4b17023SJohn Marino min = tmp;
482e4b17023SJohn Marino
483e4b17023SJohn Marino /* There's one corner case, if we had [C+1, C] before we now have
484e4b17023SJohn Marino that again. But this represents an empty value range, so drop
485e4b17023SJohn Marino to varying in this case. */
486e4b17023SJohn Marino if (tree_int_cst_lt (max, min))
487e4b17023SJohn Marino {
488e4b17023SJohn Marino set_value_range_to_varying (vr);
489e4b17023SJohn Marino return;
490e4b17023SJohn Marino }
491e4b17023SJohn Marino
492e4b17023SJohn Marino t = t == VR_RANGE ? VR_ANTI_RANGE : VR_RANGE;
493e4b17023SJohn Marino }
494e4b17023SJohn Marino
495e4b17023SJohn Marino /* Anti-ranges that can be represented as ranges should be so. */
496e4b17023SJohn Marino if (t == VR_ANTI_RANGE)
497e4b17023SJohn Marino {
498e4b17023SJohn Marino bool is_min = vrp_val_is_min (min);
499e4b17023SJohn Marino bool is_max = vrp_val_is_max (max);
500e4b17023SJohn Marino
501e4b17023SJohn Marino if (is_min && is_max)
502e4b17023SJohn Marino {
503e4b17023SJohn Marino /* We cannot deal with empty ranges, drop to varying. */
504e4b17023SJohn Marino set_value_range_to_varying (vr);
505e4b17023SJohn Marino return;
506e4b17023SJohn Marino }
507e4b17023SJohn Marino else if (is_min
508e4b17023SJohn Marino /* As a special exception preserve non-null ranges. */
509e4b17023SJohn Marino && !(TYPE_UNSIGNED (TREE_TYPE (min))
510e4b17023SJohn Marino && integer_zerop (max)))
511e4b17023SJohn Marino {
512e4b17023SJohn Marino tree one = build_int_cst (TREE_TYPE (max), 1);
513e4b17023SJohn Marino min = int_const_binop (PLUS_EXPR, max, one);
514e4b17023SJohn Marino max = vrp_val_max (TREE_TYPE (max));
515e4b17023SJohn Marino t = VR_RANGE;
516e4b17023SJohn Marino }
517e4b17023SJohn Marino else if (is_max)
518e4b17023SJohn Marino {
519e4b17023SJohn Marino tree one = build_int_cst (TREE_TYPE (min), 1);
520e4b17023SJohn Marino max = int_const_binop (MINUS_EXPR, min, one);
521e4b17023SJohn Marino min = vrp_val_min (TREE_TYPE (min));
522e4b17023SJohn Marino t = VR_RANGE;
523e4b17023SJohn Marino }
524e4b17023SJohn Marino }
525e4b17023SJohn Marino
526e4b17023SJohn Marino set_value_range (vr, t, min, max, equiv);
527e4b17023SJohn Marino }
528e4b17023SJohn Marino
529e4b17023SJohn Marino /* Copy value range FROM into value range TO. */
530e4b17023SJohn Marino
531e4b17023SJohn Marino static inline void
copy_value_range(value_range_t * to,value_range_t * from)532e4b17023SJohn Marino copy_value_range (value_range_t *to, value_range_t *from)
533e4b17023SJohn Marino {
534e4b17023SJohn Marino set_value_range (to, from->type, from->min, from->max, from->equiv);
535e4b17023SJohn Marino }
536e4b17023SJohn Marino
537e4b17023SJohn Marino /* Set value range VR to a single value. This function is only called
538e4b17023SJohn Marino with values we get from statements, and exists to clear the
539e4b17023SJohn Marino TREE_OVERFLOW flag so that we don't think we have an overflow
540e4b17023SJohn Marino infinity when we shouldn't. */
541e4b17023SJohn Marino
542e4b17023SJohn Marino static inline void
set_value_range_to_value(value_range_t * vr,tree val,bitmap equiv)543e4b17023SJohn Marino set_value_range_to_value (value_range_t *vr, tree val, bitmap equiv)
544e4b17023SJohn Marino {
545e4b17023SJohn Marino gcc_assert (is_gimple_min_invariant (val));
546e4b17023SJohn Marino val = avoid_overflow_infinity (val);
547e4b17023SJohn Marino set_value_range (vr, VR_RANGE, val, val, equiv);
548e4b17023SJohn Marino }
549e4b17023SJohn Marino
550e4b17023SJohn Marino /* Set value range VR to a non-negative range of type TYPE.
551e4b17023SJohn Marino OVERFLOW_INFINITY indicates whether to use an overflow infinity
552e4b17023SJohn Marino rather than TYPE_MAX_VALUE; this should be true if we determine
553e4b17023SJohn Marino that the range is nonnegative based on the assumption that signed
554e4b17023SJohn Marino overflow does not occur. */
555e4b17023SJohn Marino
556e4b17023SJohn Marino static inline void
set_value_range_to_nonnegative(value_range_t * vr,tree type,bool overflow_infinity)557e4b17023SJohn Marino set_value_range_to_nonnegative (value_range_t *vr, tree type,
558e4b17023SJohn Marino bool overflow_infinity)
559e4b17023SJohn Marino {
560e4b17023SJohn Marino tree zero;
561e4b17023SJohn Marino
562e4b17023SJohn Marino if (overflow_infinity && !supports_overflow_infinity (type))
563e4b17023SJohn Marino {
564e4b17023SJohn Marino set_value_range_to_varying (vr);
565e4b17023SJohn Marino return;
566e4b17023SJohn Marino }
567e4b17023SJohn Marino
568e4b17023SJohn Marino zero = build_int_cst (type, 0);
569e4b17023SJohn Marino set_value_range (vr, VR_RANGE, zero,
570e4b17023SJohn Marino (overflow_infinity
571e4b17023SJohn Marino ? positive_overflow_infinity (type)
572e4b17023SJohn Marino : TYPE_MAX_VALUE (type)),
573e4b17023SJohn Marino vr->equiv);
574e4b17023SJohn Marino }
575e4b17023SJohn Marino
576e4b17023SJohn Marino /* Set value range VR to a non-NULL range of type TYPE. */
577e4b17023SJohn Marino
578e4b17023SJohn Marino static inline void
set_value_range_to_nonnull(value_range_t * vr,tree type)579e4b17023SJohn Marino set_value_range_to_nonnull (value_range_t *vr, tree type)
580e4b17023SJohn Marino {
581e4b17023SJohn Marino tree zero = build_int_cst (type, 0);
582e4b17023SJohn Marino set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
583e4b17023SJohn Marino }
584e4b17023SJohn Marino
585e4b17023SJohn Marino
586e4b17023SJohn Marino /* Set value range VR to a NULL range of type TYPE. */
587e4b17023SJohn Marino
588e4b17023SJohn Marino static inline void
set_value_range_to_null(value_range_t * vr,tree type)589e4b17023SJohn Marino set_value_range_to_null (value_range_t *vr, tree type)
590e4b17023SJohn Marino {
591e4b17023SJohn Marino set_value_range_to_value (vr, build_int_cst (type, 0), vr->equiv);
592e4b17023SJohn Marino }
593e4b17023SJohn Marino
594e4b17023SJohn Marino
595e4b17023SJohn Marino /* Set value range VR to a range of a truthvalue of type TYPE. */
596e4b17023SJohn Marino
597e4b17023SJohn Marino static inline void
set_value_range_to_truthvalue(value_range_t * vr,tree type)598e4b17023SJohn Marino set_value_range_to_truthvalue (value_range_t *vr, tree type)
599e4b17023SJohn Marino {
600e4b17023SJohn Marino if (TYPE_PRECISION (type) == 1)
601e4b17023SJohn Marino set_value_range_to_varying (vr);
602e4b17023SJohn Marino else
603e4b17023SJohn Marino set_value_range (vr, VR_RANGE,
604e4b17023SJohn Marino build_int_cst (type, 0), build_int_cst (type, 1),
605e4b17023SJohn Marino vr->equiv);
606e4b17023SJohn Marino }
607e4b17023SJohn Marino
608e4b17023SJohn Marino
609e4b17023SJohn Marino /* Set value range VR to VR_UNDEFINED. */
610e4b17023SJohn Marino
611e4b17023SJohn Marino static inline void
set_value_range_to_undefined(value_range_t * vr)612e4b17023SJohn Marino set_value_range_to_undefined (value_range_t *vr)
613e4b17023SJohn Marino {
614e4b17023SJohn Marino vr->type = VR_UNDEFINED;
615e4b17023SJohn Marino vr->min = vr->max = NULL_TREE;
616e4b17023SJohn Marino if (vr->equiv)
617e4b17023SJohn Marino bitmap_clear (vr->equiv);
618e4b17023SJohn Marino }
619e4b17023SJohn Marino
620e4b17023SJohn Marino
621e4b17023SJohn Marino /* If abs (min) < abs (max), set VR to [-max, max], if
622e4b17023SJohn Marino abs (min) >= abs (max), set VR to [-min, min]. */
623e4b17023SJohn Marino
624e4b17023SJohn Marino static void
abs_extent_range(value_range_t * vr,tree min,tree max)625e4b17023SJohn Marino abs_extent_range (value_range_t *vr, tree min, tree max)
626e4b17023SJohn Marino {
627e4b17023SJohn Marino int cmp;
628e4b17023SJohn Marino
629e4b17023SJohn Marino gcc_assert (TREE_CODE (min) == INTEGER_CST);
630e4b17023SJohn Marino gcc_assert (TREE_CODE (max) == INTEGER_CST);
631e4b17023SJohn Marino gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (min)));
632e4b17023SJohn Marino gcc_assert (!TYPE_UNSIGNED (TREE_TYPE (min)));
633e4b17023SJohn Marino min = fold_unary (ABS_EXPR, TREE_TYPE (min), min);
634e4b17023SJohn Marino max = fold_unary (ABS_EXPR, TREE_TYPE (max), max);
635e4b17023SJohn Marino if (TREE_OVERFLOW (min) || TREE_OVERFLOW (max))
636e4b17023SJohn Marino {
637e4b17023SJohn Marino set_value_range_to_varying (vr);
638e4b17023SJohn Marino return;
639e4b17023SJohn Marino }
640e4b17023SJohn Marino cmp = compare_values (min, max);
641e4b17023SJohn Marino if (cmp == -1)
642e4b17023SJohn Marino min = fold_unary (NEGATE_EXPR, TREE_TYPE (min), max);
643e4b17023SJohn Marino else if (cmp == 0 || cmp == 1)
644e4b17023SJohn Marino {
645e4b17023SJohn Marino max = min;
646e4b17023SJohn Marino min = fold_unary (NEGATE_EXPR, TREE_TYPE (min), min);
647e4b17023SJohn Marino }
648e4b17023SJohn Marino else
649e4b17023SJohn Marino {
650e4b17023SJohn Marino set_value_range_to_varying (vr);
651e4b17023SJohn Marino return;
652e4b17023SJohn Marino }
653e4b17023SJohn Marino set_and_canonicalize_value_range (vr, VR_RANGE, min, max, NULL);
654e4b17023SJohn Marino }
655e4b17023SJohn Marino
656e4b17023SJohn Marino
657e4b17023SJohn Marino /* Return value range information for VAR.
658e4b17023SJohn Marino
659e4b17023SJohn Marino If we have no values ranges recorded (ie, VRP is not running), then
660e4b17023SJohn Marino return NULL. Otherwise create an empty range if none existed for VAR. */
661e4b17023SJohn Marino
662e4b17023SJohn Marino static value_range_t *
get_value_range(const_tree var)663e4b17023SJohn Marino get_value_range (const_tree var)
664e4b17023SJohn Marino {
665e4b17023SJohn Marino static const struct value_range_d vr_const_varying
666e4b17023SJohn Marino = { VR_VARYING, NULL_TREE, NULL_TREE, NULL };
667e4b17023SJohn Marino value_range_t *vr;
668e4b17023SJohn Marino tree sym;
669e4b17023SJohn Marino unsigned ver = SSA_NAME_VERSION (var);
670e4b17023SJohn Marino
671e4b17023SJohn Marino /* If we have no recorded ranges, then return NULL. */
672e4b17023SJohn Marino if (! vr_value)
673e4b17023SJohn Marino return NULL;
674e4b17023SJohn Marino
675e4b17023SJohn Marino /* If we query the range for a new SSA name return an unmodifiable VARYING.
676e4b17023SJohn Marino We should get here at most from the substitute-and-fold stage which
677e4b17023SJohn Marino will never try to change values. */
678e4b17023SJohn Marino if (ver >= num_vr_values)
679e4b17023SJohn Marino return CONST_CAST (value_range_t *, &vr_const_varying);
680e4b17023SJohn Marino
681e4b17023SJohn Marino vr = vr_value[ver];
682e4b17023SJohn Marino if (vr)
683e4b17023SJohn Marino return vr;
684e4b17023SJohn Marino
685e4b17023SJohn Marino /* After propagation finished do not allocate new value-ranges. */
686e4b17023SJohn Marino if (values_propagated)
687e4b17023SJohn Marino return CONST_CAST (value_range_t *, &vr_const_varying);
688e4b17023SJohn Marino
689e4b17023SJohn Marino /* Create a default value range. */
690e4b17023SJohn Marino vr_value[ver] = vr = XCNEW (value_range_t);
691e4b17023SJohn Marino
692e4b17023SJohn Marino /* Defer allocating the equivalence set. */
693e4b17023SJohn Marino vr->equiv = NULL;
694e4b17023SJohn Marino
695e4b17023SJohn Marino /* If VAR is a default definition of a parameter, the variable can
696e4b17023SJohn Marino take any value in VAR's type. */
697e4b17023SJohn Marino sym = SSA_NAME_VAR (var);
698e4b17023SJohn Marino if (SSA_NAME_IS_DEFAULT_DEF (var))
699e4b17023SJohn Marino {
700e4b17023SJohn Marino if (TREE_CODE (sym) == PARM_DECL)
701e4b17023SJohn Marino {
702e4b17023SJohn Marino /* Try to use the "nonnull" attribute to create ~[0, 0]
703e4b17023SJohn Marino anti-ranges for pointers. Note that this is only valid with
704e4b17023SJohn Marino default definitions of PARM_DECLs. */
705e4b17023SJohn Marino if (POINTER_TYPE_P (TREE_TYPE (sym))
706e4b17023SJohn Marino && nonnull_arg_p (sym))
707e4b17023SJohn Marino set_value_range_to_nonnull (vr, TREE_TYPE (sym));
708e4b17023SJohn Marino else
709e4b17023SJohn Marino set_value_range_to_varying (vr);
710e4b17023SJohn Marino }
711e4b17023SJohn Marino else if (TREE_CODE (sym) == RESULT_DECL
712e4b17023SJohn Marino && DECL_BY_REFERENCE (sym))
713e4b17023SJohn Marino set_value_range_to_nonnull (vr, TREE_TYPE (sym));
714e4b17023SJohn Marino }
715e4b17023SJohn Marino
716e4b17023SJohn Marino return vr;
717e4b17023SJohn Marino }
718e4b17023SJohn Marino
719e4b17023SJohn Marino /* Return true, if VAL1 and VAL2 are equal values for VRP purposes. */
720e4b17023SJohn Marino
721e4b17023SJohn Marino static inline bool
vrp_operand_equal_p(const_tree val1,const_tree val2)722e4b17023SJohn Marino vrp_operand_equal_p (const_tree val1, const_tree val2)
723e4b17023SJohn Marino {
724e4b17023SJohn Marino if (val1 == val2)
725e4b17023SJohn Marino return true;
726e4b17023SJohn Marino if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
727e4b17023SJohn Marino return false;
728e4b17023SJohn Marino if (is_overflow_infinity (val1))
729e4b17023SJohn Marino return is_overflow_infinity (val2);
730e4b17023SJohn Marino return true;
731e4b17023SJohn Marino }
732e4b17023SJohn Marino
733e4b17023SJohn Marino /* Return true, if the bitmaps B1 and B2 are equal. */
734e4b17023SJohn Marino
735e4b17023SJohn Marino static inline bool
vrp_bitmap_equal_p(const_bitmap b1,const_bitmap b2)736e4b17023SJohn Marino vrp_bitmap_equal_p (const_bitmap b1, const_bitmap b2)
737e4b17023SJohn Marino {
738e4b17023SJohn Marino return (b1 == b2
739e4b17023SJohn Marino || ((!b1 || bitmap_empty_p (b1))
740e4b17023SJohn Marino && (!b2 || bitmap_empty_p (b2)))
741e4b17023SJohn Marino || (b1 && b2
742e4b17023SJohn Marino && bitmap_equal_p (b1, b2)));
743e4b17023SJohn Marino }
744e4b17023SJohn Marino
745e4b17023SJohn Marino /* Update the value range and equivalence set for variable VAR to
746e4b17023SJohn Marino NEW_VR. Return true if NEW_VR is different from VAR's previous
747e4b17023SJohn Marino value.
748e4b17023SJohn Marino
749e4b17023SJohn Marino NOTE: This function assumes that NEW_VR is a temporary value range
750e4b17023SJohn Marino object created for the sole purpose of updating VAR's range. The
751e4b17023SJohn Marino storage used by the equivalence set from NEW_VR will be freed by
752e4b17023SJohn Marino this function. Do not call update_value_range when NEW_VR
753e4b17023SJohn Marino is the range object associated with another SSA name. */
754e4b17023SJohn Marino
755e4b17023SJohn Marino static inline bool
update_value_range(const_tree var,value_range_t * new_vr)756e4b17023SJohn Marino update_value_range (const_tree var, value_range_t *new_vr)
757e4b17023SJohn Marino {
758e4b17023SJohn Marino value_range_t *old_vr;
759e4b17023SJohn Marino bool is_new;
760e4b17023SJohn Marino
761e4b17023SJohn Marino /* Update the value range, if necessary. */
762e4b17023SJohn Marino old_vr = get_value_range (var);
763e4b17023SJohn Marino is_new = old_vr->type != new_vr->type
764e4b17023SJohn Marino || !vrp_operand_equal_p (old_vr->min, new_vr->min)
765e4b17023SJohn Marino || !vrp_operand_equal_p (old_vr->max, new_vr->max)
766e4b17023SJohn Marino || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
767e4b17023SJohn Marino
768e4b17023SJohn Marino if (is_new)
769e4b17023SJohn Marino set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
770e4b17023SJohn Marino new_vr->equiv);
771e4b17023SJohn Marino
772e4b17023SJohn Marino BITMAP_FREE (new_vr->equiv);
773e4b17023SJohn Marino
774e4b17023SJohn Marino return is_new;
775e4b17023SJohn Marino }
776e4b17023SJohn Marino
777e4b17023SJohn Marino
778e4b17023SJohn Marino /* Add VAR and VAR's equivalence set to EQUIV. This is the central
779e4b17023SJohn Marino point where equivalence processing can be turned on/off. */
780e4b17023SJohn Marino
781e4b17023SJohn Marino static void
add_equivalence(bitmap * equiv,const_tree var)782e4b17023SJohn Marino add_equivalence (bitmap *equiv, const_tree var)
783e4b17023SJohn Marino {
784e4b17023SJohn Marino unsigned ver = SSA_NAME_VERSION (var);
785e4b17023SJohn Marino value_range_t *vr = vr_value[ver];
786e4b17023SJohn Marino
787e4b17023SJohn Marino if (*equiv == NULL)
788e4b17023SJohn Marino *equiv = BITMAP_ALLOC (NULL);
789e4b17023SJohn Marino bitmap_set_bit (*equiv, ver);
790e4b17023SJohn Marino if (vr && vr->equiv)
791e4b17023SJohn Marino bitmap_ior_into (*equiv, vr->equiv);
792e4b17023SJohn Marino }
793e4b17023SJohn Marino
794e4b17023SJohn Marino
795e4b17023SJohn Marino /* Return true if VR is ~[0, 0]. */
796e4b17023SJohn Marino
797e4b17023SJohn Marino static inline bool
range_is_nonnull(value_range_t * vr)798e4b17023SJohn Marino range_is_nonnull (value_range_t *vr)
799e4b17023SJohn Marino {
800e4b17023SJohn Marino return vr->type == VR_ANTI_RANGE
801e4b17023SJohn Marino && integer_zerop (vr->min)
802e4b17023SJohn Marino && integer_zerop (vr->max);
803e4b17023SJohn Marino }
804e4b17023SJohn Marino
805e4b17023SJohn Marino
806e4b17023SJohn Marino /* Return true if VR is [0, 0]. */
807e4b17023SJohn Marino
808e4b17023SJohn Marino static inline bool
range_is_null(value_range_t * vr)809e4b17023SJohn Marino range_is_null (value_range_t *vr)
810e4b17023SJohn Marino {
811e4b17023SJohn Marino return vr->type == VR_RANGE
812e4b17023SJohn Marino && integer_zerop (vr->min)
813e4b17023SJohn Marino && integer_zerop (vr->max);
814e4b17023SJohn Marino }
815e4b17023SJohn Marino
816e4b17023SJohn Marino /* Return true if max and min of VR are INTEGER_CST. It's not necessary
817e4b17023SJohn Marino a singleton. */
818e4b17023SJohn Marino
819e4b17023SJohn Marino static inline bool
range_int_cst_p(value_range_t * vr)820e4b17023SJohn Marino range_int_cst_p (value_range_t *vr)
821e4b17023SJohn Marino {
822e4b17023SJohn Marino return (vr->type == VR_RANGE
823e4b17023SJohn Marino && TREE_CODE (vr->max) == INTEGER_CST
824e4b17023SJohn Marino && TREE_CODE (vr->min) == INTEGER_CST
825e4b17023SJohn Marino && !TREE_OVERFLOW (vr->max)
826e4b17023SJohn Marino && !TREE_OVERFLOW (vr->min));
827e4b17023SJohn Marino }
828e4b17023SJohn Marino
829e4b17023SJohn Marino /* Return true if VR is a INTEGER_CST singleton. */
830e4b17023SJohn Marino
831e4b17023SJohn Marino static inline bool
range_int_cst_singleton_p(value_range_t * vr)832e4b17023SJohn Marino range_int_cst_singleton_p (value_range_t *vr)
833e4b17023SJohn Marino {
834e4b17023SJohn Marino return (range_int_cst_p (vr)
835e4b17023SJohn Marino && tree_int_cst_equal (vr->min, vr->max));
836e4b17023SJohn Marino }
837e4b17023SJohn Marino
838e4b17023SJohn Marino /* Return true if value range VR involves at least one symbol. */
839e4b17023SJohn Marino
840e4b17023SJohn Marino static inline bool
symbolic_range_p(value_range_t * vr)841e4b17023SJohn Marino symbolic_range_p (value_range_t *vr)
842e4b17023SJohn Marino {
843e4b17023SJohn Marino return (!is_gimple_min_invariant (vr->min)
844e4b17023SJohn Marino || !is_gimple_min_invariant (vr->max));
845e4b17023SJohn Marino }
846e4b17023SJohn Marino
847e4b17023SJohn Marino /* Return true if value range VR uses an overflow infinity. */
848e4b17023SJohn Marino
849e4b17023SJohn Marino static inline bool
overflow_infinity_range_p(value_range_t * vr)850e4b17023SJohn Marino overflow_infinity_range_p (value_range_t *vr)
851e4b17023SJohn Marino {
852e4b17023SJohn Marino return (vr->type == VR_RANGE
853e4b17023SJohn Marino && (is_overflow_infinity (vr->min)
854e4b17023SJohn Marino || is_overflow_infinity (vr->max)));
855e4b17023SJohn Marino }
856e4b17023SJohn Marino
857e4b17023SJohn Marino /* Return false if we can not make a valid comparison based on VR;
858e4b17023SJohn Marino this will be the case if it uses an overflow infinity and overflow
859e4b17023SJohn Marino is not undefined (i.e., -fno-strict-overflow is in effect).
860e4b17023SJohn Marino Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
861e4b17023SJohn Marino uses an overflow infinity. */
862e4b17023SJohn Marino
863e4b17023SJohn Marino static bool
usable_range_p(value_range_t * vr,bool * strict_overflow_p)864e4b17023SJohn Marino usable_range_p (value_range_t *vr, bool *strict_overflow_p)
865e4b17023SJohn Marino {
866e4b17023SJohn Marino gcc_assert (vr->type == VR_RANGE);
867e4b17023SJohn Marino if (is_overflow_infinity (vr->min))
868e4b17023SJohn Marino {
869e4b17023SJohn Marino *strict_overflow_p = true;
870e4b17023SJohn Marino if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
871e4b17023SJohn Marino return false;
872e4b17023SJohn Marino }
873e4b17023SJohn Marino if (is_overflow_infinity (vr->max))
874e4b17023SJohn Marino {
875e4b17023SJohn Marino *strict_overflow_p = true;
876e4b17023SJohn Marino if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
877e4b17023SJohn Marino return false;
878e4b17023SJohn Marino }
879e4b17023SJohn Marino return true;
880e4b17023SJohn Marino }
881e4b17023SJohn Marino
882e4b17023SJohn Marino
883e4b17023SJohn Marino /* Return true if the result of assignment STMT is know to be non-negative.
884e4b17023SJohn Marino If the return value is based on the assumption that signed overflow is
885e4b17023SJohn Marino undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
886e4b17023SJohn Marino *STRICT_OVERFLOW_P.*/
887e4b17023SJohn Marino
888e4b17023SJohn Marino static bool
gimple_assign_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)889e4b17023SJohn Marino gimple_assign_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
890e4b17023SJohn Marino {
891e4b17023SJohn Marino enum tree_code code = gimple_assign_rhs_code (stmt);
892e4b17023SJohn Marino switch (get_gimple_rhs_class (code))
893e4b17023SJohn Marino {
894e4b17023SJohn Marino case GIMPLE_UNARY_RHS:
895e4b17023SJohn Marino return tree_unary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
896e4b17023SJohn Marino gimple_expr_type (stmt),
897e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
898e4b17023SJohn Marino strict_overflow_p);
899e4b17023SJohn Marino case GIMPLE_BINARY_RHS:
900e4b17023SJohn Marino return tree_binary_nonnegative_warnv_p (gimple_assign_rhs_code (stmt),
901e4b17023SJohn Marino gimple_expr_type (stmt),
902e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
903e4b17023SJohn Marino gimple_assign_rhs2 (stmt),
904e4b17023SJohn Marino strict_overflow_p);
905e4b17023SJohn Marino case GIMPLE_TERNARY_RHS:
906e4b17023SJohn Marino return false;
907e4b17023SJohn Marino case GIMPLE_SINGLE_RHS:
908e4b17023SJohn Marino return tree_single_nonnegative_warnv_p (gimple_assign_rhs1 (stmt),
909e4b17023SJohn Marino strict_overflow_p);
910e4b17023SJohn Marino case GIMPLE_INVALID_RHS:
911e4b17023SJohn Marino gcc_unreachable ();
912e4b17023SJohn Marino default:
913e4b17023SJohn Marino gcc_unreachable ();
914e4b17023SJohn Marino }
915e4b17023SJohn Marino }
916e4b17023SJohn Marino
917e4b17023SJohn Marino /* Return true if return value of call STMT is know to be non-negative.
918e4b17023SJohn Marino If the return value is based on the assumption that signed overflow is
919e4b17023SJohn Marino undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
920e4b17023SJohn Marino *STRICT_OVERFLOW_P.*/
921e4b17023SJohn Marino
922e4b17023SJohn Marino static bool
gimple_call_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)923e4b17023SJohn Marino gimple_call_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
924e4b17023SJohn Marino {
925e4b17023SJohn Marino tree arg0 = gimple_call_num_args (stmt) > 0 ?
926e4b17023SJohn Marino gimple_call_arg (stmt, 0) : NULL_TREE;
927e4b17023SJohn Marino tree arg1 = gimple_call_num_args (stmt) > 1 ?
928e4b17023SJohn Marino gimple_call_arg (stmt, 1) : NULL_TREE;
929e4b17023SJohn Marino
930e4b17023SJohn Marino return tree_call_nonnegative_warnv_p (gimple_expr_type (stmt),
931e4b17023SJohn Marino gimple_call_fndecl (stmt),
932e4b17023SJohn Marino arg0,
933e4b17023SJohn Marino arg1,
934e4b17023SJohn Marino strict_overflow_p);
935e4b17023SJohn Marino }
936e4b17023SJohn Marino
937e4b17023SJohn Marino /* Return true if STMT is know to to compute a non-negative value.
938e4b17023SJohn Marino If the return value is based on the assumption that signed overflow is
939e4b17023SJohn Marino undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
940e4b17023SJohn Marino *STRICT_OVERFLOW_P.*/
941e4b17023SJohn Marino
942e4b17023SJohn Marino static bool
gimple_stmt_nonnegative_warnv_p(gimple stmt,bool * strict_overflow_p)943e4b17023SJohn Marino gimple_stmt_nonnegative_warnv_p (gimple stmt, bool *strict_overflow_p)
944e4b17023SJohn Marino {
945e4b17023SJohn Marino switch (gimple_code (stmt))
946e4b17023SJohn Marino {
947e4b17023SJohn Marino case GIMPLE_ASSIGN:
948e4b17023SJohn Marino return gimple_assign_nonnegative_warnv_p (stmt, strict_overflow_p);
949e4b17023SJohn Marino case GIMPLE_CALL:
950e4b17023SJohn Marino return gimple_call_nonnegative_warnv_p (stmt, strict_overflow_p);
951e4b17023SJohn Marino default:
952e4b17023SJohn Marino gcc_unreachable ();
953e4b17023SJohn Marino }
954e4b17023SJohn Marino }
955e4b17023SJohn Marino
956e4b17023SJohn Marino /* Return true if the result of assignment STMT is know to be non-zero.
957e4b17023SJohn Marino If the return value is based on the assumption that signed overflow is
958e4b17023SJohn Marino undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
959e4b17023SJohn Marino *STRICT_OVERFLOW_P.*/
960e4b17023SJohn Marino
961e4b17023SJohn Marino static bool
gimple_assign_nonzero_warnv_p(gimple stmt,bool * strict_overflow_p)962e4b17023SJohn Marino gimple_assign_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
963e4b17023SJohn Marino {
964e4b17023SJohn Marino enum tree_code code = gimple_assign_rhs_code (stmt);
965e4b17023SJohn Marino switch (get_gimple_rhs_class (code))
966e4b17023SJohn Marino {
967e4b17023SJohn Marino case GIMPLE_UNARY_RHS:
968e4b17023SJohn Marino return tree_unary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
969e4b17023SJohn Marino gimple_expr_type (stmt),
970e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
971e4b17023SJohn Marino strict_overflow_p);
972e4b17023SJohn Marino case GIMPLE_BINARY_RHS:
973e4b17023SJohn Marino return tree_binary_nonzero_warnv_p (gimple_assign_rhs_code (stmt),
974e4b17023SJohn Marino gimple_expr_type (stmt),
975e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
976e4b17023SJohn Marino gimple_assign_rhs2 (stmt),
977e4b17023SJohn Marino strict_overflow_p);
978e4b17023SJohn Marino case GIMPLE_TERNARY_RHS:
979e4b17023SJohn Marino return false;
980e4b17023SJohn Marino case GIMPLE_SINGLE_RHS:
981e4b17023SJohn Marino return tree_single_nonzero_warnv_p (gimple_assign_rhs1 (stmt),
982e4b17023SJohn Marino strict_overflow_p);
983e4b17023SJohn Marino case GIMPLE_INVALID_RHS:
984e4b17023SJohn Marino gcc_unreachable ();
985e4b17023SJohn Marino default:
986e4b17023SJohn Marino gcc_unreachable ();
987e4b17023SJohn Marino }
988e4b17023SJohn Marino }
989e4b17023SJohn Marino
990e4b17023SJohn Marino /* Return true if STMT is know to to compute a non-zero value.
991e4b17023SJohn Marino If the return value is based on the assumption that signed overflow is
992e4b17023SJohn Marino undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
993e4b17023SJohn Marino *STRICT_OVERFLOW_P.*/
994e4b17023SJohn Marino
995e4b17023SJohn Marino static bool
gimple_stmt_nonzero_warnv_p(gimple stmt,bool * strict_overflow_p)996e4b17023SJohn Marino gimple_stmt_nonzero_warnv_p (gimple stmt, bool *strict_overflow_p)
997e4b17023SJohn Marino {
998e4b17023SJohn Marino switch (gimple_code (stmt))
999e4b17023SJohn Marino {
1000e4b17023SJohn Marino case GIMPLE_ASSIGN:
1001e4b17023SJohn Marino return gimple_assign_nonzero_warnv_p (stmt, strict_overflow_p);
1002e4b17023SJohn Marino case GIMPLE_CALL:
1003e4b17023SJohn Marino return gimple_alloca_call_p (stmt);
1004e4b17023SJohn Marino default:
1005e4b17023SJohn Marino gcc_unreachable ();
1006e4b17023SJohn Marino }
1007e4b17023SJohn Marino }
1008e4b17023SJohn Marino
1009e4b17023SJohn Marino /* Like tree_expr_nonzero_warnv_p, but this function uses value ranges
1010e4b17023SJohn Marino obtained so far. */
1011e4b17023SJohn Marino
1012e4b17023SJohn Marino static bool
vrp_stmt_computes_nonzero(gimple stmt,bool * strict_overflow_p)1013e4b17023SJohn Marino vrp_stmt_computes_nonzero (gimple stmt, bool *strict_overflow_p)
1014e4b17023SJohn Marino {
1015e4b17023SJohn Marino if (gimple_stmt_nonzero_warnv_p (stmt, strict_overflow_p))
1016e4b17023SJohn Marino return true;
1017e4b17023SJohn Marino
1018e4b17023SJohn Marino /* If we have an expression of the form &X->a, then the expression
1019e4b17023SJohn Marino is nonnull if X is nonnull. */
1020e4b17023SJohn Marino if (is_gimple_assign (stmt)
1021e4b17023SJohn Marino && gimple_assign_rhs_code (stmt) == ADDR_EXPR)
1022e4b17023SJohn Marino {
1023e4b17023SJohn Marino tree expr = gimple_assign_rhs1 (stmt);
1024e4b17023SJohn Marino tree base = get_base_address (TREE_OPERAND (expr, 0));
1025e4b17023SJohn Marino
1026e4b17023SJohn Marino if (base != NULL_TREE
1027e4b17023SJohn Marino && TREE_CODE (base) == MEM_REF
1028e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
1029e4b17023SJohn Marino {
1030e4b17023SJohn Marino value_range_t *vr = get_value_range (TREE_OPERAND (base, 0));
1031e4b17023SJohn Marino if (range_is_nonnull (vr))
1032e4b17023SJohn Marino return true;
1033e4b17023SJohn Marino }
1034e4b17023SJohn Marino }
1035e4b17023SJohn Marino
1036e4b17023SJohn Marino return false;
1037e4b17023SJohn Marino }
1038e4b17023SJohn Marino
1039e4b17023SJohn Marino /* Returns true if EXPR is a valid value (as expected by compare_values) --
1040e4b17023SJohn Marino a gimple invariant, or SSA_NAME +- CST. */
1041e4b17023SJohn Marino
1042e4b17023SJohn Marino static bool
valid_value_p(tree expr)1043e4b17023SJohn Marino valid_value_p (tree expr)
1044e4b17023SJohn Marino {
1045e4b17023SJohn Marino if (TREE_CODE (expr) == SSA_NAME)
1046e4b17023SJohn Marino return true;
1047e4b17023SJohn Marino
1048e4b17023SJohn Marino if (TREE_CODE (expr) == PLUS_EXPR
1049e4b17023SJohn Marino || TREE_CODE (expr) == MINUS_EXPR)
1050e4b17023SJohn Marino return (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
1051e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST);
1052e4b17023SJohn Marino
1053e4b17023SJohn Marino return is_gimple_min_invariant (expr);
1054e4b17023SJohn Marino }
1055e4b17023SJohn Marino
1056e4b17023SJohn Marino /* Return
1057e4b17023SJohn Marino 1 if VAL < VAL2
1058e4b17023SJohn Marino 0 if !(VAL < VAL2)
1059e4b17023SJohn Marino -2 if those are incomparable. */
1060e4b17023SJohn Marino static inline int
operand_less_p(tree val,tree val2)1061e4b17023SJohn Marino operand_less_p (tree val, tree val2)
1062e4b17023SJohn Marino {
1063e4b17023SJohn Marino /* LT is folded faster than GE and others. Inline the common case. */
1064e4b17023SJohn Marino if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
1065e4b17023SJohn Marino {
1066e4b17023SJohn Marino if (TYPE_UNSIGNED (TREE_TYPE (val)))
1067e4b17023SJohn Marino return INT_CST_LT_UNSIGNED (val, val2);
1068e4b17023SJohn Marino else
1069e4b17023SJohn Marino {
1070e4b17023SJohn Marino if (INT_CST_LT (val, val2))
1071e4b17023SJohn Marino return 1;
1072e4b17023SJohn Marino }
1073e4b17023SJohn Marino }
1074e4b17023SJohn Marino else
1075e4b17023SJohn Marino {
1076e4b17023SJohn Marino tree tcmp;
1077e4b17023SJohn Marino
1078e4b17023SJohn Marino fold_defer_overflow_warnings ();
1079e4b17023SJohn Marino
1080e4b17023SJohn Marino tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);
1081e4b17023SJohn Marino
1082e4b17023SJohn Marino fold_undefer_and_ignore_overflow_warnings ();
1083e4b17023SJohn Marino
1084e4b17023SJohn Marino if (!tcmp
1085e4b17023SJohn Marino || TREE_CODE (tcmp) != INTEGER_CST)
1086e4b17023SJohn Marino return -2;
1087e4b17023SJohn Marino
1088e4b17023SJohn Marino if (!integer_zerop (tcmp))
1089e4b17023SJohn Marino return 1;
1090e4b17023SJohn Marino }
1091e4b17023SJohn Marino
1092e4b17023SJohn Marino /* val >= val2, not considering overflow infinity. */
1093e4b17023SJohn Marino if (is_negative_overflow_infinity (val))
1094e4b17023SJohn Marino return is_negative_overflow_infinity (val2) ? 0 : 1;
1095e4b17023SJohn Marino else if (is_positive_overflow_infinity (val2))
1096e4b17023SJohn Marino return is_positive_overflow_infinity (val) ? 0 : 1;
1097e4b17023SJohn Marino
1098e4b17023SJohn Marino return 0;
1099e4b17023SJohn Marino }
1100e4b17023SJohn Marino
1101e4b17023SJohn Marino /* Compare two values VAL1 and VAL2. Return
1102e4b17023SJohn Marino
1103e4b17023SJohn Marino -2 if VAL1 and VAL2 cannot be compared at compile-time,
1104e4b17023SJohn Marino -1 if VAL1 < VAL2,
1105e4b17023SJohn Marino 0 if VAL1 == VAL2,
1106e4b17023SJohn Marino +1 if VAL1 > VAL2, and
1107e4b17023SJohn Marino +2 if VAL1 != VAL2
1108e4b17023SJohn Marino
1109e4b17023SJohn Marino This is similar to tree_int_cst_compare but supports pointer values
1110e4b17023SJohn Marino and values that cannot be compared at compile time.
1111e4b17023SJohn Marino
1112e4b17023SJohn Marino If STRICT_OVERFLOW_P is not NULL, then set *STRICT_OVERFLOW_P to
1113e4b17023SJohn Marino true if the return value is only valid if we assume that signed
1114e4b17023SJohn Marino overflow is undefined. */
1115e4b17023SJohn Marino
1116e4b17023SJohn Marino static int
compare_values_warnv(tree val1,tree val2,bool * strict_overflow_p)1117e4b17023SJohn Marino compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
1118e4b17023SJohn Marino {
1119e4b17023SJohn Marino if (val1 == val2)
1120e4b17023SJohn Marino return 0;
1121e4b17023SJohn Marino
1122e4b17023SJohn Marino /* Below we rely on the fact that VAL1 and VAL2 are both pointers or
1123e4b17023SJohn Marino both integers. */
1124e4b17023SJohn Marino gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
1125e4b17023SJohn Marino == POINTER_TYPE_P (TREE_TYPE (val2)));
1126e4b17023SJohn Marino /* Convert the two values into the same type. This is needed because
1127e4b17023SJohn Marino sizetype causes sign extension even for unsigned types. */
1128e4b17023SJohn Marino val2 = fold_convert (TREE_TYPE (val1), val2);
1129e4b17023SJohn Marino STRIP_USELESS_TYPE_CONVERSION (val2);
1130e4b17023SJohn Marino
1131e4b17023SJohn Marino if ((TREE_CODE (val1) == SSA_NAME
1132e4b17023SJohn Marino || TREE_CODE (val1) == PLUS_EXPR
1133e4b17023SJohn Marino || TREE_CODE (val1) == MINUS_EXPR)
1134e4b17023SJohn Marino && (TREE_CODE (val2) == SSA_NAME
1135e4b17023SJohn Marino || TREE_CODE (val2) == PLUS_EXPR
1136e4b17023SJohn Marino || TREE_CODE (val2) == MINUS_EXPR))
1137e4b17023SJohn Marino {
1138e4b17023SJohn Marino tree n1, c1, n2, c2;
1139e4b17023SJohn Marino enum tree_code code1, code2;
1140e4b17023SJohn Marino
1141e4b17023SJohn Marino /* If VAL1 and VAL2 are of the form 'NAME [+-] CST' or 'NAME',
1142e4b17023SJohn Marino return -1 or +1 accordingly. If VAL1 and VAL2 don't use the
1143e4b17023SJohn Marino same name, return -2. */
1144e4b17023SJohn Marino if (TREE_CODE (val1) == SSA_NAME)
1145e4b17023SJohn Marino {
1146e4b17023SJohn Marino code1 = SSA_NAME;
1147e4b17023SJohn Marino n1 = val1;
1148e4b17023SJohn Marino c1 = NULL_TREE;
1149e4b17023SJohn Marino }
1150e4b17023SJohn Marino else
1151e4b17023SJohn Marino {
1152e4b17023SJohn Marino code1 = TREE_CODE (val1);
1153e4b17023SJohn Marino n1 = TREE_OPERAND (val1, 0);
1154e4b17023SJohn Marino c1 = TREE_OPERAND (val1, 1);
1155e4b17023SJohn Marino if (tree_int_cst_sgn (c1) == -1)
1156e4b17023SJohn Marino {
1157e4b17023SJohn Marino if (is_negative_overflow_infinity (c1))
1158e4b17023SJohn Marino return -2;
1159e4b17023SJohn Marino c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
1160e4b17023SJohn Marino if (!c1)
1161e4b17023SJohn Marino return -2;
1162e4b17023SJohn Marino code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
1163e4b17023SJohn Marino }
1164e4b17023SJohn Marino }
1165e4b17023SJohn Marino
1166e4b17023SJohn Marino if (TREE_CODE (val2) == SSA_NAME)
1167e4b17023SJohn Marino {
1168e4b17023SJohn Marino code2 = SSA_NAME;
1169e4b17023SJohn Marino n2 = val2;
1170e4b17023SJohn Marino c2 = NULL_TREE;
1171e4b17023SJohn Marino }
1172e4b17023SJohn Marino else
1173e4b17023SJohn Marino {
1174e4b17023SJohn Marino code2 = TREE_CODE (val2);
1175e4b17023SJohn Marino n2 = TREE_OPERAND (val2, 0);
1176e4b17023SJohn Marino c2 = TREE_OPERAND (val2, 1);
1177e4b17023SJohn Marino if (tree_int_cst_sgn (c2) == -1)
1178e4b17023SJohn Marino {
1179e4b17023SJohn Marino if (is_negative_overflow_infinity (c2))
1180e4b17023SJohn Marino return -2;
1181e4b17023SJohn Marino c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
1182e4b17023SJohn Marino if (!c2)
1183e4b17023SJohn Marino return -2;
1184e4b17023SJohn Marino code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
1185e4b17023SJohn Marino }
1186e4b17023SJohn Marino }
1187e4b17023SJohn Marino
1188e4b17023SJohn Marino /* Both values must use the same name. */
1189e4b17023SJohn Marino if (n1 != n2)
1190e4b17023SJohn Marino return -2;
1191e4b17023SJohn Marino
1192e4b17023SJohn Marino if (code1 == SSA_NAME
1193e4b17023SJohn Marino && code2 == SSA_NAME)
1194e4b17023SJohn Marino /* NAME == NAME */
1195e4b17023SJohn Marino return 0;
1196e4b17023SJohn Marino
1197e4b17023SJohn Marino /* If overflow is defined we cannot simplify more. */
1198e4b17023SJohn Marino if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
1199e4b17023SJohn Marino return -2;
1200e4b17023SJohn Marino
1201e4b17023SJohn Marino if (strict_overflow_p != NULL
1202e4b17023SJohn Marino && (code1 == SSA_NAME || !TREE_NO_WARNING (val1))
1203e4b17023SJohn Marino && (code2 == SSA_NAME || !TREE_NO_WARNING (val2)))
1204e4b17023SJohn Marino *strict_overflow_p = true;
1205e4b17023SJohn Marino
1206e4b17023SJohn Marino if (code1 == SSA_NAME)
1207e4b17023SJohn Marino {
1208e4b17023SJohn Marino if (code2 == PLUS_EXPR)
1209e4b17023SJohn Marino /* NAME < NAME + CST */
1210e4b17023SJohn Marino return -1;
1211e4b17023SJohn Marino else if (code2 == MINUS_EXPR)
1212e4b17023SJohn Marino /* NAME > NAME - CST */
1213e4b17023SJohn Marino return 1;
1214e4b17023SJohn Marino }
1215e4b17023SJohn Marino else if (code1 == PLUS_EXPR)
1216e4b17023SJohn Marino {
1217e4b17023SJohn Marino if (code2 == SSA_NAME)
1218e4b17023SJohn Marino /* NAME + CST > NAME */
1219e4b17023SJohn Marino return 1;
1220e4b17023SJohn Marino else if (code2 == PLUS_EXPR)
1221e4b17023SJohn Marino /* NAME + CST1 > NAME + CST2, if CST1 > CST2 */
1222e4b17023SJohn Marino return compare_values_warnv (c1, c2, strict_overflow_p);
1223e4b17023SJohn Marino else if (code2 == MINUS_EXPR)
1224e4b17023SJohn Marino /* NAME + CST1 > NAME - CST2 */
1225e4b17023SJohn Marino return 1;
1226e4b17023SJohn Marino }
1227e4b17023SJohn Marino else if (code1 == MINUS_EXPR)
1228e4b17023SJohn Marino {
1229e4b17023SJohn Marino if (code2 == SSA_NAME)
1230e4b17023SJohn Marino /* NAME - CST < NAME */
1231e4b17023SJohn Marino return -1;
1232e4b17023SJohn Marino else if (code2 == PLUS_EXPR)
1233e4b17023SJohn Marino /* NAME - CST1 < NAME + CST2 */
1234e4b17023SJohn Marino return -1;
1235e4b17023SJohn Marino else if (code2 == MINUS_EXPR)
1236e4b17023SJohn Marino /* NAME - CST1 > NAME - CST2, if CST1 < CST2. Notice that
1237e4b17023SJohn Marino C1 and C2 are swapped in the call to compare_values. */
1238e4b17023SJohn Marino return compare_values_warnv (c2, c1, strict_overflow_p);
1239e4b17023SJohn Marino }
1240e4b17023SJohn Marino
1241e4b17023SJohn Marino gcc_unreachable ();
1242e4b17023SJohn Marino }
1243e4b17023SJohn Marino
1244e4b17023SJohn Marino /* We cannot compare non-constants. */
1245e4b17023SJohn Marino if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
1246e4b17023SJohn Marino return -2;
1247e4b17023SJohn Marino
1248e4b17023SJohn Marino if (!POINTER_TYPE_P (TREE_TYPE (val1)))
1249e4b17023SJohn Marino {
1250e4b17023SJohn Marino /* We cannot compare overflowed values, except for overflow
1251e4b17023SJohn Marino infinities. */
1252e4b17023SJohn Marino if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
1253e4b17023SJohn Marino {
1254e4b17023SJohn Marino if (strict_overflow_p != NULL)
1255e4b17023SJohn Marino *strict_overflow_p = true;
1256e4b17023SJohn Marino if (is_negative_overflow_infinity (val1))
1257e4b17023SJohn Marino return is_negative_overflow_infinity (val2) ? 0 : -1;
1258e4b17023SJohn Marino else if (is_negative_overflow_infinity (val2))
1259e4b17023SJohn Marino return 1;
1260e4b17023SJohn Marino else if (is_positive_overflow_infinity (val1))
1261e4b17023SJohn Marino return is_positive_overflow_infinity (val2) ? 0 : 1;
1262e4b17023SJohn Marino else if (is_positive_overflow_infinity (val2))
1263e4b17023SJohn Marino return -1;
1264e4b17023SJohn Marino return -2;
1265e4b17023SJohn Marino }
1266e4b17023SJohn Marino
1267e4b17023SJohn Marino return tree_int_cst_compare (val1, val2);
1268e4b17023SJohn Marino }
1269e4b17023SJohn Marino else
1270e4b17023SJohn Marino {
1271e4b17023SJohn Marino tree t;
1272e4b17023SJohn Marino
1273e4b17023SJohn Marino /* First see if VAL1 and VAL2 are not the same. */
1274e4b17023SJohn Marino if (val1 == val2 || operand_equal_p (val1, val2, 0))
1275e4b17023SJohn Marino return 0;
1276e4b17023SJohn Marino
1277e4b17023SJohn Marino /* If VAL1 is a lower address than VAL2, return -1. */
1278e4b17023SJohn Marino if (operand_less_p (val1, val2) == 1)
1279e4b17023SJohn Marino return -1;
1280e4b17023SJohn Marino
1281e4b17023SJohn Marino /* If VAL1 is a higher address than VAL2, return +1. */
1282e4b17023SJohn Marino if (operand_less_p (val2, val1) == 1)
1283e4b17023SJohn Marino return 1;
1284e4b17023SJohn Marino
1285e4b17023SJohn Marino /* If VAL1 is different than VAL2, return +2.
1286e4b17023SJohn Marino For integer constants we either have already returned -1 or 1
1287e4b17023SJohn Marino or they are equivalent. We still might succeed in proving
1288e4b17023SJohn Marino something about non-trivial operands. */
1289e4b17023SJohn Marino if (TREE_CODE (val1) != INTEGER_CST
1290e4b17023SJohn Marino || TREE_CODE (val2) != INTEGER_CST)
1291e4b17023SJohn Marino {
1292e4b17023SJohn Marino t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
1293e4b17023SJohn Marino if (t && integer_onep (t))
1294e4b17023SJohn Marino return 2;
1295e4b17023SJohn Marino }
1296e4b17023SJohn Marino
1297e4b17023SJohn Marino return -2;
1298e4b17023SJohn Marino }
1299e4b17023SJohn Marino }
1300e4b17023SJohn Marino
1301e4b17023SJohn Marino /* Compare values like compare_values_warnv, but treat comparisons of
1302e4b17023SJohn Marino nonconstants which rely on undefined overflow as incomparable. */
1303e4b17023SJohn Marino
1304e4b17023SJohn Marino static int
compare_values(tree val1,tree val2)1305e4b17023SJohn Marino compare_values (tree val1, tree val2)
1306e4b17023SJohn Marino {
1307e4b17023SJohn Marino bool sop;
1308e4b17023SJohn Marino int ret;
1309e4b17023SJohn Marino
1310e4b17023SJohn Marino sop = false;
1311e4b17023SJohn Marino ret = compare_values_warnv (val1, val2, &sop);
1312e4b17023SJohn Marino if (sop
1313e4b17023SJohn Marino && (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
1314e4b17023SJohn Marino ret = -2;
1315e4b17023SJohn Marino return ret;
1316e4b17023SJohn Marino }
1317e4b17023SJohn Marino
1318e4b17023SJohn Marino
1319e4b17023SJohn Marino /* Return 1 if VAL is inside value range MIN <= VAL <= MAX,
1320e4b17023SJohn Marino 0 if VAL is not inside [MIN, MAX],
1321e4b17023SJohn Marino -2 if we cannot tell either way.
1322e4b17023SJohn Marino
1323e4b17023SJohn Marino Benchmark compile/20001226-1.c compilation time after changing this
1324e4b17023SJohn Marino function. */
1325e4b17023SJohn Marino
1326e4b17023SJohn Marino static inline int
value_inside_range(tree val,tree min,tree max)1327e4b17023SJohn Marino value_inside_range (tree val, tree min, tree max)
1328e4b17023SJohn Marino {
1329e4b17023SJohn Marino int cmp1, cmp2;
1330e4b17023SJohn Marino
1331e4b17023SJohn Marino cmp1 = operand_less_p (val, min);
1332e4b17023SJohn Marino if (cmp1 == -2)
1333e4b17023SJohn Marino return -2;
1334e4b17023SJohn Marino if (cmp1 == 1)
1335e4b17023SJohn Marino return 0;
1336e4b17023SJohn Marino
1337e4b17023SJohn Marino cmp2 = operand_less_p (max, val);
1338e4b17023SJohn Marino if (cmp2 == -2)
1339e4b17023SJohn Marino return -2;
1340e4b17023SJohn Marino
1341e4b17023SJohn Marino return !cmp2;
1342e4b17023SJohn Marino }
1343e4b17023SJohn Marino
1344e4b17023SJohn Marino
1345e4b17023SJohn Marino /* Return true if value ranges VR0 and VR1 have a non-empty
1346e4b17023SJohn Marino intersection.
1347e4b17023SJohn Marino
1348e4b17023SJohn Marino Benchmark compile/20001226-1.c compilation time after changing this
1349e4b17023SJohn Marino function.
1350e4b17023SJohn Marino */
1351e4b17023SJohn Marino
1352e4b17023SJohn Marino static inline bool
value_ranges_intersect_p(value_range_t * vr0,value_range_t * vr1)1353e4b17023SJohn Marino value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
1354e4b17023SJohn Marino {
1355e4b17023SJohn Marino /* The value ranges do not intersect if the maximum of the first range is
1356e4b17023SJohn Marino less than the minimum of the second range or vice versa.
1357e4b17023SJohn Marino When those relations are unknown, we can't do any better. */
1358e4b17023SJohn Marino if (operand_less_p (vr0->max, vr1->min) != 0)
1359e4b17023SJohn Marino return false;
1360e4b17023SJohn Marino if (operand_less_p (vr1->max, vr0->min) != 0)
1361e4b17023SJohn Marino return false;
1362e4b17023SJohn Marino return true;
1363e4b17023SJohn Marino }
1364e4b17023SJohn Marino
1365e4b17023SJohn Marino
1366e4b17023SJohn Marino /* Return 1 if [MIN, MAX] includes the value zero, 0 if it does not
1367e4b17023SJohn Marino include the value zero, -2 if we cannot tell. */
1368e4b17023SJohn Marino
1369e4b17023SJohn Marino static inline int
range_includes_zero_p(tree min,tree max)1370e4b17023SJohn Marino range_includes_zero_p (tree min, tree max)
1371e4b17023SJohn Marino {
1372e4b17023SJohn Marino tree zero = build_int_cst (TREE_TYPE (min), 0);
1373e4b17023SJohn Marino return value_inside_range (zero, min, max);
1374e4b17023SJohn Marino }
1375e4b17023SJohn Marino
1376e4b17023SJohn Marino /* Return true if *VR is know to only contain nonnegative values. */
1377e4b17023SJohn Marino
1378e4b17023SJohn Marino static inline bool
value_range_nonnegative_p(value_range_t * vr)1379e4b17023SJohn Marino value_range_nonnegative_p (value_range_t *vr)
1380e4b17023SJohn Marino {
1381e4b17023SJohn Marino /* Testing for VR_ANTI_RANGE is not useful here as any anti-range
1382e4b17023SJohn Marino which would return a useful value should be encoded as a
1383e4b17023SJohn Marino VR_RANGE. */
1384e4b17023SJohn Marino if (vr->type == VR_RANGE)
1385e4b17023SJohn Marino {
1386e4b17023SJohn Marino int result = compare_values (vr->min, integer_zero_node);
1387e4b17023SJohn Marino return (result == 0 || result == 1);
1388e4b17023SJohn Marino }
1389e4b17023SJohn Marino
1390e4b17023SJohn Marino return false;
1391e4b17023SJohn Marino }
1392e4b17023SJohn Marino
1393e4b17023SJohn Marino /* Return true if T, an SSA_NAME, is known to be nonnegative. Return
1394e4b17023SJohn Marino false otherwise or if no value range information is available. */
1395e4b17023SJohn Marino
1396e4b17023SJohn Marino bool
ssa_name_nonnegative_p(const_tree t)1397e4b17023SJohn Marino ssa_name_nonnegative_p (const_tree t)
1398e4b17023SJohn Marino {
1399e4b17023SJohn Marino value_range_t *vr = get_value_range (t);
1400e4b17023SJohn Marino
1401e4b17023SJohn Marino if (INTEGRAL_TYPE_P (t)
1402e4b17023SJohn Marino && TYPE_UNSIGNED (t))
1403e4b17023SJohn Marino return true;
1404e4b17023SJohn Marino
1405e4b17023SJohn Marino if (!vr)
1406e4b17023SJohn Marino return false;
1407e4b17023SJohn Marino
1408e4b17023SJohn Marino return value_range_nonnegative_p (vr);
1409e4b17023SJohn Marino }
1410e4b17023SJohn Marino
1411e4b17023SJohn Marino /* If *VR has a value rante that is a single constant value return that,
1412e4b17023SJohn Marino otherwise return NULL_TREE. */
1413e4b17023SJohn Marino
1414e4b17023SJohn Marino static tree
value_range_constant_singleton(value_range_t * vr)1415e4b17023SJohn Marino value_range_constant_singleton (value_range_t *vr)
1416e4b17023SJohn Marino {
1417e4b17023SJohn Marino if (vr->type == VR_RANGE
1418e4b17023SJohn Marino && operand_equal_p (vr->min, vr->max, 0)
1419e4b17023SJohn Marino && is_gimple_min_invariant (vr->min))
1420e4b17023SJohn Marino return vr->min;
1421e4b17023SJohn Marino
1422e4b17023SJohn Marino return NULL_TREE;
1423e4b17023SJohn Marino }
1424e4b17023SJohn Marino
1425e4b17023SJohn Marino /* If OP has a value range with a single constant value return that,
1426e4b17023SJohn Marino otherwise return NULL_TREE. This returns OP itself if OP is a
1427e4b17023SJohn Marino constant. */
1428e4b17023SJohn Marino
1429e4b17023SJohn Marino static tree
op_with_constant_singleton_value_range(tree op)1430e4b17023SJohn Marino op_with_constant_singleton_value_range (tree op)
1431e4b17023SJohn Marino {
1432e4b17023SJohn Marino if (is_gimple_min_invariant (op))
1433e4b17023SJohn Marino return op;
1434e4b17023SJohn Marino
1435e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
1436e4b17023SJohn Marino return NULL_TREE;
1437e4b17023SJohn Marino
1438e4b17023SJohn Marino return value_range_constant_singleton (get_value_range (op));
1439e4b17023SJohn Marino }
1440e4b17023SJohn Marino
1441e4b17023SJohn Marino /* Return true if op is in a boolean [0, 1] value-range. */
1442e4b17023SJohn Marino
1443e4b17023SJohn Marino static bool
op_with_boolean_value_range_p(tree op)1444e4b17023SJohn Marino op_with_boolean_value_range_p (tree op)
1445e4b17023SJohn Marino {
1446e4b17023SJohn Marino value_range_t *vr;
1447e4b17023SJohn Marino
1448e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (op)) == 1)
1449e4b17023SJohn Marino return true;
1450e4b17023SJohn Marino
1451e4b17023SJohn Marino if (integer_zerop (op)
1452e4b17023SJohn Marino || integer_onep (op))
1453e4b17023SJohn Marino return true;
1454e4b17023SJohn Marino
1455e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
1456e4b17023SJohn Marino return false;
1457e4b17023SJohn Marino
1458e4b17023SJohn Marino vr = get_value_range (op);
1459e4b17023SJohn Marino return (vr->type == VR_RANGE
1460e4b17023SJohn Marino && integer_zerop (vr->min)
1461e4b17023SJohn Marino && integer_onep (vr->max));
1462e4b17023SJohn Marino }
1463e4b17023SJohn Marino
1464e4b17023SJohn Marino /* Extract value range information from an ASSERT_EXPR EXPR and store
1465e4b17023SJohn Marino it in *VR_P. */
1466e4b17023SJohn Marino
1467e4b17023SJohn Marino static void
extract_range_from_assert(value_range_t * vr_p,tree expr)1468e4b17023SJohn Marino extract_range_from_assert (value_range_t *vr_p, tree expr)
1469e4b17023SJohn Marino {
1470e4b17023SJohn Marino tree var, cond, limit, min, max, type;
1471e4b17023SJohn Marino value_range_t *var_vr, *limit_vr;
1472e4b17023SJohn Marino enum tree_code cond_code;
1473e4b17023SJohn Marino
1474e4b17023SJohn Marino var = ASSERT_EXPR_VAR (expr);
1475e4b17023SJohn Marino cond = ASSERT_EXPR_COND (expr);
1476e4b17023SJohn Marino
1477e4b17023SJohn Marino gcc_assert (COMPARISON_CLASS_P (cond));
1478e4b17023SJohn Marino
1479e4b17023SJohn Marino /* Find VAR in the ASSERT_EXPR conditional. */
1480e4b17023SJohn Marino if (var == TREE_OPERAND (cond, 0)
1481e4b17023SJohn Marino || TREE_CODE (TREE_OPERAND (cond, 0)) == PLUS_EXPR
1482e4b17023SJohn Marino || TREE_CODE (TREE_OPERAND (cond, 0)) == NOP_EXPR)
1483e4b17023SJohn Marino {
1484e4b17023SJohn Marino /* If the predicate is of the form VAR COMP LIMIT, then we just
1485e4b17023SJohn Marino take LIMIT from the RHS and use the same comparison code. */
1486e4b17023SJohn Marino cond_code = TREE_CODE (cond);
1487e4b17023SJohn Marino limit = TREE_OPERAND (cond, 1);
1488e4b17023SJohn Marino cond = TREE_OPERAND (cond, 0);
1489e4b17023SJohn Marino }
1490e4b17023SJohn Marino else
1491e4b17023SJohn Marino {
1492e4b17023SJohn Marino /* If the predicate is of the form LIMIT COMP VAR, then we need
1493e4b17023SJohn Marino to flip around the comparison code to create the proper range
1494e4b17023SJohn Marino for VAR. */
1495e4b17023SJohn Marino cond_code = swap_tree_comparison (TREE_CODE (cond));
1496e4b17023SJohn Marino limit = TREE_OPERAND (cond, 0);
1497e4b17023SJohn Marino cond = TREE_OPERAND (cond, 1);
1498e4b17023SJohn Marino }
1499e4b17023SJohn Marino
1500e4b17023SJohn Marino limit = avoid_overflow_infinity (limit);
1501e4b17023SJohn Marino
1502e4b17023SJohn Marino type = TREE_TYPE (var);
1503e4b17023SJohn Marino gcc_assert (limit != var);
1504e4b17023SJohn Marino
1505e4b17023SJohn Marino /* For pointer arithmetic, we only keep track of pointer equality
1506e4b17023SJohn Marino and inequality. */
1507e4b17023SJohn Marino if (POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
1508e4b17023SJohn Marino {
1509e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1510e4b17023SJohn Marino return;
1511e4b17023SJohn Marino }
1512e4b17023SJohn Marino
1513e4b17023SJohn Marino /* If LIMIT is another SSA name and LIMIT has a range of its own,
1514e4b17023SJohn Marino try to use LIMIT's range to avoid creating symbolic ranges
1515e4b17023SJohn Marino unnecessarily. */
1516e4b17023SJohn Marino limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
1517e4b17023SJohn Marino
1518e4b17023SJohn Marino /* LIMIT's range is only interesting if it has any useful information. */
1519e4b17023SJohn Marino if (limit_vr
1520e4b17023SJohn Marino && (limit_vr->type == VR_UNDEFINED
1521e4b17023SJohn Marino || limit_vr->type == VR_VARYING
1522e4b17023SJohn Marino || symbolic_range_p (limit_vr)))
1523e4b17023SJohn Marino limit_vr = NULL;
1524e4b17023SJohn Marino
1525e4b17023SJohn Marino /* Initially, the new range has the same set of equivalences of
1526e4b17023SJohn Marino VAR's range. This will be revised before returning the final
1527e4b17023SJohn Marino value. Since assertions may be chained via mutually exclusive
1528e4b17023SJohn Marino predicates, we will need to trim the set of equivalences before
1529e4b17023SJohn Marino we are done. */
1530e4b17023SJohn Marino gcc_assert (vr_p->equiv == NULL);
1531e4b17023SJohn Marino add_equivalence (&vr_p->equiv, var);
1532e4b17023SJohn Marino
1533e4b17023SJohn Marino /* Extract a new range based on the asserted comparison for VAR and
1534e4b17023SJohn Marino LIMIT's value range. Notice that if LIMIT has an anti-range, we
1535e4b17023SJohn Marino will only use it for equality comparisons (EQ_EXPR). For any
1536e4b17023SJohn Marino other kind of assertion, we cannot derive a range from LIMIT's
1537e4b17023SJohn Marino anti-range that can be used to describe the new range. For
1538e4b17023SJohn Marino instance, ASSERT_EXPR <x_2, x_2 <= b_4>. If b_4 is ~[2, 10],
1539e4b17023SJohn Marino then b_4 takes on the ranges [-INF, 1] and [11, +INF]. There is
1540e4b17023SJohn Marino no single range for x_2 that could describe LE_EXPR, so we might
1541e4b17023SJohn Marino as well build the range [b_4, +INF] for it.
1542e4b17023SJohn Marino One special case we handle is extracting a range from a
1543e4b17023SJohn Marino range test encoded as (unsigned)var + CST <= limit. */
1544e4b17023SJohn Marino if (TREE_CODE (cond) == NOP_EXPR
1545e4b17023SJohn Marino || TREE_CODE (cond) == PLUS_EXPR)
1546e4b17023SJohn Marino {
1547e4b17023SJohn Marino if (TREE_CODE (cond) == PLUS_EXPR)
1548e4b17023SJohn Marino {
1549e4b17023SJohn Marino min = fold_build1 (NEGATE_EXPR, TREE_TYPE (TREE_OPERAND (cond, 1)),
1550e4b17023SJohn Marino TREE_OPERAND (cond, 1));
1551e4b17023SJohn Marino max = int_const_binop (PLUS_EXPR, limit, min);
1552e4b17023SJohn Marino cond = TREE_OPERAND (cond, 0);
1553e4b17023SJohn Marino }
1554e4b17023SJohn Marino else
1555e4b17023SJohn Marino {
1556e4b17023SJohn Marino min = build_int_cst (TREE_TYPE (var), 0);
1557e4b17023SJohn Marino max = limit;
1558e4b17023SJohn Marino }
1559e4b17023SJohn Marino
1560e4b17023SJohn Marino /* Make sure to not set TREE_OVERFLOW on the final type
1561e4b17023SJohn Marino conversion. We are willingly interpreting large positive
1562e4b17023SJohn Marino unsigned values as negative singed values here. */
1563e4b17023SJohn Marino min = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (min),
1564e4b17023SJohn Marino 0, false);
1565e4b17023SJohn Marino max = force_fit_type_double (TREE_TYPE (var), tree_to_double_int (max),
1566e4b17023SJohn Marino 0, false);
1567e4b17023SJohn Marino
1568e4b17023SJohn Marino /* We can transform a max, min range to an anti-range or
1569e4b17023SJohn Marino vice-versa. Use set_and_canonicalize_value_range which does
1570e4b17023SJohn Marino this for us. */
1571e4b17023SJohn Marino if (cond_code == LE_EXPR)
1572e4b17023SJohn Marino set_and_canonicalize_value_range (vr_p, VR_RANGE,
1573e4b17023SJohn Marino min, max, vr_p->equiv);
1574e4b17023SJohn Marino else if (cond_code == GT_EXPR)
1575e4b17023SJohn Marino set_and_canonicalize_value_range (vr_p, VR_ANTI_RANGE,
1576e4b17023SJohn Marino min, max, vr_p->equiv);
1577e4b17023SJohn Marino else
1578e4b17023SJohn Marino gcc_unreachable ();
1579e4b17023SJohn Marino }
1580e4b17023SJohn Marino else if (cond_code == EQ_EXPR)
1581e4b17023SJohn Marino {
1582e4b17023SJohn Marino enum value_range_type range_type;
1583e4b17023SJohn Marino
1584e4b17023SJohn Marino if (limit_vr)
1585e4b17023SJohn Marino {
1586e4b17023SJohn Marino range_type = limit_vr->type;
1587e4b17023SJohn Marino min = limit_vr->min;
1588e4b17023SJohn Marino max = limit_vr->max;
1589e4b17023SJohn Marino }
1590e4b17023SJohn Marino else
1591e4b17023SJohn Marino {
1592e4b17023SJohn Marino range_type = VR_RANGE;
1593e4b17023SJohn Marino min = limit;
1594e4b17023SJohn Marino max = limit;
1595e4b17023SJohn Marino }
1596e4b17023SJohn Marino
1597e4b17023SJohn Marino set_value_range (vr_p, range_type, min, max, vr_p->equiv);
1598e4b17023SJohn Marino
1599e4b17023SJohn Marino /* When asserting the equality VAR == LIMIT and LIMIT is another
1600e4b17023SJohn Marino SSA name, the new range will also inherit the equivalence set
1601e4b17023SJohn Marino from LIMIT. */
1602e4b17023SJohn Marino if (TREE_CODE (limit) == SSA_NAME)
1603e4b17023SJohn Marino add_equivalence (&vr_p->equiv, limit);
1604e4b17023SJohn Marino }
1605e4b17023SJohn Marino else if (cond_code == NE_EXPR)
1606e4b17023SJohn Marino {
1607e4b17023SJohn Marino /* As described above, when LIMIT's range is an anti-range and
1608e4b17023SJohn Marino this assertion is an inequality (NE_EXPR), then we cannot
1609e4b17023SJohn Marino derive anything from the anti-range. For instance, if
1610e4b17023SJohn Marino LIMIT's range was ~[0, 0], the assertion 'VAR != LIMIT' does
1611e4b17023SJohn Marino not imply that VAR's range is [0, 0]. So, in the case of
1612e4b17023SJohn Marino anti-ranges, we just assert the inequality using LIMIT and
1613e4b17023SJohn Marino not its anti-range.
1614e4b17023SJohn Marino
1615e4b17023SJohn Marino If LIMIT_VR is a range, we can only use it to build a new
1616e4b17023SJohn Marino anti-range if LIMIT_VR is a single-valued range. For
1617e4b17023SJohn Marino instance, if LIMIT_VR is [0, 1], the predicate
1618e4b17023SJohn Marino VAR != [0, 1] does not mean that VAR's range is ~[0, 1].
1619e4b17023SJohn Marino Rather, it means that for value 0 VAR should be ~[0, 0]
1620e4b17023SJohn Marino and for value 1, VAR should be ~[1, 1]. We cannot
1621e4b17023SJohn Marino represent these ranges.
1622e4b17023SJohn Marino
1623e4b17023SJohn Marino The only situation in which we can build a valid
1624e4b17023SJohn Marino anti-range is when LIMIT_VR is a single-valued range
1625e4b17023SJohn Marino (i.e., LIMIT_VR->MIN == LIMIT_VR->MAX). In that case,
1626e4b17023SJohn Marino build the anti-range ~[LIMIT_VR->MIN, LIMIT_VR->MAX]. */
1627e4b17023SJohn Marino if (limit_vr
1628e4b17023SJohn Marino && limit_vr->type == VR_RANGE
1629e4b17023SJohn Marino && compare_values (limit_vr->min, limit_vr->max) == 0)
1630e4b17023SJohn Marino {
1631e4b17023SJohn Marino min = limit_vr->min;
1632e4b17023SJohn Marino max = limit_vr->max;
1633e4b17023SJohn Marino }
1634e4b17023SJohn Marino else
1635e4b17023SJohn Marino {
1636e4b17023SJohn Marino /* In any other case, we cannot use LIMIT's range to build a
1637e4b17023SJohn Marino valid anti-range. */
1638e4b17023SJohn Marino min = max = limit;
1639e4b17023SJohn Marino }
1640e4b17023SJohn Marino
1641e4b17023SJohn Marino /* If MIN and MAX cover the whole range for their type, then
1642e4b17023SJohn Marino just use the original LIMIT. */
1643e4b17023SJohn Marino if (INTEGRAL_TYPE_P (type)
1644e4b17023SJohn Marino && vrp_val_is_min (min)
1645e4b17023SJohn Marino && vrp_val_is_max (max))
1646e4b17023SJohn Marino min = max = limit;
1647e4b17023SJohn Marino
1648e4b17023SJohn Marino set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
1649e4b17023SJohn Marino }
1650e4b17023SJohn Marino else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
1651e4b17023SJohn Marino {
1652e4b17023SJohn Marino min = TYPE_MIN_VALUE (type);
1653e4b17023SJohn Marino
1654e4b17023SJohn Marino if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
1655e4b17023SJohn Marino max = limit;
1656e4b17023SJohn Marino else
1657e4b17023SJohn Marino {
1658e4b17023SJohn Marino /* If LIMIT_VR is of the form [N1, N2], we need to build the
1659e4b17023SJohn Marino range [MIN, N2] for LE_EXPR and [MIN, N2 - 1] for
1660e4b17023SJohn Marino LT_EXPR. */
1661e4b17023SJohn Marino max = limit_vr->max;
1662e4b17023SJohn Marino }
1663e4b17023SJohn Marino
1664e4b17023SJohn Marino /* If the maximum value forces us to be out of bounds, simply punt.
1665e4b17023SJohn Marino It would be pointless to try and do anything more since this
1666e4b17023SJohn Marino all should be optimized away above us. */
1667e4b17023SJohn Marino if ((cond_code == LT_EXPR
1668e4b17023SJohn Marino && compare_values (max, min) == 0)
1669e4b17023SJohn Marino || (CONSTANT_CLASS_P (max) && TREE_OVERFLOW (max)))
1670e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1671e4b17023SJohn Marino else
1672e4b17023SJohn Marino {
1673e4b17023SJohn Marino /* For LT_EXPR, we create the range [MIN, MAX - 1]. */
1674e4b17023SJohn Marino if (cond_code == LT_EXPR)
1675e4b17023SJohn Marino {
1676e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (max)) == 1
1677e4b17023SJohn Marino && !TYPE_UNSIGNED (TREE_TYPE (max)))
1678e4b17023SJohn Marino max = fold_build2 (PLUS_EXPR, TREE_TYPE (max), max,
1679e4b17023SJohn Marino build_int_cst (TREE_TYPE (max), -1));
1680e4b17023SJohn Marino else
1681e4b17023SJohn Marino max = fold_build2 (MINUS_EXPR, TREE_TYPE (max), max,
1682e4b17023SJohn Marino build_int_cst (TREE_TYPE (max), 1));
1683e4b17023SJohn Marino if (EXPR_P (max))
1684e4b17023SJohn Marino TREE_NO_WARNING (max) = 1;
1685e4b17023SJohn Marino }
1686e4b17023SJohn Marino
1687e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1688e4b17023SJohn Marino }
1689e4b17023SJohn Marino }
1690e4b17023SJohn Marino else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
1691e4b17023SJohn Marino {
1692e4b17023SJohn Marino max = TYPE_MAX_VALUE (type);
1693e4b17023SJohn Marino
1694e4b17023SJohn Marino if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
1695e4b17023SJohn Marino min = limit;
1696e4b17023SJohn Marino else
1697e4b17023SJohn Marino {
1698e4b17023SJohn Marino /* If LIMIT_VR is of the form [N1, N2], we need to build the
1699e4b17023SJohn Marino range [N1, MAX] for GE_EXPR and [N1 + 1, MAX] for
1700e4b17023SJohn Marino GT_EXPR. */
1701e4b17023SJohn Marino min = limit_vr->min;
1702e4b17023SJohn Marino }
1703e4b17023SJohn Marino
1704e4b17023SJohn Marino /* If the minimum value forces us to be out of bounds, simply punt.
1705e4b17023SJohn Marino It would be pointless to try and do anything more since this
1706e4b17023SJohn Marino all should be optimized away above us. */
1707e4b17023SJohn Marino if ((cond_code == GT_EXPR
1708e4b17023SJohn Marino && compare_values (min, max) == 0)
1709e4b17023SJohn Marino || (CONSTANT_CLASS_P (min) && TREE_OVERFLOW (min)))
1710e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1711e4b17023SJohn Marino else
1712e4b17023SJohn Marino {
1713e4b17023SJohn Marino /* For GT_EXPR, we create the range [MIN + 1, MAX]. */
1714e4b17023SJohn Marino if (cond_code == GT_EXPR)
1715e4b17023SJohn Marino {
1716e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (min)) == 1
1717e4b17023SJohn Marino && !TYPE_UNSIGNED (TREE_TYPE (min)))
1718e4b17023SJohn Marino min = fold_build2 (MINUS_EXPR, TREE_TYPE (min), min,
1719e4b17023SJohn Marino build_int_cst (TREE_TYPE (min), -1));
1720e4b17023SJohn Marino else
1721e4b17023SJohn Marino min = fold_build2 (PLUS_EXPR, TREE_TYPE (min), min,
1722e4b17023SJohn Marino build_int_cst (TREE_TYPE (min), 1));
1723e4b17023SJohn Marino if (EXPR_P (min))
1724e4b17023SJohn Marino TREE_NO_WARNING (min) = 1;
1725e4b17023SJohn Marino }
1726e4b17023SJohn Marino
1727e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1728e4b17023SJohn Marino }
1729e4b17023SJohn Marino }
1730e4b17023SJohn Marino else
1731e4b17023SJohn Marino gcc_unreachable ();
1732e4b17023SJohn Marino
1733e4b17023SJohn Marino /* If VAR already had a known range, it may happen that the new
1734e4b17023SJohn Marino range we have computed and VAR's range are not compatible. For
1735e4b17023SJohn Marino instance,
1736e4b17023SJohn Marino
1737e4b17023SJohn Marino if (p_5 == NULL)
1738e4b17023SJohn Marino p_6 = ASSERT_EXPR <p_5, p_5 == NULL>;
1739e4b17023SJohn Marino x_7 = p_6->fld;
1740e4b17023SJohn Marino p_8 = ASSERT_EXPR <p_6, p_6 != NULL>;
1741e4b17023SJohn Marino
1742e4b17023SJohn Marino While the above comes from a faulty program, it will cause an ICE
1743e4b17023SJohn Marino later because p_8 and p_6 will have incompatible ranges and at
1744e4b17023SJohn Marino the same time will be considered equivalent. A similar situation
1745e4b17023SJohn Marino would arise from
1746e4b17023SJohn Marino
1747e4b17023SJohn Marino if (i_5 > 10)
1748e4b17023SJohn Marino i_6 = ASSERT_EXPR <i_5, i_5 > 10>;
1749e4b17023SJohn Marino if (i_5 < 5)
1750e4b17023SJohn Marino i_7 = ASSERT_EXPR <i_6, i_6 < 5>;
1751e4b17023SJohn Marino
1752e4b17023SJohn Marino Again i_6 and i_7 will have incompatible ranges. It would be
1753e4b17023SJohn Marino pointless to try and do anything with i_7's range because
1754e4b17023SJohn Marino anything dominated by 'if (i_5 < 5)' will be optimized away.
1755e4b17023SJohn Marino Note, due to the wa in which simulation proceeds, the statement
1756e4b17023SJohn Marino i_7 = ASSERT_EXPR <...> we would never be visited because the
1757e4b17023SJohn Marino conditional 'if (i_5 < 5)' always evaluates to false. However,
1758e4b17023SJohn Marino this extra check does not hurt and may protect against future
1759e4b17023SJohn Marino changes to VRP that may get into a situation similar to the
1760e4b17023SJohn Marino NULL pointer dereference example.
1761e4b17023SJohn Marino
1762e4b17023SJohn Marino Note that these compatibility tests are only needed when dealing
1763e4b17023SJohn Marino with ranges or a mix of range and anti-range. If VAR_VR and VR_P
1764e4b17023SJohn Marino are both anti-ranges, they will always be compatible, because two
1765e4b17023SJohn Marino anti-ranges will always have a non-empty intersection. */
1766e4b17023SJohn Marino
1767e4b17023SJohn Marino var_vr = get_value_range (var);
1768e4b17023SJohn Marino
1769e4b17023SJohn Marino /* We may need to make adjustments when VR_P and VAR_VR are numeric
1770e4b17023SJohn Marino ranges or anti-ranges. */
1771e4b17023SJohn Marino if (vr_p->type == VR_VARYING
1772e4b17023SJohn Marino || vr_p->type == VR_UNDEFINED
1773e4b17023SJohn Marino || var_vr->type == VR_VARYING
1774e4b17023SJohn Marino || var_vr->type == VR_UNDEFINED
1775e4b17023SJohn Marino || symbolic_range_p (vr_p)
1776e4b17023SJohn Marino || symbolic_range_p (var_vr))
1777e4b17023SJohn Marino return;
1778e4b17023SJohn Marino
1779e4b17023SJohn Marino if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
1780e4b17023SJohn Marino {
1781e4b17023SJohn Marino /* If the two ranges have a non-empty intersection, we can
1782e4b17023SJohn Marino refine the resulting range. Since the assert expression
1783e4b17023SJohn Marino creates an equivalency and at the same time it asserts a
1784e4b17023SJohn Marino predicate, we can take the intersection of the two ranges to
1785e4b17023SJohn Marino get better precision. */
1786e4b17023SJohn Marino if (value_ranges_intersect_p (var_vr, vr_p))
1787e4b17023SJohn Marino {
1788e4b17023SJohn Marino /* Use the larger of the two minimums. */
1789e4b17023SJohn Marino if (compare_values (vr_p->min, var_vr->min) == -1)
1790e4b17023SJohn Marino min = var_vr->min;
1791e4b17023SJohn Marino else
1792e4b17023SJohn Marino min = vr_p->min;
1793e4b17023SJohn Marino
1794e4b17023SJohn Marino /* Use the smaller of the two maximums. */
1795e4b17023SJohn Marino if (compare_values (vr_p->max, var_vr->max) == 1)
1796e4b17023SJohn Marino max = var_vr->max;
1797e4b17023SJohn Marino else
1798e4b17023SJohn Marino max = vr_p->max;
1799e4b17023SJohn Marino
1800e4b17023SJohn Marino set_value_range (vr_p, vr_p->type, min, max, vr_p->equiv);
1801e4b17023SJohn Marino }
1802e4b17023SJohn Marino else
1803e4b17023SJohn Marino {
1804e4b17023SJohn Marino /* The two ranges do not intersect, set the new range to
1805e4b17023SJohn Marino VARYING, because we will not be able to do anything
1806e4b17023SJohn Marino meaningful with it. */
1807e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1808e4b17023SJohn Marino }
1809e4b17023SJohn Marino }
1810e4b17023SJohn Marino else if ((var_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
1811e4b17023SJohn Marino || (var_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
1812e4b17023SJohn Marino {
1813e4b17023SJohn Marino /* A range and an anti-range will cancel each other only if
1814e4b17023SJohn Marino their ends are the same. For instance, in the example above,
1815e4b17023SJohn Marino p_8's range ~[0, 0] and p_6's range [0, 0] are incompatible,
1816e4b17023SJohn Marino so VR_P should be set to VR_VARYING. */
1817e4b17023SJohn Marino if (compare_values (var_vr->min, vr_p->min) == 0
1818e4b17023SJohn Marino && compare_values (var_vr->max, vr_p->max) == 0)
1819e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1820e4b17023SJohn Marino else
1821e4b17023SJohn Marino {
1822e4b17023SJohn Marino tree min, max, anti_min, anti_max, real_min, real_max;
1823e4b17023SJohn Marino int cmp;
1824e4b17023SJohn Marino
1825e4b17023SJohn Marino /* We want to compute the logical AND of the two ranges;
1826e4b17023SJohn Marino there are three cases to consider.
1827e4b17023SJohn Marino
1828e4b17023SJohn Marino
1829e4b17023SJohn Marino 1. The VR_ANTI_RANGE range is completely within the
1830e4b17023SJohn Marino VR_RANGE and the endpoints of the ranges are
1831e4b17023SJohn Marino different. In that case the resulting range
1832e4b17023SJohn Marino should be whichever range is more precise.
1833e4b17023SJohn Marino Typically that will be the VR_RANGE.
1834e4b17023SJohn Marino
1835e4b17023SJohn Marino 2. The VR_ANTI_RANGE is completely disjoint from
1836e4b17023SJohn Marino the VR_RANGE. In this case the resulting range
1837e4b17023SJohn Marino should be the VR_RANGE.
1838e4b17023SJohn Marino
1839e4b17023SJohn Marino 3. There is some overlap between the VR_ANTI_RANGE
1840e4b17023SJohn Marino and the VR_RANGE.
1841e4b17023SJohn Marino
1842e4b17023SJohn Marino 3a. If the high limit of the VR_ANTI_RANGE resides
1843e4b17023SJohn Marino within the VR_RANGE, then the result is a new
1844e4b17023SJohn Marino VR_RANGE starting at the high limit of the
1845e4b17023SJohn Marino VR_ANTI_RANGE + 1 and extending to the
1846e4b17023SJohn Marino high limit of the original VR_RANGE.
1847e4b17023SJohn Marino
1848e4b17023SJohn Marino 3b. If the low limit of the VR_ANTI_RANGE resides
1849e4b17023SJohn Marino within the VR_RANGE, then the result is a new
1850e4b17023SJohn Marino VR_RANGE starting at the low limit of the original
1851e4b17023SJohn Marino VR_RANGE and extending to the low limit of the
1852e4b17023SJohn Marino VR_ANTI_RANGE - 1. */
1853e4b17023SJohn Marino if (vr_p->type == VR_ANTI_RANGE)
1854e4b17023SJohn Marino {
1855e4b17023SJohn Marino anti_min = vr_p->min;
1856e4b17023SJohn Marino anti_max = vr_p->max;
1857e4b17023SJohn Marino real_min = var_vr->min;
1858e4b17023SJohn Marino real_max = var_vr->max;
1859e4b17023SJohn Marino }
1860e4b17023SJohn Marino else
1861e4b17023SJohn Marino {
1862e4b17023SJohn Marino anti_min = var_vr->min;
1863e4b17023SJohn Marino anti_max = var_vr->max;
1864e4b17023SJohn Marino real_min = vr_p->min;
1865e4b17023SJohn Marino real_max = vr_p->max;
1866e4b17023SJohn Marino }
1867e4b17023SJohn Marino
1868e4b17023SJohn Marino
1869e4b17023SJohn Marino /* Case 1, VR_ANTI_RANGE completely within VR_RANGE,
1870e4b17023SJohn Marino not including any endpoints. */
1871e4b17023SJohn Marino if (compare_values (anti_max, real_max) == -1
1872e4b17023SJohn Marino && compare_values (anti_min, real_min) == 1)
1873e4b17023SJohn Marino {
1874e4b17023SJohn Marino /* If the range is covering the whole valid range of
1875e4b17023SJohn Marino the type keep the anti-range. */
1876e4b17023SJohn Marino if (!vrp_val_is_min (real_min)
1877e4b17023SJohn Marino || !vrp_val_is_max (real_max))
1878e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, real_min,
1879e4b17023SJohn Marino real_max, vr_p->equiv);
1880e4b17023SJohn Marino }
1881e4b17023SJohn Marino /* Case 2, VR_ANTI_RANGE completely disjoint from
1882e4b17023SJohn Marino VR_RANGE. */
1883e4b17023SJohn Marino else if (compare_values (anti_min, real_max) == 1
1884e4b17023SJohn Marino || compare_values (anti_max, real_min) == -1)
1885e4b17023SJohn Marino {
1886e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, real_min,
1887e4b17023SJohn Marino real_max, vr_p->equiv);
1888e4b17023SJohn Marino }
1889e4b17023SJohn Marino /* Case 3a, the anti-range extends into the low
1890e4b17023SJohn Marino part of the real range. Thus creating a new
1891e4b17023SJohn Marino low for the real range. */
1892e4b17023SJohn Marino else if (((cmp = compare_values (anti_max, real_min)) == 1
1893e4b17023SJohn Marino || cmp == 0)
1894e4b17023SJohn Marino && compare_values (anti_max, real_max) == -1)
1895e4b17023SJohn Marino {
1896e4b17023SJohn Marino gcc_assert (!is_positive_overflow_infinity (anti_max));
1897e4b17023SJohn Marino if (needs_overflow_infinity (TREE_TYPE (anti_max))
1898e4b17023SJohn Marino && vrp_val_is_max (anti_max))
1899e4b17023SJohn Marino {
1900e4b17023SJohn Marino if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
1901e4b17023SJohn Marino {
1902e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1903e4b17023SJohn Marino return;
1904e4b17023SJohn Marino }
1905e4b17023SJohn Marino min = positive_overflow_infinity (TREE_TYPE (var_vr->min));
1906e4b17023SJohn Marino }
1907e4b17023SJohn Marino else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
1908e4b17023SJohn Marino {
1909e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
1910e4b17023SJohn Marino && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
1911e4b17023SJohn Marino min = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
1912e4b17023SJohn Marino anti_max,
1913e4b17023SJohn Marino build_int_cst (TREE_TYPE (var_vr->min),
1914e4b17023SJohn Marino -1));
1915e4b17023SJohn Marino else
1916e4b17023SJohn Marino min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
1917e4b17023SJohn Marino anti_max,
1918e4b17023SJohn Marino build_int_cst (TREE_TYPE (var_vr->min),
1919e4b17023SJohn Marino 1));
1920e4b17023SJohn Marino }
1921e4b17023SJohn Marino else
1922e4b17023SJohn Marino min = fold_build_pointer_plus_hwi (anti_max, 1);
1923e4b17023SJohn Marino max = real_max;
1924e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1925e4b17023SJohn Marino }
1926e4b17023SJohn Marino /* Case 3b, the anti-range extends into the high
1927e4b17023SJohn Marino part of the real range. Thus creating a new
1928e4b17023SJohn Marino higher for the real range. */
1929e4b17023SJohn Marino else if (compare_values (anti_min, real_min) == 1
1930e4b17023SJohn Marino && ((cmp = compare_values (anti_min, real_max)) == -1
1931e4b17023SJohn Marino || cmp == 0))
1932e4b17023SJohn Marino {
1933e4b17023SJohn Marino gcc_assert (!is_negative_overflow_infinity (anti_min));
1934e4b17023SJohn Marino if (needs_overflow_infinity (TREE_TYPE (anti_min))
1935e4b17023SJohn Marino && vrp_val_is_min (anti_min))
1936e4b17023SJohn Marino {
1937e4b17023SJohn Marino if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
1938e4b17023SJohn Marino {
1939e4b17023SJohn Marino set_value_range_to_varying (vr_p);
1940e4b17023SJohn Marino return;
1941e4b17023SJohn Marino }
1942e4b17023SJohn Marino max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
1943e4b17023SJohn Marino }
1944e4b17023SJohn Marino else if (!POINTER_TYPE_P (TREE_TYPE (var_vr->min)))
1945e4b17023SJohn Marino {
1946e4b17023SJohn Marino if (TYPE_PRECISION (TREE_TYPE (var_vr->min)) == 1
1947e4b17023SJohn Marino && !TYPE_UNSIGNED (TREE_TYPE (var_vr->min)))
1948e4b17023SJohn Marino max = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
1949e4b17023SJohn Marino anti_min,
1950e4b17023SJohn Marino build_int_cst (TREE_TYPE (var_vr->min),
1951e4b17023SJohn Marino -1));
1952e4b17023SJohn Marino else
1953e4b17023SJohn Marino max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
1954e4b17023SJohn Marino anti_min,
1955e4b17023SJohn Marino build_int_cst (TREE_TYPE (var_vr->min),
1956e4b17023SJohn Marino 1));
1957e4b17023SJohn Marino }
1958e4b17023SJohn Marino else
1959e4b17023SJohn Marino max = fold_build_pointer_plus_hwi (anti_min, -1);
1960e4b17023SJohn Marino min = real_min;
1961e4b17023SJohn Marino set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
1962e4b17023SJohn Marino }
1963e4b17023SJohn Marino }
1964e4b17023SJohn Marino }
1965e4b17023SJohn Marino }
1966e4b17023SJohn Marino
1967e4b17023SJohn Marino
1968e4b17023SJohn Marino /* Extract range information from SSA name VAR and store it in VR. If
1969e4b17023SJohn Marino VAR has an interesting range, use it. Otherwise, create the
1970e4b17023SJohn Marino range [VAR, VAR] and return it. This is useful in situations where
1971e4b17023SJohn Marino we may have conditionals testing values of VARYING names. For
1972e4b17023SJohn Marino instance,
1973e4b17023SJohn Marino
1974e4b17023SJohn Marino x_3 = y_5;
1975e4b17023SJohn Marino if (x_3 > y_5)
1976e4b17023SJohn Marino ...
1977e4b17023SJohn Marino
1978e4b17023SJohn Marino Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
1979e4b17023SJohn Marino always false. */
1980e4b17023SJohn Marino
1981e4b17023SJohn Marino static void
extract_range_from_ssa_name(value_range_t * vr,tree var)1982e4b17023SJohn Marino extract_range_from_ssa_name (value_range_t *vr, tree var)
1983e4b17023SJohn Marino {
1984e4b17023SJohn Marino value_range_t *var_vr = get_value_range (var);
1985e4b17023SJohn Marino
1986e4b17023SJohn Marino if (var_vr->type != VR_UNDEFINED && var_vr->type != VR_VARYING)
1987e4b17023SJohn Marino copy_value_range (vr, var_vr);
1988e4b17023SJohn Marino else
1989e4b17023SJohn Marino set_value_range (vr, VR_RANGE, var, var, NULL);
1990e4b17023SJohn Marino
1991e4b17023SJohn Marino add_equivalence (&vr->equiv, var);
1992e4b17023SJohn Marino }
1993e4b17023SJohn Marino
1994e4b17023SJohn Marino
1995e4b17023SJohn Marino /* Wrapper around int_const_binop. If the operation overflows and we
1996e4b17023SJohn Marino are not using wrapping arithmetic, then adjust the result to be
1997e4b17023SJohn Marino -INF or +INF depending on CODE, VAL1 and VAL2. This can return
1998e4b17023SJohn Marino NULL_TREE if we need to use an overflow infinity representation but
1999e4b17023SJohn Marino the type does not support it. */
2000e4b17023SJohn Marino
2001e4b17023SJohn Marino static tree
vrp_int_const_binop(enum tree_code code,tree val1,tree val2)2002e4b17023SJohn Marino vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
2003e4b17023SJohn Marino {
2004e4b17023SJohn Marino tree res;
2005e4b17023SJohn Marino
2006e4b17023SJohn Marino res = int_const_binop (code, val1, val2);
2007e4b17023SJohn Marino
2008e4b17023SJohn Marino /* If we are using unsigned arithmetic, operate symbolically
2009e4b17023SJohn Marino on -INF and +INF as int_const_binop only handles signed overflow. */
2010e4b17023SJohn Marino if (TYPE_UNSIGNED (TREE_TYPE (val1)))
2011e4b17023SJohn Marino {
2012e4b17023SJohn Marino int checkz = compare_values (res, val1);
2013e4b17023SJohn Marino bool overflow = false;
2014e4b17023SJohn Marino
2015e4b17023SJohn Marino /* Ensure that res = val1 [+*] val2 >= val1
2016e4b17023SJohn Marino or that res = val1 - val2 <= val1. */
2017e4b17023SJohn Marino if ((code == PLUS_EXPR
2018e4b17023SJohn Marino && !(checkz == 1 || checkz == 0))
2019e4b17023SJohn Marino || (code == MINUS_EXPR
2020e4b17023SJohn Marino && !(checkz == 0 || checkz == -1)))
2021e4b17023SJohn Marino {
2022e4b17023SJohn Marino overflow = true;
2023e4b17023SJohn Marino }
2024e4b17023SJohn Marino /* Checking for multiplication overflow is done by dividing the
2025e4b17023SJohn Marino output of the multiplication by the first input of the
2026e4b17023SJohn Marino multiplication. If the result of that division operation is
2027e4b17023SJohn Marino not equal to the second input of the multiplication, then the
2028e4b17023SJohn Marino multiplication overflowed. */
2029e4b17023SJohn Marino else if (code == MULT_EXPR && !integer_zerop (val1))
2030e4b17023SJohn Marino {
2031e4b17023SJohn Marino tree tmp = int_const_binop (TRUNC_DIV_EXPR,
2032e4b17023SJohn Marino res,
2033e4b17023SJohn Marino val1);
2034e4b17023SJohn Marino int check = compare_values (tmp, val2);
2035e4b17023SJohn Marino
2036e4b17023SJohn Marino if (check != 0)
2037e4b17023SJohn Marino overflow = true;
2038e4b17023SJohn Marino }
2039e4b17023SJohn Marino
2040e4b17023SJohn Marino if (overflow)
2041e4b17023SJohn Marino {
2042e4b17023SJohn Marino res = copy_node (res);
2043e4b17023SJohn Marino TREE_OVERFLOW (res) = 1;
2044e4b17023SJohn Marino }
2045e4b17023SJohn Marino
2046e4b17023SJohn Marino }
2047e4b17023SJohn Marino else if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
2048e4b17023SJohn Marino /* If the singed operation wraps then int_const_binop has done
2049e4b17023SJohn Marino everything we want. */
2050e4b17023SJohn Marino ;
2051e4b17023SJohn Marino else if ((TREE_OVERFLOW (res)
2052e4b17023SJohn Marino && !TREE_OVERFLOW (val1)
2053e4b17023SJohn Marino && !TREE_OVERFLOW (val2))
2054e4b17023SJohn Marino || is_overflow_infinity (val1)
2055e4b17023SJohn Marino || is_overflow_infinity (val2))
2056e4b17023SJohn Marino {
2057e4b17023SJohn Marino /* If the operation overflowed but neither VAL1 nor VAL2 are
2058e4b17023SJohn Marino overflown, return -INF or +INF depending on the operation
2059e4b17023SJohn Marino and the combination of signs of the operands. */
2060e4b17023SJohn Marino int sgn1 = tree_int_cst_sgn (val1);
2061e4b17023SJohn Marino int sgn2 = tree_int_cst_sgn (val2);
2062e4b17023SJohn Marino
2063e4b17023SJohn Marino if (needs_overflow_infinity (TREE_TYPE (res))
2064e4b17023SJohn Marino && !supports_overflow_infinity (TREE_TYPE (res)))
2065e4b17023SJohn Marino return NULL_TREE;
2066e4b17023SJohn Marino
2067e4b17023SJohn Marino /* We have to punt on adding infinities of different signs,
2068e4b17023SJohn Marino since we can't tell what the sign of the result should be.
2069e4b17023SJohn Marino Likewise for subtracting infinities of the same sign. */
2070e4b17023SJohn Marino if (((code == PLUS_EXPR && sgn1 != sgn2)
2071e4b17023SJohn Marino || (code == MINUS_EXPR && sgn1 == sgn2))
2072e4b17023SJohn Marino && is_overflow_infinity (val1)
2073e4b17023SJohn Marino && is_overflow_infinity (val2))
2074e4b17023SJohn Marino return NULL_TREE;
2075e4b17023SJohn Marino
2076e4b17023SJohn Marino /* Don't try to handle division or shifting of infinities. */
2077e4b17023SJohn Marino if ((code == TRUNC_DIV_EXPR
2078e4b17023SJohn Marino || code == FLOOR_DIV_EXPR
2079e4b17023SJohn Marino || code == CEIL_DIV_EXPR
2080e4b17023SJohn Marino || code == EXACT_DIV_EXPR
2081e4b17023SJohn Marino || code == ROUND_DIV_EXPR
2082e4b17023SJohn Marino || code == RSHIFT_EXPR)
2083e4b17023SJohn Marino && (is_overflow_infinity (val1)
2084e4b17023SJohn Marino || is_overflow_infinity (val2)))
2085e4b17023SJohn Marino return NULL_TREE;
2086e4b17023SJohn Marino
2087e4b17023SJohn Marino /* Notice that we only need to handle the restricted set of
2088e4b17023SJohn Marino operations handled by extract_range_from_binary_expr.
2089e4b17023SJohn Marino Among them, only multiplication, addition and subtraction
2090e4b17023SJohn Marino can yield overflow without overflown operands because we
2091e4b17023SJohn Marino are working with integral types only... except in the
2092e4b17023SJohn Marino case VAL1 = -INF and VAL2 = -1 which overflows to +INF
2093e4b17023SJohn Marino for division too. */
2094e4b17023SJohn Marino
2095e4b17023SJohn Marino /* For multiplication, the sign of the overflow is given
2096e4b17023SJohn Marino by the comparison of the signs of the operands. */
2097e4b17023SJohn Marino if ((code == MULT_EXPR && sgn1 == sgn2)
2098e4b17023SJohn Marino /* For addition, the operands must be of the same sign
2099e4b17023SJohn Marino to yield an overflow. Its sign is therefore that
2100e4b17023SJohn Marino of one of the operands, for example the first. For
2101e4b17023SJohn Marino infinite operands X + -INF is negative, not positive. */
2102e4b17023SJohn Marino || (code == PLUS_EXPR
2103e4b17023SJohn Marino && (sgn1 >= 0
2104e4b17023SJohn Marino ? !is_negative_overflow_infinity (val2)
2105e4b17023SJohn Marino : is_positive_overflow_infinity (val2)))
2106e4b17023SJohn Marino /* For subtraction, non-infinite operands must be of
2107e4b17023SJohn Marino different signs to yield an overflow. Its sign is
2108e4b17023SJohn Marino therefore that of the first operand or the opposite of
2109e4b17023SJohn Marino that of the second operand. A first operand of 0 counts
2110e4b17023SJohn Marino as positive here, for the corner case 0 - (-INF), which
2111e4b17023SJohn Marino overflows, but must yield +INF. For infinite operands 0
2112e4b17023SJohn Marino - INF is negative, not positive. */
2113e4b17023SJohn Marino || (code == MINUS_EXPR
2114e4b17023SJohn Marino && (sgn1 >= 0
2115e4b17023SJohn Marino ? !is_positive_overflow_infinity (val2)
2116e4b17023SJohn Marino : is_negative_overflow_infinity (val2)))
2117e4b17023SJohn Marino /* We only get in here with positive shift count, so the
2118e4b17023SJohn Marino overflow direction is the same as the sign of val1.
2119e4b17023SJohn Marino Actually rshift does not overflow at all, but we only
2120e4b17023SJohn Marino handle the case of shifting overflowed -INF and +INF. */
2121e4b17023SJohn Marino || (code == RSHIFT_EXPR
2122e4b17023SJohn Marino && sgn1 >= 0)
2123e4b17023SJohn Marino /* For division, the only case is -INF / -1 = +INF. */
2124e4b17023SJohn Marino || code == TRUNC_DIV_EXPR
2125e4b17023SJohn Marino || code == FLOOR_DIV_EXPR
2126e4b17023SJohn Marino || code == CEIL_DIV_EXPR
2127e4b17023SJohn Marino || code == EXACT_DIV_EXPR
2128e4b17023SJohn Marino || code == ROUND_DIV_EXPR)
2129e4b17023SJohn Marino return (needs_overflow_infinity (TREE_TYPE (res))
2130e4b17023SJohn Marino ? positive_overflow_infinity (TREE_TYPE (res))
2131e4b17023SJohn Marino : TYPE_MAX_VALUE (TREE_TYPE (res)));
2132e4b17023SJohn Marino else
2133e4b17023SJohn Marino return (needs_overflow_infinity (TREE_TYPE (res))
2134e4b17023SJohn Marino ? negative_overflow_infinity (TREE_TYPE (res))
2135e4b17023SJohn Marino : TYPE_MIN_VALUE (TREE_TYPE (res)));
2136e4b17023SJohn Marino }
2137e4b17023SJohn Marino
2138e4b17023SJohn Marino return res;
2139e4b17023SJohn Marino }
2140e4b17023SJohn Marino
2141e4b17023SJohn Marino
2142e4b17023SJohn Marino /* For range VR compute two double_int bitmasks. In *MAY_BE_NONZERO
2143e4b17023SJohn Marino bitmask if some bit is unset, it means for all numbers in the range
2144e4b17023SJohn Marino the bit is 0, otherwise it might be 0 or 1. In *MUST_BE_NONZERO
2145e4b17023SJohn Marino bitmask if some bit is set, it means for all numbers in the range
2146e4b17023SJohn Marino the bit is 1, otherwise it might be 0 or 1. */
2147e4b17023SJohn Marino
2148e4b17023SJohn Marino static bool
zero_nonzero_bits_from_vr(value_range_t * vr,double_int * may_be_nonzero,double_int * must_be_nonzero)2149e4b17023SJohn Marino zero_nonzero_bits_from_vr (value_range_t *vr,
2150e4b17023SJohn Marino double_int *may_be_nonzero,
2151e4b17023SJohn Marino double_int *must_be_nonzero)
2152e4b17023SJohn Marino {
2153e4b17023SJohn Marino *may_be_nonzero = double_int_minus_one;
2154e4b17023SJohn Marino *must_be_nonzero = double_int_zero;
2155e4b17023SJohn Marino if (!range_int_cst_p (vr))
2156e4b17023SJohn Marino return false;
2157e4b17023SJohn Marino
2158e4b17023SJohn Marino if (range_int_cst_singleton_p (vr))
2159e4b17023SJohn Marino {
2160e4b17023SJohn Marino *may_be_nonzero = tree_to_double_int (vr->min);
2161e4b17023SJohn Marino *must_be_nonzero = *may_be_nonzero;
2162e4b17023SJohn Marino }
2163e4b17023SJohn Marino else if (tree_int_cst_sgn (vr->min) >= 0
2164e4b17023SJohn Marino || tree_int_cst_sgn (vr->max) < 0)
2165e4b17023SJohn Marino {
2166e4b17023SJohn Marino double_int dmin = tree_to_double_int (vr->min);
2167e4b17023SJohn Marino double_int dmax = tree_to_double_int (vr->max);
2168e4b17023SJohn Marino double_int xor_mask = double_int_xor (dmin, dmax);
2169e4b17023SJohn Marino *may_be_nonzero = double_int_ior (dmin, dmax);
2170e4b17023SJohn Marino *must_be_nonzero = double_int_and (dmin, dmax);
2171e4b17023SJohn Marino if (xor_mask.high != 0)
2172e4b17023SJohn Marino {
2173e4b17023SJohn Marino unsigned HOST_WIDE_INT mask
2174e4b17023SJohn Marino = ((unsigned HOST_WIDE_INT) 1
2175e4b17023SJohn Marino << floor_log2 (xor_mask.high)) - 1;
2176e4b17023SJohn Marino may_be_nonzero->low = ALL_ONES;
2177e4b17023SJohn Marino may_be_nonzero->high |= mask;
2178e4b17023SJohn Marino must_be_nonzero->low = 0;
2179e4b17023SJohn Marino must_be_nonzero->high &= ~mask;
2180e4b17023SJohn Marino }
2181e4b17023SJohn Marino else if (xor_mask.low != 0)
2182e4b17023SJohn Marino {
2183e4b17023SJohn Marino unsigned HOST_WIDE_INT mask
2184e4b17023SJohn Marino = ((unsigned HOST_WIDE_INT) 1
2185e4b17023SJohn Marino << floor_log2 (xor_mask.low)) - 1;
2186e4b17023SJohn Marino may_be_nonzero->low |= mask;
2187e4b17023SJohn Marino must_be_nonzero->low &= ~mask;
2188e4b17023SJohn Marino }
2189e4b17023SJohn Marino }
2190e4b17023SJohn Marino
2191e4b17023SJohn Marino return true;
2192e4b17023SJohn Marino }
2193e4b17023SJohn Marino
2194e4b17023SJohn Marino /* Helper to extract a value-range *VR for a multiplicative operation
2195e4b17023SJohn Marino *VR0 CODE *VR1. */
2196e4b17023SJohn Marino
2197e4b17023SJohn Marino static void
extract_range_from_multiplicative_op_1(value_range_t * vr,enum tree_code code,value_range_t * vr0,value_range_t * vr1)2198e4b17023SJohn Marino extract_range_from_multiplicative_op_1 (value_range_t *vr,
2199e4b17023SJohn Marino enum tree_code code,
2200e4b17023SJohn Marino value_range_t *vr0, value_range_t *vr1)
2201e4b17023SJohn Marino {
2202e4b17023SJohn Marino enum value_range_type type;
2203e4b17023SJohn Marino tree val[4];
2204e4b17023SJohn Marino size_t i;
2205e4b17023SJohn Marino tree min, max;
2206e4b17023SJohn Marino bool sop;
2207e4b17023SJohn Marino int cmp;
2208e4b17023SJohn Marino
2209e4b17023SJohn Marino /* Multiplications, divisions and shifts are a bit tricky to handle,
2210e4b17023SJohn Marino depending on the mix of signs we have in the two ranges, we
2211e4b17023SJohn Marino need to operate on different values to get the minimum and
2212e4b17023SJohn Marino maximum values for the new range. One approach is to figure
2213e4b17023SJohn Marino out all the variations of range combinations and do the
2214e4b17023SJohn Marino operations.
2215e4b17023SJohn Marino
2216e4b17023SJohn Marino However, this involves several calls to compare_values and it
2217e4b17023SJohn Marino is pretty convoluted. It's simpler to do the 4 operations
2218e4b17023SJohn Marino (MIN0 OP MIN1, MIN0 OP MAX1, MAX0 OP MIN1 and MAX0 OP MAX0 OP
2219e4b17023SJohn Marino MAX1) and then figure the smallest and largest values to form
2220e4b17023SJohn Marino the new range. */
2221e4b17023SJohn Marino gcc_assert (code == MULT_EXPR
2222e4b17023SJohn Marino || code == TRUNC_DIV_EXPR
2223e4b17023SJohn Marino || code == FLOOR_DIV_EXPR
2224e4b17023SJohn Marino || code == CEIL_DIV_EXPR
2225e4b17023SJohn Marino || code == EXACT_DIV_EXPR
2226e4b17023SJohn Marino || code == ROUND_DIV_EXPR
2227e4b17023SJohn Marino || code == RSHIFT_EXPR);
2228e4b17023SJohn Marino gcc_assert ((vr0->type == VR_RANGE
2229e4b17023SJohn Marino || (code == MULT_EXPR && vr0->type == VR_ANTI_RANGE))
2230e4b17023SJohn Marino && vr0->type == vr1->type);
2231e4b17023SJohn Marino
2232e4b17023SJohn Marino type = vr0->type;
2233e4b17023SJohn Marino
2234e4b17023SJohn Marino /* Compute the 4 cross operations. */
2235e4b17023SJohn Marino sop = false;
2236e4b17023SJohn Marino val[0] = vrp_int_const_binop (code, vr0->min, vr1->min);
2237e4b17023SJohn Marino if (val[0] == NULL_TREE)
2238e4b17023SJohn Marino sop = true;
2239e4b17023SJohn Marino
2240e4b17023SJohn Marino if (vr1->max == vr1->min)
2241e4b17023SJohn Marino val[1] = NULL_TREE;
2242e4b17023SJohn Marino else
2243e4b17023SJohn Marino {
2244e4b17023SJohn Marino val[1] = vrp_int_const_binop (code, vr0->min, vr1->max);
2245e4b17023SJohn Marino if (val[1] == NULL_TREE)
2246e4b17023SJohn Marino sop = true;
2247e4b17023SJohn Marino }
2248e4b17023SJohn Marino
2249e4b17023SJohn Marino if (vr0->max == vr0->min)
2250e4b17023SJohn Marino val[2] = NULL_TREE;
2251e4b17023SJohn Marino else
2252e4b17023SJohn Marino {
2253e4b17023SJohn Marino val[2] = vrp_int_const_binop (code, vr0->max, vr1->min);
2254e4b17023SJohn Marino if (val[2] == NULL_TREE)
2255e4b17023SJohn Marino sop = true;
2256e4b17023SJohn Marino }
2257e4b17023SJohn Marino
2258e4b17023SJohn Marino if (vr0->min == vr0->max || vr1->min == vr1->max)
2259e4b17023SJohn Marino val[3] = NULL_TREE;
2260e4b17023SJohn Marino else
2261e4b17023SJohn Marino {
2262e4b17023SJohn Marino val[3] = vrp_int_const_binop (code, vr0->max, vr1->max);
2263e4b17023SJohn Marino if (val[3] == NULL_TREE)
2264e4b17023SJohn Marino sop = true;
2265e4b17023SJohn Marino }
2266e4b17023SJohn Marino
2267e4b17023SJohn Marino if (sop)
2268e4b17023SJohn Marino {
2269e4b17023SJohn Marino set_value_range_to_varying (vr);
2270e4b17023SJohn Marino return;
2271e4b17023SJohn Marino }
2272e4b17023SJohn Marino
2273e4b17023SJohn Marino /* Set MIN to the minimum of VAL[i] and MAX to the maximum
2274e4b17023SJohn Marino of VAL[i]. */
2275e4b17023SJohn Marino min = val[0];
2276e4b17023SJohn Marino max = val[0];
2277e4b17023SJohn Marino for (i = 1; i < 4; i++)
2278e4b17023SJohn Marino {
2279e4b17023SJohn Marino if (!is_gimple_min_invariant (min)
2280e4b17023SJohn Marino || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2281e4b17023SJohn Marino || !is_gimple_min_invariant (max)
2282e4b17023SJohn Marino || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2283e4b17023SJohn Marino break;
2284e4b17023SJohn Marino
2285e4b17023SJohn Marino if (val[i])
2286e4b17023SJohn Marino {
2287e4b17023SJohn Marino if (!is_gimple_min_invariant (val[i])
2288e4b17023SJohn Marino || (TREE_OVERFLOW (val[i])
2289e4b17023SJohn Marino && !is_overflow_infinity (val[i])))
2290e4b17023SJohn Marino {
2291e4b17023SJohn Marino /* If we found an overflowed value, set MIN and MAX
2292e4b17023SJohn Marino to it so that we set the resulting range to
2293e4b17023SJohn Marino VARYING. */
2294e4b17023SJohn Marino min = max = val[i];
2295e4b17023SJohn Marino break;
2296e4b17023SJohn Marino }
2297e4b17023SJohn Marino
2298e4b17023SJohn Marino if (compare_values (val[i], min) == -1)
2299e4b17023SJohn Marino min = val[i];
2300e4b17023SJohn Marino
2301e4b17023SJohn Marino if (compare_values (val[i], max) == 1)
2302e4b17023SJohn Marino max = val[i];
2303e4b17023SJohn Marino }
2304e4b17023SJohn Marino }
2305e4b17023SJohn Marino
2306e4b17023SJohn Marino /* If either MIN or MAX overflowed, then set the resulting range to
2307e4b17023SJohn Marino VARYING. But we do accept an overflow infinity
2308e4b17023SJohn Marino representation. */
2309e4b17023SJohn Marino if (min == NULL_TREE
2310e4b17023SJohn Marino || !is_gimple_min_invariant (min)
2311e4b17023SJohn Marino || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2312e4b17023SJohn Marino || max == NULL_TREE
2313e4b17023SJohn Marino || !is_gimple_min_invariant (max)
2314e4b17023SJohn Marino || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2315e4b17023SJohn Marino {
2316e4b17023SJohn Marino set_value_range_to_varying (vr);
2317e4b17023SJohn Marino return;
2318e4b17023SJohn Marino }
2319e4b17023SJohn Marino
2320e4b17023SJohn Marino /* We punt if:
2321e4b17023SJohn Marino 1) [-INF, +INF]
2322e4b17023SJohn Marino 2) [-INF, +-INF(OVF)]
2323e4b17023SJohn Marino 3) [+-INF(OVF), +INF]
2324e4b17023SJohn Marino 4) [+-INF(OVF), +-INF(OVF)]
2325e4b17023SJohn Marino We learn nothing when we have INF and INF(OVF) on both sides.
2326e4b17023SJohn Marino Note that we do accept [-INF, -INF] and [+INF, +INF] without
2327e4b17023SJohn Marino overflow. */
2328e4b17023SJohn Marino if ((vrp_val_is_min (min) || is_overflow_infinity (min))
2329e4b17023SJohn Marino && (vrp_val_is_max (max) || is_overflow_infinity (max)))
2330e4b17023SJohn Marino {
2331e4b17023SJohn Marino set_value_range_to_varying (vr);
2332e4b17023SJohn Marino return;
2333e4b17023SJohn Marino }
2334e4b17023SJohn Marino
2335e4b17023SJohn Marino cmp = compare_values (min, max);
2336e4b17023SJohn Marino if (cmp == -2 || cmp == 1)
2337e4b17023SJohn Marino {
2338e4b17023SJohn Marino /* If the new range has its limits swapped around (MIN > MAX),
2339e4b17023SJohn Marino then the operation caused one of them to wrap around, mark
2340e4b17023SJohn Marino the new range VARYING. */
2341e4b17023SJohn Marino set_value_range_to_varying (vr);
2342e4b17023SJohn Marino }
2343e4b17023SJohn Marino else
2344e4b17023SJohn Marino set_value_range (vr, type, min, max, NULL);
2345e4b17023SJohn Marino }
2346e4b17023SJohn Marino
2347e4b17023SJohn Marino /* Extract range information from a binary operation CODE based on
2348e4b17023SJohn Marino the ranges of each of its operands, *VR0 and *VR1 with resulting
2349e4b17023SJohn Marino type EXPR_TYPE. The resulting range is stored in *VR. */
2350e4b17023SJohn Marino
2351e4b17023SJohn Marino static void
extract_range_from_binary_expr_1(value_range_t * vr,enum tree_code code,tree expr_type,value_range_t * vr0_,value_range_t * vr1_)2352e4b17023SJohn Marino extract_range_from_binary_expr_1 (value_range_t *vr,
2353e4b17023SJohn Marino enum tree_code code, tree expr_type,
2354e4b17023SJohn Marino value_range_t *vr0_, value_range_t *vr1_)
2355e4b17023SJohn Marino {
2356e4b17023SJohn Marino value_range_t vr0 = *vr0_, vr1 = *vr1_;
2357e4b17023SJohn Marino enum value_range_type type;
2358e4b17023SJohn Marino tree min = NULL_TREE, max = NULL_TREE;
2359e4b17023SJohn Marino int cmp;
2360e4b17023SJohn Marino
2361e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (expr_type)
2362e4b17023SJohn Marino && !POINTER_TYPE_P (expr_type))
2363e4b17023SJohn Marino {
2364e4b17023SJohn Marino set_value_range_to_varying (vr);
2365e4b17023SJohn Marino return;
2366e4b17023SJohn Marino }
2367e4b17023SJohn Marino
2368e4b17023SJohn Marino /* Not all binary expressions can be applied to ranges in a
2369e4b17023SJohn Marino meaningful way. Handle only arithmetic operations. */
2370e4b17023SJohn Marino if (code != PLUS_EXPR
2371e4b17023SJohn Marino && code != MINUS_EXPR
2372e4b17023SJohn Marino && code != POINTER_PLUS_EXPR
2373e4b17023SJohn Marino && code != MULT_EXPR
2374e4b17023SJohn Marino && code != TRUNC_DIV_EXPR
2375e4b17023SJohn Marino && code != FLOOR_DIV_EXPR
2376e4b17023SJohn Marino && code != CEIL_DIV_EXPR
2377e4b17023SJohn Marino && code != EXACT_DIV_EXPR
2378e4b17023SJohn Marino && code != ROUND_DIV_EXPR
2379e4b17023SJohn Marino && code != TRUNC_MOD_EXPR
2380e4b17023SJohn Marino && code != RSHIFT_EXPR
2381e4b17023SJohn Marino && code != MIN_EXPR
2382e4b17023SJohn Marino && code != MAX_EXPR
2383e4b17023SJohn Marino && code != BIT_AND_EXPR
2384e4b17023SJohn Marino && code != BIT_IOR_EXPR
2385e4b17023SJohn Marino && code != BIT_XOR_EXPR)
2386e4b17023SJohn Marino {
2387e4b17023SJohn Marino set_value_range_to_varying (vr);
2388e4b17023SJohn Marino return;
2389e4b17023SJohn Marino }
2390e4b17023SJohn Marino
2391e4b17023SJohn Marino /* If both ranges are UNDEFINED, so is the result. */
2392e4b17023SJohn Marino if (vr0.type == VR_UNDEFINED && vr1.type == VR_UNDEFINED)
2393e4b17023SJohn Marino {
2394e4b17023SJohn Marino set_value_range_to_undefined (vr);
2395e4b17023SJohn Marino return;
2396e4b17023SJohn Marino }
2397e4b17023SJohn Marino /* If one of the ranges is UNDEFINED drop it to VARYING for the following
2398e4b17023SJohn Marino code. At some point we may want to special-case operations that
2399e4b17023SJohn Marino have UNDEFINED result for all or some value-ranges of the not UNDEFINED
2400e4b17023SJohn Marino operand. */
2401e4b17023SJohn Marino else if (vr0.type == VR_UNDEFINED)
2402e4b17023SJohn Marino set_value_range_to_varying (&vr0);
2403e4b17023SJohn Marino else if (vr1.type == VR_UNDEFINED)
2404e4b17023SJohn Marino set_value_range_to_varying (&vr1);
2405e4b17023SJohn Marino
2406e4b17023SJohn Marino /* The type of the resulting value range defaults to VR0.TYPE. */
2407e4b17023SJohn Marino type = vr0.type;
2408e4b17023SJohn Marino
2409e4b17023SJohn Marino /* Refuse to operate on VARYING ranges, ranges of different kinds
2410e4b17023SJohn Marino and symbolic ranges. As an exception, we allow BIT_AND_EXPR
2411e4b17023SJohn Marino because we may be able to derive a useful range even if one of
2412e4b17023SJohn Marino the operands is VR_VARYING or symbolic range. Similarly for
2413e4b17023SJohn Marino divisions. TODO, we may be able to derive anti-ranges in
2414e4b17023SJohn Marino some cases. */
2415e4b17023SJohn Marino if (code != BIT_AND_EXPR
2416e4b17023SJohn Marino && code != BIT_IOR_EXPR
2417e4b17023SJohn Marino && code != TRUNC_DIV_EXPR
2418e4b17023SJohn Marino && code != FLOOR_DIV_EXPR
2419e4b17023SJohn Marino && code != CEIL_DIV_EXPR
2420e4b17023SJohn Marino && code != EXACT_DIV_EXPR
2421e4b17023SJohn Marino && code != ROUND_DIV_EXPR
2422e4b17023SJohn Marino && code != TRUNC_MOD_EXPR
2423e4b17023SJohn Marino && (vr0.type == VR_VARYING
2424e4b17023SJohn Marino || vr1.type == VR_VARYING
2425e4b17023SJohn Marino || vr0.type != vr1.type
2426e4b17023SJohn Marino || symbolic_range_p (&vr0)
2427e4b17023SJohn Marino || symbolic_range_p (&vr1)))
2428e4b17023SJohn Marino {
2429e4b17023SJohn Marino set_value_range_to_varying (vr);
2430e4b17023SJohn Marino return;
2431e4b17023SJohn Marino }
2432e4b17023SJohn Marino
2433e4b17023SJohn Marino /* Now evaluate the expression to determine the new range. */
2434e4b17023SJohn Marino if (POINTER_TYPE_P (expr_type))
2435e4b17023SJohn Marino {
2436e4b17023SJohn Marino if (code == MIN_EXPR || code == MAX_EXPR)
2437e4b17023SJohn Marino {
2438e4b17023SJohn Marino /* For MIN/MAX expressions with pointers, we only care about
2439e4b17023SJohn Marino nullness, if both are non null, then the result is nonnull.
2440e4b17023SJohn Marino If both are null, then the result is null. Otherwise they
2441e4b17023SJohn Marino are varying. */
2442e4b17023SJohn Marino if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
2443e4b17023SJohn Marino set_value_range_to_nonnull (vr, expr_type);
2444e4b17023SJohn Marino else if (range_is_null (&vr0) && range_is_null (&vr1))
2445e4b17023SJohn Marino set_value_range_to_null (vr, expr_type);
2446e4b17023SJohn Marino else
2447e4b17023SJohn Marino set_value_range_to_varying (vr);
2448e4b17023SJohn Marino }
2449e4b17023SJohn Marino else if (code == POINTER_PLUS_EXPR)
2450e4b17023SJohn Marino {
2451e4b17023SJohn Marino /* For pointer types, we are really only interested in asserting
2452e4b17023SJohn Marino whether the expression evaluates to non-NULL. */
2453e4b17023SJohn Marino if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
2454e4b17023SJohn Marino set_value_range_to_nonnull (vr, expr_type);
2455e4b17023SJohn Marino else if (range_is_null (&vr0) && range_is_null (&vr1))
2456e4b17023SJohn Marino set_value_range_to_null (vr, expr_type);
2457e4b17023SJohn Marino else
2458e4b17023SJohn Marino set_value_range_to_varying (vr);
2459e4b17023SJohn Marino }
2460e4b17023SJohn Marino else if (code == BIT_AND_EXPR)
2461e4b17023SJohn Marino {
2462e4b17023SJohn Marino /* For pointer types, we are really only interested in asserting
2463e4b17023SJohn Marino whether the expression evaluates to non-NULL. */
2464e4b17023SJohn Marino if (range_is_nonnull (&vr0) && range_is_nonnull (&vr1))
2465e4b17023SJohn Marino set_value_range_to_nonnull (vr, expr_type);
2466e4b17023SJohn Marino else if (range_is_null (&vr0) || range_is_null (&vr1))
2467e4b17023SJohn Marino set_value_range_to_null (vr, expr_type);
2468e4b17023SJohn Marino else
2469e4b17023SJohn Marino set_value_range_to_varying (vr);
2470e4b17023SJohn Marino }
2471e4b17023SJohn Marino else
2472e4b17023SJohn Marino set_value_range_to_varying (vr);
2473e4b17023SJohn Marino
2474e4b17023SJohn Marino return;
2475e4b17023SJohn Marino }
2476e4b17023SJohn Marino
2477e4b17023SJohn Marino /* For integer ranges, apply the operation to each end of the
2478e4b17023SJohn Marino range and see what we end up with. */
2479e4b17023SJohn Marino if (code == PLUS_EXPR)
2480e4b17023SJohn Marino {
2481e4b17023SJohn Marino /* If we have a PLUS_EXPR with two VR_ANTI_RANGEs, drop to
2482e4b17023SJohn Marino VR_VARYING. It would take more effort to compute a precise
2483e4b17023SJohn Marino range for such a case. For example, if we have op0 == 1 and
2484e4b17023SJohn Marino op1 == -1 with their ranges both being ~[0,0], we would have
2485e4b17023SJohn Marino op0 + op1 == 0, so we cannot claim that the sum is in ~[0,0].
2486e4b17023SJohn Marino Note that we are guaranteed to have vr0.type == vr1.type at
2487e4b17023SJohn Marino this point. */
2488e4b17023SJohn Marino if (vr0.type == VR_ANTI_RANGE)
2489e4b17023SJohn Marino {
2490e4b17023SJohn Marino set_value_range_to_varying (vr);
2491e4b17023SJohn Marino return;
2492e4b17023SJohn Marino }
2493e4b17023SJohn Marino
2494e4b17023SJohn Marino /* For operations that make the resulting range directly
2495e4b17023SJohn Marino proportional to the original ranges, apply the operation to
2496e4b17023SJohn Marino the same end of each range. */
2497e4b17023SJohn Marino min = vrp_int_const_binop (code, vr0.min, vr1.min);
2498e4b17023SJohn Marino max = vrp_int_const_binop (code, vr0.max, vr1.max);
2499e4b17023SJohn Marino
2500e4b17023SJohn Marino /* If both additions overflowed the range kind is still correct.
2501e4b17023SJohn Marino This happens regularly with subtracting something in unsigned
2502e4b17023SJohn Marino arithmetic.
2503e4b17023SJohn Marino ??? See PR30318 for all the cases we do not handle. */
2504e4b17023SJohn Marino if ((TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2505e4b17023SJohn Marino && (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2506e4b17023SJohn Marino {
2507e4b17023SJohn Marino min = build_int_cst_wide (TREE_TYPE (min),
2508e4b17023SJohn Marino TREE_INT_CST_LOW (min),
2509e4b17023SJohn Marino TREE_INT_CST_HIGH (min));
2510e4b17023SJohn Marino max = build_int_cst_wide (TREE_TYPE (max),
2511e4b17023SJohn Marino TREE_INT_CST_LOW (max),
2512e4b17023SJohn Marino TREE_INT_CST_HIGH (max));
2513e4b17023SJohn Marino }
2514e4b17023SJohn Marino }
2515e4b17023SJohn Marino else if (code == MIN_EXPR
2516e4b17023SJohn Marino || code == MAX_EXPR)
2517e4b17023SJohn Marino {
2518e4b17023SJohn Marino if (vr0.type == VR_ANTI_RANGE)
2519e4b17023SJohn Marino {
2520e4b17023SJohn Marino /* For MIN_EXPR and MAX_EXPR with two VR_ANTI_RANGEs,
2521e4b17023SJohn Marino the resulting VR_ANTI_RANGE is the same - intersection
2522e4b17023SJohn Marino of the two ranges. */
2523e4b17023SJohn Marino min = vrp_int_const_binop (MAX_EXPR, vr0.min, vr1.min);
2524e4b17023SJohn Marino max = vrp_int_const_binop (MIN_EXPR, vr0.max, vr1.max);
2525e4b17023SJohn Marino }
2526e4b17023SJohn Marino else
2527e4b17023SJohn Marino {
2528e4b17023SJohn Marino /* For operations that make the resulting range directly
2529e4b17023SJohn Marino proportional to the original ranges, apply the operation to
2530e4b17023SJohn Marino the same end of each range. */
2531e4b17023SJohn Marino min = vrp_int_const_binop (code, vr0.min, vr1.min);
2532e4b17023SJohn Marino max = vrp_int_const_binop (code, vr0.max, vr1.max);
2533e4b17023SJohn Marino }
2534e4b17023SJohn Marino }
2535e4b17023SJohn Marino else if (code == MULT_EXPR)
2536e4b17023SJohn Marino {
2537e4b17023SJohn Marino /* If we have an unsigned MULT_EXPR with two VR_ANTI_RANGEs,
2538e4b17023SJohn Marino drop to VR_VARYING. It would take more effort to compute a
2539e4b17023SJohn Marino precise range for such a case. For example, if we have
2540e4b17023SJohn Marino op0 == 65536 and op1 == 65536 with their ranges both being
2541e4b17023SJohn Marino ~[0,0] on a 32-bit machine, we would have op0 * op1 == 0, so
2542e4b17023SJohn Marino we cannot claim that the product is in ~[0,0]. Note that we
2543e4b17023SJohn Marino are guaranteed to have vr0.type == vr1.type at this
2544e4b17023SJohn Marino point. */
2545e4b17023SJohn Marino if (vr0.type == VR_ANTI_RANGE
2546e4b17023SJohn Marino && !TYPE_OVERFLOW_UNDEFINED (expr_type))
2547e4b17023SJohn Marino {
2548e4b17023SJohn Marino set_value_range_to_varying (vr);
2549e4b17023SJohn Marino return;
2550e4b17023SJohn Marino }
2551e4b17023SJohn Marino
2552e4b17023SJohn Marino extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2553e4b17023SJohn Marino return;
2554e4b17023SJohn Marino }
2555e4b17023SJohn Marino else if (code == RSHIFT_EXPR)
2556e4b17023SJohn Marino {
2557e4b17023SJohn Marino /* If we have a RSHIFT_EXPR with any shift values outside [0..prec-1],
2558e4b17023SJohn Marino then drop to VR_VARYING. Outside of this range we get undefined
2559e4b17023SJohn Marino behavior from the shift operation. We cannot even trust
2560e4b17023SJohn Marino SHIFT_COUNT_TRUNCATED at this stage, because that applies to rtl
2561e4b17023SJohn Marino shifts, and the operation at the tree level may be widened. */
2562e4b17023SJohn Marino if (vr1.type != VR_RANGE
2563e4b17023SJohn Marino || !value_range_nonnegative_p (&vr1)
2564e4b17023SJohn Marino || TREE_CODE (vr1.max) != INTEGER_CST
2565e4b17023SJohn Marino || compare_tree_int (vr1.max, TYPE_PRECISION (expr_type) - 1) == 1)
2566e4b17023SJohn Marino {
2567e4b17023SJohn Marino set_value_range_to_varying (vr);
2568e4b17023SJohn Marino return;
2569e4b17023SJohn Marino }
2570e4b17023SJohn Marino
2571e4b17023SJohn Marino extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2572e4b17023SJohn Marino return;
2573e4b17023SJohn Marino }
2574e4b17023SJohn Marino else if (code == TRUNC_DIV_EXPR
2575e4b17023SJohn Marino || code == FLOOR_DIV_EXPR
2576e4b17023SJohn Marino || code == CEIL_DIV_EXPR
2577e4b17023SJohn Marino || code == EXACT_DIV_EXPR
2578e4b17023SJohn Marino || code == ROUND_DIV_EXPR)
2579e4b17023SJohn Marino {
2580e4b17023SJohn Marino if (vr0.type != VR_RANGE || symbolic_range_p (&vr0))
2581e4b17023SJohn Marino {
2582e4b17023SJohn Marino /* For division, if op1 has VR_RANGE but op0 does not, something
2583e4b17023SJohn Marino can be deduced just from that range. Say [min, max] / [4, max]
2584e4b17023SJohn Marino gives [min / 4, max / 4] range. */
2585e4b17023SJohn Marino if (vr1.type == VR_RANGE
2586e4b17023SJohn Marino && !symbolic_range_p (&vr1)
2587e4b17023SJohn Marino && range_includes_zero_p (vr1.min, vr1.max) == 0)
2588e4b17023SJohn Marino {
2589e4b17023SJohn Marino vr0.type = type = VR_RANGE;
2590e4b17023SJohn Marino vr0.min = vrp_val_min (expr_type);
2591e4b17023SJohn Marino vr0.max = vrp_val_max (expr_type);
2592e4b17023SJohn Marino }
2593e4b17023SJohn Marino else
2594e4b17023SJohn Marino {
2595e4b17023SJohn Marino set_value_range_to_varying (vr);
2596e4b17023SJohn Marino return;
2597e4b17023SJohn Marino }
2598e4b17023SJohn Marino }
2599e4b17023SJohn Marino
2600e4b17023SJohn Marino /* For divisions, if flag_non_call_exceptions is true, we must
2601e4b17023SJohn Marino not eliminate a division by zero. */
2602e4b17023SJohn Marino if (cfun->can_throw_non_call_exceptions
2603e4b17023SJohn Marino && (vr1.type != VR_RANGE
2604e4b17023SJohn Marino || range_includes_zero_p (vr1.min, vr1.max) != 0))
2605e4b17023SJohn Marino {
2606e4b17023SJohn Marino set_value_range_to_varying (vr);
2607e4b17023SJohn Marino return;
2608e4b17023SJohn Marino }
2609e4b17023SJohn Marino
2610e4b17023SJohn Marino /* For divisions, if op0 is VR_RANGE, we can deduce a range
2611e4b17023SJohn Marino even if op1 is VR_VARYING, VR_ANTI_RANGE, symbolic or can
2612e4b17023SJohn Marino include 0. */
2613e4b17023SJohn Marino if (vr0.type == VR_RANGE
2614e4b17023SJohn Marino && (vr1.type != VR_RANGE
2615e4b17023SJohn Marino || range_includes_zero_p (vr1.min, vr1.max) != 0))
2616e4b17023SJohn Marino {
2617e4b17023SJohn Marino tree zero = build_int_cst (TREE_TYPE (vr0.min), 0);
2618e4b17023SJohn Marino int cmp;
2619e4b17023SJohn Marino
2620e4b17023SJohn Marino min = NULL_TREE;
2621e4b17023SJohn Marino max = NULL_TREE;
2622e4b17023SJohn Marino if (TYPE_UNSIGNED (expr_type)
2623e4b17023SJohn Marino || value_range_nonnegative_p (&vr1))
2624e4b17023SJohn Marino {
2625e4b17023SJohn Marino /* For unsigned division or when divisor is known
2626e4b17023SJohn Marino to be non-negative, the range has to cover
2627e4b17023SJohn Marino all numbers from 0 to max for positive max
2628e4b17023SJohn Marino and all numbers from min to 0 for negative min. */
2629e4b17023SJohn Marino cmp = compare_values (vr0.max, zero);
2630e4b17023SJohn Marino if (cmp == -1)
2631e4b17023SJohn Marino max = zero;
2632e4b17023SJohn Marino else if (cmp == 0 || cmp == 1)
2633e4b17023SJohn Marino max = vr0.max;
2634e4b17023SJohn Marino else
2635e4b17023SJohn Marino type = VR_VARYING;
2636e4b17023SJohn Marino cmp = compare_values (vr0.min, zero);
2637e4b17023SJohn Marino if (cmp == 1)
2638e4b17023SJohn Marino min = zero;
2639e4b17023SJohn Marino else if (cmp == 0 || cmp == -1)
2640e4b17023SJohn Marino min = vr0.min;
2641e4b17023SJohn Marino else
2642e4b17023SJohn Marino type = VR_VARYING;
2643e4b17023SJohn Marino }
2644e4b17023SJohn Marino else
2645e4b17023SJohn Marino {
2646e4b17023SJohn Marino /* Otherwise the range is -max .. max or min .. -min
2647e4b17023SJohn Marino depending on which bound is bigger in absolute value,
2648e4b17023SJohn Marino as the division can change the sign. */
2649e4b17023SJohn Marino abs_extent_range (vr, vr0.min, vr0.max);
2650e4b17023SJohn Marino return;
2651e4b17023SJohn Marino }
2652e4b17023SJohn Marino if (type == VR_VARYING)
2653e4b17023SJohn Marino {
2654e4b17023SJohn Marino set_value_range_to_varying (vr);
2655e4b17023SJohn Marino return;
2656e4b17023SJohn Marino }
2657e4b17023SJohn Marino }
2658e4b17023SJohn Marino else
2659e4b17023SJohn Marino {
2660e4b17023SJohn Marino extract_range_from_multiplicative_op_1 (vr, code, &vr0, &vr1);
2661e4b17023SJohn Marino return;
2662e4b17023SJohn Marino }
2663e4b17023SJohn Marino }
2664e4b17023SJohn Marino else if (code == TRUNC_MOD_EXPR)
2665e4b17023SJohn Marino {
2666e4b17023SJohn Marino if (vr1.type != VR_RANGE
2667e4b17023SJohn Marino || range_includes_zero_p (vr1.min, vr1.max) != 0
2668e4b17023SJohn Marino || vrp_val_is_min (vr1.min))
2669e4b17023SJohn Marino {
2670e4b17023SJohn Marino set_value_range_to_varying (vr);
2671e4b17023SJohn Marino return;
2672e4b17023SJohn Marino }
2673e4b17023SJohn Marino type = VR_RANGE;
2674e4b17023SJohn Marino /* Compute MAX <|vr1.min|, |vr1.max|> - 1. */
2675e4b17023SJohn Marino max = fold_unary_to_constant (ABS_EXPR, expr_type, vr1.min);
2676e4b17023SJohn Marino if (tree_int_cst_lt (max, vr1.max))
2677e4b17023SJohn Marino max = vr1.max;
2678e4b17023SJohn Marino max = int_const_binop (MINUS_EXPR, max, integer_one_node);
2679e4b17023SJohn Marino /* If the dividend is non-negative the modulus will be
2680e4b17023SJohn Marino non-negative as well. */
2681e4b17023SJohn Marino if (TYPE_UNSIGNED (expr_type)
2682e4b17023SJohn Marino || value_range_nonnegative_p (&vr0))
2683e4b17023SJohn Marino min = build_int_cst (TREE_TYPE (max), 0);
2684e4b17023SJohn Marino else
2685e4b17023SJohn Marino min = fold_unary_to_constant (NEGATE_EXPR, expr_type, max);
2686e4b17023SJohn Marino }
2687e4b17023SJohn Marino else if (code == MINUS_EXPR)
2688e4b17023SJohn Marino {
2689e4b17023SJohn Marino /* If we have a MINUS_EXPR with two VR_ANTI_RANGEs, drop to
2690e4b17023SJohn Marino VR_VARYING. It would take more effort to compute a precise
2691e4b17023SJohn Marino range for such a case. For example, if we have op0 == 1 and
2692e4b17023SJohn Marino op1 == 1 with their ranges both being ~[0,0], we would have
2693e4b17023SJohn Marino op0 - op1 == 0, so we cannot claim that the difference is in
2694e4b17023SJohn Marino ~[0,0]. Note that we are guaranteed to have
2695e4b17023SJohn Marino vr0.type == vr1.type at this point. */
2696e4b17023SJohn Marino if (vr0.type == VR_ANTI_RANGE)
2697e4b17023SJohn Marino {
2698e4b17023SJohn Marino set_value_range_to_varying (vr);
2699e4b17023SJohn Marino return;
2700e4b17023SJohn Marino }
2701e4b17023SJohn Marino
2702e4b17023SJohn Marino /* For MINUS_EXPR, apply the operation to the opposite ends of
2703e4b17023SJohn Marino each range. */
2704e4b17023SJohn Marino min = vrp_int_const_binop (code, vr0.min, vr1.max);
2705e4b17023SJohn Marino max = vrp_int_const_binop (code, vr0.max, vr1.min);
2706e4b17023SJohn Marino }
2707e4b17023SJohn Marino else if (code == BIT_AND_EXPR || code == BIT_IOR_EXPR || code == BIT_XOR_EXPR)
2708e4b17023SJohn Marino {
2709e4b17023SJohn Marino bool int_cst_range0, int_cst_range1;
2710e4b17023SJohn Marino double_int may_be_nonzero0, may_be_nonzero1;
2711e4b17023SJohn Marino double_int must_be_nonzero0, must_be_nonzero1;
2712e4b17023SJohn Marino
2713e4b17023SJohn Marino int_cst_range0 = zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0,
2714e4b17023SJohn Marino &must_be_nonzero0);
2715e4b17023SJohn Marino int_cst_range1 = zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1,
2716e4b17023SJohn Marino &must_be_nonzero1);
2717e4b17023SJohn Marino
2718e4b17023SJohn Marino type = VR_RANGE;
2719e4b17023SJohn Marino if (code == BIT_AND_EXPR)
2720e4b17023SJohn Marino {
2721e4b17023SJohn Marino double_int dmax;
2722e4b17023SJohn Marino min = double_int_to_tree (expr_type,
2723e4b17023SJohn Marino double_int_and (must_be_nonzero0,
2724e4b17023SJohn Marino must_be_nonzero1));
2725e4b17023SJohn Marino dmax = double_int_and (may_be_nonzero0, may_be_nonzero1);
2726e4b17023SJohn Marino /* If both input ranges contain only negative values we can
2727e4b17023SJohn Marino truncate the result range maximum to the minimum of the
2728e4b17023SJohn Marino input range maxima. */
2729e4b17023SJohn Marino if (int_cst_range0 && int_cst_range1
2730e4b17023SJohn Marino && tree_int_cst_sgn (vr0.max) < 0
2731e4b17023SJohn Marino && tree_int_cst_sgn (vr1.max) < 0)
2732e4b17023SJohn Marino {
2733e4b17023SJohn Marino dmax = double_int_min (dmax, tree_to_double_int (vr0.max),
2734e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2735e4b17023SJohn Marino dmax = double_int_min (dmax, tree_to_double_int (vr1.max),
2736e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2737e4b17023SJohn Marino }
2738e4b17023SJohn Marino /* If either input range contains only non-negative values
2739e4b17023SJohn Marino we can truncate the result range maximum to the respective
2740e4b17023SJohn Marino maximum of the input range. */
2741e4b17023SJohn Marino if (int_cst_range0 && tree_int_cst_sgn (vr0.min) >= 0)
2742e4b17023SJohn Marino dmax = double_int_min (dmax, tree_to_double_int (vr0.max),
2743e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2744e4b17023SJohn Marino if (int_cst_range1 && tree_int_cst_sgn (vr1.min) >= 0)
2745e4b17023SJohn Marino dmax = double_int_min (dmax, tree_to_double_int (vr1.max),
2746e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2747e4b17023SJohn Marino max = double_int_to_tree (expr_type, dmax);
2748e4b17023SJohn Marino }
2749e4b17023SJohn Marino else if (code == BIT_IOR_EXPR)
2750e4b17023SJohn Marino {
2751e4b17023SJohn Marino double_int dmin;
2752e4b17023SJohn Marino max = double_int_to_tree (expr_type,
2753e4b17023SJohn Marino double_int_ior (may_be_nonzero0,
2754e4b17023SJohn Marino may_be_nonzero1));
2755e4b17023SJohn Marino dmin = double_int_ior (must_be_nonzero0, must_be_nonzero1);
2756e4b17023SJohn Marino /* If the input ranges contain only positive values we can
2757e4b17023SJohn Marino truncate the minimum of the result range to the maximum
2758e4b17023SJohn Marino of the input range minima. */
2759e4b17023SJohn Marino if (int_cst_range0 && int_cst_range1
2760e4b17023SJohn Marino && tree_int_cst_sgn (vr0.min) >= 0
2761e4b17023SJohn Marino && tree_int_cst_sgn (vr1.min) >= 0)
2762e4b17023SJohn Marino {
2763e4b17023SJohn Marino dmin = double_int_max (dmin, tree_to_double_int (vr0.min),
2764e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2765e4b17023SJohn Marino dmin = double_int_max (dmin, tree_to_double_int (vr1.min),
2766e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2767e4b17023SJohn Marino }
2768e4b17023SJohn Marino /* If either input range contains only negative values
2769e4b17023SJohn Marino we can truncate the minimum of the result range to the
2770e4b17023SJohn Marino respective minimum range. */
2771e4b17023SJohn Marino if (int_cst_range0 && tree_int_cst_sgn (vr0.max) < 0)
2772e4b17023SJohn Marino dmin = double_int_max (dmin, tree_to_double_int (vr0.min),
2773e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2774e4b17023SJohn Marino if (int_cst_range1 && tree_int_cst_sgn (vr1.max) < 0)
2775e4b17023SJohn Marino dmin = double_int_max (dmin, tree_to_double_int (vr1.min),
2776e4b17023SJohn Marino TYPE_UNSIGNED (expr_type));
2777e4b17023SJohn Marino min = double_int_to_tree (expr_type, dmin);
2778e4b17023SJohn Marino }
2779e4b17023SJohn Marino else if (code == BIT_XOR_EXPR)
2780e4b17023SJohn Marino {
2781e4b17023SJohn Marino double_int result_zero_bits, result_one_bits;
2782e4b17023SJohn Marino result_zero_bits
2783e4b17023SJohn Marino = double_int_ior (double_int_and (must_be_nonzero0,
2784e4b17023SJohn Marino must_be_nonzero1),
2785e4b17023SJohn Marino double_int_not
2786e4b17023SJohn Marino (double_int_ior (may_be_nonzero0,
2787e4b17023SJohn Marino may_be_nonzero1)));
2788e4b17023SJohn Marino result_one_bits
2789e4b17023SJohn Marino = double_int_ior (double_int_and
2790e4b17023SJohn Marino (must_be_nonzero0,
2791e4b17023SJohn Marino double_int_not (may_be_nonzero1)),
2792e4b17023SJohn Marino double_int_and
2793e4b17023SJohn Marino (must_be_nonzero1,
2794e4b17023SJohn Marino double_int_not (may_be_nonzero0)));
2795e4b17023SJohn Marino max = double_int_to_tree (expr_type,
2796e4b17023SJohn Marino double_int_not (result_zero_bits));
2797e4b17023SJohn Marino min = double_int_to_tree (expr_type, result_one_bits);
2798e4b17023SJohn Marino /* If the range has all positive or all negative values the
2799e4b17023SJohn Marino result is better than VARYING. */
2800e4b17023SJohn Marino if (tree_int_cst_sgn (min) < 0
2801e4b17023SJohn Marino || tree_int_cst_sgn (max) >= 0)
2802e4b17023SJohn Marino ;
2803e4b17023SJohn Marino else
2804e4b17023SJohn Marino max = min = NULL_TREE;
2805e4b17023SJohn Marino }
2806e4b17023SJohn Marino }
2807e4b17023SJohn Marino else
2808e4b17023SJohn Marino gcc_unreachable ();
2809e4b17023SJohn Marino
2810e4b17023SJohn Marino /* If either MIN or MAX overflowed, then set the resulting range to
2811e4b17023SJohn Marino VARYING. But we do accept an overflow infinity
2812e4b17023SJohn Marino representation. */
2813e4b17023SJohn Marino if (min == NULL_TREE
2814e4b17023SJohn Marino || !is_gimple_min_invariant (min)
2815e4b17023SJohn Marino || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
2816e4b17023SJohn Marino || max == NULL_TREE
2817e4b17023SJohn Marino || !is_gimple_min_invariant (max)
2818e4b17023SJohn Marino || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
2819e4b17023SJohn Marino {
2820e4b17023SJohn Marino set_value_range_to_varying (vr);
2821e4b17023SJohn Marino return;
2822e4b17023SJohn Marino }
2823e4b17023SJohn Marino
2824e4b17023SJohn Marino /* We punt if:
2825e4b17023SJohn Marino 1) [-INF, +INF]
2826e4b17023SJohn Marino 2) [-INF, +-INF(OVF)]
2827e4b17023SJohn Marino 3) [+-INF(OVF), +INF]
2828e4b17023SJohn Marino 4) [+-INF(OVF), +-INF(OVF)]
2829e4b17023SJohn Marino We learn nothing when we have INF and INF(OVF) on both sides.
2830e4b17023SJohn Marino Note that we do accept [-INF, -INF] and [+INF, +INF] without
2831e4b17023SJohn Marino overflow. */
2832e4b17023SJohn Marino if ((vrp_val_is_min (min) || is_overflow_infinity (min))
2833e4b17023SJohn Marino && (vrp_val_is_max (max) || is_overflow_infinity (max)))
2834e4b17023SJohn Marino {
2835e4b17023SJohn Marino set_value_range_to_varying (vr);
2836e4b17023SJohn Marino return;
2837e4b17023SJohn Marino }
2838e4b17023SJohn Marino
2839e4b17023SJohn Marino cmp = compare_values (min, max);
2840e4b17023SJohn Marino if (cmp == -2 || cmp == 1)
2841e4b17023SJohn Marino {
2842e4b17023SJohn Marino /* If the new range has its limits swapped around (MIN > MAX),
2843e4b17023SJohn Marino then the operation caused one of them to wrap around, mark
2844e4b17023SJohn Marino the new range VARYING. */
2845e4b17023SJohn Marino set_value_range_to_varying (vr);
2846e4b17023SJohn Marino }
2847e4b17023SJohn Marino else
2848e4b17023SJohn Marino set_value_range (vr, type, min, max, NULL);
2849e4b17023SJohn Marino }
2850e4b17023SJohn Marino
2851e4b17023SJohn Marino /* Extract range information from a binary expression OP0 CODE OP1 based on
2852e4b17023SJohn Marino the ranges of each of its operands with resulting type EXPR_TYPE.
2853e4b17023SJohn Marino The resulting range is stored in *VR. */
2854e4b17023SJohn Marino
2855e4b17023SJohn Marino static void
extract_range_from_binary_expr(value_range_t * vr,enum tree_code code,tree expr_type,tree op0,tree op1)2856e4b17023SJohn Marino extract_range_from_binary_expr (value_range_t *vr,
2857e4b17023SJohn Marino enum tree_code code,
2858e4b17023SJohn Marino tree expr_type, tree op0, tree op1)
2859e4b17023SJohn Marino {
2860e4b17023SJohn Marino value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2861e4b17023SJohn Marino value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2862e4b17023SJohn Marino
2863e4b17023SJohn Marino /* Get value ranges for each operand. For constant operands, create
2864e4b17023SJohn Marino a new value range with the operand to simplify processing. */
2865e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME)
2866e4b17023SJohn Marino vr0 = *(get_value_range (op0));
2867e4b17023SJohn Marino else if (is_gimple_min_invariant (op0))
2868e4b17023SJohn Marino set_value_range_to_value (&vr0, op0, NULL);
2869e4b17023SJohn Marino else
2870e4b17023SJohn Marino set_value_range_to_varying (&vr0);
2871e4b17023SJohn Marino
2872e4b17023SJohn Marino if (TREE_CODE (op1) == SSA_NAME)
2873e4b17023SJohn Marino vr1 = *(get_value_range (op1));
2874e4b17023SJohn Marino else if (is_gimple_min_invariant (op1))
2875e4b17023SJohn Marino set_value_range_to_value (&vr1, op1, NULL);
2876e4b17023SJohn Marino else
2877e4b17023SJohn Marino set_value_range_to_varying (&vr1);
2878e4b17023SJohn Marino
2879e4b17023SJohn Marino extract_range_from_binary_expr_1 (vr, code, expr_type, &vr0, &vr1);
2880e4b17023SJohn Marino }
2881e4b17023SJohn Marino
2882e4b17023SJohn Marino /* Extract range information from a unary operation CODE based on
2883e4b17023SJohn Marino the range of its operand *VR0 with type OP0_TYPE with resulting type TYPE.
2884e4b17023SJohn Marino The The resulting range is stored in *VR. */
2885e4b17023SJohn Marino
2886e4b17023SJohn Marino static void
extract_range_from_unary_expr_1(value_range_t * vr,enum tree_code code,tree type,value_range_t * vr0_,tree op0_type)2887e4b17023SJohn Marino extract_range_from_unary_expr_1 (value_range_t *vr,
2888e4b17023SJohn Marino enum tree_code code, tree type,
2889e4b17023SJohn Marino value_range_t *vr0_, tree op0_type)
2890e4b17023SJohn Marino {
2891e4b17023SJohn Marino value_range_t vr0 = *vr0_;
2892e4b17023SJohn Marino
2893e4b17023SJohn Marino /* VRP only operates on integral and pointer types. */
2894e4b17023SJohn Marino if (!(INTEGRAL_TYPE_P (op0_type)
2895e4b17023SJohn Marino || POINTER_TYPE_P (op0_type))
2896e4b17023SJohn Marino || !(INTEGRAL_TYPE_P (type)
2897e4b17023SJohn Marino || POINTER_TYPE_P (type)))
2898e4b17023SJohn Marino {
2899e4b17023SJohn Marino set_value_range_to_varying (vr);
2900e4b17023SJohn Marino return;
2901e4b17023SJohn Marino }
2902e4b17023SJohn Marino
2903e4b17023SJohn Marino /* If VR0 is UNDEFINED, so is the result. */
2904e4b17023SJohn Marino if (vr0.type == VR_UNDEFINED)
2905e4b17023SJohn Marino {
2906e4b17023SJohn Marino set_value_range_to_undefined (vr);
2907e4b17023SJohn Marino return;
2908e4b17023SJohn Marino }
2909e4b17023SJohn Marino
2910e4b17023SJohn Marino if (CONVERT_EXPR_CODE_P (code))
2911e4b17023SJohn Marino {
2912e4b17023SJohn Marino tree inner_type = op0_type;
2913e4b17023SJohn Marino tree outer_type = type;
2914e4b17023SJohn Marino
2915e4b17023SJohn Marino /* If the expression evaluates to a pointer, we are only interested in
2916e4b17023SJohn Marino determining if it evaluates to NULL [0, 0] or non-NULL (~[0, 0]). */
2917e4b17023SJohn Marino if (POINTER_TYPE_P (type))
2918e4b17023SJohn Marino {
2919e4b17023SJohn Marino if (range_is_nonnull (&vr0))
2920e4b17023SJohn Marino set_value_range_to_nonnull (vr, type);
2921e4b17023SJohn Marino else if (range_is_null (&vr0))
2922e4b17023SJohn Marino set_value_range_to_null (vr, type);
2923e4b17023SJohn Marino else
2924e4b17023SJohn Marino set_value_range_to_varying (vr);
2925e4b17023SJohn Marino return;
2926e4b17023SJohn Marino }
2927e4b17023SJohn Marino
2928e4b17023SJohn Marino /* If VR0 is varying and we increase the type precision, assume
2929e4b17023SJohn Marino a full range for the following transformation. */
2930e4b17023SJohn Marino if (vr0.type == VR_VARYING
2931e4b17023SJohn Marino && INTEGRAL_TYPE_P (inner_type)
2932e4b17023SJohn Marino && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
2933e4b17023SJohn Marino {
2934e4b17023SJohn Marino vr0.type = VR_RANGE;
2935e4b17023SJohn Marino vr0.min = TYPE_MIN_VALUE (inner_type);
2936e4b17023SJohn Marino vr0.max = TYPE_MAX_VALUE (inner_type);
2937e4b17023SJohn Marino }
2938e4b17023SJohn Marino
2939e4b17023SJohn Marino /* If VR0 is a constant range or anti-range and the conversion is
2940e4b17023SJohn Marino not truncating we can convert the min and max values and
2941e4b17023SJohn Marino canonicalize the resulting range. Otherwise we can do the
2942e4b17023SJohn Marino conversion if the size of the range is less than what the
2943e4b17023SJohn Marino precision of the target type can represent and the range is
2944e4b17023SJohn Marino not an anti-range. */
2945e4b17023SJohn Marino if ((vr0.type == VR_RANGE
2946e4b17023SJohn Marino || vr0.type == VR_ANTI_RANGE)
2947e4b17023SJohn Marino && TREE_CODE (vr0.min) == INTEGER_CST
2948e4b17023SJohn Marino && TREE_CODE (vr0.max) == INTEGER_CST
2949e4b17023SJohn Marino && (!is_overflow_infinity (vr0.min)
2950e4b17023SJohn Marino || (vr0.type == VR_RANGE
2951e4b17023SJohn Marino && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
2952e4b17023SJohn Marino && needs_overflow_infinity (outer_type)
2953e4b17023SJohn Marino && supports_overflow_infinity (outer_type)))
2954e4b17023SJohn Marino && (!is_overflow_infinity (vr0.max)
2955e4b17023SJohn Marino || (vr0.type == VR_RANGE
2956e4b17023SJohn Marino && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)
2957e4b17023SJohn Marino && needs_overflow_infinity (outer_type)
2958e4b17023SJohn Marino && supports_overflow_infinity (outer_type)))
2959e4b17023SJohn Marino && (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
2960e4b17023SJohn Marino || (vr0.type == VR_RANGE
2961e4b17023SJohn Marino && integer_zerop (int_const_binop (RSHIFT_EXPR,
2962e4b17023SJohn Marino int_const_binop (MINUS_EXPR, vr0.max, vr0.min),
2963e4b17023SJohn Marino size_int (TYPE_PRECISION (outer_type)))))))
2964e4b17023SJohn Marino {
2965e4b17023SJohn Marino tree new_min, new_max;
2966e4b17023SJohn Marino if (is_overflow_infinity (vr0.min))
2967e4b17023SJohn Marino new_min = negative_overflow_infinity (outer_type);
2968e4b17023SJohn Marino else
2969e4b17023SJohn Marino new_min = force_fit_type_double (outer_type,
2970e4b17023SJohn Marino tree_to_double_int (vr0.min),
2971e4b17023SJohn Marino 0, false);
2972e4b17023SJohn Marino if (is_overflow_infinity (vr0.max))
2973e4b17023SJohn Marino new_max = positive_overflow_infinity (outer_type);
2974e4b17023SJohn Marino else
2975e4b17023SJohn Marino new_max = force_fit_type_double (outer_type,
2976e4b17023SJohn Marino tree_to_double_int (vr0.max),
2977e4b17023SJohn Marino 0, false);
2978e4b17023SJohn Marino set_and_canonicalize_value_range (vr, vr0.type,
2979e4b17023SJohn Marino new_min, new_max, NULL);
2980e4b17023SJohn Marino return;
2981e4b17023SJohn Marino }
2982e4b17023SJohn Marino
2983e4b17023SJohn Marino set_value_range_to_varying (vr);
2984e4b17023SJohn Marino return;
2985e4b17023SJohn Marino }
2986e4b17023SJohn Marino else if (code == NEGATE_EXPR)
2987e4b17023SJohn Marino {
2988e4b17023SJohn Marino /* -X is simply 0 - X, so re-use existing code that also handles
2989e4b17023SJohn Marino anti-ranges fine. */
2990e4b17023SJohn Marino value_range_t zero = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
2991e4b17023SJohn Marino set_value_range_to_value (&zero, build_int_cst (type, 0), NULL);
2992e4b17023SJohn Marino extract_range_from_binary_expr_1 (vr, MINUS_EXPR, type, &zero, &vr0);
2993e4b17023SJohn Marino return;
2994e4b17023SJohn Marino }
2995e4b17023SJohn Marino else if (code == ABS_EXPR)
2996e4b17023SJohn Marino {
2997e4b17023SJohn Marino tree min, max;
2998e4b17023SJohn Marino int cmp;
2999e4b17023SJohn Marino
3000e4b17023SJohn Marino /* Pass through vr0 in the easy cases. */
3001e4b17023SJohn Marino if (TYPE_UNSIGNED (type)
3002e4b17023SJohn Marino || value_range_nonnegative_p (&vr0))
3003e4b17023SJohn Marino {
3004e4b17023SJohn Marino copy_value_range (vr, &vr0);
3005e4b17023SJohn Marino return;
3006e4b17023SJohn Marino }
3007e4b17023SJohn Marino
3008e4b17023SJohn Marino /* For the remaining varying or symbolic ranges we can't do anything
3009e4b17023SJohn Marino useful. */
3010e4b17023SJohn Marino if (vr0.type == VR_VARYING
3011e4b17023SJohn Marino || symbolic_range_p (&vr0))
3012e4b17023SJohn Marino {
3013e4b17023SJohn Marino set_value_range_to_varying (vr);
3014e4b17023SJohn Marino return;
3015e4b17023SJohn Marino }
3016e4b17023SJohn Marino
3017e4b17023SJohn Marino /* -TYPE_MIN_VALUE = TYPE_MIN_VALUE with flag_wrapv so we can't get a
3018e4b17023SJohn Marino useful range. */
3019e4b17023SJohn Marino if (!TYPE_OVERFLOW_UNDEFINED (type)
3020e4b17023SJohn Marino && ((vr0.type == VR_RANGE
3021e4b17023SJohn Marino && vrp_val_is_min (vr0.min))
3022e4b17023SJohn Marino || (vr0.type == VR_ANTI_RANGE
3023e4b17023SJohn Marino && !vrp_val_is_min (vr0.min))))
3024e4b17023SJohn Marino {
3025e4b17023SJohn Marino set_value_range_to_varying (vr);
3026e4b17023SJohn Marino return;
3027e4b17023SJohn Marino }
3028e4b17023SJohn Marino
3029e4b17023SJohn Marino /* ABS_EXPR may flip the range around, if the original range
3030e4b17023SJohn Marino included negative values. */
3031e4b17023SJohn Marino if (is_overflow_infinity (vr0.min))
3032e4b17023SJohn Marino min = positive_overflow_infinity (type);
3033e4b17023SJohn Marino else if (!vrp_val_is_min (vr0.min))
3034e4b17023SJohn Marino min = fold_unary_to_constant (code, type, vr0.min);
3035e4b17023SJohn Marino else if (!needs_overflow_infinity (type))
3036e4b17023SJohn Marino min = TYPE_MAX_VALUE (type);
3037e4b17023SJohn Marino else if (supports_overflow_infinity (type))
3038e4b17023SJohn Marino min = positive_overflow_infinity (type);
3039e4b17023SJohn Marino else
3040e4b17023SJohn Marino {
3041e4b17023SJohn Marino set_value_range_to_varying (vr);
3042e4b17023SJohn Marino return;
3043e4b17023SJohn Marino }
3044e4b17023SJohn Marino
3045e4b17023SJohn Marino if (is_overflow_infinity (vr0.max))
3046e4b17023SJohn Marino max = positive_overflow_infinity (type);
3047e4b17023SJohn Marino else if (!vrp_val_is_min (vr0.max))
3048e4b17023SJohn Marino max = fold_unary_to_constant (code, type, vr0.max);
3049e4b17023SJohn Marino else if (!needs_overflow_infinity (type))
3050e4b17023SJohn Marino max = TYPE_MAX_VALUE (type);
3051e4b17023SJohn Marino else if (supports_overflow_infinity (type)
3052e4b17023SJohn Marino /* We shouldn't generate [+INF, +INF] as set_value_range
3053e4b17023SJohn Marino doesn't like this and ICEs. */
3054e4b17023SJohn Marino && !is_positive_overflow_infinity (min))
3055e4b17023SJohn Marino max = positive_overflow_infinity (type);
3056e4b17023SJohn Marino else
3057e4b17023SJohn Marino {
3058e4b17023SJohn Marino set_value_range_to_varying (vr);
3059e4b17023SJohn Marino return;
3060e4b17023SJohn Marino }
3061e4b17023SJohn Marino
3062e4b17023SJohn Marino cmp = compare_values (min, max);
3063e4b17023SJohn Marino
3064e4b17023SJohn Marino /* If a VR_ANTI_RANGEs contains zero, then we have
3065e4b17023SJohn Marino ~[-INF, min(MIN, MAX)]. */
3066e4b17023SJohn Marino if (vr0.type == VR_ANTI_RANGE)
3067e4b17023SJohn Marino {
3068e4b17023SJohn Marino if (range_includes_zero_p (vr0.min, vr0.max) == 1)
3069e4b17023SJohn Marino {
3070e4b17023SJohn Marino /* Take the lower of the two values. */
3071e4b17023SJohn Marino if (cmp != 1)
3072e4b17023SJohn Marino max = min;
3073e4b17023SJohn Marino
3074e4b17023SJohn Marino /* Create ~[-INF, min (abs(MIN), abs(MAX))]
3075e4b17023SJohn Marino or ~[-INF + 1, min (abs(MIN), abs(MAX))] when
3076e4b17023SJohn Marino flag_wrapv is set and the original anti-range doesn't include
3077e4b17023SJohn Marino TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE. */
3078e4b17023SJohn Marino if (TYPE_OVERFLOW_WRAPS (type))
3079e4b17023SJohn Marino {
3080e4b17023SJohn Marino tree type_min_value = TYPE_MIN_VALUE (type);
3081e4b17023SJohn Marino
3082e4b17023SJohn Marino min = (vr0.min != type_min_value
3083e4b17023SJohn Marino ? int_const_binop (PLUS_EXPR, type_min_value,
3084e4b17023SJohn Marino integer_one_node)
3085e4b17023SJohn Marino : type_min_value);
3086e4b17023SJohn Marino }
3087e4b17023SJohn Marino else
3088e4b17023SJohn Marino {
3089e4b17023SJohn Marino if (overflow_infinity_range_p (&vr0))
3090e4b17023SJohn Marino min = negative_overflow_infinity (type);
3091e4b17023SJohn Marino else
3092e4b17023SJohn Marino min = TYPE_MIN_VALUE (type);
3093e4b17023SJohn Marino }
3094e4b17023SJohn Marino }
3095e4b17023SJohn Marino else
3096e4b17023SJohn Marino {
3097e4b17023SJohn Marino /* All else has failed, so create the range [0, INF], even for
3098e4b17023SJohn Marino flag_wrapv since TYPE_MIN_VALUE is in the original
3099e4b17023SJohn Marino anti-range. */
3100e4b17023SJohn Marino vr0.type = VR_RANGE;
3101e4b17023SJohn Marino min = build_int_cst (type, 0);
3102e4b17023SJohn Marino if (needs_overflow_infinity (type))
3103e4b17023SJohn Marino {
3104e4b17023SJohn Marino if (supports_overflow_infinity (type))
3105e4b17023SJohn Marino max = positive_overflow_infinity (type);
3106e4b17023SJohn Marino else
3107e4b17023SJohn Marino {
3108e4b17023SJohn Marino set_value_range_to_varying (vr);
3109e4b17023SJohn Marino return;
3110e4b17023SJohn Marino }
3111e4b17023SJohn Marino }
3112e4b17023SJohn Marino else
3113e4b17023SJohn Marino max = TYPE_MAX_VALUE (type);
3114e4b17023SJohn Marino }
3115e4b17023SJohn Marino }
3116e4b17023SJohn Marino
3117e4b17023SJohn Marino /* If the range contains zero then we know that the minimum value in the
3118e4b17023SJohn Marino range will be zero. */
3119e4b17023SJohn Marino else if (range_includes_zero_p (vr0.min, vr0.max) == 1)
3120e4b17023SJohn Marino {
3121e4b17023SJohn Marino if (cmp == 1)
3122e4b17023SJohn Marino max = min;
3123e4b17023SJohn Marino min = build_int_cst (type, 0);
3124e4b17023SJohn Marino }
3125e4b17023SJohn Marino else
3126e4b17023SJohn Marino {
3127e4b17023SJohn Marino /* If the range was reversed, swap MIN and MAX. */
3128e4b17023SJohn Marino if (cmp == 1)
3129e4b17023SJohn Marino {
3130e4b17023SJohn Marino tree t = min;
3131e4b17023SJohn Marino min = max;
3132e4b17023SJohn Marino max = t;
3133e4b17023SJohn Marino }
3134e4b17023SJohn Marino }
3135e4b17023SJohn Marino
3136e4b17023SJohn Marino cmp = compare_values (min, max);
3137e4b17023SJohn Marino if (cmp == -2 || cmp == 1)
3138e4b17023SJohn Marino {
3139e4b17023SJohn Marino /* If the new range has its limits swapped around (MIN > MAX),
3140e4b17023SJohn Marino then the operation caused one of them to wrap around, mark
3141e4b17023SJohn Marino the new range VARYING. */
3142e4b17023SJohn Marino set_value_range_to_varying (vr);
3143e4b17023SJohn Marino }
3144e4b17023SJohn Marino else
3145e4b17023SJohn Marino set_value_range (vr, vr0.type, min, max, NULL);
3146e4b17023SJohn Marino return;
3147e4b17023SJohn Marino }
3148e4b17023SJohn Marino else if (code == BIT_NOT_EXPR)
3149e4b17023SJohn Marino {
3150e4b17023SJohn Marino /* ~X is simply -1 - X, so re-use existing code that also handles
3151e4b17023SJohn Marino anti-ranges fine. */
3152e4b17023SJohn Marino value_range_t minusone = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3153e4b17023SJohn Marino set_value_range_to_value (&minusone, build_int_cst (type, -1), NULL);
3154e4b17023SJohn Marino extract_range_from_binary_expr_1 (vr, MINUS_EXPR,
3155e4b17023SJohn Marino type, &minusone, &vr0);
3156e4b17023SJohn Marino return;
3157e4b17023SJohn Marino }
3158e4b17023SJohn Marino else if (code == PAREN_EXPR)
3159e4b17023SJohn Marino {
3160e4b17023SJohn Marino copy_value_range (vr, &vr0);
3161e4b17023SJohn Marino return;
3162e4b17023SJohn Marino }
3163e4b17023SJohn Marino
3164e4b17023SJohn Marino /* For unhandled operations fall back to varying. */
3165e4b17023SJohn Marino set_value_range_to_varying (vr);
3166e4b17023SJohn Marino return;
3167e4b17023SJohn Marino }
3168e4b17023SJohn Marino
3169e4b17023SJohn Marino
3170e4b17023SJohn Marino /* Extract range information from a unary expression CODE OP0 based on
3171e4b17023SJohn Marino the range of its operand with resulting type TYPE.
3172e4b17023SJohn Marino The resulting range is stored in *VR. */
3173e4b17023SJohn Marino
3174e4b17023SJohn Marino static void
extract_range_from_unary_expr(value_range_t * vr,enum tree_code code,tree type,tree op0)3175e4b17023SJohn Marino extract_range_from_unary_expr (value_range_t *vr, enum tree_code code,
3176e4b17023SJohn Marino tree type, tree op0)
3177e4b17023SJohn Marino {
3178e4b17023SJohn Marino value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3179e4b17023SJohn Marino
3180e4b17023SJohn Marino /* Get value ranges for the operand. For constant operands, create
3181e4b17023SJohn Marino a new value range with the operand to simplify processing. */
3182e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME)
3183e4b17023SJohn Marino vr0 = *(get_value_range (op0));
3184e4b17023SJohn Marino else if (is_gimple_min_invariant (op0))
3185e4b17023SJohn Marino set_value_range_to_value (&vr0, op0, NULL);
3186e4b17023SJohn Marino else
3187e4b17023SJohn Marino set_value_range_to_varying (&vr0);
3188e4b17023SJohn Marino
3189e4b17023SJohn Marino extract_range_from_unary_expr_1 (vr, code, type, &vr0, TREE_TYPE (op0));
3190e4b17023SJohn Marino }
3191e4b17023SJohn Marino
3192e4b17023SJohn Marino
3193e4b17023SJohn Marino /* Extract range information from a conditional expression STMT based on
3194e4b17023SJohn Marino the ranges of each of its operands and the expression code. */
3195e4b17023SJohn Marino
3196e4b17023SJohn Marino static void
extract_range_from_cond_expr(value_range_t * vr,gimple stmt)3197e4b17023SJohn Marino extract_range_from_cond_expr (value_range_t *vr, gimple stmt)
3198e4b17023SJohn Marino {
3199e4b17023SJohn Marino tree op0, op1;
3200e4b17023SJohn Marino value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3201e4b17023SJohn Marino value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3202e4b17023SJohn Marino
3203e4b17023SJohn Marino /* Get value ranges for each operand. For constant operands, create
3204e4b17023SJohn Marino a new value range with the operand to simplify processing. */
3205e4b17023SJohn Marino op0 = gimple_assign_rhs2 (stmt);
3206e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME)
3207e4b17023SJohn Marino vr0 = *(get_value_range (op0));
3208e4b17023SJohn Marino else if (is_gimple_min_invariant (op0))
3209e4b17023SJohn Marino set_value_range_to_value (&vr0, op0, NULL);
3210e4b17023SJohn Marino else
3211e4b17023SJohn Marino set_value_range_to_varying (&vr0);
3212e4b17023SJohn Marino
3213e4b17023SJohn Marino op1 = gimple_assign_rhs3 (stmt);
3214e4b17023SJohn Marino if (TREE_CODE (op1) == SSA_NAME)
3215e4b17023SJohn Marino vr1 = *(get_value_range (op1));
3216e4b17023SJohn Marino else if (is_gimple_min_invariant (op1))
3217e4b17023SJohn Marino set_value_range_to_value (&vr1, op1, NULL);
3218e4b17023SJohn Marino else
3219e4b17023SJohn Marino set_value_range_to_varying (&vr1);
3220e4b17023SJohn Marino
3221e4b17023SJohn Marino /* The resulting value range is the union of the operand ranges */
3222e4b17023SJohn Marino copy_value_range (vr, &vr0);
3223e4b17023SJohn Marino vrp_meet (vr, &vr1);
3224e4b17023SJohn Marino }
3225e4b17023SJohn Marino
3226e4b17023SJohn Marino
3227e4b17023SJohn Marino /* Extract range information from a comparison expression EXPR based
3228e4b17023SJohn Marino on the range of its operand and the expression code. */
3229e4b17023SJohn Marino
3230e4b17023SJohn Marino static void
extract_range_from_comparison(value_range_t * vr,enum tree_code code,tree type,tree op0,tree op1)3231e4b17023SJohn Marino extract_range_from_comparison (value_range_t *vr, enum tree_code code,
3232e4b17023SJohn Marino tree type, tree op0, tree op1)
3233e4b17023SJohn Marino {
3234e4b17023SJohn Marino bool sop = false;
3235e4b17023SJohn Marino tree val;
3236e4b17023SJohn Marino
3237e4b17023SJohn Marino val = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, false, &sop,
3238e4b17023SJohn Marino NULL);
3239e4b17023SJohn Marino
3240e4b17023SJohn Marino /* A disadvantage of using a special infinity as an overflow
3241e4b17023SJohn Marino representation is that we lose the ability to record overflow
3242e4b17023SJohn Marino when we don't have an infinity. So we have to ignore a result
3243e4b17023SJohn Marino which relies on overflow. */
3244e4b17023SJohn Marino
3245e4b17023SJohn Marino if (val && !is_overflow_infinity (val) && !sop)
3246e4b17023SJohn Marino {
3247e4b17023SJohn Marino /* Since this expression was found on the RHS of an assignment,
3248e4b17023SJohn Marino its type may be different from _Bool. Convert VAL to EXPR's
3249e4b17023SJohn Marino type. */
3250e4b17023SJohn Marino val = fold_convert (type, val);
3251e4b17023SJohn Marino if (is_gimple_min_invariant (val))
3252e4b17023SJohn Marino set_value_range_to_value (vr, val, vr->equiv);
3253e4b17023SJohn Marino else
3254e4b17023SJohn Marino set_value_range (vr, VR_RANGE, val, val, vr->equiv);
3255e4b17023SJohn Marino }
3256e4b17023SJohn Marino else
3257e4b17023SJohn Marino /* The result of a comparison is always true or false. */
3258e4b17023SJohn Marino set_value_range_to_truthvalue (vr, type);
3259e4b17023SJohn Marino }
3260e4b17023SJohn Marino
3261e4b17023SJohn Marino /* Try to derive a nonnegative or nonzero range out of STMT relying
3262e4b17023SJohn Marino primarily on generic routines in fold in conjunction with range data.
3263e4b17023SJohn Marino Store the result in *VR */
3264e4b17023SJohn Marino
3265e4b17023SJohn Marino static void
extract_range_basic(value_range_t * vr,gimple stmt)3266e4b17023SJohn Marino extract_range_basic (value_range_t *vr, gimple stmt)
3267e4b17023SJohn Marino {
3268e4b17023SJohn Marino bool sop = false;
3269e4b17023SJohn Marino tree type = gimple_expr_type (stmt);
3270e4b17023SJohn Marino
32715ce9237cSJohn Marino /* If the call is __builtin_constant_p and the argument is a
32725ce9237cSJohn Marino function parameter resolve it to false. This avoids bogus
32735ce9237cSJohn Marino array bound warnings.
32745ce9237cSJohn Marino ??? We could do this as early as inlining is finished. */
32755ce9237cSJohn Marino if (gimple_call_builtin_p (stmt, BUILT_IN_CONSTANT_P))
32765ce9237cSJohn Marino {
32775ce9237cSJohn Marino tree arg = gimple_call_arg (stmt, 0);
32785ce9237cSJohn Marino if (TREE_CODE (arg) == SSA_NAME
32795ce9237cSJohn Marino && SSA_NAME_IS_DEFAULT_DEF (arg)
32805ce9237cSJohn Marino && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
32815ce9237cSJohn Marino set_value_range_to_null (vr, type);
32825ce9237cSJohn Marino }
32835ce9237cSJohn Marino else if (INTEGRAL_TYPE_P (type)
3284e4b17023SJohn Marino && gimple_stmt_nonnegative_warnv_p (stmt, &sop))
3285e4b17023SJohn Marino set_value_range_to_nonnegative (vr, type,
3286e4b17023SJohn Marino sop || stmt_overflow_infinity (stmt));
3287e4b17023SJohn Marino else if (vrp_stmt_computes_nonzero (stmt, &sop)
3288e4b17023SJohn Marino && !sop)
3289e4b17023SJohn Marino set_value_range_to_nonnull (vr, type);
3290e4b17023SJohn Marino else
3291e4b17023SJohn Marino set_value_range_to_varying (vr);
3292e4b17023SJohn Marino }
3293e4b17023SJohn Marino
3294e4b17023SJohn Marino
3295e4b17023SJohn Marino /* Try to compute a useful range out of assignment STMT and store it
3296e4b17023SJohn Marino in *VR. */
3297e4b17023SJohn Marino
3298e4b17023SJohn Marino static void
extract_range_from_assignment(value_range_t * vr,gimple stmt)3299e4b17023SJohn Marino extract_range_from_assignment (value_range_t *vr, gimple stmt)
3300e4b17023SJohn Marino {
3301e4b17023SJohn Marino enum tree_code code = gimple_assign_rhs_code (stmt);
3302e4b17023SJohn Marino
3303e4b17023SJohn Marino if (code == ASSERT_EXPR)
3304e4b17023SJohn Marino extract_range_from_assert (vr, gimple_assign_rhs1 (stmt));
3305e4b17023SJohn Marino else if (code == SSA_NAME)
3306e4b17023SJohn Marino extract_range_from_ssa_name (vr, gimple_assign_rhs1 (stmt));
3307e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_binary)
3308e4b17023SJohn Marino extract_range_from_binary_expr (vr, gimple_assign_rhs_code (stmt),
3309e4b17023SJohn Marino gimple_expr_type (stmt),
3310e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
3311e4b17023SJohn Marino gimple_assign_rhs2 (stmt));
3312e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_unary)
3313e4b17023SJohn Marino extract_range_from_unary_expr (vr, gimple_assign_rhs_code (stmt),
3314e4b17023SJohn Marino gimple_expr_type (stmt),
3315e4b17023SJohn Marino gimple_assign_rhs1 (stmt));
3316e4b17023SJohn Marino else if (code == COND_EXPR)
3317e4b17023SJohn Marino extract_range_from_cond_expr (vr, stmt);
3318e4b17023SJohn Marino else if (TREE_CODE_CLASS (code) == tcc_comparison)
3319e4b17023SJohn Marino extract_range_from_comparison (vr, gimple_assign_rhs_code (stmt),
3320e4b17023SJohn Marino gimple_expr_type (stmt),
3321e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
3322e4b17023SJohn Marino gimple_assign_rhs2 (stmt));
3323e4b17023SJohn Marino else if (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
3324e4b17023SJohn Marino && is_gimple_min_invariant (gimple_assign_rhs1 (stmt)))
3325e4b17023SJohn Marino set_value_range_to_value (vr, gimple_assign_rhs1 (stmt), NULL);
3326e4b17023SJohn Marino else
3327e4b17023SJohn Marino set_value_range_to_varying (vr);
3328e4b17023SJohn Marino
3329e4b17023SJohn Marino if (vr->type == VR_VARYING)
3330e4b17023SJohn Marino extract_range_basic (vr, stmt);
3331e4b17023SJohn Marino }
3332e4b17023SJohn Marino
3333e4b17023SJohn Marino /* Given a range VR, a LOOP and a variable VAR, determine whether it
3334e4b17023SJohn Marino would be profitable to adjust VR using scalar evolution information
3335e4b17023SJohn Marino for VAR. If so, update VR with the new limits. */
3336e4b17023SJohn Marino
3337e4b17023SJohn Marino static void
adjust_range_with_scev(value_range_t * vr,struct loop * loop,gimple stmt,tree var)3338e4b17023SJohn Marino adjust_range_with_scev (value_range_t *vr, struct loop *loop,
3339e4b17023SJohn Marino gimple stmt, tree var)
3340e4b17023SJohn Marino {
3341e4b17023SJohn Marino tree init, step, chrec, tmin, tmax, min, max, type, tem;
3342e4b17023SJohn Marino enum ev_direction dir;
3343e4b17023SJohn Marino
3344e4b17023SJohn Marino /* TODO. Don't adjust anti-ranges. An anti-range may provide
3345e4b17023SJohn Marino better opportunities than a regular range, but I'm not sure. */
3346e4b17023SJohn Marino if (vr->type == VR_ANTI_RANGE)
3347e4b17023SJohn Marino return;
3348e4b17023SJohn Marino
3349e4b17023SJohn Marino chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
3350e4b17023SJohn Marino
3351e4b17023SJohn Marino /* Like in PR19590, scev can return a constant function. */
3352e4b17023SJohn Marino if (is_gimple_min_invariant (chrec))
3353e4b17023SJohn Marino {
3354e4b17023SJohn Marino set_value_range_to_value (vr, chrec, vr->equiv);
3355e4b17023SJohn Marino return;
3356e4b17023SJohn Marino }
3357e4b17023SJohn Marino
3358e4b17023SJohn Marino if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
3359e4b17023SJohn Marino return;
3360e4b17023SJohn Marino
3361e4b17023SJohn Marino init = initial_condition_in_loop_num (chrec, loop->num);
3362e4b17023SJohn Marino tem = op_with_constant_singleton_value_range (init);
3363e4b17023SJohn Marino if (tem)
3364e4b17023SJohn Marino init = tem;
3365e4b17023SJohn Marino step = evolution_part_in_loop_num (chrec, loop->num);
3366e4b17023SJohn Marino tem = op_with_constant_singleton_value_range (step);
3367e4b17023SJohn Marino if (tem)
3368e4b17023SJohn Marino step = tem;
3369e4b17023SJohn Marino
3370e4b17023SJohn Marino /* If STEP is symbolic, we can't know whether INIT will be the
3371e4b17023SJohn Marino minimum or maximum value in the range. Also, unless INIT is
3372e4b17023SJohn Marino a simple expression, compare_values and possibly other functions
3373e4b17023SJohn Marino in tree-vrp won't be able to handle it. */
3374e4b17023SJohn Marino if (step == NULL_TREE
3375e4b17023SJohn Marino || !is_gimple_min_invariant (step)
3376e4b17023SJohn Marino || !valid_value_p (init))
3377e4b17023SJohn Marino return;
3378e4b17023SJohn Marino
3379e4b17023SJohn Marino dir = scev_direction (chrec);
3380e4b17023SJohn Marino if (/* Do not adjust ranges if we do not know whether the iv increases
3381e4b17023SJohn Marino or decreases, ... */
3382e4b17023SJohn Marino dir == EV_DIR_UNKNOWN
3383e4b17023SJohn Marino /* ... or if it may wrap. */
3384e4b17023SJohn Marino || scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
3385e4b17023SJohn Marino true))
3386e4b17023SJohn Marino return;
3387e4b17023SJohn Marino
3388e4b17023SJohn Marino /* We use TYPE_MIN_VALUE and TYPE_MAX_VALUE here instead of
3389e4b17023SJohn Marino negative_overflow_infinity and positive_overflow_infinity,
3390e4b17023SJohn Marino because we have concluded that the loop probably does not
3391e4b17023SJohn Marino wrap. */
3392e4b17023SJohn Marino
3393e4b17023SJohn Marino type = TREE_TYPE (var);
3394e4b17023SJohn Marino if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
3395e4b17023SJohn Marino tmin = lower_bound_in_type (type, type);
3396e4b17023SJohn Marino else
3397e4b17023SJohn Marino tmin = TYPE_MIN_VALUE (type);
3398e4b17023SJohn Marino if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
3399e4b17023SJohn Marino tmax = upper_bound_in_type (type, type);
3400e4b17023SJohn Marino else
3401e4b17023SJohn Marino tmax = TYPE_MAX_VALUE (type);
3402e4b17023SJohn Marino
3403e4b17023SJohn Marino /* Try to use estimated number of iterations for the loop to constrain the
3404e4b17023SJohn Marino final value in the evolution. */
3405e4b17023SJohn Marino if (TREE_CODE (step) == INTEGER_CST
3406e4b17023SJohn Marino && is_gimple_val (init)
3407e4b17023SJohn Marino && (TREE_CODE (init) != SSA_NAME
3408e4b17023SJohn Marino || get_value_range (init)->type == VR_RANGE))
3409e4b17023SJohn Marino {
3410e4b17023SJohn Marino double_int nit;
3411e4b17023SJohn Marino
3412e4b17023SJohn Marino if (estimated_loop_iterations (loop, true, &nit))
3413e4b17023SJohn Marino {
3414e4b17023SJohn Marino value_range_t maxvr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
3415e4b17023SJohn Marino double_int dtmp;
3416e4b17023SJohn Marino bool unsigned_p = TYPE_UNSIGNED (TREE_TYPE (step));
3417e4b17023SJohn Marino int overflow = 0;
3418e4b17023SJohn Marino
3419e4b17023SJohn Marino dtmp = double_int_mul_with_sign (tree_to_double_int (step), nit,
3420e4b17023SJohn Marino unsigned_p, &overflow);
3421e4b17023SJohn Marino /* If the multiplication overflowed we can't do a meaningful
3422e4b17023SJohn Marino adjustment. Likewise if the result doesn't fit in the type
3423e4b17023SJohn Marino of the induction variable. For a signed type we have to
3424e4b17023SJohn Marino check whether the result has the expected signedness which
3425e4b17023SJohn Marino is that of the step as number of iterations is unsigned. */
3426e4b17023SJohn Marino if (!overflow
3427e4b17023SJohn Marino && double_int_fits_to_tree_p (TREE_TYPE (init), dtmp)
3428e4b17023SJohn Marino && (unsigned_p
3429e4b17023SJohn Marino || ((dtmp.high ^ TREE_INT_CST_HIGH (step)) >= 0)))
3430e4b17023SJohn Marino {
3431e4b17023SJohn Marino tem = double_int_to_tree (TREE_TYPE (init), dtmp);
3432e4b17023SJohn Marino extract_range_from_binary_expr (&maxvr, PLUS_EXPR,
3433e4b17023SJohn Marino TREE_TYPE (init), init, tem);
3434e4b17023SJohn Marino /* Likewise if the addition did. */
3435e4b17023SJohn Marino if (maxvr.type == VR_RANGE)
3436e4b17023SJohn Marino {
3437e4b17023SJohn Marino tmin = maxvr.min;
3438e4b17023SJohn Marino tmax = maxvr.max;
3439e4b17023SJohn Marino }
3440e4b17023SJohn Marino }
3441e4b17023SJohn Marino }
3442e4b17023SJohn Marino }
3443e4b17023SJohn Marino
3444e4b17023SJohn Marino if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
3445e4b17023SJohn Marino {
3446e4b17023SJohn Marino min = tmin;
3447e4b17023SJohn Marino max = tmax;
3448e4b17023SJohn Marino
3449e4b17023SJohn Marino /* For VARYING or UNDEFINED ranges, just about anything we get
3450e4b17023SJohn Marino from scalar evolutions should be better. */
3451e4b17023SJohn Marino
3452e4b17023SJohn Marino if (dir == EV_DIR_DECREASES)
3453e4b17023SJohn Marino max = init;
3454e4b17023SJohn Marino else
3455e4b17023SJohn Marino min = init;
3456e4b17023SJohn Marino
3457e4b17023SJohn Marino /* If we would create an invalid range, then just assume we
3458e4b17023SJohn Marino know absolutely nothing. This may be over-conservative,
3459e4b17023SJohn Marino but it's clearly safe, and should happen only in unreachable
3460e4b17023SJohn Marino parts of code, or for invalid programs. */
3461e4b17023SJohn Marino if (compare_values (min, max) == 1)
3462e4b17023SJohn Marino return;
3463e4b17023SJohn Marino
3464e4b17023SJohn Marino set_value_range (vr, VR_RANGE, min, max, vr->equiv);
3465e4b17023SJohn Marino }
3466e4b17023SJohn Marino else if (vr->type == VR_RANGE)
3467e4b17023SJohn Marino {
3468e4b17023SJohn Marino min = vr->min;
3469e4b17023SJohn Marino max = vr->max;
3470e4b17023SJohn Marino
3471e4b17023SJohn Marino if (dir == EV_DIR_DECREASES)
3472e4b17023SJohn Marino {
3473e4b17023SJohn Marino /* INIT is the maximum value. If INIT is lower than VR->MAX
3474e4b17023SJohn Marino but no smaller than VR->MIN, set VR->MAX to INIT. */
3475e4b17023SJohn Marino if (compare_values (init, max) == -1)
3476e4b17023SJohn Marino max = init;
3477e4b17023SJohn Marino
3478e4b17023SJohn Marino /* According to the loop information, the variable does not
3479e4b17023SJohn Marino overflow. If we think it does, probably because of an
3480e4b17023SJohn Marino overflow due to arithmetic on a different INF value,
3481e4b17023SJohn Marino reset now. */
3482e4b17023SJohn Marino if (is_negative_overflow_infinity (min)
3483e4b17023SJohn Marino || compare_values (min, tmin) == -1)
3484e4b17023SJohn Marino min = tmin;
3485e4b17023SJohn Marino
3486e4b17023SJohn Marino }
3487e4b17023SJohn Marino else
3488e4b17023SJohn Marino {
3489e4b17023SJohn Marino /* If INIT is bigger than VR->MIN, set VR->MIN to INIT. */
3490e4b17023SJohn Marino if (compare_values (init, min) == 1)
3491e4b17023SJohn Marino min = init;
3492e4b17023SJohn Marino
3493e4b17023SJohn Marino if (is_positive_overflow_infinity (max)
3494e4b17023SJohn Marino || compare_values (tmax, max) == -1)
3495e4b17023SJohn Marino max = tmax;
3496e4b17023SJohn Marino }
3497e4b17023SJohn Marino
3498e4b17023SJohn Marino /* If we just created an invalid range with the minimum
3499e4b17023SJohn Marino greater than the maximum, we fail conservatively.
3500e4b17023SJohn Marino This should happen only in unreachable
3501e4b17023SJohn Marino parts of code, or for invalid programs. */
3502e4b17023SJohn Marino if (compare_values (min, max) == 1)
3503e4b17023SJohn Marino return;
3504e4b17023SJohn Marino
3505e4b17023SJohn Marino set_value_range (vr, VR_RANGE, min, max, vr->equiv);
3506e4b17023SJohn Marino }
3507e4b17023SJohn Marino }
3508e4b17023SJohn Marino
3509e4b17023SJohn Marino /* Return true if VAR may overflow at STMT. This checks any available
3510e4b17023SJohn Marino loop information to see if we can determine that VAR does not
3511e4b17023SJohn Marino overflow. */
3512e4b17023SJohn Marino
3513e4b17023SJohn Marino static bool
vrp_var_may_overflow(tree var,gimple stmt)3514e4b17023SJohn Marino vrp_var_may_overflow (tree var, gimple stmt)
3515e4b17023SJohn Marino {
3516e4b17023SJohn Marino struct loop *l;
3517e4b17023SJohn Marino tree chrec, init, step;
3518e4b17023SJohn Marino
3519e4b17023SJohn Marino if (current_loops == NULL)
3520e4b17023SJohn Marino return true;
3521e4b17023SJohn Marino
3522e4b17023SJohn Marino l = loop_containing_stmt (stmt);
3523e4b17023SJohn Marino if (l == NULL
3524e4b17023SJohn Marino || !loop_outer (l))
3525e4b17023SJohn Marino return true;
3526e4b17023SJohn Marino
3527e4b17023SJohn Marino chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
3528e4b17023SJohn Marino if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
3529e4b17023SJohn Marino return true;
3530e4b17023SJohn Marino
3531e4b17023SJohn Marino init = initial_condition_in_loop_num (chrec, l->num);
3532e4b17023SJohn Marino step = evolution_part_in_loop_num (chrec, l->num);
3533e4b17023SJohn Marino
3534e4b17023SJohn Marino if (step == NULL_TREE
3535e4b17023SJohn Marino || !is_gimple_min_invariant (step)
3536e4b17023SJohn Marino || !valid_value_p (init))
3537e4b17023SJohn Marino return true;
3538e4b17023SJohn Marino
3539e4b17023SJohn Marino /* If we get here, we know something useful about VAR based on the
3540e4b17023SJohn Marino loop information. If it wraps, it may overflow. */
3541e4b17023SJohn Marino
3542e4b17023SJohn Marino if (scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
3543e4b17023SJohn Marino true))
3544e4b17023SJohn Marino return true;
3545e4b17023SJohn Marino
3546e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS) != 0)
3547e4b17023SJohn Marino {
3548e4b17023SJohn Marino print_generic_expr (dump_file, var, 0);
3549e4b17023SJohn Marino fprintf (dump_file, ": loop information indicates does not overflow\n");
3550e4b17023SJohn Marino }
3551e4b17023SJohn Marino
3552e4b17023SJohn Marino return false;
3553e4b17023SJohn Marino }
3554e4b17023SJohn Marino
3555e4b17023SJohn Marino
3556e4b17023SJohn Marino /* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
3557e4b17023SJohn Marino
3558e4b17023SJohn Marino - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
3559e4b17023SJohn Marino all the values in the ranges.
3560e4b17023SJohn Marino
3561e4b17023SJohn Marino - Return BOOLEAN_FALSE_NODE if the comparison always returns false.
3562e4b17023SJohn Marino
3563e4b17023SJohn Marino - Return NULL_TREE if it is not always possible to determine the
3564e4b17023SJohn Marino value of the comparison.
3565e4b17023SJohn Marino
3566e4b17023SJohn Marino Also set *STRICT_OVERFLOW_P to indicate whether a range with an
3567e4b17023SJohn Marino overflow infinity was used in the test. */
3568e4b17023SJohn Marino
3569e4b17023SJohn Marino
3570e4b17023SJohn Marino static tree
compare_ranges(enum tree_code comp,value_range_t * vr0,value_range_t * vr1,bool * strict_overflow_p)3571e4b17023SJohn Marino compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
3572e4b17023SJohn Marino bool *strict_overflow_p)
3573e4b17023SJohn Marino {
3574e4b17023SJohn Marino /* VARYING or UNDEFINED ranges cannot be compared. */
3575e4b17023SJohn Marino if (vr0->type == VR_VARYING
3576e4b17023SJohn Marino || vr0->type == VR_UNDEFINED
3577e4b17023SJohn Marino || vr1->type == VR_VARYING
3578e4b17023SJohn Marino || vr1->type == VR_UNDEFINED)
3579e4b17023SJohn Marino return NULL_TREE;
3580e4b17023SJohn Marino
3581e4b17023SJohn Marino /* Anti-ranges need to be handled separately. */
3582e4b17023SJohn Marino if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
3583e4b17023SJohn Marino {
3584e4b17023SJohn Marino /* If both are anti-ranges, then we cannot compute any
3585e4b17023SJohn Marino comparison. */
3586e4b17023SJohn Marino if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
3587e4b17023SJohn Marino return NULL_TREE;
3588e4b17023SJohn Marino
3589e4b17023SJohn Marino /* These comparisons are never statically computable. */
3590e4b17023SJohn Marino if (comp == GT_EXPR
3591e4b17023SJohn Marino || comp == GE_EXPR
3592e4b17023SJohn Marino || comp == LT_EXPR
3593e4b17023SJohn Marino || comp == LE_EXPR)
3594e4b17023SJohn Marino return NULL_TREE;
3595e4b17023SJohn Marino
3596e4b17023SJohn Marino /* Equality can be computed only between a range and an
3597e4b17023SJohn Marino anti-range. ~[VAL1, VAL2] == [VAL1, VAL2] is always false. */
3598e4b17023SJohn Marino if (vr0->type == VR_RANGE)
3599e4b17023SJohn Marino {
3600e4b17023SJohn Marino /* To simplify processing, make VR0 the anti-range. */
3601e4b17023SJohn Marino value_range_t *tmp = vr0;
3602e4b17023SJohn Marino vr0 = vr1;
3603e4b17023SJohn Marino vr1 = tmp;
3604e4b17023SJohn Marino }
3605e4b17023SJohn Marino
3606e4b17023SJohn Marino gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
3607e4b17023SJohn Marino
3608e4b17023SJohn Marino if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
3609e4b17023SJohn Marino && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
3610e4b17023SJohn Marino return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
3611e4b17023SJohn Marino
3612e4b17023SJohn Marino return NULL_TREE;
3613e4b17023SJohn Marino }
3614e4b17023SJohn Marino
3615e4b17023SJohn Marino if (!usable_range_p (vr0, strict_overflow_p)
3616e4b17023SJohn Marino || !usable_range_p (vr1, strict_overflow_p))
3617e4b17023SJohn Marino return NULL_TREE;
3618e4b17023SJohn Marino
3619e4b17023SJohn Marino /* Simplify processing. If COMP is GT_EXPR or GE_EXPR, switch the
3620e4b17023SJohn Marino operands around and change the comparison code. */
3621e4b17023SJohn Marino if (comp == GT_EXPR || comp == GE_EXPR)
3622e4b17023SJohn Marino {
3623e4b17023SJohn Marino value_range_t *tmp;
3624e4b17023SJohn Marino comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
3625e4b17023SJohn Marino tmp = vr0;
3626e4b17023SJohn Marino vr0 = vr1;
3627e4b17023SJohn Marino vr1 = tmp;
3628e4b17023SJohn Marino }
3629e4b17023SJohn Marino
3630e4b17023SJohn Marino if (comp == EQ_EXPR)
3631e4b17023SJohn Marino {
3632e4b17023SJohn Marino /* Equality may only be computed if both ranges represent
3633e4b17023SJohn Marino exactly one value. */
3634e4b17023SJohn Marino if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
3635e4b17023SJohn Marino && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
3636e4b17023SJohn Marino {
3637e4b17023SJohn Marino int cmp_min = compare_values_warnv (vr0->min, vr1->min,
3638e4b17023SJohn Marino strict_overflow_p);
3639e4b17023SJohn Marino int cmp_max = compare_values_warnv (vr0->max, vr1->max,
3640e4b17023SJohn Marino strict_overflow_p);
3641e4b17023SJohn Marino if (cmp_min == 0 && cmp_max == 0)
3642e4b17023SJohn Marino return boolean_true_node;
3643e4b17023SJohn Marino else if (cmp_min != -2 && cmp_max != -2)
3644e4b17023SJohn Marino return boolean_false_node;
3645e4b17023SJohn Marino }
3646e4b17023SJohn Marino /* If [V0_MIN, V1_MAX] < [V1_MIN, V1_MAX] then V0 != V1. */
3647e4b17023SJohn Marino else if (compare_values_warnv (vr0->min, vr1->max,
3648e4b17023SJohn Marino strict_overflow_p) == 1
3649e4b17023SJohn Marino || compare_values_warnv (vr1->min, vr0->max,
3650e4b17023SJohn Marino strict_overflow_p) == 1)
3651e4b17023SJohn Marino return boolean_false_node;
3652e4b17023SJohn Marino
3653e4b17023SJohn Marino return NULL_TREE;
3654e4b17023SJohn Marino }
3655e4b17023SJohn Marino else if (comp == NE_EXPR)
3656e4b17023SJohn Marino {
3657e4b17023SJohn Marino int cmp1, cmp2;
3658e4b17023SJohn Marino
3659e4b17023SJohn Marino /* If VR0 is completely to the left or completely to the right
3660e4b17023SJohn Marino of VR1, they are always different. Notice that we need to
3661e4b17023SJohn Marino make sure that both comparisons yield similar results to
3662e4b17023SJohn Marino avoid comparing values that cannot be compared at
3663e4b17023SJohn Marino compile-time. */
3664e4b17023SJohn Marino cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
3665e4b17023SJohn Marino cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
3666e4b17023SJohn Marino if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
3667e4b17023SJohn Marino return boolean_true_node;
3668e4b17023SJohn Marino
3669e4b17023SJohn Marino /* If VR0 and VR1 represent a single value and are identical,
3670e4b17023SJohn Marino return false. */
3671e4b17023SJohn Marino else if (compare_values_warnv (vr0->min, vr0->max,
3672e4b17023SJohn Marino strict_overflow_p) == 0
3673e4b17023SJohn Marino && compare_values_warnv (vr1->min, vr1->max,
3674e4b17023SJohn Marino strict_overflow_p) == 0
3675e4b17023SJohn Marino && compare_values_warnv (vr0->min, vr1->min,
3676e4b17023SJohn Marino strict_overflow_p) == 0
3677e4b17023SJohn Marino && compare_values_warnv (vr0->max, vr1->max,
3678e4b17023SJohn Marino strict_overflow_p) == 0)
3679e4b17023SJohn Marino return boolean_false_node;
3680e4b17023SJohn Marino
3681e4b17023SJohn Marino /* Otherwise, they may or may not be different. */
3682e4b17023SJohn Marino else
3683e4b17023SJohn Marino return NULL_TREE;
3684e4b17023SJohn Marino }
3685e4b17023SJohn Marino else if (comp == LT_EXPR || comp == LE_EXPR)
3686e4b17023SJohn Marino {
3687e4b17023SJohn Marino int tst;
3688e4b17023SJohn Marino
3689e4b17023SJohn Marino /* If VR0 is to the left of VR1, return true. */
3690e4b17023SJohn Marino tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
3691e4b17023SJohn Marino if ((comp == LT_EXPR && tst == -1)
3692e4b17023SJohn Marino || (comp == LE_EXPR && (tst == -1 || tst == 0)))
3693e4b17023SJohn Marino {
3694e4b17023SJohn Marino if (overflow_infinity_range_p (vr0)
3695e4b17023SJohn Marino || overflow_infinity_range_p (vr1))
3696e4b17023SJohn Marino *strict_overflow_p = true;
3697e4b17023SJohn Marino return boolean_true_node;
3698e4b17023SJohn Marino }
3699e4b17023SJohn Marino
3700e4b17023SJohn Marino /* If VR0 is to the right of VR1, return false. */
3701e4b17023SJohn Marino tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
3702e4b17023SJohn Marino if ((comp == LT_EXPR && (tst == 0 || tst == 1))
3703e4b17023SJohn Marino || (comp == LE_EXPR && tst == 1))
3704e4b17023SJohn Marino {
3705e4b17023SJohn Marino if (overflow_infinity_range_p (vr0)
3706e4b17023SJohn Marino || overflow_infinity_range_p (vr1))
3707e4b17023SJohn Marino *strict_overflow_p = true;
3708e4b17023SJohn Marino return boolean_false_node;
3709e4b17023SJohn Marino }
3710e4b17023SJohn Marino
3711e4b17023SJohn Marino /* Otherwise, we don't know. */
3712e4b17023SJohn Marino return NULL_TREE;
3713e4b17023SJohn Marino }
3714e4b17023SJohn Marino
3715e4b17023SJohn Marino gcc_unreachable ();
3716e4b17023SJohn Marino }
3717e4b17023SJohn Marino
3718e4b17023SJohn Marino
3719e4b17023SJohn Marino /* Given a value range VR, a value VAL and a comparison code COMP, return
3720e4b17023SJohn Marino BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
3721e4b17023SJohn Marino values in VR. Return BOOLEAN_FALSE_NODE if the comparison
3722e4b17023SJohn Marino always returns false. Return NULL_TREE if it is not always
3723e4b17023SJohn Marino possible to determine the value of the comparison. Also set
3724e4b17023SJohn Marino *STRICT_OVERFLOW_P to indicate whether a range with an overflow
3725e4b17023SJohn Marino infinity was used in the test. */
3726e4b17023SJohn Marino
3727e4b17023SJohn Marino static tree
compare_range_with_value(enum tree_code comp,value_range_t * vr,tree val,bool * strict_overflow_p)3728e4b17023SJohn Marino compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
3729e4b17023SJohn Marino bool *strict_overflow_p)
3730e4b17023SJohn Marino {
3731e4b17023SJohn Marino if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
3732e4b17023SJohn Marino return NULL_TREE;
3733e4b17023SJohn Marino
3734e4b17023SJohn Marino /* Anti-ranges need to be handled separately. */
3735e4b17023SJohn Marino if (vr->type == VR_ANTI_RANGE)
3736e4b17023SJohn Marino {
3737e4b17023SJohn Marino /* For anti-ranges, the only predicates that we can compute at
3738e4b17023SJohn Marino compile time are equality and inequality. */
3739e4b17023SJohn Marino if (comp == GT_EXPR
3740e4b17023SJohn Marino || comp == GE_EXPR
3741e4b17023SJohn Marino || comp == LT_EXPR
3742e4b17023SJohn Marino || comp == LE_EXPR)
3743e4b17023SJohn Marino return NULL_TREE;
3744e4b17023SJohn Marino
3745e4b17023SJohn Marino /* ~[VAL_1, VAL_2] OP VAL is known if VAL_1 <= VAL <= VAL_2. */
3746e4b17023SJohn Marino if (value_inside_range (val, vr->min, vr->max) == 1)
3747e4b17023SJohn Marino return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
3748e4b17023SJohn Marino
3749e4b17023SJohn Marino return NULL_TREE;
3750e4b17023SJohn Marino }
3751e4b17023SJohn Marino
3752e4b17023SJohn Marino if (!usable_range_p (vr, strict_overflow_p))
3753e4b17023SJohn Marino return NULL_TREE;
3754e4b17023SJohn Marino
3755e4b17023SJohn Marino if (comp == EQ_EXPR)
3756e4b17023SJohn Marino {
3757e4b17023SJohn Marino /* EQ_EXPR may only be computed if VR represents exactly
3758e4b17023SJohn Marino one value. */
3759e4b17023SJohn Marino if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
3760e4b17023SJohn Marino {
3761e4b17023SJohn Marino int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
3762e4b17023SJohn Marino if (cmp == 0)
3763e4b17023SJohn Marino return boolean_true_node;
3764e4b17023SJohn Marino else if (cmp == -1 || cmp == 1 || cmp == 2)
3765e4b17023SJohn Marino return boolean_false_node;
3766e4b17023SJohn Marino }
3767e4b17023SJohn Marino else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
3768e4b17023SJohn Marino || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
3769e4b17023SJohn Marino return boolean_false_node;
3770e4b17023SJohn Marino
3771e4b17023SJohn Marino return NULL_TREE;
3772e4b17023SJohn Marino }
3773e4b17023SJohn Marino else if (comp == NE_EXPR)
3774e4b17023SJohn Marino {
3775e4b17023SJohn Marino /* If VAL is not inside VR, then they are always different. */
3776e4b17023SJohn Marino if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
3777e4b17023SJohn Marino || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
3778e4b17023SJohn Marino return boolean_true_node;
3779e4b17023SJohn Marino
3780e4b17023SJohn Marino /* If VR represents exactly one value equal to VAL, then return
3781e4b17023SJohn Marino false. */
3782e4b17023SJohn Marino if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
3783e4b17023SJohn Marino && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
3784e4b17023SJohn Marino return boolean_false_node;
3785e4b17023SJohn Marino
3786e4b17023SJohn Marino /* Otherwise, they may or may not be different. */
3787e4b17023SJohn Marino return NULL_TREE;
3788e4b17023SJohn Marino }
3789e4b17023SJohn Marino else if (comp == LT_EXPR || comp == LE_EXPR)
3790e4b17023SJohn Marino {
3791e4b17023SJohn Marino int tst;
3792e4b17023SJohn Marino
3793e4b17023SJohn Marino /* If VR is to the left of VAL, return true. */
3794e4b17023SJohn Marino tst = compare_values_warnv (vr->max, val, strict_overflow_p);
3795e4b17023SJohn Marino if ((comp == LT_EXPR && tst == -1)
3796e4b17023SJohn Marino || (comp == LE_EXPR && (tst == -1 || tst == 0)))
3797e4b17023SJohn Marino {
3798e4b17023SJohn Marino if (overflow_infinity_range_p (vr))
3799e4b17023SJohn Marino *strict_overflow_p = true;
3800e4b17023SJohn Marino return boolean_true_node;
3801e4b17023SJohn Marino }
3802e4b17023SJohn Marino
3803e4b17023SJohn Marino /* If VR is to the right of VAL, return false. */
3804e4b17023SJohn Marino tst = compare_values_warnv (vr->min, val, strict_overflow_p);
3805e4b17023SJohn Marino if ((comp == LT_EXPR && (tst == 0 || tst == 1))
3806e4b17023SJohn Marino || (comp == LE_EXPR && tst == 1))
3807e4b17023SJohn Marino {
3808e4b17023SJohn Marino if (overflow_infinity_range_p (vr))
3809e4b17023SJohn Marino *strict_overflow_p = true;
3810e4b17023SJohn Marino return boolean_false_node;
3811e4b17023SJohn Marino }
3812e4b17023SJohn Marino
3813e4b17023SJohn Marino /* Otherwise, we don't know. */
3814e4b17023SJohn Marino return NULL_TREE;
3815e4b17023SJohn Marino }
3816e4b17023SJohn Marino else if (comp == GT_EXPR || comp == GE_EXPR)
3817e4b17023SJohn Marino {
3818e4b17023SJohn Marino int tst;
3819e4b17023SJohn Marino
3820e4b17023SJohn Marino /* If VR is to the right of VAL, return true. */
3821e4b17023SJohn Marino tst = compare_values_warnv (vr->min, val, strict_overflow_p);
3822e4b17023SJohn Marino if ((comp == GT_EXPR && tst == 1)
3823e4b17023SJohn Marino || (comp == GE_EXPR && (tst == 0 || tst == 1)))
3824e4b17023SJohn Marino {
3825e4b17023SJohn Marino if (overflow_infinity_range_p (vr))
3826e4b17023SJohn Marino *strict_overflow_p = true;
3827e4b17023SJohn Marino return boolean_true_node;
3828e4b17023SJohn Marino }
3829e4b17023SJohn Marino
3830e4b17023SJohn Marino /* If VR is to the left of VAL, return false. */
3831e4b17023SJohn Marino tst = compare_values_warnv (vr->max, val, strict_overflow_p);
3832e4b17023SJohn Marino if ((comp == GT_EXPR && (tst == -1 || tst == 0))
3833e4b17023SJohn Marino || (comp == GE_EXPR && tst == -1))
3834e4b17023SJohn Marino {
3835e4b17023SJohn Marino if (overflow_infinity_range_p (vr))
3836e4b17023SJohn Marino *strict_overflow_p = true;
3837e4b17023SJohn Marino return boolean_false_node;
3838e4b17023SJohn Marino }
3839e4b17023SJohn Marino
3840e4b17023SJohn Marino /* Otherwise, we don't know. */
3841e4b17023SJohn Marino return NULL_TREE;
3842e4b17023SJohn Marino }
3843e4b17023SJohn Marino
3844e4b17023SJohn Marino gcc_unreachable ();
3845e4b17023SJohn Marino }
3846e4b17023SJohn Marino
3847e4b17023SJohn Marino
3848e4b17023SJohn Marino /* Debugging dumps. */
3849e4b17023SJohn Marino
3850e4b17023SJohn Marino void dump_value_range (FILE *, value_range_t *);
3851e4b17023SJohn Marino void debug_value_range (value_range_t *);
3852e4b17023SJohn Marino void dump_all_value_ranges (FILE *);
3853e4b17023SJohn Marino void debug_all_value_ranges (void);
3854e4b17023SJohn Marino void dump_vr_equiv (FILE *, bitmap);
3855e4b17023SJohn Marino void debug_vr_equiv (bitmap);
3856e4b17023SJohn Marino
3857e4b17023SJohn Marino
3858e4b17023SJohn Marino /* Dump value range VR to FILE. */
3859e4b17023SJohn Marino
3860e4b17023SJohn Marino void
dump_value_range(FILE * file,value_range_t * vr)3861e4b17023SJohn Marino dump_value_range (FILE *file, value_range_t *vr)
3862e4b17023SJohn Marino {
3863e4b17023SJohn Marino if (vr == NULL)
3864e4b17023SJohn Marino fprintf (file, "[]");
3865e4b17023SJohn Marino else if (vr->type == VR_UNDEFINED)
3866e4b17023SJohn Marino fprintf (file, "UNDEFINED");
3867e4b17023SJohn Marino else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
3868e4b17023SJohn Marino {
3869e4b17023SJohn Marino tree type = TREE_TYPE (vr->min);
3870e4b17023SJohn Marino
3871e4b17023SJohn Marino fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
3872e4b17023SJohn Marino
3873e4b17023SJohn Marino if (is_negative_overflow_infinity (vr->min))
3874e4b17023SJohn Marino fprintf (file, "-INF(OVF)");
3875e4b17023SJohn Marino else if (INTEGRAL_TYPE_P (type)
3876e4b17023SJohn Marino && !TYPE_UNSIGNED (type)
3877e4b17023SJohn Marino && vrp_val_is_min (vr->min))
3878e4b17023SJohn Marino fprintf (file, "-INF");
3879e4b17023SJohn Marino else
3880e4b17023SJohn Marino print_generic_expr (file, vr->min, 0);
3881e4b17023SJohn Marino
3882e4b17023SJohn Marino fprintf (file, ", ");
3883e4b17023SJohn Marino
3884e4b17023SJohn Marino if (is_positive_overflow_infinity (vr->max))
3885e4b17023SJohn Marino fprintf (file, "+INF(OVF)");
3886e4b17023SJohn Marino else if (INTEGRAL_TYPE_P (type)
3887e4b17023SJohn Marino && vrp_val_is_max (vr->max))
3888e4b17023SJohn Marino fprintf (file, "+INF");
3889e4b17023SJohn Marino else
3890e4b17023SJohn Marino print_generic_expr (file, vr->max, 0);
3891e4b17023SJohn Marino
3892e4b17023SJohn Marino fprintf (file, "]");
3893e4b17023SJohn Marino
3894e4b17023SJohn Marino if (vr->equiv)
3895e4b17023SJohn Marino {
3896e4b17023SJohn Marino bitmap_iterator bi;
3897e4b17023SJohn Marino unsigned i, c = 0;
3898e4b17023SJohn Marino
3899e4b17023SJohn Marino fprintf (file, " EQUIVALENCES: { ");
3900e4b17023SJohn Marino
3901e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
3902e4b17023SJohn Marino {
3903e4b17023SJohn Marino print_generic_expr (file, ssa_name (i), 0);
3904e4b17023SJohn Marino fprintf (file, " ");
3905e4b17023SJohn Marino c++;
3906e4b17023SJohn Marino }
3907e4b17023SJohn Marino
3908e4b17023SJohn Marino fprintf (file, "} (%u elements)", c);
3909e4b17023SJohn Marino }
3910e4b17023SJohn Marino }
3911e4b17023SJohn Marino else if (vr->type == VR_VARYING)
3912e4b17023SJohn Marino fprintf (file, "VARYING");
3913e4b17023SJohn Marino else
3914e4b17023SJohn Marino fprintf (file, "INVALID RANGE");
3915e4b17023SJohn Marino }
3916e4b17023SJohn Marino
3917e4b17023SJohn Marino
3918e4b17023SJohn Marino /* Dump value range VR to stderr. */
3919e4b17023SJohn Marino
3920e4b17023SJohn Marino DEBUG_FUNCTION void
debug_value_range(value_range_t * vr)3921e4b17023SJohn Marino debug_value_range (value_range_t *vr)
3922e4b17023SJohn Marino {
3923e4b17023SJohn Marino dump_value_range (stderr, vr);
3924e4b17023SJohn Marino fprintf (stderr, "\n");
3925e4b17023SJohn Marino }
3926e4b17023SJohn Marino
3927e4b17023SJohn Marino
3928e4b17023SJohn Marino /* Dump value ranges of all SSA_NAMEs to FILE. */
3929e4b17023SJohn Marino
3930e4b17023SJohn Marino void
dump_all_value_ranges(FILE * file)3931e4b17023SJohn Marino dump_all_value_ranges (FILE *file)
3932e4b17023SJohn Marino {
3933e4b17023SJohn Marino size_t i;
3934e4b17023SJohn Marino
3935e4b17023SJohn Marino for (i = 0; i < num_vr_values; i++)
3936e4b17023SJohn Marino {
3937e4b17023SJohn Marino if (vr_value[i])
3938e4b17023SJohn Marino {
3939e4b17023SJohn Marino print_generic_expr (file, ssa_name (i), 0);
3940e4b17023SJohn Marino fprintf (file, ": ");
3941e4b17023SJohn Marino dump_value_range (file, vr_value[i]);
3942e4b17023SJohn Marino fprintf (file, "\n");
3943e4b17023SJohn Marino }
3944e4b17023SJohn Marino }
3945e4b17023SJohn Marino
3946e4b17023SJohn Marino fprintf (file, "\n");
3947e4b17023SJohn Marino }
3948e4b17023SJohn Marino
3949e4b17023SJohn Marino
3950e4b17023SJohn Marino /* Dump all value ranges to stderr. */
3951e4b17023SJohn Marino
3952e4b17023SJohn Marino DEBUG_FUNCTION void
debug_all_value_ranges(void)3953e4b17023SJohn Marino debug_all_value_ranges (void)
3954e4b17023SJohn Marino {
3955e4b17023SJohn Marino dump_all_value_ranges (stderr);
3956e4b17023SJohn Marino }
3957e4b17023SJohn Marino
3958e4b17023SJohn Marino
3959e4b17023SJohn Marino /* Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
3960e4b17023SJohn Marino create a new SSA name N and return the assertion assignment
3961e4b17023SJohn Marino 'V = ASSERT_EXPR <V, V OP W>'. */
3962e4b17023SJohn Marino
3963e4b17023SJohn Marino static gimple
build_assert_expr_for(tree cond,tree v)3964e4b17023SJohn Marino build_assert_expr_for (tree cond, tree v)
3965e4b17023SJohn Marino {
3966e4b17023SJohn Marino tree n;
3967e4b17023SJohn Marino gimple assertion;
3968e4b17023SJohn Marino
3969e4b17023SJohn Marino gcc_assert (TREE_CODE (v) == SSA_NAME);
3970e4b17023SJohn Marino n = duplicate_ssa_name (v, NULL);
3971e4b17023SJohn Marino
3972e4b17023SJohn Marino if (COMPARISON_CLASS_P (cond))
3973e4b17023SJohn Marino {
3974e4b17023SJohn Marino tree a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
3975e4b17023SJohn Marino assertion = gimple_build_assign (n, a);
3976e4b17023SJohn Marino }
3977e4b17023SJohn Marino else if (TREE_CODE (cond) == SSA_NAME)
3978e4b17023SJohn Marino {
3979e4b17023SJohn Marino /* Given V, build the assignment N = true. */
3980e4b17023SJohn Marino gcc_assert (v == cond);
3981e4b17023SJohn Marino assertion = gimple_build_assign (n, boolean_true_node);
3982e4b17023SJohn Marino }
3983e4b17023SJohn Marino else
3984e4b17023SJohn Marino gcc_unreachable ();
3985e4b17023SJohn Marino
3986e4b17023SJohn Marino SSA_NAME_DEF_STMT (n) = assertion;
3987e4b17023SJohn Marino
3988e4b17023SJohn Marino /* The new ASSERT_EXPR, creates a new SSA name that replaces the
3989e4b17023SJohn Marino operand of the ASSERT_EXPR. Register the new name and the old one
3990e4b17023SJohn Marino in the replacement table so that we can fix the SSA web after
3991e4b17023SJohn Marino adding all the ASSERT_EXPRs. */
3992e4b17023SJohn Marino register_new_name_mapping (n, v);
3993e4b17023SJohn Marino
3994e4b17023SJohn Marino return assertion;
3995e4b17023SJohn Marino }
3996e4b17023SJohn Marino
3997e4b17023SJohn Marino
3998e4b17023SJohn Marino /* Return false if EXPR is a predicate expression involving floating
3999e4b17023SJohn Marino point values. */
4000e4b17023SJohn Marino
4001e4b17023SJohn Marino static inline bool
fp_predicate(gimple stmt)4002e4b17023SJohn Marino fp_predicate (gimple stmt)
4003e4b17023SJohn Marino {
4004e4b17023SJohn Marino GIMPLE_CHECK (stmt, GIMPLE_COND);
4005e4b17023SJohn Marino
4006e4b17023SJohn Marino return FLOAT_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt)));
4007e4b17023SJohn Marino }
4008e4b17023SJohn Marino
4009e4b17023SJohn Marino
4010e4b17023SJohn Marino /* If the range of values taken by OP can be inferred after STMT executes,
4011e4b17023SJohn Marino return the comparison code (COMP_CODE_P) and value (VAL_P) that
4012e4b17023SJohn Marino describes the inferred range. Return true if a range could be
4013e4b17023SJohn Marino inferred. */
4014e4b17023SJohn Marino
4015e4b17023SJohn Marino static bool
infer_value_range(gimple stmt,tree op,enum tree_code * comp_code_p,tree * val_p)4016e4b17023SJohn Marino infer_value_range (gimple stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
4017e4b17023SJohn Marino {
4018e4b17023SJohn Marino *val_p = NULL_TREE;
4019e4b17023SJohn Marino *comp_code_p = ERROR_MARK;
4020e4b17023SJohn Marino
4021e4b17023SJohn Marino /* Do not attempt to infer anything in names that flow through
4022e4b17023SJohn Marino abnormal edges. */
4023e4b17023SJohn Marino if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
4024e4b17023SJohn Marino return false;
4025e4b17023SJohn Marino
4026e4b17023SJohn Marino /* Similarly, don't infer anything from statements that may throw
4027e4b17023SJohn Marino exceptions. */
4028e4b17023SJohn Marino if (stmt_could_throw_p (stmt))
4029e4b17023SJohn Marino return false;
4030e4b17023SJohn Marino
4031e4b17023SJohn Marino /* If STMT is the last statement of a basic block with no
4032e4b17023SJohn Marino successors, there is no point inferring anything about any of its
4033e4b17023SJohn Marino operands. We would not be able to find a proper insertion point
4034e4b17023SJohn Marino for the assertion, anyway. */
4035e4b17023SJohn Marino if (stmt_ends_bb_p (stmt) && EDGE_COUNT (gimple_bb (stmt)->succs) == 0)
4036e4b17023SJohn Marino return false;
4037e4b17023SJohn Marino
4038e4b17023SJohn Marino /* We can only assume that a pointer dereference will yield
4039e4b17023SJohn Marino non-NULL if -fdelete-null-pointer-checks is enabled. */
4040e4b17023SJohn Marino if (flag_delete_null_pointer_checks
4041e4b17023SJohn Marino && POINTER_TYPE_P (TREE_TYPE (op))
4042e4b17023SJohn Marino && gimple_code (stmt) != GIMPLE_ASM)
4043e4b17023SJohn Marino {
4044e4b17023SJohn Marino unsigned num_uses, num_loads, num_stores;
4045e4b17023SJohn Marino
4046e4b17023SJohn Marino count_uses_and_derefs (op, stmt, &num_uses, &num_loads, &num_stores);
4047e4b17023SJohn Marino if (num_loads + num_stores > 0)
4048e4b17023SJohn Marino {
4049e4b17023SJohn Marino *val_p = build_int_cst (TREE_TYPE (op), 0);
4050e4b17023SJohn Marino *comp_code_p = NE_EXPR;
4051e4b17023SJohn Marino return true;
4052e4b17023SJohn Marino }
4053e4b17023SJohn Marino }
4054e4b17023SJohn Marino
4055e4b17023SJohn Marino return false;
4056e4b17023SJohn Marino }
4057e4b17023SJohn Marino
4058e4b17023SJohn Marino
4059e4b17023SJohn Marino void dump_asserts_for (FILE *, tree);
4060e4b17023SJohn Marino void debug_asserts_for (tree);
4061e4b17023SJohn Marino void dump_all_asserts (FILE *);
4062e4b17023SJohn Marino void debug_all_asserts (void);
4063e4b17023SJohn Marino
4064e4b17023SJohn Marino /* Dump all the registered assertions for NAME to FILE. */
4065e4b17023SJohn Marino
4066e4b17023SJohn Marino void
dump_asserts_for(FILE * file,tree name)4067e4b17023SJohn Marino dump_asserts_for (FILE *file, tree name)
4068e4b17023SJohn Marino {
4069e4b17023SJohn Marino assert_locus_t loc;
4070e4b17023SJohn Marino
4071e4b17023SJohn Marino fprintf (file, "Assertions to be inserted for ");
4072e4b17023SJohn Marino print_generic_expr (file, name, 0);
4073e4b17023SJohn Marino fprintf (file, "\n");
4074e4b17023SJohn Marino
4075e4b17023SJohn Marino loc = asserts_for[SSA_NAME_VERSION (name)];
4076e4b17023SJohn Marino while (loc)
4077e4b17023SJohn Marino {
4078e4b17023SJohn Marino fprintf (file, "\t");
4079e4b17023SJohn Marino print_gimple_stmt (file, gsi_stmt (loc->si), 0, 0);
4080e4b17023SJohn Marino fprintf (file, "\n\tBB #%d", loc->bb->index);
4081e4b17023SJohn Marino if (loc->e)
4082e4b17023SJohn Marino {
4083e4b17023SJohn Marino fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
4084e4b17023SJohn Marino loc->e->dest->index);
4085e4b17023SJohn Marino dump_edge_info (file, loc->e, 0);
4086e4b17023SJohn Marino }
4087e4b17023SJohn Marino fprintf (file, "\n\tPREDICATE: ");
4088e4b17023SJohn Marino print_generic_expr (file, name, 0);
4089e4b17023SJohn Marino fprintf (file, " %s ", tree_code_name[(int)loc->comp_code]);
4090e4b17023SJohn Marino print_generic_expr (file, loc->val, 0);
4091e4b17023SJohn Marino fprintf (file, "\n\n");
4092e4b17023SJohn Marino loc = loc->next;
4093e4b17023SJohn Marino }
4094e4b17023SJohn Marino
4095e4b17023SJohn Marino fprintf (file, "\n");
4096e4b17023SJohn Marino }
4097e4b17023SJohn Marino
4098e4b17023SJohn Marino
4099e4b17023SJohn Marino /* Dump all the registered assertions for NAME to stderr. */
4100e4b17023SJohn Marino
4101e4b17023SJohn Marino DEBUG_FUNCTION void
debug_asserts_for(tree name)4102e4b17023SJohn Marino debug_asserts_for (tree name)
4103e4b17023SJohn Marino {
4104e4b17023SJohn Marino dump_asserts_for (stderr, name);
4105e4b17023SJohn Marino }
4106e4b17023SJohn Marino
4107e4b17023SJohn Marino
4108e4b17023SJohn Marino /* Dump all the registered assertions for all the names to FILE. */
4109e4b17023SJohn Marino
4110e4b17023SJohn Marino void
dump_all_asserts(FILE * file)4111e4b17023SJohn Marino dump_all_asserts (FILE *file)
4112e4b17023SJohn Marino {
4113e4b17023SJohn Marino unsigned i;
4114e4b17023SJohn Marino bitmap_iterator bi;
4115e4b17023SJohn Marino
4116e4b17023SJohn Marino fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
4117e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
4118e4b17023SJohn Marino dump_asserts_for (file, ssa_name (i));
4119e4b17023SJohn Marino fprintf (file, "\n");
4120e4b17023SJohn Marino }
4121e4b17023SJohn Marino
4122e4b17023SJohn Marino
4123e4b17023SJohn Marino /* Dump all the registered assertions for all the names to stderr. */
4124e4b17023SJohn Marino
4125e4b17023SJohn Marino DEBUG_FUNCTION void
debug_all_asserts(void)4126e4b17023SJohn Marino debug_all_asserts (void)
4127e4b17023SJohn Marino {
4128e4b17023SJohn Marino dump_all_asserts (stderr);
4129e4b17023SJohn Marino }
4130e4b17023SJohn Marino
4131e4b17023SJohn Marino
4132e4b17023SJohn Marino /* If NAME doesn't have an ASSERT_EXPR registered for asserting
4133e4b17023SJohn Marino 'EXPR COMP_CODE VAL' at a location that dominates block BB or
4134e4b17023SJohn Marino E->DEST, then register this location as a possible insertion point
4135e4b17023SJohn Marino for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.
4136e4b17023SJohn Marino
4137e4b17023SJohn Marino BB, E and SI provide the exact insertion point for the new
4138e4b17023SJohn Marino ASSERT_EXPR. If BB is NULL, then the ASSERT_EXPR is to be inserted
4139e4b17023SJohn Marino on edge E. Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
4140e4b17023SJohn Marino BB. If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
4141e4b17023SJohn Marino must not be NULL. */
4142e4b17023SJohn Marino
4143e4b17023SJohn Marino static void
register_new_assert_for(tree name,tree expr,enum tree_code comp_code,tree val,basic_block bb,edge e,gimple_stmt_iterator si)4144e4b17023SJohn Marino register_new_assert_for (tree name, tree expr,
4145e4b17023SJohn Marino enum tree_code comp_code,
4146e4b17023SJohn Marino tree val,
4147e4b17023SJohn Marino basic_block bb,
4148e4b17023SJohn Marino edge e,
4149e4b17023SJohn Marino gimple_stmt_iterator si)
4150e4b17023SJohn Marino {
4151e4b17023SJohn Marino assert_locus_t n, loc, last_loc;
4152e4b17023SJohn Marino basic_block dest_bb;
4153e4b17023SJohn Marino
4154e4b17023SJohn Marino gcc_checking_assert (bb == NULL || e == NULL);
4155e4b17023SJohn Marino
4156e4b17023SJohn Marino if (e == NULL)
4157e4b17023SJohn Marino gcc_checking_assert (gimple_code (gsi_stmt (si)) != GIMPLE_COND
4158e4b17023SJohn Marino && gimple_code (gsi_stmt (si)) != GIMPLE_SWITCH);
4159e4b17023SJohn Marino
4160e4b17023SJohn Marino /* Never build an assert comparing against an integer constant with
4161e4b17023SJohn Marino TREE_OVERFLOW set. This confuses our undefined overflow warning
4162e4b17023SJohn Marino machinery. */
4163e4b17023SJohn Marino if (TREE_CODE (val) == INTEGER_CST
4164e4b17023SJohn Marino && TREE_OVERFLOW (val))
4165e4b17023SJohn Marino val = build_int_cst_wide (TREE_TYPE (val),
4166e4b17023SJohn Marino TREE_INT_CST_LOW (val), TREE_INT_CST_HIGH (val));
4167e4b17023SJohn Marino
4168e4b17023SJohn Marino /* The new assertion A will be inserted at BB or E. We need to
4169e4b17023SJohn Marino determine if the new location is dominated by a previously
4170e4b17023SJohn Marino registered location for A. If we are doing an edge insertion,
4171e4b17023SJohn Marino assume that A will be inserted at E->DEST. Note that this is not
4172e4b17023SJohn Marino necessarily true.
4173e4b17023SJohn Marino
4174e4b17023SJohn Marino If E is a critical edge, it will be split. But even if E is
4175e4b17023SJohn Marino split, the new block will dominate the same set of blocks that
4176e4b17023SJohn Marino E->DEST dominates.
4177e4b17023SJohn Marino
4178e4b17023SJohn Marino The reverse, however, is not true, blocks dominated by E->DEST
4179e4b17023SJohn Marino will not be dominated by the new block created to split E. So,
4180e4b17023SJohn Marino if the insertion location is on a critical edge, we will not use
4181e4b17023SJohn Marino the new location to move another assertion previously registered
4182e4b17023SJohn Marino at a block dominated by E->DEST. */
4183e4b17023SJohn Marino dest_bb = (bb) ? bb : e->dest;
4184e4b17023SJohn Marino
4185e4b17023SJohn Marino /* If NAME already has an ASSERT_EXPR registered for COMP_CODE and
4186e4b17023SJohn Marino VAL at a block dominating DEST_BB, then we don't need to insert a new
4187e4b17023SJohn Marino one. Similarly, if the same assertion already exists at a block
4188e4b17023SJohn Marino dominated by DEST_BB and the new location is not on a critical
4189e4b17023SJohn Marino edge, then update the existing location for the assertion (i.e.,
4190e4b17023SJohn Marino move the assertion up in the dominance tree).
4191e4b17023SJohn Marino
4192e4b17023SJohn Marino Note, this is implemented as a simple linked list because there
4193e4b17023SJohn Marino should not be more than a handful of assertions registered per
4194e4b17023SJohn Marino name. If this becomes a performance problem, a table hashed by
4195e4b17023SJohn Marino COMP_CODE and VAL could be implemented. */
4196e4b17023SJohn Marino loc = asserts_for[SSA_NAME_VERSION (name)];
4197e4b17023SJohn Marino last_loc = loc;
4198e4b17023SJohn Marino while (loc)
4199e4b17023SJohn Marino {
4200e4b17023SJohn Marino if (loc->comp_code == comp_code
4201e4b17023SJohn Marino && (loc->val == val
4202e4b17023SJohn Marino || operand_equal_p (loc->val, val, 0))
4203e4b17023SJohn Marino && (loc->expr == expr
4204e4b17023SJohn Marino || operand_equal_p (loc->expr, expr, 0)))
4205e4b17023SJohn Marino {
4206e4b17023SJohn Marino /* If the assertion NAME COMP_CODE VAL has already been
4207e4b17023SJohn Marino registered at a basic block that dominates DEST_BB, then
4208e4b17023SJohn Marino we don't need to insert the same assertion again. Note
4209e4b17023SJohn Marino that we don't check strict dominance here to avoid
4210e4b17023SJohn Marino replicating the same assertion inside the same basic
4211e4b17023SJohn Marino block more than once (e.g., when a pointer is
4212e4b17023SJohn Marino dereferenced several times inside a block).
4213e4b17023SJohn Marino
4214e4b17023SJohn Marino An exception to this rule are edge insertions. If the
4215e4b17023SJohn Marino new assertion is to be inserted on edge E, then it will
4216e4b17023SJohn Marino dominate all the other insertions that we may want to
4217e4b17023SJohn Marino insert in DEST_BB. So, if we are doing an edge
4218e4b17023SJohn Marino insertion, don't do this dominance check. */
4219e4b17023SJohn Marino if (e == NULL
4220e4b17023SJohn Marino && dominated_by_p (CDI_DOMINATORS, dest_bb, loc->bb))
4221e4b17023SJohn Marino return;
4222e4b17023SJohn Marino
4223e4b17023SJohn Marino /* Otherwise, if E is not a critical edge and DEST_BB
4224e4b17023SJohn Marino dominates the existing location for the assertion, move
4225e4b17023SJohn Marino the assertion up in the dominance tree by updating its
4226e4b17023SJohn Marino location information. */
4227e4b17023SJohn Marino if ((e == NULL || !EDGE_CRITICAL_P (e))
4228e4b17023SJohn Marino && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
4229e4b17023SJohn Marino {
4230e4b17023SJohn Marino loc->bb = dest_bb;
4231e4b17023SJohn Marino loc->e = e;
4232e4b17023SJohn Marino loc->si = si;
4233e4b17023SJohn Marino return;
4234e4b17023SJohn Marino }
4235e4b17023SJohn Marino }
4236e4b17023SJohn Marino
4237e4b17023SJohn Marino /* Update the last node of the list and move to the next one. */
4238e4b17023SJohn Marino last_loc = loc;
4239e4b17023SJohn Marino loc = loc->next;
4240e4b17023SJohn Marino }
4241e4b17023SJohn Marino
4242e4b17023SJohn Marino /* If we didn't find an assertion already registered for
4243e4b17023SJohn Marino NAME COMP_CODE VAL, add a new one at the end of the list of
4244e4b17023SJohn Marino assertions associated with NAME. */
4245e4b17023SJohn Marino n = XNEW (struct assert_locus_d);
4246e4b17023SJohn Marino n->bb = dest_bb;
4247e4b17023SJohn Marino n->e = e;
4248e4b17023SJohn Marino n->si = si;
4249e4b17023SJohn Marino n->comp_code = comp_code;
4250e4b17023SJohn Marino n->val = val;
4251e4b17023SJohn Marino n->expr = expr;
4252e4b17023SJohn Marino n->next = NULL;
4253e4b17023SJohn Marino
4254e4b17023SJohn Marino if (last_loc)
4255e4b17023SJohn Marino last_loc->next = n;
4256e4b17023SJohn Marino else
4257e4b17023SJohn Marino asserts_for[SSA_NAME_VERSION (name)] = n;
4258e4b17023SJohn Marino
4259e4b17023SJohn Marino bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
4260e4b17023SJohn Marino }
4261e4b17023SJohn Marino
4262e4b17023SJohn Marino /* (COND_OP0 COND_CODE COND_OP1) is a predicate which uses NAME.
4263e4b17023SJohn Marino Extract a suitable test code and value and store them into *CODE_P and
4264e4b17023SJohn Marino *VAL_P so the predicate is normalized to NAME *CODE_P *VAL_P.
4265e4b17023SJohn Marino
4266e4b17023SJohn Marino If no extraction was possible, return FALSE, otherwise return TRUE.
4267e4b17023SJohn Marino
4268e4b17023SJohn Marino If INVERT is true, then we invert the result stored into *CODE_P. */
4269e4b17023SJohn Marino
4270e4b17023SJohn Marino static bool
extract_code_and_val_from_cond_with_ops(tree name,enum tree_code cond_code,tree cond_op0,tree cond_op1,bool invert,enum tree_code * code_p,tree * val_p)4271e4b17023SJohn Marino extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code,
4272e4b17023SJohn Marino tree cond_op0, tree cond_op1,
4273e4b17023SJohn Marino bool invert, enum tree_code *code_p,
4274e4b17023SJohn Marino tree *val_p)
4275e4b17023SJohn Marino {
4276e4b17023SJohn Marino enum tree_code comp_code;
4277e4b17023SJohn Marino tree val;
4278e4b17023SJohn Marino
4279e4b17023SJohn Marino /* Otherwise, we have a comparison of the form NAME COMP VAL
4280e4b17023SJohn Marino or VAL COMP NAME. */
4281e4b17023SJohn Marino if (name == cond_op1)
4282e4b17023SJohn Marino {
4283e4b17023SJohn Marino /* If the predicate is of the form VAL COMP NAME, flip
4284e4b17023SJohn Marino COMP around because we need to register NAME as the
4285e4b17023SJohn Marino first operand in the predicate. */
4286e4b17023SJohn Marino comp_code = swap_tree_comparison (cond_code);
4287e4b17023SJohn Marino val = cond_op0;
4288e4b17023SJohn Marino }
4289e4b17023SJohn Marino else
4290e4b17023SJohn Marino {
4291e4b17023SJohn Marino /* The comparison is of the form NAME COMP VAL, so the
4292e4b17023SJohn Marino comparison code remains unchanged. */
4293e4b17023SJohn Marino comp_code = cond_code;
4294e4b17023SJohn Marino val = cond_op1;
4295e4b17023SJohn Marino }
4296e4b17023SJohn Marino
4297e4b17023SJohn Marino /* Invert the comparison code as necessary. */
4298e4b17023SJohn Marino if (invert)
4299e4b17023SJohn Marino comp_code = invert_tree_comparison (comp_code, 0);
4300e4b17023SJohn Marino
4301e4b17023SJohn Marino /* VRP does not handle float types. */
4302e4b17023SJohn Marino if (SCALAR_FLOAT_TYPE_P (TREE_TYPE (val)))
4303e4b17023SJohn Marino return false;
4304e4b17023SJohn Marino
4305e4b17023SJohn Marino /* Do not register always-false predicates.
4306e4b17023SJohn Marino FIXME: this works around a limitation in fold() when dealing with
4307e4b17023SJohn Marino enumerations. Given 'enum { N1, N2 } x;', fold will not
4308e4b17023SJohn Marino fold 'if (x > N2)' to 'if (0)'. */
4309e4b17023SJohn Marino if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
4310e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (val)))
4311e4b17023SJohn Marino {
4312e4b17023SJohn Marino tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
4313e4b17023SJohn Marino tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
4314e4b17023SJohn Marino
4315e4b17023SJohn Marino if (comp_code == GT_EXPR
4316e4b17023SJohn Marino && (!max
4317e4b17023SJohn Marino || compare_values (val, max) == 0))
4318e4b17023SJohn Marino return false;
4319e4b17023SJohn Marino
4320e4b17023SJohn Marino if (comp_code == LT_EXPR
4321e4b17023SJohn Marino && (!min
4322e4b17023SJohn Marino || compare_values (val, min) == 0))
4323e4b17023SJohn Marino return false;
4324e4b17023SJohn Marino }
4325e4b17023SJohn Marino *code_p = comp_code;
4326e4b17023SJohn Marino *val_p = val;
4327e4b17023SJohn Marino return true;
4328e4b17023SJohn Marino }
4329e4b17023SJohn Marino
4330e4b17023SJohn Marino /* Try to register an edge assertion for SSA name NAME on edge E for
4331e4b17023SJohn Marino the condition COND contributing to the conditional jump pointed to by BSI.
4332e4b17023SJohn Marino Invert the condition COND if INVERT is true.
4333e4b17023SJohn Marino Return true if an assertion for NAME could be registered. */
4334e4b17023SJohn Marino
4335e4b17023SJohn Marino static bool
register_edge_assert_for_2(tree name,edge e,gimple_stmt_iterator bsi,enum tree_code cond_code,tree cond_op0,tree cond_op1,bool invert)4336e4b17023SJohn Marino register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
4337e4b17023SJohn Marino enum tree_code cond_code,
4338e4b17023SJohn Marino tree cond_op0, tree cond_op1, bool invert)
4339e4b17023SJohn Marino {
4340e4b17023SJohn Marino tree val;
4341e4b17023SJohn Marino enum tree_code comp_code;
4342e4b17023SJohn Marino bool retval = false;
4343e4b17023SJohn Marino
4344e4b17023SJohn Marino if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
4345e4b17023SJohn Marino cond_op0,
4346e4b17023SJohn Marino cond_op1,
4347e4b17023SJohn Marino invert, &comp_code, &val))
4348e4b17023SJohn Marino return false;
4349e4b17023SJohn Marino
4350e4b17023SJohn Marino /* Only register an ASSERT_EXPR if NAME was found in the sub-graph
4351e4b17023SJohn Marino reachable from E. */
4352e4b17023SJohn Marino if (live_on_edge (e, name)
4353e4b17023SJohn Marino && !has_single_use (name))
4354e4b17023SJohn Marino {
4355e4b17023SJohn Marino register_new_assert_for (name, name, comp_code, val, NULL, e, bsi);
4356e4b17023SJohn Marino retval = true;
4357e4b17023SJohn Marino }
4358e4b17023SJohn Marino
4359e4b17023SJohn Marino /* In the case of NAME <= CST and NAME being defined as
4360e4b17023SJohn Marino NAME = (unsigned) NAME2 + CST2 we can assert NAME2 >= -CST2
4361e4b17023SJohn Marino and NAME2 <= CST - CST2. We can do the same for NAME > CST.
4362e4b17023SJohn Marino This catches range and anti-range tests. */
4363e4b17023SJohn Marino if ((comp_code == LE_EXPR
4364e4b17023SJohn Marino || comp_code == GT_EXPR)
4365e4b17023SJohn Marino && TREE_CODE (val) == INTEGER_CST
4366e4b17023SJohn Marino && TYPE_UNSIGNED (TREE_TYPE (val)))
4367e4b17023SJohn Marino {
4368e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (name);
4369e4b17023SJohn Marino tree cst2 = NULL_TREE, name2 = NULL_TREE, name3 = NULL_TREE;
4370e4b17023SJohn Marino
4371e4b17023SJohn Marino /* Extract CST2 from the (optional) addition. */
4372e4b17023SJohn Marino if (is_gimple_assign (def_stmt)
4373e4b17023SJohn Marino && gimple_assign_rhs_code (def_stmt) == PLUS_EXPR)
4374e4b17023SJohn Marino {
4375e4b17023SJohn Marino name2 = gimple_assign_rhs1 (def_stmt);
4376e4b17023SJohn Marino cst2 = gimple_assign_rhs2 (def_stmt);
4377e4b17023SJohn Marino if (TREE_CODE (name2) == SSA_NAME
4378e4b17023SJohn Marino && TREE_CODE (cst2) == INTEGER_CST)
4379e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (name2);
4380e4b17023SJohn Marino }
4381e4b17023SJohn Marino
4382e4b17023SJohn Marino /* Extract NAME2 from the (optional) sign-changing cast. */
4383e4b17023SJohn Marino if (gimple_assign_cast_p (def_stmt))
4384e4b17023SJohn Marino {
4385e4b17023SJohn Marino if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
4386e4b17023SJohn Marino && ! TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
4387e4b17023SJohn Marino && (TYPE_PRECISION (gimple_expr_type (def_stmt))
4388e4b17023SJohn Marino == TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))))
4389e4b17023SJohn Marino name3 = gimple_assign_rhs1 (def_stmt);
4390e4b17023SJohn Marino }
4391e4b17023SJohn Marino
4392e4b17023SJohn Marino /* If name3 is used later, create an ASSERT_EXPR for it. */
4393e4b17023SJohn Marino if (name3 != NULL_TREE
4394e4b17023SJohn Marino && TREE_CODE (name3) == SSA_NAME
4395e4b17023SJohn Marino && (cst2 == NULL_TREE
4396e4b17023SJohn Marino || TREE_CODE (cst2) == INTEGER_CST)
4397e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (name3))
4398e4b17023SJohn Marino && live_on_edge (e, name3)
4399e4b17023SJohn Marino && !has_single_use (name3))
4400e4b17023SJohn Marino {
4401e4b17023SJohn Marino tree tmp;
4402e4b17023SJohn Marino
4403e4b17023SJohn Marino /* Build an expression for the range test. */
4404e4b17023SJohn Marino tmp = build1 (NOP_EXPR, TREE_TYPE (name), name3);
4405e4b17023SJohn Marino if (cst2 != NULL_TREE)
4406e4b17023SJohn Marino tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
4407e4b17023SJohn Marino
4408e4b17023SJohn Marino if (dump_file)
4409e4b17023SJohn Marino {
4410e4b17023SJohn Marino fprintf (dump_file, "Adding assert for ");
4411e4b17023SJohn Marino print_generic_expr (dump_file, name3, 0);
4412e4b17023SJohn Marino fprintf (dump_file, " from ");
4413e4b17023SJohn Marino print_generic_expr (dump_file, tmp, 0);
4414e4b17023SJohn Marino fprintf (dump_file, "\n");
4415e4b17023SJohn Marino }
4416e4b17023SJohn Marino
4417e4b17023SJohn Marino register_new_assert_for (name3, tmp, comp_code, val, NULL, e, bsi);
4418e4b17023SJohn Marino
4419e4b17023SJohn Marino retval = true;
4420e4b17023SJohn Marino }
4421e4b17023SJohn Marino
4422e4b17023SJohn Marino /* If name2 is used later, create an ASSERT_EXPR for it. */
4423e4b17023SJohn Marino if (name2 != NULL_TREE
4424e4b17023SJohn Marino && TREE_CODE (name2) == SSA_NAME
4425e4b17023SJohn Marino && TREE_CODE (cst2) == INTEGER_CST
4426e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (name2))
4427e4b17023SJohn Marino && live_on_edge (e, name2)
4428e4b17023SJohn Marino && !has_single_use (name2))
4429e4b17023SJohn Marino {
4430e4b17023SJohn Marino tree tmp;
4431e4b17023SJohn Marino
4432e4b17023SJohn Marino /* Build an expression for the range test. */
4433e4b17023SJohn Marino tmp = name2;
4434e4b17023SJohn Marino if (TREE_TYPE (name) != TREE_TYPE (name2))
4435e4b17023SJohn Marino tmp = build1 (NOP_EXPR, TREE_TYPE (name), tmp);
4436e4b17023SJohn Marino if (cst2 != NULL_TREE)
4437e4b17023SJohn Marino tmp = build2 (PLUS_EXPR, TREE_TYPE (name), tmp, cst2);
4438e4b17023SJohn Marino
4439e4b17023SJohn Marino if (dump_file)
4440e4b17023SJohn Marino {
4441e4b17023SJohn Marino fprintf (dump_file, "Adding assert for ");
4442e4b17023SJohn Marino print_generic_expr (dump_file, name2, 0);
4443e4b17023SJohn Marino fprintf (dump_file, " from ");
4444e4b17023SJohn Marino print_generic_expr (dump_file, tmp, 0);
4445e4b17023SJohn Marino fprintf (dump_file, "\n");
4446e4b17023SJohn Marino }
4447e4b17023SJohn Marino
4448e4b17023SJohn Marino register_new_assert_for (name2, tmp, comp_code, val, NULL, e, bsi);
4449e4b17023SJohn Marino
4450e4b17023SJohn Marino retval = true;
4451e4b17023SJohn Marino }
4452e4b17023SJohn Marino }
4453e4b17023SJohn Marino
4454e4b17023SJohn Marino return retval;
4455e4b17023SJohn Marino }
4456e4b17023SJohn Marino
4457e4b17023SJohn Marino /* OP is an operand of a truth value expression which is known to have
4458e4b17023SJohn Marino a particular value. Register any asserts for OP and for any
4459e4b17023SJohn Marino operands in OP's defining statement.
4460e4b17023SJohn Marino
4461e4b17023SJohn Marino If CODE is EQ_EXPR, then we want to register OP is zero (false),
4462e4b17023SJohn Marino if CODE is NE_EXPR, then we want to register OP is nonzero (true). */
4463e4b17023SJohn Marino
4464e4b17023SJohn Marino static bool
register_edge_assert_for_1(tree op,enum tree_code code,edge e,gimple_stmt_iterator bsi)4465e4b17023SJohn Marino register_edge_assert_for_1 (tree op, enum tree_code code,
4466e4b17023SJohn Marino edge e, gimple_stmt_iterator bsi)
4467e4b17023SJohn Marino {
4468e4b17023SJohn Marino bool retval = false;
4469e4b17023SJohn Marino gimple op_def;
4470e4b17023SJohn Marino tree val;
4471e4b17023SJohn Marino enum tree_code rhs_code;
4472e4b17023SJohn Marino
4473e4b17023SJohn Marino /* We only care about SSA_NAMEs. */
4474e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
4475e4b17023SJohn Marino return false;
4476e4b17023SJohn Marino
4477e4b17023SJohn Marino /* We know that OP will have a zero or nonzero value. If OP is used
4478e4b17023SJohn Marino more than once go ahead and register an assert for OP.
4479e4b17023SJohn Marino
4480e4b17023SJohn Marino The FOUND_IN_SUBGRAPH support is not helpful in this situation as
4481e4b17023SJohn Marino it will always be set for OP (because OP is used in a COND_EXPR in
4482e4b17023SJohn Marino the subgraph). */
4483e4b17023SJohn Marino if (!has_single_use (op))
4484e4b17023SJohn Marino {
4485e4b17023SJohn Marino val = build_int_cst (TREE_TYPE (op), 0);
4486e4b17023SJohn Marino register_new_assert_for (op, op, code, val, NULL, e, bsi);
4487e4b17023SJohn Marino retval = true;
4488e4b17023SJohn Marino }
4489e4b17023SJohn Marino
4490e4b17023SJohn Marino /* Now look at how OP is set. If it's set from a comparison,
4491e4b17023SJohn Marino a truth operation or some bit operations, then we may be able
4492e4b17023SJohn Marino to register information about the operands of that assignment. */
4493e4b17023SJohn Marino op_def = SSA_NAME_DEF_STMT (op);
4494e4b17023SJohn Marino if (gimple_code (op_def) != GIMPLE_ASSIGN)
4495e4b17023SJohn Marino return retval;
4496e4b17023SJohn Marino
4497e4b17023SJohn Marino rhs_code = gimple_assign_rhs_code (op_def);
4498e4b17023SJohn Marino
4499e4b17023SJohn Marino if (TREE_CODE_CLASS (rhs_code) == tcc_comparison)
4500e4b17023SJohn Marino {
4501e4b17023SJohn Marino bool invert = (code == EQ_EXPR ? true : false);
4502e4b17023SJohn Marino tree op0 = gimple_assign_rhs1 (op_def);
4503e4b17023SJohn Marino tree op1 = gimple_assign_rhs2 (op_def);
4504e4b17023SJohn Marino
4505e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME)
4506e4b17023SJohn Marino retval |= register_edge_assert_for_2 (op0, e, bsi, rhs_code, op0, op1,
4507e4b17023SJohn Marino invert);
4508e4b17023SJohn Marino if (TREE_CODE (op1) == SSA_NAME)
4509e4b17023SJohn Marino retval |= register_edge_assert_for_2 (op1, e, bsi, rhs_code, op0, op1,
4510e4b17023SJohn Marino invert);
4511e4b17023SJohn Marino }
4512e4b17023SJohn Marino else if ((code == NE_EXPR
4513e4b17023SJohn Marino && gimple_assign_rhs_code (op_def) == BIT_AND_EXPR)
4514e4b17023SJohn Marino || (code == EQ_EXPR
4515e4b17023SJohn Marino && gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
4516e4b17023SJohn Marino {
4517e4b17023SJohn Marino /* Recurse on each operand. */
4518e4b17023SJohn Marino retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4519e4b17023SJohn Marino code, e, bsi);
4520e4b17023SJohn Marino retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
4521e4b17023SJohn Marino code, e, bsi);
4522e4b17023SJohn Marino }
4523e4b17023SJohn Marino else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
4524e4b17023SJohn Marino && TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
4525e4b17023SJohn Marino {
4526e4b17023SJohn Marino /* Recurse, flipping CODE. */
4527e4b17023SJohn Marino code = invert_tree_comparison (code, false);
4528e4b17023SJohn Marino retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4529e4b17023SJohn Marino code, e, bsi);
4530e4b17023SJohn Marino }
4531e4b17023SJohn Marino else if (gimple_assign_rhs_code (op_def) == SSA_NAME)
4532e4b17023SJohn Marino {
4533e4b17023SJohn Marino /* Recurse through the copy. */
4534e4b17023SJohn Marino retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
4535e4b17023SJohn Marino code, e, bsi);
4536e4b17023SJohn Marino }
4537e4b17023SJohn Marino else if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (op_def)))
4538e4b17023SJohn Marino {
4539*95d28233SJohn Marino /* Recurse through the type conversion, unless it is a narrowing
4540*95d28233SJohn Marino conversion or conversion from non-integral type. */
4541*95d28233SJohn Marino tree rhs = gimple_assign_rhs1 (op_def);
4542*95d28233SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (rhs))
4543*95d28233SJohn Marino && (TYPE_PRECISION (TREE_TYPE (rhs))
4544*95d28233SJohn Marino <= TYPE_PRECISION (TREE_TYPE (op))))
4545*95d28233SJohn Marino retval |= register_edge_assert_for_1 (rhs, code, e, bsi);
4546e4b17023SJohn Marino }
4547e4b17023SJohn Marino
4548e4b17023SJohn Marino return retval;
4549e4b17023SJohn Marino }
4550e4b17023SJohn Marino
4551e4b17023SJohn Marino /* Try to register an edge assertion for SSA name NAME on edge E for
4552e4b17023SJohn Marino the condition COND contributing to the conditional jump pointed to by SI.
4553e4b17023SJohn Marino Return true if an assertion for NAME could be registered. */
4554e4b17023SJohn Marino
4555e4b17023SJohn Marino static bool
register_edge_assert_for(tree name,edge e,gimple_stmt_iterator si,enum tree_code cond_code,tree cond_op0,tree cond_op1)4556e4b17023SJohn Marino register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si,
4557e4b17023SJohn Marino enum tree_code cond_code, tree cond_op0,
4558e4b17023SJohn Marino tree cond_op1)
4559e4b17023SJohn Marino {
4560e4b17023SJohn Marino tree val;
4561e4b17023SJohn Marino enum tree_code comp_code;
4562e4b17023SJohn Marino bool retval = false;
4563e4b17023SJohn Marino bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;
4564e4b17023SJohn Marino
4565e4b17023SJohn Marino /* Do not attempt to infer anything in names that flow through
4566e4b17023SJohn Marino abnormal edges. */
4567e4b17023SJohn Marino if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
4568e4b17023SJohn Marino return false;
4569e4b17023SJohn Marino
4570e4b17023SJohn Marino if (!extract_code_and_val_from_cond_with_ops (name, cond_code,
4571e4b17023SJohn Marino cond_op0, cond_op1,
4572e4b17023SJohn Marino is_else_edge,
4573e4b17023SJohn Marino &comp_code, &val))
4574e4b17023SJohn Marino return false;
4575e4b17023SJohn Marino
4576e4b17023SJohn Marino /* Register ASSERT_EXPRs for name. */
4577e4b17023SJohn Marino retval |= register_edge_assert_for_2 (name, e, si, cond_code, cond_op0,
4578e4b17023SJohn Marino cond_op1, is_else_edge);
4579e4b17023SJohn Marino
4580e4b17023SJohn Marino
4581e4b17023SJohn Marino /* If COND is effectively an equality test of an SSA_NAME against
4582e4b17023SJohn Marino the value zero or one, then we may be able to assert values
4583e4b17023SJohn Marino for SSA_NAMEs which flow into COND. */
4584e4b17023SJohn Marino
4585e4b17023SJohn Marino /* In the case of NAME == 1 or NAME != 0, for BIT_AND_EXPR defining
4586e4b17023SJohn Marino statement of NAME we can assert both operands of the BIT_AND_EXPR
4587e4b17023SJohn Marino have nonzero value. */
4588e4b17023SJohn Marino if (((comp_code == EQ_EXPR && integer_onep (val))
4589e4b17023SJohn Marino || (comp_code == NE_EXPR && integer_zerop (val))))
4590e4b17023SJohn Marino {
4591e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (name);
4592e4b17023SJohn Marino
4593e4b17023SJohn Marino if (is_gimple_assign (def_stmt)
4594e4b17023SJohn Marino && gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR)
4595e4b17023SJohn Marino {
4596e4b17023SJohn Marino tree op0 = gimple_assign_rhs1 (def_stmt);
4597e4b17023SJohn Marino tree op1 = gimple_assign_rhs2 (def_stmt);
4598e4b17023SJohn Marino retval |= register_edge_assert_for_1 (op0, NE_EXPR, e, si);
4599e4b17023SJohn Marino retval |= register_edge_assert_for_1 (op1, NE_EXPR, e, si);
4600e4b17023SJohn Marino }
4601e4b17023SJohn Marino }
4602e4b17023SJohn Marino
4603e4b17023SJohn Marino /* In the case of NAME == 0 or NAME != 1, for BIT_IOR_EXPR defining
4604e4b17023SJohn Marino statement of NAME we can assert both operands of the BIT_IOR_EXPR
4605e4b17023SJohn Marino have zero value. */
4606e4b17023SJohn Marino if (((comp_code == EQ_EXPR && integer_zerop (val))
4607e4b17023SJohn Marino || (comp_code == NE_EXPR && integer_onep (val))))
4608e4b17023SJohn Marino {
4609e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (name);
4610e4b17023SJohn Marino
4611e4b17023SJohn Marino /* For BIT_IOR_EXPR only if NAME == 0 both operands have
4612e4b17023SJohn Marino necessarily zero value, or if type-precision is one. */
4613e4b17023SJohn Marino if (is_gimple_assign (def_stmt)
4614e4b17023SJohn Marino && (gimple_assign_rhs_code (def_stmt) == BIT_IOR_EXPR
4615e4b17023SJohn Marino && (TYPE_PRECISION (TREE_TYPE (name)) == 1
4616e4b17023SJohn Marino || comp_code == EQ_EXPR)))
4617e4b17023SJohn Marino {
4618e4b17023SJohn Marino tree op0 = gimple_assign_rhs1 (def_stmt);
4619e4b17023SJohn Marino tree op1 = gimple_assign_rhs2 (def_stmt);
4620e4b17023SJohn Marino retval |= register_edge_assert_for_1 (op0, EQ_EXPR, e, si);
4621e4b17023SJohn Marino retval |= register_edge_assert_for_1 (op1, EQ_EXPR, e, si);
4622e4b17023SJohn Marino }
4623e4b17023SJohn Marino }
4624e4b17023SJohn Marino
4625e4b17023SJohn Marino return retval;
4626e4b17023SJohn Marino }
4627e4b17023SJohn Marino
4628e4b17023SJohn Marino
4629e4b17023SJohn Marino /* Determine whether the outgoing edges of BB should receive an
4630e4b17023SJohn Marino ASSERT_EXPR for each of the operands of BB's LAST statement.
4631e4b17023SJohn Marino The last statement of BB must be a COND_EXPR.
4632e4b17023SJohn Marino
4633e4b17023SJohn Marino If any of the sub-graphs rooted at BB have an interesting use of
4634e4b17023SJohn Marino the predicate operands, an assert location node is added to the
4635e4b17023SJohn Marino list of assertions for the corresponding operands. */
4636e4b17023SJohn Marino
4637e4b17023SJohn Marino static bool
find_conditional_asserts(basic_block bb,gimple last)4638e4b17023SJohn Marino find_conditional_asserts (basic_block bb, gimple last)
4639e4b17023SJohn Marino {
4640e4b17023SJohn Marino bool need_assert;
4641e4b17023SJohn Marino gimple_stmt_iterator bsi;
4642e4b17023SJohn Marino tree op;
4643e4b17023SJohn Marino edge_iterator ei;
4644e4b17023SJohn Marino edge e;
4645e4b17023SJohn Marino ssa_op_iter iter;
4646e4b17023SJohn Marino
4647e4b17023SJohn Marino need_assert = false;
4648e4b17023SJohn Marino bsi = gsi_for_stmt (last);
4649e4b17023SJohn Marino
4650e4b17023SJohn Marino /* Look for uses of the operands in each of the sub-graphs
4651e4b17023SJohn Marino rooted at BB. We need to check each of the outgoing edges
4652e4b17023SJohn Marino separately, so that we know what kind of ASSERT_EXPR to
4653e4b17023SJohn Marino insert. */
4654e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
4655e4b17023SJohn Marino {
4656e4b17023SJohn Marino if (e->dest == bb)
4657e4b17023SJohn Marino continue;
4658e4b17023SJohn Marino
4659e4b17023SJohn Marino /* Register the necessary assertions for each operand in the
4660e4b17023SJohn Marino conditional predicate. */
4661e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
4662e4b17023SJohn Marino {
4663e4b17023SJohn Marino need_assert |= register_edge_assert_for (op, e, bsi,
4664e4b17023SJohn Marino gimple_cond_code (last),
4665e4b17023SJohn Marino gimple_cond_lhs (last),
4666e4b17023SJohn Marino gimple_cond_rhs (last));
4667e4b17023SJohn Marino }
4668e4b17023SJohn Marino }
4669e4b17023SJohn Marino
4670e4b17023SJohn Marino return need_assert;
4671e4b17023SJohn Marino }
4672e4b17023SJohn Marino
4673e4b17023SJohn Marino struct case_info
4674e4b17023SJohn Marino {
4675e4b17023SJohn Marino tree expr;
4676e4b17023SJohn Marino basic_block bb;
4677e4b17023SJohn Marino };
4678e4b17023SJohn Marino
4679e4b17023SJohn Marino /* Compare two case labels sorting first by the destination bb index
4680e4b17023SJohn Marino and then by the case value. */
4681e4b17023SJohn Marino
4682e4b17023SJohn Marino static int
compare_case_labels(const void * p1,const void * p2)4683e4b17023SJohn Marino compare_case_labels (const void *p1, const void *p2)
4684e4b17023SJohn Marino {
4685e4b17023SJohn Marino const struct case_info *ci1 = (const struct case_info *) p1;
4686e4b17023SJohn Marino const struct case_info *ci2 = (const struct case_info *) p2;
4687e4b17023SJohn Marino int idx1 = ci1->bb->index;
4688e4b17023SJohn Marino int idx2 = ci2->bb->index;
4689e4b17023SJohn Marino
4690e4b17023SJohn Marino if (idx1 < idx2)
4691e4b17023SJohn Marino return -1;
4692e4b17023SJohn Marino else if (idx1 == idx2)
4693e4b17023SJohn Marino {
4694e4b17023SJohn Marino /* Make sure the default label is first in a group. */
4695e4b17023SJohn Marino if (!CASE_LOW (ci1->expr))
4696e4b17023SJohn Marino return -1;
4697e4b17023SJohn Marino else if (!CASE_LOW (ci2->expr))
4698e4b17023SJohn Marino return 1;
4699e4b17023SJohn Marino else
4700e4b17023SJohn Marino return tree_int_cst_compare (CASE_LOW (ci1->expr),
4701e4b17023SJohn Marino CASE_LOW (ci2->expr));
4702e4b17023SJohn Marino }
4703e4b17023SJohn Marino else
4704e4b17023SJohn Marino return 1;
4705e4b17023SJohn Marino }
4706e4b17023SJohn Marino
4707e4b17023SJohn Marino /* Determine whether the outgoing edges of BB should receive an
4708e4b17023SJohn Marino ASSERT_EXPR for each of the operands of BB's LAST statement.
4709e4b17023SJohn Marino The last statement of BB must be a SWITCH_EXPR.
4710e4b17023SJohn Marino
4711e4b17023SJohn Marino If any of the sub-graphs rooted at BB have an interesting use of
4712e4b17023SJohn Marino the predicate operands, an assert location node is added to the
4713e4b17023SJohn Marino list of assertions for the corresponding operands. */
4714e4b17023SJohn Marino
4715e4b17023SJohn Marino static bool
find_switch_asserts(basic_block bb,gimple last)4716e4b17023SJohn Marino find_switch_asserts (basic_block bb, gimple last)
4717e4b17023SJohn Marino {
4718e4b17023SJohn Marino bool need_assert;
4719e4b17023SJohn Marino gimple_stmt_iterator bsi;
4720e4b17023SJohn Marino tree op;
4721e4b17023SJohn Marino edge e;
4722e4b17023SJohn Marino struct case_info *ci;
4723e4b17023SJohn Marino size_t n = gimple_switch_num_labels (last);
4724e4b17023SJohn Marino #if GCC_VERSION >= 4000
4725e4b17023SJohn Marino unsigned int idx;
4726e4b17023SJohn Marino #else
4727e4b17023SJohn Marino /* Work around GCC 3.4 bug (PR 37086). */
4728e4b17023SJohn Marino volatile unsigned int idx;
4729e4b17023SJohn Marino #endif
4730e4b17023SJohn Marino
4731e4b17023SJohn Marino need_assert = false;
4732e4b17023SJohn Marino bsi = gsi_for_stmt (last);
4733e4b17023SJohn Marino op = gimple_switch_index (last);
4734e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
4735e4b17023SJohn Marino return false;
4736e4b17023SJohn Marino
4737e4b17023SJohn Marino /* Build a vector of case labels sorted by destination label. */
4738e4b17023SJohn Marino ci = XNEWVEC (struct case_info, n);
4739e4b17023SJohn Marino for (idx = 0; idx < n; ++idx)
4740e4b17023SJohn Marino {
4741e4b17023SJohn Marino ci[idx].expr = gimple_switch_label (last, idx);
4742e4b17023SJohn Marino ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
4743e4b17023SJohn Marino }
4744e4b17023SJohn Marino qsort (ci, n, sizeof (struct case_info), compare_case_labels);
4745e4b17023SJohn Marino
4746e4b17023SJohn Marino for (idx = 0; idx < n; ++idx)
4747e4b17023SJohn Marino {
4748e4b17023SJohn Marino tree min, max;
4749e4b17023SJohn Marino tree cl = ci[idx].expr;
4750e4b17023SJohn Marino basic_block cbb = ci[idx].bb;
4751e4b17023SJohn Marino
4752e4b17023SJohn Marino min = CASE_LOW (cl);
4753e4b17023SJohn Marino max = CASE_HIGH (cl);
4754e4b17023SJohn Marino
4755e4b17023SJohn Marino /* If there are multiple case labels with the same destination
4756e4b17023SJohn Marino we need to combine them to a single value range for the edge. */
4757e4b17023SJohn Marino if (idx + 1 < n && cbb == ci[idx + 1].bb)
4758e4b17023SJohn Marino {
4759e4b17023SJohn Marino /* Skip labels until the last of the group. */
4760e4b17023SJohn Marino do {
4761e4b17023SJohn Marino ++idx;
4762e4b17023SJohn Marino } while (idx < n && cbb == ci[idx].bb);
4763e4b17023SJohn Marino --idx;
4764e4b17023SJohn Marino
4765e4b17023SJohn Marino /* Pick up the maximum of the case label range. */
4766e4b17023SJohn Marino if (CASE_HIGH (ci[idx].expr))
4767e4b17023SJohn Marino max = CASE_HIGH (ci[idx].expr);
4768e4b17023SJohn Marino else
4769e4b17023SJohn Marino max = CASE_LOW (ci[idx].expr);
4770e4b17023SJohn Marino }
4771e4b17023SJohn Marino
4772e4b17023SJohn Marino /* Nothing to do if the range includes the default label until we
4773e4b17023SJohn Marino can register anti-ranges. */
4774e4b17023SJohn Marino if (min == NULL_TREE)
4775e4b17023SJohn Marino continue;
4776e4b17023SJohn Marino
4777e4b17023SJohn Marino /* Find the edge to register the assert expr on. */
4778e4b17023SJohn Marino e = find_edge (bb, cbb);
4779e4b17023SJohn Marino
4780e4b17023SJohn Marino /* Register the necessary assertions for the operand in the
4781e4b17023SJohn Marino SWITCH_EXPR. */
4782e4b17023SJohn Marino need_assert |= register_edge_assert_for (op, e, bsi,
4783e4b17023SJohn Marino max ? GE_EXPR : EQ_EXPR,
4784e4b17023SJohn Marino op,
4785e4b17023SJohn Marino fold_convert (TREE_TYPE (op),
4786e4b17023SJohn Marino min));
4787e4b17023SJohn Marino if (max)
4788e4b17023SJohn Marino {
4789e4b17023SJohn Marino need_assert |= register_edge_assert_for (op, e, bsi, LE_EXPR,
4790e4b17023SJohn Marino op,
4791e4b17023SJohn Marino fold_convert (TREE_TYPE (op),
4792e4b17023SJohn Marino max));
4793e4b17023SJohn Marino }
4794e4b17023SJohn Marino }
4795e4b17023SJohn Marino
4796e4b17023SJohn Marino XDELETEVEC (ci);
4797e4b17023SJohn Marino return need_assert;
4798e4b17023SJohn Marino }
4799e4b17023SJohn Marino
4800e4b17023SJohn Marino
4801e4b17023SJohn Marino /* Traverse all the statements in block BB looking for statements that
4802e4b17023SJohn Marino may generate useful assertions for the SSA names in their operand.
4803e4b17023SJohn Marino If a statement produces a useful assertion A for name N_i, then the
4804e4b17023SJohn Marino list of assertions already generated for N_i is scanned to
4805e4b17023SJohn Marino determine if A is actually needed.
4806e4b17023SJohn Marino
4807e4b17023SJohn Marino If N_i already had the assertion A at a location dominating the
4808e4b17023SJohn Marino current location, then nothing needs to be done. Otherwise, the
4809e4b17023SJohn Marino new location for A is recorded instead.
4810e4b17023SJohn Marino
4811e4b17023SJohn Marino 1- For every statement S in BB, all the variables used by S are
4812e4b17023SJohn Marino added to bitmap FOUND_IN_SUBGRAPH.
4813e4b17023SJohn Marino
4814e4b17023SJohn Marino 2- If statement S uses an operand N in a way that exposes a known
4815e4b17023SJohn Marino value range for N, then if N was not already generated by an
4816e4b17023SJohn Marino ASSERT_EXPR, create a new assert location for N. For instance,
4817e4b17023SJohn Marino if N is a pointer and the statement dereferences it, we can
4818e4b17023SJohn Marino assume that N is not NULL.
4819e4b17023SJohn Marino
4820e4b17023SJohn Marino 3- COND_EXPRs are a special case of #2. We can derive range
4821e4b17023SJohn Marino information from the predicate but need to insert different
4822e4b17023SJohn Marino ASSERT_EXPRs for each of the sub-graphs rooted at the
4823e4b17023SJohn Marino conditional block. If the last statement of BB is a conditional
4824e4b17023SJohn Marino expression of the form 'X op Y', then
4825e4b17023SJohn Marino
4826e4b17023SJohn Marino a) Remove X and Y from the set FOUND_IN_SUBGRAPH.
4827e4b17023SJohn Marino
4828e4b17023SJohn Marino b) If the conditional is the only entry point to the sub-graph
4829e4b17023SJohn Marino corresponding to the THEN_CLAUSE, recurse into it. On
4830e4b17023SJohn Marino return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
4831e4b17023SJohn Marino an ASSERT_EXPR is added for the corresponding variable.
4832e4b17023SJohn Marino
4833e4b17023SJohn Marino c) Repeat step (b) on the ELSE_CLAUSE.
4834e4b17023SJohn Marino
4835e4b17023SJohn Marino d) Mark X and Y in FOUND_IN_SUBGRAPH.
4836e4b17023SJohn Marino
4837e4b17023SJohn Marino For instance,
4838e4b17023SJohn Marino
4839e4b17023SJohn Marino if (a == 9)
4840e4b17023SJohn Marino b = a;
4841e4b17023SJohn Marino else
4842e4b17023SJohn Marino b = c + 1;
4843e4b17023SJohn Marino
4844e4b17023SJohn Marino In this case, an assertion on the THEN clause is useful to
4845e4b17023SJohn Marino determine that 'a' is always 9 on that edge. However, an assertion
4846e4b17023SJohn Marino on the ELSE clause would be unnecessary.
4847e4b17023SJohn Marino
4848e4b17023SJohn Marino 4- If BB does not end in a conditional expression, then we recurse
4849e4b17023SJohn Marino into BB's dominator children.
4850e4b17023SJohn Marino
4851e4b17023SJohn Marino At the end of the recursive traversal, every SSA name will have a
4852e4b17023SJohn Marino list of locations where ASSERT_EXPRs should be added. When a new
4853e4b17023SJohn Marino location for name N is found, it is registered by calling
4854e4b17023SJohn Marino register_new_assert_for. That function keeps track of all the
4855e4b17023SJohn Marino registered assertions to prevent adding unnecessary assertions.
4856e4b17023SJohn Marino For instance, if a pointer P_4 is dereferenced more than once in a
4857e4b17023SJohn Marino dominator tree, only the location dominating all the dereference of
4858e4b17023SJohn Marino P_4 will receive an ASSERT_EXPR.
4859e4b17023SJohn Marino
4860e4b17023SJohn Marino If this function returns true, then it means that there are names
4861e4b17023SJohn Marino for which we need to generate ASSERT_EXPRs. Those assertions are
4862e4b17023SJohn Marino inserted by process_assert_insertions. */
4863e4b17023SJohn Marino
4864e4b17023SJohn Marino static bool
find_assert_locations_1(basic_block bb,sbitmap live)4865e4b17023SJohn Marino find_assert_locations_1 (basic_block bb, sbitmap live)
4866e4b17023SJohn Marino {
4867e4b17023SJohn Marino gimple_stmt_iterator si;
4868e4b17023SJohn Marino gimple last;
4869e4b17023SJohn Marino gimple phi;
4870e4b17023SJohn Marino bool need_assert;
4871e4b17023SJohn Marino
4872e4b17023SJohn Marino need_assert = false;
4873e4b17023SJohn Marino last = last_stmt (bb);
4874e4b17023SJohn Marino
4875e4b17023SJohn Marino /* If BB's last statement is a conditional statement involving integer
4876e4b17023SJohn Marino operands, determine if we need to add ASSERT_EXPRs. */
4877e4b17023SJohn Marino if (last
4878e4b17023SJohn Marino && gimple_code (last) == GIMPLE_COND
4879e4b17023SJohn Marino && !fp_predicate (last)
4880e4b17023SJohn Marino && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
4881e4b17023SJohn Marino need_assert |= find_conditional_asserts (bb, last);
4882e4b17023SJohn Marino
4883e4b17023SJohn Marino /* If BB's last statement is a switch statement involving integer
4884e4b17023SJohn Marino operands, determine if we need to add ASSERT_EXPRs. */
4885e4b17023SJohn Marino if (last
4886e4b17023SJohn Marino && gimple_code (last) == GIMPLE_SWITCH
4887e4b17023SJohn Marino && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
4888e4b17023SJohn Marino need_assert |= find_switch_asserts (bb, last);
4889e4b17023SJohn Marino
4890e4b17023SJohn Marino /* Traverse all the statements in BB marking used names and looking
4891e4b17023SJohn Marino for statements that may infer assertions for their used operands. */
4892e4b17023SJohn Marino for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
4893e4b17023SJohn Marino {
4894e4b17023SJohn Marino gimple stmt;
4895e4b17023SJohn Marino tree op;
4896e4b17023SJohn Marino ssa_op_iter i;
4897e4b17023SJohn Marino
4898e4b17023SJohn Marino stmt = gsi_stmt (si);
4899e4b17023SJohn Marino
4900e4b17023SJohn Marino if (is_gimple_debug (stmt))
4901e4b17023SJohn Marino continue;
4902e4b17023SJohn Marino
4903e4b17023SJohn Marino /* See if we can derive an assertion for any of STMT's operands. */
4904e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
4905e4b17023SJohn Marino {
4906e4b17023SJohn Marino tree value;
4907e4b17023SJohn Marino enum tree_code comp_code;
4908e4b17023SJohn Marino
4909e4b17023SJohn Marino /* Mark OP in our live bitmap. */
4910e4b17023SJohn Marino SET_BIT (live, SSA_NAME_VERSION (op));
4911e4b17023SJohn Marino
4912e4b17023SJohn Marino /* If OP is used in such a way that we can infer a value
4913e4b17023SJohn Marino range for it, and we don't find a previous assertion for
4914e4b17023SJohn Marino it, create a new assertion location node for OP. */
4915e4b17023SJohn Marino if (infer_value_range (stmt, op, &comp_code, &value))
4916e4b17023SJohn Marino {
4917e4b17023SJohn Marino /* If we are able to infer a nonzero value range for OP,
4918e4b17023SJohn Marino then walk backwards through the use-def chain to see if OP
4919e4b17023SJohn Marino was set via a typecast.
4920e4b17023SJohn Marino
4921e4b17023SJohn Marino If so, then we can also infer a nonzero value range
4922e4b17023SJohn Marino for the operand of the NOP_EXPR. */
4923e4b17023SJohn Marino if (comp_code == NE_EXPR && integer_zerop (value))
4924e4b17023SJohn Marino {
4925e4b17023SJohn Marino tree t = op;
4926e4b17023SJohn Marino gimple def_stmt = SSA_NAME_DEF_STMT (t);
4927e4b17023SJohn Marino
4928e4b17023SJohn Marino while (is_gimple_assign (def_stmt)
4929e4b17023SJohn Marino && gimple_assign_rhs_code (def_stmt) == NOP_EXPR
4930e4b17023SJohn Marino && TREE_CODE
4931e4b17023SJohn Marino (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
4932e4b17023SJohn Marino && POINTER_TYPE_P
4933e4b17023SJohn Marino (TREE_TYPE (gimple_assign_rhs1 (def_stmt))))
4934e4b17023SJohn Marino {
4935e4b17023SJohn Marino t = gimple_assign_rhs1 (def_stmt);
4936e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (t);
4937e4b17023SJohn Marino
4938e4b17023SJohn Marino /* Note we want to register the assert for the
4939e4b17023SJohn Marino operand of the NOP_EXPR after SI, not after the
4940e4b17023SJohn Marino conversion. */
4941e4b17023SJohn Marino if (! has_single_use (t))
4942e4b17023SJohn Marino {
4943e4b17023SJohn Marino register_new_assert_for (t, t, comp_code, value,
4944e4b17023SJohn Marino bb, NULL, si);
4945e4b17023SJohn Marino need_assert = true;
4946e4b17023SJohn Marino }
4947e4b17023SJohn Marino }
4948e4b17023SJohn Marino }
4949e4b17023SJohn Marino
4950e4b17023SJohn Marino /* If OP is used only once, namely in this STMT, don't
4951e4b17023SJohn Marino bother creating an ASSERT_EXPR for it. Such an
4952e4b17023SJohn Marino ASSERT_EXPR would do nothing but increase compile time. */
4953e4b17023SJohn Marino if (!has_single_use (op))
4954e4b17023SJohn Marino {
4955e4b17023SJohn Marino register_new_assert_for (op, op, comp_code, value,
4956e4b17023SJohn Marino bb, NULL, si);
4957e4b17023SJohn Marino need_assert = true;
4958e4b17023SJohn Marino }
4959e4b17023SJohn Marino }
4960e4b17023SJohn Marino }
4961e4b17023SJohn Marino }
4962e4b17023SJohn Marino
4963e4b17023SJohn Marino /* Traverse all PHI nodes in BB marking used operands. */
4964e4b17023SJohn Marino for (si = gsi_start_phis (bb); !gsi_end_p(si); gsi_next (&si))
4965e4b17023SJohn Marino {
4966e4b17023SJohn Marino use_operand_p arg_p;
4967e4b17023SJohn Marino ssa_op_iter i;
4968e4b17023SJohn Marino phi = gsi_stmt (si);
4969e4b17023SJohn Marino
4970e4b17023SJohn Marino FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
4971e4b17023SJohn Marino {
4972e4b17023SJohn Marino tree arg = USE_FROM_PTR (arg_p);
4973e4b17023SJohn Marino if (TREE_CODE (arg) == SSA_NAME)
4974e4b17023SJohn Marino SET_BIT (live, SSA_NAME_VERSION (arg));
4975e4b17023SJohn Marino }
4976e4b17023SJohn Marino }
4977e4b17023SJohn Marino
4978e4b17023SJohn Marino return need_assert;
4979e4b17023SJohn Marino }
4980e4b17023SJohn Marino
4981e4b17023SJohn Marino /* Do an RPO walk over the function computing SSA name liveness
4982e4b17023SJohn Marino on-the-fly and deciding on assert expressions to insert.
4983e4b17023SJohn Marino Returns true if there are assert expressions to be inserted. */
4984e4b17023SJohn Marino
4985e4b17023SJohn Marino static bool
find_assert_locations(void)4986e4b17023SJohn Marino find_assert_locations (void)
4987e4b17023SJohn Marino {
4988e4b17023SJohn Marino int *rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4989e4b17023SJohn Marino int *bb_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4990e4b17023SJohn Marino int *last_rpo = XCNEWVEC (int, last_basic_block + NUM_FIXED_BLOCKS);
4991e4b17023SJohn Marino int rpo_cnt, i;
4992e4b17023SJohn Marino bool need_asserts;
4993e4b17023SJohn Marino
4994e4b17023SJohn Marino live = XCNEWVEC (sbitmap, last_basic_block + NUM_FIXED_BLOCKS);
4995e4b17023SJohn Marino rpo_cnt = pre_and_rev_post_order_compute (NULL, rpo, false);
4996e4b17023SJohn Marino for (i = 0; i < rpo_cnt; ++i)
4997e4b17023SJohn Marino bb_rpo[rpo[i]] = i;
4998e4b17023SJohn Marino
4999e4b17023SJohn Marino need_asserts = false;
5000e4b17023SJohn Marino for (i = rpo_cnt-1; i >= 0; --i)
5001e4b17023SJohn Marino {
5002e4b17023SJohn Marino basic_block bb = BASIC_BLOCK (rpo[i]);
5003e4b17023SJohn Marino edge e;
5004e4b17023SJohn Marino edge_iterator ei;
5005e4b17023SJohn Marino
5006e4b17023SJohn Marino if (!live[rpo[i]])
5007e4b17023SJohn Marino {
5008e4b17023SJohn Marino live[rpo[i]] = sbitmap_alloc (num_ssa_names);
5009e4b17023SJohn Marino sbitmap_zero (live[rpo[i]]);
5010e4b17023SJohn Marino }
5011e4b17023SJohn Marino
5012e4b17023SJohn Marino /* Process BB and update the live information with uses in
5013e4b17023SJohn Marino this block. */
5014e4b17023SJohn Marino need_asserts |= find_assert_locations_1 (bb, live[rpo[i]]);
5015e4b17023SJohn Marino
5016e4b17023SJohn Marino /* Merge liveness into the predecessor blocks and free it. */
5017e4b17023SJohn Marino if (!sbitmap_empty_p (live[rpo[i]]))
5018e4b17023SJohn Marino {
5019e4b17023SJohn Marino int pred_rpo = i;
5020e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
5021e4b17023SJohn Marino {
5022e4b17023SJohn Marino int pred = e->src->index;
5023e4b17023SJohn Marino if (e->flags & EDGE_DFS_BACK)
5024e4b17023SJohn Marino continue;
5025e4b17023SJohn Marino
5026e4b17023SJohn Marino if (!live[pred])
5027e4b17023SJohn Marino {
5028e4b17023SJohn Marino live[pred] = sbitmap_alloc (num_ssa_names);
5029e4b17023SJohn Marino sbitmap_zero (live[pred]);
5030e4b17023SJohn Marino }
5031e4b17023SJohn Marino sbitmap_a_or_b (live[pred], live[pred], live[rpo[i]]);
5032e4b17023SJohn Marino
5033e4b17023SJohn Marino if (bb_rpo[pred] < pred_rpo)
5034e4b17023SJohn Marino pred_rpo = bb_rpo[pred];
5035e4b17023SJohn Marino }
5036e4b17023SJohn Marino
5037e4b17023SJohn Marino /* Record the RPO number of the last visited block that needs
5038e4b17023SJohn Marino live information from this block. */
5039e4b17023SJohn Marino last_rpo[rpo[i]] = pred_rpo;
5040e4b17023SJohn Marino }
5041e4b17023SJohn Marino else
5042e4b17023SJohn Marino {
5043e4b17023SJohn Marino sbitmap_free (live[rpo[i]]);
5044e4b17023SJohn Marino live[rpo[i]] = NULL;
5045e4b17023SJohn Marino }
5046e4b17023SJohn Marino
5047e4b17023SJohn Marino /* We can free all successors live bitmaps if all their
5048e4b17023SJohn Marino predecessors have been visited already. */
5049e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->succs)
5050e4b17023SJohn Marino if (last_rpo[e->dest->index] == i
5051e4b17023SJohn Marino && live[e->dest->index])
5052e4b17023SJohn Marino {
5053e4b17023SJohn Marino sbitmap_free (live[e->dest->index]);
5054e4b17023SJohn Marino live[e->dest->index] = NULL;
5055e4b17023SJohn Marino }
5056e4b17023SJohn Marino }
5057e4b17023SJohn Marino
5058e4b17023SJohn Marino XDELETEVEC (rpo);
5059e4b17023SJohn Marino XDELETEVEC (bb_rpo);
5060e4b17023SJohn Marino XDELETEVEC (last_rpo);
5061e4b17023SJohn Marino for (i = 0; i < last_basic_block + NUM_FIXED_BLOCKS; ++i)
5062e4b17023SJohn Marino if (live[i])
5063e4b17023SJohn Marino sbitmap_free (live[i]);
5064e4b17023SJohn Marino XDELETEVEC (live);
5065e4b17023SJohn Marino
5066e4b17023SJohn Marino return need_asserts;
5067e4b17023SJohn Marino }
5068e4b17023SJohn Marino
5069e4b17023SJohn Marino /* Create an ASSERT_EXPR for NAME and insert it in the location
5070e4b17023SJohn Marino indicated by LOC. Return true if we made any edge insertions. */
5071e4b17023SJohn Marino
5072e4b17023SJohn Marino static bool
process_assert_insertions_for(tree name,assert_locus_t loc)5073e4b17023SJohn Marino process_assert_insertions_for (tree name, assert_locus_t loc)
5074e4b17023SJohn Marino {
5075e4b17023SJohn Marino /* Build the comparison expression NAME_i COMP_CODE VAL. */
5076e4b17023SJohn Marino gimple stmt;
5077e4b17023SJohn Marino tree cond;
5078e4b17023SJohn Marino gimple assert_stmt;
5079e4b17023SJohn Marino edge_iterator ei;
5080e4b17023SJohn Marino edge e;
5081e4b17023SJohn Marino
5082e4b17023SJohn Marino /* If we have X <=> X do not insert an assert expr for that. */
5083e4b17023SJohn Marino if (loc->expr == loc->val)
5084e4b17023SJohn Marino return false;
5085e4b17023SJohn Marino
5086e4b17023SJohn Marino cond = build2 (loc->comp_code, boolean_type_node, loc->expr, loc->val);
5087e4b17023SJohn Marino assert_stmt = build_assert_expr_for (cond, name);
5088e4b17023SJohn Marino if (loc->e)
5089e4b17023SJohn Marino {
5090e4b17023SJohn Marino /* We have been asked to insert the assertion on an edge. This
5091e4b17023SJohn Marino is used only by COND_EXPR and SWITCH_EXPR assertions. */
5092e4b17023SJohn Marino gcc_checking_assert (gimple_code (gsi_stmt (loc->si)) == GIMPLE_COND
5093e4b17023SJohn Marino || (gimple_code (gsi_stmt (loc->si))
5094e4b17023SJohn Marino == GIMPLE_SWITCH));
5095e4b17023SJohn Marino
5096e4b17023SJohn Marino gsi_insert_on_edge (loc->e, assert_stmt);
5097e4b17023SJohn Marino return true;
5098e4b17023SJohn Marino }
5099e4b17023SJohn Marino
5100e4b17023SJohn Marino /* Otherwise, we can insert right after LOC->SI iff the
5101e4b17023SJohn Marino statement must not be the last statement in the block. */
5102e4b17023SJohn Marino stmt = gsi_stmt (loc->si);
5103e4b17023SJohn Marino if (!stmt_ends_bb_p (stmt))
5104e4b17023SJohn Marino {
5105e4b17023SJohn Marino gsi_insert_after (&loc->si, assert_stmt, GSI_SAME_STMT);
5106e4b17023SJohn Marino return false;
5107e4b17023SJohn Marino }
5108e4b17023SJohn Marino
5109e4b17023SJohn Marino /* If STMT must be the last statement in BB, we can only insert new
5110e4b17023SJohn Marino assertions on the non-abnormal edge out of BB. Note that since
5111e4b17023SJohn Marino STMT is not control flow, there may only be one non-abnormal edge
5112e4b17023SJohn Marino out of BB. */
5113e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, loc->bb->succs)
5114e4b17023SJohn Marino if (!(e->flags & EDGE_ABNORMAL))
5115e4b17023SJohn Marino {
5116e4b17023SJohn Marino gsi_insert_on_edge (e, assert_stmt);
5117e4b17023SJohn Marino return true;
5118e4b17023SJohn Marino }
5119e4b17023SJohn Marino
5120e4b17023SJohn Marino gcc_unreachable ();
5121e4b17023SJohn Marino }
5122e4b17023SJohn Marino
5123e4b17023SJohn Marino
5124e4b17023SJohn Marino /* Process all the insertions registered for every name N_i registered
5125e4b17023SJohn Marino in NEED_ASSERT_FOR. The list of assertions to be inserted are
5126e4b17023SJohn Marino found in ASSERTS_FOR[i]. */
5127e4b17023SJohn Marino
5128e4b17023SJohn Marino static void
process_assert_insertions(void)5129e4b17023SJohn Marino process_assert_insertions (void)
5130e4b17023SJohn Marino {
5131e4b17023SJohn Marino unsigned i;
5132e4b17023SJohn Marino bitmap_iterator bi;
5133e4b17023SJohn Marino bool update_edges_p = false;
5134e4b17023SJohn Marino int num_asserts = 0;
5135e4b17023SJohn Marino
5136e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
5137e4b17023SJohn Marino dump_all_asserts (dump_file);
5138e4b17023SJohn Marino
5139e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
5140e4b17023SJohn Marino {
5141e4b17023SJohn Marino assert_locus_t loc = asserts_for[i];
5142e4b17023SJohn Marino gcc_assert (loc);
5143e4b17023SJohn Marino
5144e4b17023SJohn Marino while (loc)
5145e4b17023SJohn Marino {
5146e4b17023SJohn Marino assert_locus_t next = loc->next;
5147e4b17023SJohn Marino update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
5148e4b17023SJohn Marino free (loc);
5149e4b17023SJohn Marino loc = next;
5150e4b17023SJohn Marino num_asserts++;
5151e4b17023SJohn Marino }
5152e4b17023SJohn Marino }
5153e4b17023SJohn Marino
5154e4b17023SJohn Marino if (update_edges_p)
5155e4b17023SJohn Marino gsi_commit_edge_inserts ();
5156e4b17023SJohn Marino
5157e4b17023SJohn Marino statistics_counter_event (cfun, "Number of ASSERT_EXPR expressions inserted",
5158e4b17023SJohn Marino num_asserts);
5159e4b17023SJohn Marino }
5160e4b17023SJohn Marino
5161e4b17023SJohn Marino
5162e4b17023SJohn Marino /* Traverse the flowgraph looking for conditional jumps to insert range
5163e4b17023SJohn Marino expressions. These range expressions are meant to provide information
5164e4b17023SJohn Marino to optimizations that need to reason in terms of value ranges. They
5165e4b17023SJohn Marino will not be expanded into RTL. For instance, given:
5166e4b17023SJohn Marino
5167e4b17023SJohn Marino x = ...
5168e4b17023SJohn Marino y = ...
5169e4b17023SJohn Marino if (x < y)
5170e4b17023SJohn Marino y = x - 2;
5171e4b17023SJohn Marino else
5172e4b17023SJohn Marino x = y + 3;
5173e4b17023SJohn Marino
5174e4b17023SJohn Marino this pass will transform the code into:
5175e4b17023SJohn Marino
5176e4b17023SJohn Marino x = ...
5177e4b17023SJohn Marino y = ...
5178e4b17023SJohn Marino if (x < y)
5179e4b17023SJohn Marino {
5180e4b17023SJohn Marino x = ASSERT_EXPR <x, x < y>
5181e4b17023SJohn Marino y = x - 2
5182e4b17023SJohn Marino }
5183e4b17023SJohn Marino else
5184e4b17023SJohn Marino {
5185e4b17023SJohn Marino y = ASSERT_EXPR <y, x <= y>
5186e4b17023SJohn Marino x = y + 3
5187e4b17023SJohn Marino }
5188e4b17023SJohn Marino
5189e4b17023SJohn Marino The idea is that once copy and constant propagation have run, other
5190e4b17023SJohn Marino optimizations will be able to determine what ranges of values can 'x'
5191e4b17023SJohn Marino take in different paths of the code, simply by checking the reaching
5192e4b17023SJohn Marino definition of 'x'. */
5193e4b17023SJohn Marino
5194e4b17023SJohn Marino static void
insert_range_assertions(void)5195e4b17023SJohn Marino insert_range_assertions (void)
5196e4b17023SJohn Marino {
5197e4b17023SJohn Marino need_assert_for = BITMAP_ALLOC (NULL);
5198e4b17023SJohn Marino asserts_for = XCNEWVEC (assert_locus_t, num_ssa_names);
5199e4b17023SJohn Marino
5200e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
5201e4b17023SJohn Marino
5202e4b17023SJohn Marino if (find_assert_locations ())
5203e4b17023SJohn Marino {
5204e4b17023SJohn Marino process_assert_insertions ();
5205e4b17023SJohn Marino update_ssa (TODO_update_ssa_no_phi);
5206e4b17023SJohn Marino }
5207e4b17023SJohn Marino
5208e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
5209e4b17023SJohn Marino {
5210e4b17023SJohn Marino fprintf (dump_file, "\nSSA form after inserting ASSERT_EXPRs\n");
5211e4b17023SJohn Marino dump_function_to_file (current_function_decl, dump_file, dump_flags);
5212e4b17023SJohn Marino }
5213e4b17023SJohn Marino
5214e4b17023SJohn Marino free (asserts_for);
5215e4b17023SJohn Marino BITMAP_FREE (need_assert_for);
5216e4b17023SJohn Marino }
5217e4b17023SJohn Marino
5218e4b17023SJohn Marino /* Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
5219e4b17023SJohn Marino and "struct" hacks. If VRP can determine that the
5220e4b17023SJohn Marino array subscript is a constant, check if it is outside valid
5221e4b17023SJohn Marino range. If the array subscript is a RANGE, warn if it is
5222e4b17023SJohn Marino non-overlapping with valid range.
5223e4b17023SJohn Marino IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR. */
5224e4b17023SJohn Marino
5225e4b17023SJohn Marino static void
check_array_ref(location_t location,tree ref,bool ignore_off_by_one)5226e4b17023SJohn Marino check_array_ref (location_t location, tree ref, bool ignore_off_by_one)
5227e4b17023SJohn Marino {
5228e4b17023SJohn Marino value_range_t* vr = NULL;
5229e4b17023SJohn Marino tree low_sub, up_sub;
5230e4b17023SJohn Marino tree low_bound, up_bound, up_bound_p1;
5231e4b17023SJohn Marino tree base;
5232e4b17023SJohn Marino
5233e4b17023SJohn Marino if (TREE_NO_WARNING (ref))
5234e4b17023SJohn Marino return;
5235e4b17023SJohn Marino
5236e4b17023SJohn Marino low_sub = up_sub = TREE_OPERAND (ref, 1);
5237e4b17023SJohn Marino up_bound = array_ref_up_bound (ref);
5238e4b17023SJohn Marino
5239e4b17023SJohn Marino /* Can not check flexible arrays. */
5240e4b17023SJohn Marino if (!up_bound
5241e4b17023SJohn Marino || TREE_CODE (up_bound) != INTEGER_CST)
5242e4b17023SJohn Marino return;
5243e4b17023SJohn Marino
5244e4b17023SJohn Marino /* Accesses to trailing arrays via pointers may access storage
5245e4b17023SJohn Marino beyond the types array bounds. */
5246e4b17023SJohn Marino base = get_base_address (ref);
5247e4b17023SJohn Marino if (base && TREE_CODE (base) == MEM_REF)
5248e4b17023SJohn Marino {
5249e4b17023SJohn Marino tree cref, next = NULL_TREE;
5250e4b17023SJohn Marino
5251e4b17023SJohn Marino if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF)
5252e4b17023SJohn Marino return;
5253e4b17023SJohn Marino
5254e4b17023SJohn Marino cref = TREE_OPERAND (ref, 0);
5255e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (TREE_OPERAND (cref, 0))) == RECORD_TYPE)
5256e4b17023SJohn Marino for (next = DECL_CHAIN (TREE_OPERAND (cref, 1));
5257e4b17023SJohn Marino next && TREE_CODE (next) != FIELD_DECL;
5258e4b17023SJohn Marino next = DECL_CHAIN (next))
5259e4b17023SJohn Marino ;
5260e4b17023SJohn Marino
5261e4b17023SJohn Marino /* If this is the last field in a struct type or a field in a
5262e4b17023SJohn Marino union type do not warn. */
5263e4b17023SJohn Marino if (!next)
5264e4b17023SJohn Marino return;
5265e4b17023SJohn Marino }
5266e4b17023SJohn Marino
5267e4b17023SJohn Marino low_bound = array_ref_low_bound (ref);
5268e4b17023SJohn Marino up_bound_p1 = int_const_binop (PLUS_EXPR, up_bound, integer_one_node);
5269e4b17023SJohn Marino
5270e4b17023SJohn Marino if (TREE_CODE (low_sub) == SSA_NAME)
5271e4b17023SJohn Marino {
5272e4b17023SJohn Marino vr = get_value_range (low_sub);
5273e4b17023SJohn Marino if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
5274e4b17023SJohn Marino {
5275e4b17023SJohn Marino low_sub = vr->type == VR_RANGE ? vr->max : vr->min;
5276e4b17023SJohn Marino up_sub = vr->type == VR_RANGE ? vr->min : vr->max;
5277e4b17023SJohn Marino }
5278e4b17023SJohn Marino }
5279e4b17023SJohn Marino
5280e4b17023SJohn Marino if (vr && vr->type == VR_ANTI_RANGE)
5281e4b17023SJohn Marino {
5282e4b17023SJohn Marino if (TREE_CODE (up_sub) == INTEGER_CST
5283e4b17023SJohn Marino && tree_int_cst_lt (up_bound, up_sub)
5284e4b17023SJohn Marino && TREE_CODE (low_sub) == INTEGER_CST
5285e4b17023SJohn Marino && tree_int_cst_lt (low_sub, low_bound))
5286e4b17023SJohn Marino {
5287e4b17023SJohn Marino warning_at (location, OPT_Warray_bounds,
5288e4b17023SJohn Marino "array subscript is outside array bounds");
5289e4b17023SJohn Marino TREE_NO_WARNING (ref) = 1;
5290e4b17023SJohn Marino }
5291e4b17023SJohn Marino }
5292e4b17023SJohn Marino else if (TREE_CODE (up_sub) == INTEGER_CST
5293e4b17023SJohn Marino && (ignore_off_by_one
5294e4b17023SJohn Marino ? (tree_int_cst_lt (up_bound, up_sub)
5295e4b17023SJohn Marino && !tree_int_cst_equal (up_bound_p1, up_sub))
5296e4b17023SJohn Marino : (tree_int_cst_lt (up_bound, up_sub)
5297e4b17023SJohn Marino || tree_int_cst_equal (up_bound_p1, up_sub))))
5298e4b17023SJohn Marino {
5299e4b17023SJohn Marino warning_at (location, OPT_Warray_bounds,
5300e4b17023SJohn Marino "array subscript is above array bounds");
5301e4b17023SJohn Marino TREE_NO_WARNING (ref) = 1;
5302e4b17023SJohn Marino }
5303e4b17023SJohn Marino else if (TREE_CODE (low_sub) == INTEGER_CST
5304e4b17023SJohn Marino && tree_int_cst_lt (low_sub, low_bound))
5305e4b17023SJohn Marino {
5306e4b17023SJohn Marino warning_at (location, OPT_Warray_bounds,
5307e4b17023SJohn Marino "array subscript is below array bounds");
5308e4b17023SJohn Marino TREE_NO_WARNING (ref) = 1;
5309e4b17023SJohn Marino }
5310e4b17023SJohn Marino }
5311e4b17023SJohn Marino
5312e4b17023SJohn Marino /* Searches if the expr T, located at LOCATION computes
5313e4b17023SJohn Marino address of an ARRAY_REF, and call check_array_ref on it. */
5314e4b17023SJohn Marino
5315e4b17023SJohn Marino static void
search_for_addr_array(tree t,location_t location)5316e4b17023SJohn Marino search_for_addr_array (tree t, location_t location)
5317e4b17023SJohn Marino {
5318e4b17023SJohn Marino while (TREE_CODE (t) == SSA_NAME)
5319e4b17023SJohn Marino {
5320e4b17023SJohn Marino gimple g = SSA_NAME_DEF_STMT (t);
5321e4b17023SJohn Marino
5322e4b17023SJohn Marino if (gimple_code (g) != GIMPLE_ASSIGN)
5323e4b17023SJohn Marino return;
5324e4b17023SJohn Marino
5325e4b17023SJohn Marino if (get_gimple_rhs_class (gimple_assign_rhs_code (g))
5326e4b17023SJohn Marino != GIMPLE_SINGLE_RHS)
5327e4b17023SJohn Marino return;
5328e4b17023SJohn Marino
5329e4b17023SJohn Marino t = gimple_assign_rhs1 (g);
5330e4b17023SJohn Marino }
5331e4b17023SJohn Marino
5332e4b17023SJohn Marino
5333e4b17023SJohn Marino /* We are only interested in addresses of ARRAY_REF's. */
5334e4b17023SJohn Marino if (TREE_CODE (t) != ADDR_EXPR)
5335e4b17023SJohn Marino return;
5336e4b17023SJohn Marino
5337e4b17023SJohn Marino /* Check each ARRAY_REFs in the reference chain. */
5338e4b17023SJohn Marino do
5339e4b17023SJohn Marino {
5340e4b17023SJohn Marino if (TREE_CODE (t) == ARRAY_REF)
5341e4b17023SJohn Marino check_array_ref (location, t, true /*ignore_off_by_one*/);
5342e4b17023SJohn Marino
5343e4b17023SJohn Marino t = TREE_OPERAND (t, 0);
5344e4b17023SJohn Marino }
5345e4b17023SJohn Marino while (handled_component_p (t));
5346e4b17023SJohn Marino
5347e4b17023SJohn Marino if (TREE_CODE (t) == MEM_REF
5348e4b17023SJohn Marino && TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
5349e4b17023SJohn Marino && !TREE_NO_WARNING (t))
5350e4b17023SJohn Marino {
5351e4b17023SJohn Marino tree tem = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
5352e4b17023SJohn Marino tree low_bound, up_bound, el_sz;
5353e4b17023SJohn Marino double_int idx;
5354e4b17023SJohn Marino if (TREE_CODE (TREE_TYPE (tem)) != ARRAY_TYPE
5355e4b17023SJohn Marino || TREE_CODE (TREE_TYPE (TREE_TYPE (tem))) == ARRAY_TYPE
5356e4b17023SJohn Marino || !TYPE_DOMAIN (TREE_TYPE (tem)))
5357e4b17023SJohn Marino return;
5358e4b17023SJohn Marino
5359e4b17023SJohn Marino low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (tem)));
5360e4b17023SJohn Marino up_bound = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (tem)));
5361e4b17023SJohn Marino el_sz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (tem)));
5362e4b17023SJohn Marino if (!low_bound
5363e4b17023SJohn Marino || TREE_CODE (low_bound) != INTEGER_CST
5364e4b17023SJohn Marino || !up_bound
5365e4b17023SJohn Marino || TREE_CODE (up_bound) != INTEGER_CST
5366e4b17023SJohn Marino || !el_sz
5367e4b17023SJohn Marino || TREE_CODE (el_sz) != INTEGER_CST)
5368e4b17023SJohn Marino return;
5369e4b17023SJohn Marino
5370e4b17023SJohn Marino idx = mem_ref_offset (t);
5371e4b17023SJohn Marino idx = double_int_sdiv (idx, tree_to_double_int (el_sz), TRUNC_DIV_EXPR);
5372e4b17023SJohn Marino if (double_int_scmp (idx, double_int_zero) < 0)
5373e4b17023SJohn Marino {
5374e4b17023SJohn Marino warning_at (location, OPT_Warray_bounds,
5375e4b17023SJohn Marino "array subscript is below array bounds");
5376e4b17023SJohn Marino TREE_NO_WARNING (t) = 1;
5377e4b17023SJohn Marino }
5378e4b17023SJohn Marino else if (double_int_scmp (idx,
5379e4b17023SJohn Marino double_int_add
5380e4b17023SJohn Marino (double_int_add
5381e4b17023SJohn Marino (tree_to_double_int (up_bound),
5382e4b17023SJohn Marino double_int_neg
5383e4b17023SJohn Marino (tree_to_double_int (low_bound))),
5384e4b17023SJohn Marino double_int_one)) > 0)
5385e4b17023SJohn Marino {
5386e4b17023SJohn Marino warning_at (location, OPT_Warray_bounds,
5387e4b17023SJohn Marino "array subscript is above array bounds");
5388e4b17023SJohn Marino TREE_NO_WARNING (t) = 1;
5389e4b17023SJohn Marino }
5390e4b17023SJohn Marino }
5391e4b17023SJohn Marino }
5392e4b17023SJohn Marino
5393e4b17023SJohn Marino /* walk_tree() callback that checks if *TP is
5394e4b17023SJohn Marino an ARRAY_REF inside an ADDR_EXPR (in which an array
5395e4b17023SJohn Marino subscript one outside the valid range is allowed). Call
5396e4b17023SJohn Marino check_array_ref for each ARRAY_REF found. The location is
5397e4b17023SJohn Marino passed in DATA. */
5398e4b17023SJohn Marino
5399e4b17023SJohn Marino static tree
check_array_bounds(tree * tp,int * walk_subtree,void * data)5400e4b17023SJohn Marino check_array_bounds (tree *tp, int *walk_subtree, void *data)
5401e4b17023SJohn Marino {
5402e4b17023SJohn Marino tree t = *tp;
5403e4b17023SJohn Marino struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
5404e4b17023SJohn Marino location_t location;
5405e4b17023SJohn Marino
5406e4b17023SJohn Marino if (EXPR_HAS_LOCATION (t))
5407e4b17023SJohn Marino location = EXPR_LOCATION (t);
5408e4b17023SJohn Marino else
5409e4b17023SJohn Marino {
5410e4b17023SJohn Marino location_t *locp = (location_t *) wi->info;
5411e4b17023SJohn Marino location = *locp;
5412e4b17023SJohn Marino }
5413e4b17023SJohn Marino
5414e4b17023SJohn Marino *walk_subtree = TRUE;
5415e4b17023SJohn Marino
5416e4b17023SJohn Marino if (TREE_CODE (t) == ARRAY_REF)
5417e4b17023SJohn Marino check_array_ref (location, t, false /*ignore_off_by_one*/);
5418e4b17023SJohn Marino
5419e4b17023SJohn Marino if (TREE_CODE (t) == MEM_REF
5420e4b17023SJohn Marino || (TREE_CODE (t) == RETURN_EXPR && TREE_OPERAND (t, 0)))
5421e4b17023SJohn Marino search_for_addr_array (TREE_OPERAND (t, 0), location);
5422e4b17023SJohn Marino
5423e4b17023SJohn Marino if (TREE_CODE (t) == ADDR_EXPR)
5424e4b17023SJohn Marino *walk_subtree = FALSE;
5425e4b17023SJohn Marino
5426e4b17023SJohn Marino return NULL_TREE;
5427e4b17023SJohn Marino }
5428e4b17023SJohn Marino
5429e4b17023SJohn Marino /* Walk over all statements of all reachable BBs and call check_array_bounds
5430e4b17023SJohn Marino on them. */
5431e4b17023SJohn Marino
5432e4b17023SJohn Marino static void
check_all_array_refs(void)5433e4b17023SJohn Marino check_all_array_refs (void)
5434e4b17023SJohn Marino {
5435e4b17023SJohn Marino basic_block bb;
5436e4b17023SJohn Marino gimple_stmt_iterator si;
5437e4b17023SJohn Marino
5438e4b17023SJohn Marino FOR_EACH_BB (bb)
5439e4b17023SJohn Marino {
5440e4b17023SJohn Marino edge_iterator ei;
5441e4b17023SJohn Marino edge e;
5442e4b17023SJohn Marino bool executable = false;
5443e4b17023SJohn Marino
5444e4b17023SJohn Marino /* Skip blocks that were found to be unreachable. */
5445e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
5446e4b17023SJohn Marino executable |= !!(e->flags & EDGE_EXECUTABLE);
5447e4b17023SJohn Marino if (!executable)
5448e4b17023SJohn Marino continue;
5449e4b17023SJohn Marino
5450e4b17023SJohn Marino for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
5451e4b17023SJohn Marino {
5452e4b17023SJohn Marino gimple stmt = gsi_stmt (si);
5453e4b17023SJohn Marino struct walk_stmt_info wi;
5454e4b17023SJohn Marino if (!gimple_has_location (stmt))
5455e4b17023SJohn Marino continue;
5456e4b17023SJohn Marino
5457e4b17023SJohn Marino if (is_gimple_call (stmt))
5458e4b17023SJohn Marino {
5459e4b17023SJohn Marino size_t i;
5460e4b17023SJohn Marino size_t n = gimple_call_num_args (stmt);
5461e4b17023SJohn Marino for (i = 0; i < n; i++)
5462e4b17023SJohn Marino {
5463e4b17023SJohn Marino tree arg = gimple_call_arg (stmt, i);
5464e4b17023SJohn Marino search_for_addr_array (arg, gimple_location (stmt));
5465e4b17023SJohn Marino }
5466e4b17023SJohn Marino }
5467e4b17023SJohn Marino else
5468e4b17023SJohn Marino {
5469e4b17023SJohn Marino memset (&wi, 0, sizeof (wi));
5470e4b17023SJohn Marino wi.info = CONST_CAST (void *, (const void *)
5471e4b17023SJohn Marino gimple_location_ptr (stmt));
5472e4b17023SJohn Marino
5473e4b17023SJohn Marino walk_gimple_op (gsi_stmt (si),
5474e4b17023SJohn Marino check_array_bounds,
5475e4b17023SJohn Marino &wi);
5476e4b17023SJohn Marino }
5477e4b17023SJohn Marino }
5478e4b17023SJohn Marino }
5479e4b17023SJohn Marino }
5480e4b17023SJohn Marino
5481e4b17023SJohn Marino /* Convert range assertion expressions into the implied copies and
5482e4b17023SJohn Marino copy propagate away the copies. Doing the trivial copy propagation
5483e4b17023SJohn Marino here avoids the need to run the full copy propagation pass after
5484e4b17023SJohn Marino VRP.
5485e4b17023SJohn Marino
5486e4b17023SJohn Marino FIXME, this will eventually lead to copy propagation removing the
5487e4b17023SJohn Marino names that had useful range information attached to them. For
5488e4b17023SJohn Marino instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
5489e4b17023SJohn Marino then N_i will have the range [3, +INF].
5490e4b17023SJohn Marino
5491e4b17023SJohn Marino However, by converting the assertion into the implied copy
5492e4b17023SJohn Marino operation N_i = N_j, we will then copy-propagate N_j into the uses
5493e4b17023SJohn Marino of N_i and lose the range information. We may want to hold on to
5494e4b17023SJohn Marino ASSERT_EXPRs a little while longer as the ranges could be used in
5495e4b17023SJohn Marino things like jump threading.
5496e4b17023SJohn Marino
5497e4b17023SJohn Marino The problem with keeping ASSERT_EXPRs around is that passes after
5498e4b17023SJohn Marino VRP need to handle them appropriately.
5499e4b17023SJohn Marino
5500e4b17023SJohn Marino Another approach would be to make the range information a first
5501e4b17023SJohn Marino class property of the SSA_NAME so that it can be queried from
5502e4b17023SJohn Marino any pass. This is made somewhat more complex by the need for
5503e4b17023SJohn Marino multiple ranges to be associated with one SSA_NAME. */
5504e4b17023SJohn Marino
5505e4b17023SJohn Marino static void
remove_range_assertions(void)5506e4b17023SJohn Marino remove_range_assertions (void)
5507e4b17023SJohn Marino {
5508e4b17023SJohn Marino basic_block bb;
5509e4b17023SJohn Marino gimple_stmt_iterator si;
5510e4b17023SJohn Marino
5511e4b17023SJohn Marino /* Note that the BSI iterator bump happens at the bottom of the
5512e4b17023SJohn Marino loop and no bump is necessary if we're removing the statement
5513e4b17023SJohn Marino referenced by the current BSI. */
5514e4b17023SJohn Marino FOR_EACH_BB (bb)
5515e4b17023SJohn Marino for (si = gsi_start_bb (bb); !gsi_end_p (si);)
5516e4b17023SJohn Marino {
5517e4b17023SJohn Marino gimple stmt = gsi_stmt (si);
5518e4b17023SJohn Marino gimple use_stmt;
5519e4b17023SJohn Marino
5520e4b17023SJohn Marino if (is_gimple_assign (stmt)
5521e4b17023SJohn Marino && gimple_assign_rhs_code (stmt) == ASSERT_EXPR)
5522e4b17023SJohn Marino {
5523e4b17023SJohn Marino tree rhs = gimple_assign_rhs1 (stmt);
5524e4b17023SJohn Marino tree var;
5525e4b17023SJohn Marino tree cond = fold (ASSERT_EXPR_COND (rhs));
5526e4b17023SJohn Marino use_operand_p use_p;
5527e4b17023SJohn Marino imm_use_iterator iter;
5528e4b17023SJohn Marino
5529e4b17023SJohn Marino gcc_assert (cond != boolean_false_node);
5530e4b17023SJohn Marino
5531e4b17023SJohn Marino /* Propagate the RHS into every use of the LHS. */
5532e4b17023SJohn Marino var = ASSERT_EXPR_VAR (rhs);
5533e4b17023SJohn Marino FOR_EACH_IMM_USE_STMT (use_stmt, iter,
5534e4b17023SJohn Marino gimple_assign_lhs (stmt))
5535e4b17023SJohn Marino FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
5536e4b17023SJohn Marino {
5537e4b17023SJohn Marino SET_USE (use_p, var);
5538e4b17023SJohn Marino gcc_assert (TREE_CODE (var) == SSA_NAME);
5539e4b17023SJohn Marino }
5540e4b17023SJohn Marino
5541e4b17023SJohn Marino /* And finally, remove the copy, it is not needed. */
5542e4b17023SJohn Marino gsi_remove (&si, true);
5543e4b17023SJohn Marino release_defs (stmt);
5544e4b17023SJohn Marino }
5545e4b17023SJohn Marino else
5546e4b17023SJohn Marino gsi_next (&si);
5547e4b17023SJohn Marino }
5548e4b17023SJohn Marino }
5549e4b17023SJohn Marino
5550e4b17023SJohn Marino
5551e4b17023SJohn Marino /* Return true if STMT is interesting for VRP. */
5552e4b17023SJohn Marino
5553e4b17023SJohn Marino static bool
stmt_interesting_for_vrp(gimple stmt)5554e4b17023SJohn Marino stmt_interesting_for_vrp (gimple stmt)
5555e4b17023SJohn Marino {
5556e4b17023SJohn Marino if (gimple_code (stmt) == GIMPLE_PHI
5557e4b17023SJohn Marino && is_gimple_reg (gimple_phi_result (stmt))
5558e4b17023SJohn Marino && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))
5559e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (gimple_phi_result (stmt)))))
5560e4b17023SJohn Marino return true;
5561e4b17023SJohn Marino else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
5562e4b17023SJohn Marino {
5563e4b17023SJohn Marino tree lhs = gimple_get_lhs (stmt);
5564e4b17023SJohn Marino
5565e4b17023SJohn Marino /* In general, assignments with virtual operands are not useful
5566e4b17023SJohn Marino for deriving ranges, with the obvious exception of calls to
5567e4b17023SJohn Marino builtin functions. */
5568e4b17023SJohn Marino if (lhs && TREE_CODE (lhs) == SSA_NAME
5569e4b17023SJohn Marino && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
5570e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (lhs)))
5571e4b17023SJohn Marino && ((is_gimple_call (stmt)
5572e4b17023SJohn Marino && gimple_call_fndecl (stmt) != NULL_TREE
5573e4b17023SJohn Marino && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
5574e4b17023SJohn Marino || !gimple_vuse (stmt)))
5575e4b17023SJohn Marino return true;
5576e4b17023SJohn Marino }
5577e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_COND
5578e4b17023SJohn Marino || gimple_code (stmt) == GIMPLE_SWITCH)
5579e4b17023SJohn Marino return true;
5580e4b17023SJohn Marino
5581e4b17023SJohn Marino return false;
5582e4b17023SJohn Marino }
5583e4b17023SJohn Marino
5584e4b17023SJohn Marino
5585e4b17023SJohn Marino /* Initialize local data structures for VRP. */
5586e4b17023SJohn Marino
5587e4b17023SJohn Marino static void
vrp_initialize(void)5588e4b17023SJohn Marino vrp_initialize (void)
5589e4b17023SJohn Marino {
5590e4b17023SJohn Marino basic_block bb;
5591e4b17023SJohn Marino
5592e4b17023SJohn Marino values_propagated = false;
5593e4b17023SJohn Marino num_vr_values = num_ssa_names;
5594e4b17023SJohn Marino vr_value = XCNEWVEC (value_range_t *, num_vr_values);
5595e4b17023SJohn Marino vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
5596e4b17023SJohn Marino
5597e4b17023SJohn Marino FOR_EACH_BB (bb)
5598e4b17023SJohn Marino {
5599e4b17023SJohn Marino gimple_stmt_iterator si;
5600e4b17023SJohn Marino
5601e4b17023SJohn Marino for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
5602e4b17023SJohn Marino {
5603e4b17023SJohn Marino gimple phi = gsi_stmt (si);
5604e4b17023SJohn Marino if (!stmt_interesting_for_vrp (phi))
5605e4b17023SJohn Marino {
5606e4b17023SJohn Marino tree lhs = PHI_RESULT (phi);
5607e4b17023SJohn Marino set_value_range_to_varying (get_value_range (lhs));
5608e4b17023SJohn Marino prop_set_simulate_again (phi, false);
5609e4b17023SJohn Marino }
5610e4b17023SJohn Marino else
5611e4b17023SJohn Marino prop_set_simulate_again (phi, true);
5612e4b17023SJohn Marino }
5613e4b17023SJohn Marino
5614e4b17023SJohn Marino for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
5615e4b17023SJohn Marino {
5616e4b17023SJohn Marino gimple stmt = gsi_stmt (si);
5617e4b17023SJohn Marino
5618e4b17023SJohn Marino /* If the statement is a control insn, then we do not
5619e4b17023SJohn Marino want to avoid simulating the statement once. Failure
5620e4b17023SJohn Marino to do so means that those edges will never get added. */
5621e4b17023SJohn Marino if (stmt_ends_bb_p (stmt))
5622e4b17023SJohn Marino prop_set_simulate_again (stmt, true);
5623e4b17023SJohn Marino else if (!stmt_interesting_for_vrp (stmt))
5624e4b17023SJohn Marino {
5625e4b17023SJohn Marino ssa_op_iter i;
5626e4b17023SJohn Marino tree def;
5627e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
5628e4b17023SJohn Marino set_value_range_to_varying (get_value_range (def));
5629e4b17023SJohn Marino prop_set_simulate_again (stmt, false);
5630e4b17023SJohn Marino }
5631e4b17023SJohn Marino else
5632e4b17023SJohn Marino prop_set_simulate_again (stmt, true);
5633e4b17023SJohn Marino }
5634e4b17023SJohn Marino }
5635e4b17023SJohn Marino }
5636e4b17023SJohn Marino
5637e4b17023SJohn Marino /* Return the singleton value-range for NAME or NAME. */
5638e4b17023SJohn Marino
5639e4b17023SJohn Marino static inline tree
vrp_valueize(tree name)5640e4b17023SJohn Marino vrp_valueize (tree name)
5641e4b17023SJohn Marino {
5642e4b17023SJohn Marino if (TREE_CODE (name) == SSA_NAME)
5643e4b17023SJohn Marino {
5644e4b17023SJohn Marino value_range_t *vr = get_value_range (name);
5645e4b17023SJohn Marino if (vr->type == VR_RANGE
5646e4b17023SJohn Marino && (vr->min == vr->max
5647e4b17023SJohn Marino || operand_equal_p (vr->min, vr->max, 0)))
5648e4b17023SJohn Marino return vr->min;
5649e4b17023SJohn Marino }
5650e4b17023SJohn Marino return name;
5651e4b17023SJohn Marino }
5652e4b17023SJohn Marino
5653e4b17023SJohn Marino /* Visit assignment STMT. If it produces an interesting range, record
5654e4b17023SJohn Marino the SSA name in *OUTPUT_P. */
5655e4b17023SJohn Marino
5656e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_assignment_or_call(gimple stmt,tree * output_p)5657e4b17023SJohn Marino vrp_visit_assignment_or_call (gimple stmt, tree *output_p)
5658e4b17023SJohn Marino {
5659e4b17023SJohn Marino tree def, lhs;
5660e4b17023SJohn Marino ssa_op_iter iter;
5661e4b17023SJohn Marino enum gimple_code code = gimple_code (stmt);
5662e4b17023SJohn Marino lhs = gimple_get_lhs (stmt);
5663e4b17023SJohn Marino
5664e4b17023SJohn Marino /* We only keep track of ranges in integral and pointer types. */
5665e4b17023SJohn Marino if (TREE_CODE (lhs) == SSA_NAME
5666e4b17023SJohn Marino && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
5667e4b17023SJohn Marino /* It is valid to have NULL MIN/MAX values on a type. See
5668e4b17023SJohn Marino build_range_type. */
5669e4b17023SJohn Marino && TYPE_MIN_VALUE (TREE_TYPE (lhs))
5670e4b17023SJohn Marino && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
5671e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (lhs))))
5672e4b17023SJohn Marino {
5673e4b17023SJohn Marino value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
5674e4b17023SJohn Marino
5675e4b17023SJohn Marino /* Try folding the statement to a constant first. */
5676e4b17023SJohn Marino tree tem = gimple_fold_stmt_to_constant (stmt, vrp_valueize);
5677e4b17023SJohn Marino if (tem && !is_overflow_infinity (tem))
5678e4b17023SJohn Marino set_value_range (&new_vr, VR_RANGE, tem, tem, NULL);
5679e4b17023SJohn Marino /* Then dispatch to value-range extracting functions. */
5680e4b17023SJohn Marino else if (code == GIMPLE_CALL)
5681e4b17023SJohn Marino extract_range_basic (&new_vr, stmt);
5682e4b17023SJohn Marino else
5683e4b17023SJohn Marino extract_range_from_assignment (&new_vr, stmt);
5684e4b17023SJohn Marino
5685e4b17023SJohn Marino if (update_value_range (lhs, &new_vr))
5686e4b17023SJohn Marino {
5687e4b17023SJohn Marino *output_p = lhs;
5688e4b17023SJohn Marino
5689e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
5690e4b17023SJohn Marino {
5691e4b17023SJohn Marino fprintf (dump_file, "Found new range for ");
5692e4b17023SJohn Marino print_generic_expr (dump_file, lhs, 0);
5693e4b17023SJohn Marino fprintf (dump_file, ": ");
5694e4b17023SJohn Marino dump_value_range (dump_file, &new_vr);
5695e4b17023SJohn Marino fprintf (dump_file, "\n\n");
5696e4b17023SJohn Marino }
5697e4b17023SJohn Marino
5698e4b17023SJohn Marino if (new_vr.type == VR_VARYING)
5699e4b17023SJohn Marino return SSA_PROP_VARYING;
5700e4b17023SJohn Marino
5701e4b17023SJohn Marino return SSA_PROP_INTERESTING;
5702e4b17023SJohn Marino }
5703e4b17023SJohn Marino
5704e4b17023SJohn Marino return SSA_PROP_NOT_INTERESTING;
5705e4b17023SJohn Marino }
5706e4b17023SJohn Marino
5707e4b17023SJohn Marino /* Every other statement produces no useful ranges. */
5708e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
5709e4b17023SJohn Marino set_value_range_to_varying (get_value_range (def));
5710e4b17023SJohn Marino
5711e4b17023SJohn Marino return SSA_PROP_VARYING;
5712e4b17023SJohn Marino }
5713e4b17023SJohn Marino
5714e4b17023SJohn Marino /* Helper that gets the value range of the SSA_NAME with version I
5715e4b17023SJohn Marino or a symbolic range containing the SSA_NAME only if the value range
5716e4b17023SJohn Marino is varying or undefined. */
5717e4b17023SJohn Marino
5718e4b17023SJohn Marino static inline value_range_t
get_vr_for_comparison(int i)5719e4b17023SJohn Marino get_vr_for_comparison (int i)
5720e4b17023SJohn Marino {
5721e4b17023SJohn Marino value_range_t vr = *get_value_range (ssa_name (i));
5722e4b17023SJohn Marino
5723e4b17023SJohn Marino /* If name N_i does not have a valid range, use N_i as its own
5724e4b17023SJohn Marino range. This allows us to compare against names that may
5725e4b17023SJohn Marino have N_i in their ranges. */
5726e4b17023SJohn Marino if (vr.type == VR_VARYING || vr.type == VR_UNDEFINED)
5727e4b17023SJohn Marino {
5728e4b17023SJohn Marino vr.type = VR_RANGE;
5729e4b17023SJohn Marino vr.min = ssa_name (i);
5730e4b17023SJohn Marino vr.max = ssa_name (i);
5731e4b17023SJohn Marino }
5732e4b17023SJohn Marino
5733e4b17023SJohn Marino return vr;
5734e4b17023SJohn Marino }
5735e4b17023SJohn Marino
5736e4b17023SJohn Marino /* Compare all the value ranges for names equivalent to VAR with VAL
5737e4b17023SJohn Marino using comparison code COMP. Return the same value returned by
5738e4b17023SJohn Marino compare_range_with_value, including the setting of
5739e4b17023SJohn Marino *STRICT_OVERFLOW_P. */
5740e4b17023SJohn Marino
5741e4b17023SJohn Marino static tree
compare_name_with_value(enum tree_code comp,tree var,tree val,bool * strict_overflow_p)5742e4b17023SJohn Marino compare_name_with_value (enum tree_code comp, tree var, tree val,
5743e4b17023SJohn Marino bool *strict_overflow_p)
5744e4b17023SJohn Marino {
5745e4b17023SJohn Marino bitmap_iterator bi;
5746e4b17023SJohn Marino unsigned i;
5747e4b17023SJohn Marino bitmap e;
5748e4b17023SJohn Marino tree retval, t;
5749e4b17023SJohn Marino int used_strict_overflow;
5750e4b17023SJohn Marino bool sop;
5751e4b17023SJohn Marino value_range_t equiv_vr;
5752e4b17023SJohn Marino
5753e4b17023SJohn Marino /* Get the set of equivalences for VAR. */
5754e4b17023SJohn Marino e = get_value_range (var)->equiv;
5755e4b17023SJohn Marino
5756e4b17023SJohn Marino /* Start at -1. Set it to 0 if we do a comparison without relying
5757e4b17023SJohn Marino on overflow, or 1 if all comparisons rely on overflow. */
5758e4b17023SJohn Marino used_strict_overflow = -1;
5759e4b17023SJohn Marino
5760e4b17023SJohn Marino /* Compare vars' value range with val. */
5761e4b17023SJohn Marino equiv_vr = get_vr_for_comparison (SSA_NAME_VERSION (var));
5762e4b17023SJohn Marino sop = false;
5763e4b17023SJohn Marino retval = compare_range_with_value (comp, &equiv_vr, val, &sop);
5764e4b17023SJohn Marino if (retval)
5765e4b17023SJohn Marino used_strict_overflow = sop ? 1 : 0;
5766e4b17023SJohn Marino
5767e4b17023SJohn Marino /* If the equiv set is empty we have done all work we need to do. */
5768e4b17023SJohn Marino if (e == NULL)
5769e4b17023SJohn Marino {
5770e4b17023SJohn Marino if (retval
5771e4b17023SJohn Marino && used_strict_overflow > 0)
5772e4b17023SJohn Marino *strict_overflow_p = true;
5773e4b17023SJohn Marino return retval;
5774e4b17023SJohn Marino }
5775e4b17023SJohn Marino
5776e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
5777e4b17023SJohn Marino {
5778e4b17023SJohn Marino equiv_vr = get_vr_for_comparison (i);
5779e4b17023SJohn Marino sop = false;
5780e4b17023SJohn Marino t = compare_range_with_value (comp, &equiv_vr, val, &sop);
5781e4b17023SJohn Marino if (t)
5782e4b17023SJohn Marino {
5783e4b17023SJohn Marino /* If we get different answers from different members
5784e4b17023SJohn Marino of the equivalence set this check must be in a dead
5785e4b17023SJohn Marino code region. Folding it to a trap representation
5786e4b17023SJohn Marino would be correct here. For now just return don't-know. */
5787e4b17023SJohn Marino if (retval != NULL
5788e4b17023SJohn Marino && t != retval)
5789e4b17023SJohn Marino {
5790e4b17023SJohn Marino retval = NULL_TREE;
5791e4b17023SJohn Marino break;
5792e4b17023SJohn Marino }
5793e4b17023SJohn Marino retval = t;
5794e4b17023SJohn Marino
5795e4b17023SJohn Marino if (!sop)
5796e4b17023SJohn Marino used_strict_overflow = 0;
5797e4b17023SJohn Marino else if (used_strict_overflow < 0)
5798e4b17023SJohn Marino used_strict_overflow = 1;
5799e4b17023SJohn Marino }
5800e4b17023SJohn Marino }
5801e4b17023SJohn Marino
5802e4b17023SJohn Marino if (retval
5803e4b17023SJohn Marino && used_strict_overflow > 0)
5804e4b17023SJohn Marino *strict_overflow_p = true;
5805e4b17023SJohn Marino
5806e4b17023SJohn Marino return retval;
5807e4b17023SJohn Marino }
5808e4b17023SJohn Marino
5809e4b17023SJohn Marino
5810e4b17023SJohn Marino /* Given a comparison code COMP and names N1 and N2, compare all the
5811e4b17023SJohn Marino ranges equivalent to N1 against all the ranges equivalent to N2
5812e4b17023SJohn Marino to determine the value of N1 COMP N2. Return the same value
5813e4b17023SJohn Marino returned by compare_ranges. Set *STRICT_OVERFLOW_P to indicate
5814e4b17023SJohn Marino whether we relied on an overflow infinity in the comparison. */
5815e4b17023SJohn Marino
5816e4b17023SJohn Marino
5817e4b17023SJohn Marino static tree
compare_names(enum tree_code comp,tree n1,tree n2,bool * strict_overflow_p)5818e4b17023SJohn Marino compare_names (enum tree_code comp, tree n1, tree n2,
5819e4b17023SJohn Marino bool *strict_overflow_p)
5820e4b17023SJohn Marino {
5821e4b17023SJohn Marino tree t, retval;
5822e4b17023SJohn Marino bitmap e1, e2;
5823e4b17023SJohn Marino bitmap_iterator bi1, bi2;
5824e4b17023SJohn Marino unsigned i1, i2;
5825e4b17023SJohn Marino int used_strict_overflow;
5826e4b17023SJohn Marino static bitmap_obstack *s_obstack = NULL;
5827e4b17023SJohn Marino static bitmap s_e1 = NULL, s_e2 = NULL;
5828e4b17023SJohn Marino
5829e4b17023SJohn Marino /* Compare the ranges of every name equivalent to N1 against the
5830e4b17023SJohn Marino ranges of every name equivalent to N2. */
5831e4b17023SJohn Marino e1 = get_value_range (n1)->equiv;
5832e4b17023SJohn Marino e2 = get_value_range (n2)->equiv;
5833e4b17023SJohn Marino
5834e4b17023SJohn Marino /* Use the fake bitmaps if e1 or e2 are not available. */
5835e4b17023SJohn Marino if (s_obstack == NULL)
5836e4b17023SJohn Marino {
5837e4b17023SJohn Marino s_obstack = XNEW (bitmap_obstack);
5838e4b17023SJohn Marino bitmap_obstack_initialize (s_obstack);
5839e4b17023SJohn Marino s_e1 = BITMAP_ALLOC (s_obstack);
5840e4b17023SJohn Marino s_e2 = BITMAP_ALLOC (s_obstack);
5841e4b17023SJohn Marino }
5842e4b17023SJohn Marino if (e1 == NULL)
5843e4b17023SJohn Marino e1 = s_e1;
5844e4b17023SJohn Marino if (e2 == NULL)
5845e4b17023SJohn Marino e2 = s_e2;
5846e4b17023SJohn Marino
5847e4b17023SJohn Marino /* Add N1 and N2 to their own set of equivalences to avoid
5848e4b17023SJohn Marino duplicating the body of the loop just to check N1 and N2
5849e4b17023SJohn Marino ranges. */
5850e4b17023SJohn Marino bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
5851e4b17023SJohn Marino bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
5852e4b17023SJohn Marino
5853e4b17023SJohn Marino /* If the equivalence sets have a common intersection, then the two
5854e4b17023SJohn Marino names can be compared without checking their ranges. */
5855e4b17023SJohn Marino if (bitmap_intersect_p (e1, e2))
5856e4b17023SJohn Marino {
5857e4b17023SJohn Marino bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5858e4b17023SJohn Marino bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5859e4b17023SJohn Marino
5860e4b17023SJohn Marino return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
5861e4b17023SJohn Marino ? boolean_true_node
5862e4b17023SJohn Marino : boolean_false_node;
5863e4b17023SJohn Marino }
5864e4b17023SJohn Marino
5865e4b17023SJohn Marino /* Start at -1. Set it to 0 if we do a comparison without relying
5866e4b17023SJohn Marino on overflow, or 1 if all comparisons rely on overflow. */
5867e4b17023SJohn Marino used_strict_overflow = -1;
5868e4b17023SJohn Marino
5869e4b17023SJohn Marino /* Otherwise, compare all the equivalent ranges. First, add N1 and
5870e4b17023SJohn Marino N2 to their own set of equivalences to avoid duplicating the body
5871e4b17023SJohn Marino of the loop just to check N1 and N2 ranges. */
5872e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
5873e4b17023SJohn Marino {
5874e4b17023SJohn Marino value_range_t vr1 = get_vr_for_comparison (i1);
5875e4b17023SJohn Marino
5876e4b17023SJohn Marino t = retval = NULL_TREE;
5877e4b17023SJohn Marino EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
5878e4b17023SJohn Marino {
5879e4b17023SJohn Marino bool sop = false;
5880e4b17023SJohn Marino
5881e4b17023SJohn Marino value_range_t vr2 = get_vr_for_comparison (i2);
5882e4b17023SJohn Marino
5883e4b17023SJohn Marino t = compare_ranges (comp, &vr1, &vr2, &sop);
5884e4b17023SJohn Marino if (t)
5885e4b17023SJohn Marino {
5886e4b17023SJohn Marino /* If we get different answers from different members
5887e4b17023SJohn Marino of the equivalence set this check must be in a dead
5888e4b17023SJohn Marino code region. Folding it to a trap representation
5889e4b17023SJohn Marino would be correct here. For now just return don't-know. */
5890e4b17023SJohn Marino if (retval != NULL
5891e4b17023SJohn Marino && t != retval)
5892e4b17023SJohn Marino {
5893e4b17023SJohn Marino bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5894e4b17023SJohn Marino bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5895e4b17023SJohn Marino return NULL_TREE;
5896e4b17023SJohn Marino }
5897e4b17023SJohn Marino retval = t;
5898e4b17023SJohn Marino
5899e4b17023SJohn Marino if (!sop)
5900e4b17023SJohn Marino used_strict_overflow = 0;
5901e4b17023SJohn Marino else if (used_strict_overflow < 0)
5902e4b17023SJohn Marino used_strict_overflow = 1;
5903e4b17023SJohn Marino }
5904e4b17023SJohn Marino }
5905e4b17023SJohn Marino
5906e4b17023SJohn Marino if (retval)
5907e4b17023SJohn Marino {
5908e4b17023SJohn Marino bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5909e4b17023SJohn Marino bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5910e4b17023SJohn Marino if (used_strict_overflow > 0)
5911e4b17023SJohn Marino *strict_overflow_p = true;
5912e4b17023SJohn Marino return retval;
5913e4b17023SJohn Marino }
5914e4b17023SJohn Marino }
5915e4b17023SJohn Marino
5916e4b17023SJohn Marino /* None of the equivalent ranges are useful in computing this
5917e4b17023SJohn Marino comparison. */
5918e4b17023SJohn Marino bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
5919e4b17023SJohn Marino bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
5920e4b17023SJohn Marino return NULL_TREE;
5921e4b17023SJohn Marino }
5922e4b17023SJohn Marino
5923e4b17023SJohn Marino /* Helper function for vrp_evaluate_conditional_warnv. */
5924e4b17023SJohn Marino
5925e4b17023SJohn Marino static tree
vrp_evaluate_conditional_warnv_with_ops_using_ranges(enum tree_code code,tree op0,tree op1,bool * strict_overflow_p)5926e4b17023SJohn Marino vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code code,
5927e4b17023SJohn Marino tree op0, tree op1,
5928e4b17023SJohn Marino bool * strict_overflow_p)
5929e4b17023SJohn Marino {
5930e4b17023SJohn Marino value_range_t *vr0, *vr1;
5931e4b17023SJohn Marino
5932e4b17023SJohn Marino vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
5933e4b17023SJohn Marino vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
5934e4b17023SJohn Marino
5935e4b17023SJohn Marino if (vr0 && vr1)
5936e4b17023SJohn Marino return compare_ranges (code, vr0, vr1, strict_overflow_p);
5937e4b17023SJohn Marino else if (vr0 && vr1 == NULL)
5938e4b17023SJohn Marino return compare_range_with_value (code, vr0, op1, strict_overflow_p);
5939e4b17023SJohn Marino else if (vr0 == NULL && vr1)
5940e4b17023SJohn Marino return (compare_range_with_value
5941e4b17023SJohn Marino (swap_tree_comparison (code), vr1, op0, strict_overflow_p));
5942e4b17023SJohn Marino return NULL;
5943e4b17023SJohn Marino }
5944e4b17023SJohn Marino
5945e4b17023SJohn Marino /* Helper function for vrp_evaluate_conditional_warnv. */
5946e4b17023SJohn Marino
5947e4b17023SJohn Marino static tree
vrp_evaluate_conditional_warnv_with_ops(enum tree_code code,tree op0,tree op1,bool use_equiv_p,bool * strict_overflow_p,bool * only_ranges)5948e4b17023SJohn Marino vrp_evaluate_conditional_warnv_with_ops (enum tree_code code, tree op0,
5949e4b17023SJohn Marino tree op1, bool use_equiv_p,
5950e4b17023SJohn Marino bool *strict_overflow_p, bool *only_ranges)
5951e4b17023SJohn Marino {
5952e4b17023SJohn Marino tree ret;
5953e4b17023SJohn Marino if (only_ranges)
5954e4b17023SJohn Marino *only_ranges = true;
5955e4b17023SJohn Marino
5956e4b17023SJohn Marino /* We only deal with integral and pointer types. */
5957e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
5958e4b17023SJohn Marino && !POINTER_TYPE_P (TREE_TYPE (op0)))
5959e4b17023SJohn Marino return NULL_TREE;
5960e4b17023SJohn Marino
5961e4b17023SJohn Marino if (use_equiv_p)
5962e4b17023SJohn Marino {
5963e4b17023SJohn Marino if (only_ranges
5964e4b17023SJohn Marino && (ret = vrp_evaluate_conditional_warnv_with_ops_using_ranges
5965e4b17023SJohn Marino (code, op0, op1, strict_overflow_p)))
5966e4b17023SJohn Marino return ret;
5967e4b17023SJohn Marino *only_ranges = false;
5968e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
5969e4b17023SJohn Marino return compare_names (code, op0, op1, strict_overflow_p);
5970e4b17023SJohn Marino else if (TREE_CODE (op0) == SSA_NAME)
5971e4b17023SJohn Marino return compare_name_with_value (code, op0, op1, strict_overflow_p);
5972e4b17023SJohn Marino else if (TREE_CODE (op1) == SSA_NAME)
5973e4b17023SJohn Marino return (compare_name_with_value
5974e4b17023SJohn Marino (swap_tree_comparison (code), op1, op0, strict_overflow_p));
5975e4b17023SJohn Marino }
5976e4b17023SJohn Marino else
5977e4b17023SJohn Marino return vrp_evaluate_conditional_warnv_with_ops_using_ranges (code, op0, op1,
5978e4b17023SJohn Marino strict_overflow_p);
5979e4b17023SJohn Marino return NULL_TREE;
5980e4b17023SJohn Marino }
5981e4b17023SJohn Marino
5982e4b17023SJohn Marino /* Given (CODE OP0 OP1) within STMT, try to simplify it based on value range
5983e4b17023SJohn Marino information. Return NULL if the conditional can not be evaluated.
5984e4b17023SJohn Marino The ranges of all the names equivalent with the operands in COND
5985e4b17023SJohn Marino will be used when trying to compute the value. If the result is
5986e4b17023SJohn Marino based on undefined signed overflow, issue a warning if
5987e4b17023SJohn Marino appropriate. */
5988e4b17023SJohn Marino
5989e4b17023SJohn Marino static tree
vrp_evaluate_conditional(enum tree_code code,tree op0,tree op1,gimple stmt)5990e4b17023SJohn Marino vrp_evaluate_conditional (enum tree_code code, tree op0, tree op1, gimple stmt)
5991e4b17023SJohn Marino {
5992e4b17023SJohn Marino bool sop;
5993e4b17023SJohn Marino tree ret;
5994e4b17023SJohn Marino bool only_ranges;
5995e4b17023SJohn Marino
5996e4b17023SJohn Marino /* Some passes and foldings leak constants with overflow flag set
5997e4b17023SJohn Marino into the IL. Avoid doing wrong things with these and bail out. */
5998e4b17023SJohn Marino if ((TREE_CODE (op0) == INTEGER_CST
5999e4b17023SJohn Marino && TREE_OVERFLOW (op0))
6000e4b17023SJohn Marino || (TREE_CODE (op1) == INTEGER_CST
6001e4b17023SJohn Marino && TREE_OVERFLOW (op1)))
6002e4b17023SJohn Marino return NULL_TREE;
6003e4b17023SJohn Marino
6004e4b17023SJohn Marino sop = false;
6005e4b17023SJohn Marino ret = vrp_evaluate_conditional_warnv_with_ops (code, op0, op1, true, &sop,
6006e4b17023SJohn Marino &only_ranges);
6007e4b17023SJohn Marino
6008e4b17023SJohn Marino if (ret && sop)
6009e4b17023SJohn Marino {
6010e4b17023SJohn Marino enum warn_strict_overflow_code wc;
6011e4b17023SJohn Marino const char* warnmsg;
6012e4b17023SJohn Marino
6013e4b17023SJohn Marino if (is_gimple_min_invariant (ret))
6014e4b17023SJohn Marino {
6015e4b17023SJohn Marino wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
6016e4b17023SJohn Marino warnmsg = G_("assuming signed overflow does not occur when "
6017e4b17023SJohn Marino "simplifying conditional to constant");
6018e4b17023SJohn Marino }
6019e4b17023SJohn Marino else
6020e4b17023SJohn Marino {
6021e4b17023SJohn Marino wc = WARN_STRICT_OVERFLOW_COMPARISON;
6022e4b17023SJohn Marino warnmsg = G_("assuming signed overflow does not occur when "
6023e4b17023SJohn Marino "simplifying conditional");
6024e4b17023SJohn Marino }
6025e4b17023SJohn Marino
6026e4b17023SJohn Marino if (issue_strict_overflow_warning (wc))
6027e4b17023SJohn Marino {
6028e4b17023SJohn Marino location_t location;
6029e4b17023SJohn Marino
6030e4b17023SJohn Marino if (!gimple_has_location (stmt))
6031e4b17023SJohn Marino location = input_location;
6032e4b17023SJohn Marino else
6033e4b17023SJohn Marino location = gimple_location (stmt);
6034e4b17023SJohn Marino warning_at (location, OPT_Wstrict_overflow, "%s", warnmsg);
6035e4b17023SJohn Marino }
6036e4b17023SJohn Marino }
6037e4b17023SJohn Marino
6038e4b17023SJohn Marino if (warn_type_limits
6039e4b17023SJohn Marino && ret && only_ranges
6040e4b17023SJohn Marino && TREE_CODE_CLASS (code) == tcc_comparison
6041e4b17023SJohn Marino && TREE_CODE (op0) == SSA_NAME)
6042e4b17023SJohn Marino {
6043e4b17023SJohn Marino /* If the comparison is being folded and the operand on the LHS
6044e4b17023SJohn Marino is being compared against a constant value that is outside of
6045e4b17023SJohn Marino the natural range of OP0's type, then the predicate will
6046e4b17023SJohn Marino always fold regardless of the value of OP0. If -Wtype-limits
6047e4b17023SJohn Marino was specified, emit a warning. */
6048e4b17023SJohn Marino tree type = TREE_TYPE (op0);
6049e4b17023SJohn Marino value_range_t *vr0 = get_value_range (op0);
6050e4b17023SJohn Marino
6051e4b17023SJohn Marino if (vr0->type != VR_VARYING
6052e4b17023SJohn Marino && INTEGRAL_TYPE_P (type)
6053e4b17023SJohn Marino && vrp_val_is_min (vr0->min)
6054e4b17023SJohn Marino && vrp_val_is_max (vr0->max)
6055e4b17023SJohn Marino && is_gimple_min_invariant (op1))
6056e4b17023SJohn Marino {
6057e4b17023SJohn Marino location_t location;
6058e4b17023SJohn Marino
6059e4b17023SJohn Marino if (!gimple_has_location (stmt))
6060e4b17023SJohn Marino location = input_location;
6061e4b17023SJohn Marino else
6062e4b17023SJohn Marino location = gimple_location (stmt);
6063e4b17023SJohn Marino
6064e4b17023SJohn Marino warning_at (location, OPT_Wtype_limits,
6065e4b17023SJohn Marino integer_zerop (ret)
6066e4b17023SJohn Marino ? G_("comparison always false "
6067e4b17023SJohn Marino "due to limited range of data type")
6068e4b17023SJohn Marino : G_("comparison always true "
6069e4b17023SJohn Marino "due to limited range of data type"));
6070e4b17023SJohn Marino }
6071e4b17023SJohn Marino }
6072e4b17023SJohn Marino
6073e4b17023SJohn Marino return ret;
6074e4b17023SJohn Marino }
6075e4b17023SJohn Marino
6076e4b17023SJohn Marino
6077e4b17023SJohn Marino /* Visit conditional statement STMT. If we can determine which edge
6078e4b17023SJohn Marino will be taken out of STMT's basic block, record it in
6079e4b17023SJohn Marino *TAKEN_EDGE_P and return SSA_PROP_INTERESTING. Otherwise, return
6080e4b17023SJohn Marino SSA_PROP_VARYING. */
6081e4b17023SJohn Marino
6082e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_cond_stmt(gimple stmt,edge * taken_edge_p)6083e4b17023SJohn Marino vrp_visit_cond_stmt (gimple stmt, edge *taken_edge_p)
6084e4b17023SJohn Marino {
6085e4b17023SJohn Marino tree val;
6086e4b17023SJohn Marino bool sop;
6087e4b17023SJohn Marino
6088e4b17023SJohn Marino *taken_edge_p = NULL;
6089e4b17023SJohn Marino
6090e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6091e4b17023SJohn Marino {
6092e4b17023SJohn Marino tree use;
6093e4b17023SJohn Marino ssa_op_iter i;
6094e4b17023SJohn Marino
6095e4b17023SJohn Marino fprintf (dump_file, "\nVisiting conditional with predicate: ");
6096e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, 0);
6097e4b17023SJohn Marino fprintf (dump_file, "\nWith known ranges\n");
6098e4b17023SJohn Marino
6099e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
6100e4b17023SJohn Marino {
6101e4b17023SJohn Marino fprintf (dump_file, "\t");
6102e4b17023SJohn Marino print_generic_expr (dump_file, use, 0);
6103e4b17023SJohn Marino fprintf (dump_file, ": ");
6104e4b17023SJohn Marino dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
6105e4b17023SJohn Marino }
6106e4b17023SJohn Marino
6107e4b17023SJohn Marino fprintf (dump_file, "\n");
6108e4b17023SJohn Marino }
6109e4b17023SJohn Marino
6110e4b17023SJohn Marino /* Compute the value of the predicate COND by checking the known
6111e4b17023SJohn Marino ranges of each of its operands.
6112e4b17023SJohn Marino
6113e4b17023SJohn Marino Note that we cannot evaluate all the equivalent ranges here
6114e4b17023SJohn Marino because those ranges may not yet be final and with the current
6115e4b17023SJohn Marino propagation strategy, we cannot determine when the value ranges
6116e4b17023SJohn Marino of the names in the equivalence set have changed.
6117e4b17023SJohn Marino
6118e4b17023SJohn Marino For instance, given the following code fragment
6119e4b17023SJohn Marino
6120e4b17023SJohn Marino i_5 = PHI <8, i_13>
6121e4b17023SJohn Marino ...
6122e4b17023SJohn Marino i_14 = ASSERT_EXPR <i_5, i_5 != 0>
6123e4b17023SJohn Marino if (i_14 == 1)
6124e4b17023SJohn Marino ...
6125e4b17023SJohn Marino
6126e4b17023SJohn Marino Assume that on the first visit to i_14, i_5 has the temporary
6127e4b17023SJohn Marino range [8, 8] because the second argument to the PHI function is
6128e4b17023SJohn Marino not yet executable. We derive the range ~[0, 0] for i_14 and the
6129e4b17023SJohn Marino equivalence set { i_5 }. So, when we visit 'if (i_14 == 1)' for
6130e4b17023SJohn Marino the first time, since i_14 is equivalent to the range [8, 8], we
6131e4b17023SJohn Marino determine that the predicate is always false.
6132e4b17023SJohn Marino
6133e4b17023SJohn Marino On the next round of propagation, i_13 is determined to be
6134e4b17023SJohn Marino VARYING, which causes i_5 to drop down to VARYING. So, another
6135e4b17023SJohn Marino visit to i_14 is scheduled. In this second visit, we compute the
6136e4b17023SJohn Marino exact same range and equivalence set for i_14, namely ~[0, 0] and
6137e4b17023SJohn Marino { i_5 }. But we did not have the previous range for i_5
6138e4b17023SJohn Marino registered, so vrp_visit_assignment thinks that the range for
6139e4b17023SJohn Marino i_14 has not changed. Therefore, the predicate 'if (i_14 == 1)'
6140e4b17023SJohn Marino is not visited again, which stops propagation from visiting
6141e4b17023SJohn Marino statements in the THEN clause of that if().
6142e4b17023SJohn Marino
6143e4b17023SJohn Marino To properly fix this we would need to keep the previous range
6144e4b17023SJohn Marino value for the names in the equivalence set. This way we would've
6145e4b17023SJohn Marino discovered that from one visit to the other i_5 changed from
6146e4b17023SJohn Marino range [8, 8] to VR_VARYING.
6147e4b17023SJohn Marino
6148e4b17023SJohn Marino However, fixing this apparent limitation may not be worth the
6149e4b17023SJohn Marino additional checking. Testing on several code bases (GCC, DLV,
6150e4b17023SJohn Marino MICO, TRAMP3D and SPEC2000) showed that doing this results in
6151e4b17023SJohn Marino 4 more predicates folded in SPEC. */
6152e4b17023SJohn Marino sop = false;
6153e4b17023SJohn Marino
6154e4b17023SJohn Marino val = vrp_evaluate_conditional_warnv_with_ops (gimple_cond_code (stmt),
6155e4b17023SJohn Marino gimple_cond_lhs (stmt),
6156e4b17023SJohn Marino gimple_cond_rhs (stmt),
6157e4b17023SJohn Marino false, &sop, NULL);
6158e4b17023SJohn Marino if (val)
6159e4b17023SJohn Marino {
6160e4b17023SJohn Marino if (!sop)
6161e4b17023SJohn Marino *taken_edge_p = find_taken_edge (gimple_bb (stmt), val);
6162e4b17023SJohn Marino else
6163e4b17023SJohn Marino {
6164e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6165e4b17023SJohn Marino fprintf (dump_file,
6166e4b17023SJohn Marino "\nIgnoring predicate evaluation because "
6167e4b17023SJohn Marino "it assumes that signed overflow is undefined");
6168e4b17023SJohn Marino val = NULL_TREE;
6169e4b17023SJohn Marino }
6170e4b17023SJohn Marino }
6171e4b17023SJohn Marino
6172e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6173e4b17023SJohn Marino {
6174e4b17023SJohn Marino fprintf (dump_file, "\nPredicate evaluates to: ");
6175e4b17023SJohn Marino if (val == NULL_TREE)
6176e4b17023SJohn Marino fprintf (dump_file, "DON'T KNOW\n");
6177e4b17023SJohn Marino else
6178e4b17023SJohn Marino print_generic_stmt (dump_file, val, 0);
6179e4b17023SJohn Marino }
6180e4b17023SJohn Marino
6181e4b17023SJohn Marino return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
6182e4b17023SJohn Marino }
6183e4b17023SJohn Marino
6184e4b17023SJohn Marino /* Searches the case label vector VEC for the index *IDX of the CASE_LABEL
6185e4b17023SJohn Marino that includes the value VAL. The search is restricted to the range
6186e4b17023SJohn Marino [START_IDX, n - 1] where n is the size of VEC.
6187e4b17023SJohn Marino
6188e4b17023SJohn Marino If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
6189e4b17023SJohn Marino returned.
6190e4b17023SJohn Marino
6191e4b17023SJohn Marino If there is no CASE_LABEL for VAL and there is one that is larger than VAL,
6192e4b17023SJohn Marino it is placed in IDX and false is returned.
6193e4b17023SJohn Marino
6194e4b17023SJohn Marino If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
6195e4b17023SJohn Marino returned. */
6196e4b17023SJohn Marino
6197e4b17023SJohn Marino static bool
find_case_label_index(gimple stmt,size_t start_idx,tree val,size_t * idx)6198e4b17023SJohn Marino find_case_label_index (gimple stmt, size_t start_idx, tree val, size_t *idx)
6199e4b17023SJohn Marino {
6200e4b17023SJohn Marino size_t n = gimple_switch_num_labels (stmt);
6201e4b17023SJohn Marino size_t low, high;
6202e4b17023SJohn Marino
6203e4b17023SJohn Marino /* Find case label for minimum of the value range or the next one.
6204e4b17023SJohn Marino At each iteration we are searching in [low, high - 1]. */
6205e4b17023SJohn Marino
6206e4b17023SJohn Marino for (low = start_idx, high = n; high != low; )
6207e4b17023SJohn Marino {
6208e4b17023SJohn Marino tree t;
6209e4b17023SJohn Marino int cmp;
6210e4b17023SJohn Marino /* Note that i != high, so we never ask for n. */
6211e4b17023SJohn Marino size_t i = (high + low) / 2;
6212e4b17023SJohn Marino t = gimple_switch_label (stmt, i);
6213e4b17023SJohn Marino
6214e4b17023SJohn Marino /* Cache the result of comparing CASE_LOW and val. */
6215e4b17023SJohn Marino cmp = tree_int_cst_compare (CASE_LOW (t), val);
6216e4b17023SJohn Marino
6217e4b17023SJohn Marino if (cmp == 0)
6218e4b17023SJohn Marino {
6219e4b17023SJohn Marino /* Ranges cannot be empty. */
6220e4b17023SJohn Marino *idx = i;
6221e4b17023SJohn Marino return true;
6222e4b17023SJohn Marino }
6223e4b17023SJohn Marino else if (cmp > 0)
6224e4b17023SJohn Marino high = i;
6225e4b17023SJohn Marino else
6226e4b17023SJohn Marino {
6227e4b17023SJohn Marino low = i + 1;
6228e4b17023SJohn Marino if (CASE_HIGH (t) != NULL
6229e4b17023SJohn Marino && tree_int_cst_compare (CASE_HIGH (t), val) >= 0)
6230e4b17023SJohn Marino {
6231e4b17023SJohn Marino *idx = i;
6232e4b17023SJohn Marino return true;
6233e4b17023SJohn Marino }
6234e4b17023SJohn Marino }
6235e4b17023SJohn Marino }
6236e4b17023SJohn Marino
6237e4b17023SJohn Marino *idx = high;
6238e4b17023SJohn Marino return false;
6239e4b17023SJohn Marino }
6240e4b17023SJohn Marino
6241e4b17023SJohn Marino /* Searches the case label vector VEC for the range of CASE_LABELs that is used
6242e4b17023SJohn Marino for values between MIN and MAX. The first index is placed in MIN_IDX. The
6243e4b17023SJohn Marino last index is placed in MAX_IDX. If the range of CASE_LABELs is empty
6244e4b17023SJohn Marino then MAX_IDX < MIN_IDX.
6245e4b17023SJohn Marino Returns true if the default label is not needed. */
6246e4b17023SJohn Marino
6247e4b17023SJohn Marino static bool
find_case_label_range(gimple stmt,tree min,tree max,size_t * min_idx,size_t * max_idx)6248e4b17023SJohn Marino find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx,
6249e4b17023SJohn Marino size_t *max_idx)
6250e4b17023SJohn Marino {
6251e4b17023SJohn Marino size_t i, j;
6252e4b17023SJohn Marino bool min_take_default = !find_case_label_index (stmt, 1, min, &i);
6253e4b17023SJohn Marino bool max_take_default = !find_case_label_index (stmt, i, max, &j);
6254e4b17023SJohn Marino
6255e4b17023SJohn Marino if (i == j
6256e4b17023SJohn Marino && min_take_default
6257e4b17023SJohn Marino && max_take_default)
6258e4b17023SJohn Marino {
6259e4b17023SJohn Marino /* Only the default case label reached.
6260e4b17023SJohn Marino Return an empty range. */
6261e4b17023SJohn Marino *min_idx = 1;
6262e4b17023SJohn Marino *max_idx = 0;
6263e4b17023SJohn Marino return false;
6264e4b17023SJohn Marino }
6265e4b17023SJohn Marino else
6266e4b17023SJohn Marino {
6267e4b17023SJohn Marino bool take_default = min_take_default || max_take_default;
6268e4b17023SJohn Marino tree low, high;
6269e4b17023SJohn Marino size_t k;
6270e4b17023SJohn Marino
6271e4b17023SJohn Marino if (max_take_default)
6272e4b17023SJohn Marino j--;
6273e4b17023SJohn Marino
6274e4b17023SJohn Marino /* If the case label range is continuous, we do not need
6275e4b17023SJohn Marino the default case label. Verify that. */
6276e4b17023SJohn Marino high = CASE_LOW (gimple_switch_label (stmt, i));
6277e4b17023SJohn Marino if (CASE_HIGH (gimple_switch_label (stmt, i)))
6278e4b17023SJohn Marino high = CASE_HIGH (gimple_switch_label (stmt, i));
6279e4b17023SJohn Marino for (k = i + 1; k <= j; ++k)
6280e4b17023SJohn Marino {
6281e4b17023SJohn Marino low = CASE_LOW (gimple_switch_label (stmt, k));
6282e4b17023SJohn Marino if (!integer_onep (int_const_binop (MINUS_EXPR, low, high)))
6283e4b17023SJohn Marino {
6284e4b17023SJohn Marino take_default = true;
6285e4b17023SJohn Marino break;
6286e4b17023SJohn Marino }
6287e4b17023SJohn Marino high = low;
6288e4b17023SJohn Marino if (CASE_HIGH (gimple_switch_label (stmt, k)))
6289e4b17023SJohn Marino high = CASE_HIGH (gimple_switch_label (stmt, k));
6290e4b17023SJohn Marino }
6291e4b17023SJohn Marino
6292e4b17023SJohn Marino *min_idx = i;
6293e4b17023SJohn Marino *max_idx = j;
6294e4b17023SJohn Marino return !take_default;
6295e4b17023SJohn Marino }
6296e4b17023SJohn Marino }
6297e4b17023SJohn Marino
6298e4b17023SJohn Marino /* Visit switch statement STMT. If we can determine which edge
6299e4b17023SJohn Marino will be taken out of STMT's basic block, record it in
6300e4b17023SJohn Marino *TAKEN_EDGE_P and return SSA_PROP_INTERESTING. Otherwise, return
6301e4b17023SJohn Marino SSA_PROP_VARYING. */
6302e4b17023SJohn Marino
6303e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_switch_stmt(gimple stmt,edge * taken_edge_p)6304e4b17023SJohn Marino vrp_visit_switch_stmt (gimple stmt, edge *taken_edge_p)
6305e4b17023SJohn Marino {
6306e4b17023SJohn Marino tree op, val;
6307e4b17023SJohn Marino value_range_t *vr;
6308e4b17023SJohn Marino size_t i = 0, j = 0;
6309e4b17023SJohn Marino bool take_default;
6310e4b17023SJohn Marino
6311e4b17023SJohn Marino *taken_edge_p = NULL;
6312e4b17023SJohn Marino op = gimple_switch_index (stmt);
6313e4b17023SJohn Marino if (TREE_CODE (op) != SSA_NAME)
6314e4b17023SJohn Marino return SSA_PROP_VARYING;
6315e4b17023SJohn Marino
6316e4b17023SJohn Marino vr = get_value_range (op);
6317e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6318e4b17023SJohn Marino {
6319e4b17023SJohn Marino fprintf (dump_file, "\nVisiting switch expression with operand ");
6320e4b17023SJohn Marino print_generic_expr (dump_file, op, 0);
6321e4b17023SJohn Marino fprintf (dump_file, " with known range ");
6322e4b17023SJohn Marino dump_value_range (dump_file, vr);
6323e4b17023SJohn Marino fprintf (dump_file, "\n");
6324e4b17023SJohn Marino }
6325e4b17023SJohn Marino
6326e4b17023SJohn Marino if (vr->type != VR_RANGE
6327e4b17023SJohn Marino || symbolic_range_p (vr))
6328e4b17023SJohn Marino return SSA_PROP_VARYING;
6329e4b17023SJohn Marino
6330e4b17023SJohn Marino /* Find the single edge that is taken from the switch expression. */
6331e4b17023SJohn Marino take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
6332e4b17023SJohn Marino
6333e4b17023SJohn Marino /* Check if the range spans no CASE_LABEL. If so, we only reach the default
6334e4b17023SJohn Marino label */
6335e4b17023SJohn Marino if (j < i)
6336e4b17023SJohn Marino {
6337e4b17023SJohn Marino gcc_assert (take_default);
6338e4b17023SJohn Marino val = gimple_switch_default_label (stmt);
6339e4b17023SJohn Marino }
6340e4b17023SJohn Marino else
6341e4b17023SJohn Marino {
6342e4b17023SJohn Marino /* Check if labels with index i to j and maybe the default label
6343e4b17023SJohn Marino are all reaching the same label. */
6344e4b17023SJohn Marino
6345e4b17023SJohn Marino val = gimple_switch_label (stmt, i);
6346e4b17023SJohn Marino if (take_default
6347e4b17023SJohn Marino && CASE_LABEL (gimple_switch_default_label (stmt))
6348e4b17023SJohn Marino != CASE_LABEL (val))
6349e4b17023SJohn Marino {
6350e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6351e4b17023SJohn Marino fprintf (dump_file, " not a single destination for this "
6352e4b17023SJohn Marino "range\n");
6353e4b17023SJohn Marino return SSA_PROP_VARYING;
6354e4b17023SJohn Marino }
6355e4b17023SJohn Marino for (++i; i <= j; ++i)
6356e4b17023SJohn Marino {
6357e4b17023SJohn Marino if (CASE_LABEL (gimple_switch_label (stmt, i)) != CASE_LABEL (val))
6358e4b17023SJohn Marino {
6359e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6360e4b17023SJohn Marino fprintf (dump_file, " not a single destination for this "
6361e4b17023SJohn Marino "range\n");
6362e4b17023SJohn Marino return SSA_PROP_VARYING;
6363e4b17023SJohn Marino }
6364e4b17023SJohn Marino }
6365e4b17023SJohn Marino }
6366e4b17023SJohn Marino
6367e4b17023SJohn Marino *taken_edge_p = find_edge (gimple_bb (stmt),
6368e4b17023SJohn Marino label_to_block (CASE_LABEL (val)));
6369e4b17023SJohn Marino
6370e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6371e4b17023SJohn Marino {
6372e4b17023SJohn Marino fprintf (dump_file, " will take edge to ");
6373e4b17023SJohn Marino print_generic_stmt (dump_file, CASE_LABEL (val), 0);
6374e4b17023SJohn Marino }
6375e4b17023SJohn Marino
6376e4b17023SJohn Marino return SSA_PROP_INTERESTING;
6377e4b17023SJohn Marino }
6378e4b17023SJohn Marino
6379e4b17023SJohn Marino
6380e4b17023SJohn Marino /* Evaluate statement STMT. If the statement produces a useful range,
6381e4b17023SJohn Marino return SSA_PROP_INTERESTING and record the SSA name with the
6382e4b17023SJohn Marino interesting range into *OUTPUT_P.
6383e4b17023SJohn Marino
6384e4b17023SJohn Marino If STMT is a conditional branch and we can determine its truth
6385e4b17023SJohn Marino value, the taken edge is recorded in *TAKEN_EDGE_P.
6386e4b17023SJohn Marino
6387e4b17023SJohn Marino If STMT produces a varying value, return SSA_PROP_VARYING. */
6388e4b17023SJohn Marino
6389e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_stmt(gimple stmt,edge * taken_edge_p,tree * output_p)6390e4b17023SJohn Marino vrp_visit_stmt (gimple stmt, edge *taken_edge_p, tree *output_p)
6391e4b17023SJohn Marino {
6392e4b17023SJohn Marino tree def;
6393e4b17023SJohn Marino ssa_op_iter iter;
6394e4b17023SJohn Marino
6395e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6396e4b17023SJohn Marino {
6397e4b17023SJohn Marino fprintf (dump_file, "\nVisiting statement:\n");
6398e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, dump_flags);
6399e4b17023SJohn Marino fprintf (dump_file, "\n");
6400e4b17023SJohn Marino }
6401e4b17023SJohn Marino
6402e4b17023SJohn Marino if (!stmt_interesting_for_vrp (stmt))
6403e4b17023SJohn Marino gcc_assert (stmt_ends_bb_p (stmt));
6404e4b17023SJohn Marino else if (is_gimple_assign (stmt) || is_gimple_call (stmt))
6405e4b17023SJohn Marino {
6406e4b17023SJohn Marino /* In general, assignments with virtual operands are not useful
6407e4b17023SJohn Marino for deriving ranges, with the obvious exception of calls to
6408e4b17023SJohn Marino builtin functions. */
6409e4b17023SJohn Marino if ((is_gimple_call (stmt)
6410e4b17023SJohn Marino && gimple_call_fndecl (stmt) != NULL_TREE
6411e4b17023SJohn Marino && DECL_BUILT_IN (gimple_call_fndecl (stmt)))
6412e4b17023SJohn Marino || !gimple_vuse (stmt))
6413e4b17023SJohn Marino return vrp_visit_assignment_or_call (stmt, output_p);
6414e4b17023SJohn Marino }
6415e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_COND)
6416e4b17023SJohn Marino return vrp_visit_cond_stmt (stmt, taken_edge_p);
6417e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_SWITCH)
6418e4b17023SJohn Marino return vrp_visit_switch_stmt (stmt, taken_edge_p);
6419e4b17023SJohn Marino
6420e4b17023SJohn Marino /* All other statements produce nothing of interest for VRP, so mark
6421e4b17023SJohn Marino their outputs varying and prevent further simulation. */
6422e4b17023SJohn Marino FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
6423e4b17023SJohn Marino set_value_range_to_varying (get_value_range (def));
6424e4b17023SJohn Marino
6425e4b17023SJohn Marino return SSA_PROP_VARYING;
6426e4b17023SJohn Marino }
6427e4b17023SJohn Marino
6428e4b17023SJohn Marino
6429e4b17023SJohn Marino /* Meet operation for value ranges. Given two value ranges VR0 and
6430e4b17023SJohn Marino VR1, store in VR0 a range that contains both VR0 and VR1. This
6431e4b17023SJohn Marino may not be the smallest possible such range. */
6432e4b17023SJohn Marino
6433e4b17023SJohn Marino static void
vrp_meet(value_range_t * vr0,value_range_t * vr1)6434e4b17023SJohn Marino vrp_meet (value_range_t *vr0, value_range_t *vr1)
6435e4b17023SJohn Marino {
6436e4b17023SJohn Marino if (vr0->type == VR_UNDEFINED)
6437e4b17023SJohn Marino {
6438e4b17023SJohn Marino /* Drop equivalences. See PR53465. */
6439e4b17023SJohn Marino set_value_range (vr0, vr1->type, vr1->min, vr1->max, NULL);
6440e4b17023SJohn Marino return;
6441e4b17023SJohn Marino }
6442e4b17023SJohn Marino
6443e4b17023SJohn Marino if (vr1->type == VR_UNDEFINED)
6444e4b17023SJohn Marino {
6445e4b17023SJohn Marino /* VR0 already has the resulting range, just drop equivalences.
6446e4b17023SJohn Marino See PR53465. */
6447e4b17023SJohn Marino if (vr0->equiv)
6448e4b17023SJohn Marino bitmap_clear (vr0->equiv);
6449e4b17023SJohn Marino return;
6450e4b17023SJohn Marino }
6451e4b17023SJohn Marino
6452e4b17023SJohn Marino if (vr0->type == VR_VARYING)
6453e4b17023SJohn Marino {
6454e4b17023SJohn Marino /* Nothing to do. VR0 already has the resulting range. */
6455e4b17023SJohn Marino return;
6456e4b17023SJohn Marino }
6457e4b17023SJohn Marino
6458e4b17023SJohn Marino if (vr1->type == VR_VARYING)
6459e4b17023SJohn Marino {
6460e4b17023SJohn Marino set_value_range_to_varying (vr0);
6461e4b17023SJohn Marino return;
6462e4b17023SJohn Marino }
6463e4b17023SJohn Marino
6464e4b17023SJohn Marino if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
6465e4b17023SJohn Marino {
6466e4b17023SJohn Marino int cmp;
6467e4b17023SJohn Marino tree min, max;
6468e4b17023SJohn Marino
6469e4b17023SJohn Marino /* Compute the convex hull of the ranges. The lower limit of
6470e4b17023SJohn Marino the new range is the minimum of the two ranges. If they
6471e4b17023SJohn Marino cannot be compared, then give up. */
6472e4b17023SJohn Marino cmp = compare_values (vr0->min, vr1->min);
6473e4b17023SJohn Marino if (cmp == 0 || cmp == 1)
6474e4b17023SJohn Marino min = vr1->min;
6475e4b17023SJohn Marino else if (cmp == -1)
6476e4b17023SJohn Marino min = vr0->min;
6477e4b17023SJohn Marino else
6478e4b17023SJohn Marino goto give_up;
6479e4b17023SJohn Marino
6480e4b17023SJohn Marino /* Similarly, the upper limit of the new range is the maximum
6481e4b17023SJohn Marino of the two ranges. If they cannot be compared, then
6482e4b17023SJohn Marino give up. */
6483e4b17023SJohn Marino cmp = compare_values (vr0->max, vr1->max);
6484e4b17023SJohn Marino if (cmp == 0 || cmp == -1)
6485e4b17023SJohn Marino max = vr1->max;
6486e4b17023SJohn Marino else if (cmp == 1)
6487e4b17023SJohn Marino max = vr0->max;
6488e4b17023SJohn Marino else
6489e4b17023SJohn Marino goto give_up;
6490e4b17023SJohn Marino
6491e4b17023SJohn Marino /* Check for useless ranges. */
6492e4b17023SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (min))
6493e4b17023SJohn Marino && ((vrp_val_is_min (min) || is_overflow_infinity (min))
6494e4b17023SJohn Marino && (vrp_val_is_max (max) || is_overflow_infinity (max))))
6495e4b17023SJohn Marino goto give_up;
6496e4b17023SJohn Marino
6497e4b17023SJohn Marino /* The resulting set of equivalences is the intersection of
6498e4b17023SJohn Marino the two sets. */
6499e4b17023SJohn Marino if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6500e4b17023SJohn Marino bitmap_and_into (vr0->equiv, vr1->equiv);
6501e4b17023SJohn Marino else if (vr0->equiv && !vr1->equiv)
6502e4b17023SJohn Marino bitmap_clear (vr0->equiv);
6503e4b17023SJohn Marino
6504e4b17023SJohn Marino set_value_range (vr0, vr0->type, min, max, vr0->equiv);
6505e4b17023SJohn Marino }
6506e4b17023SJohn Marino else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
6507e4b17023SJohn Marino {
6508e4b17023SJohn Marino /* Two anti-ranges meet only if their complements intersect.
6509e4b17023SJohn Marino Only handle the case of identical ranges. */
6510e4b17023SJohn Marino if (compare_values (vr0->min, vr1->min) == 0
6511e4b17023SJohn Marino && compare_values (vr0->max, vr1->max) == 0
6512e4b17023SJohn Marino && compare_values (vr0->min, vr0->max) == 0)
6513e4b17023SJohn Marino {
6514e4b17023SJohn Marino /* The resulting set of equivalences is the intersection of
6515e4b17023SJohn Marino the two sets. */
6516e4b17023SJohn Marino if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6517e4b17023SJohn Marino bitmap_and_into (vr0->equiv, vr1->equiv);
6518e4b17023SJohn Marino else if (vr0->equiv && !vr1->equiv)
6519e4b17023SJohn Marino bitmap_clear (vr0->equiv);
6520e4b17023SJohn Marino }
6521e4b17023SJohn Marino else
6522e4b17023SJohn Marino goto give_up;
6523e4b17023SJohn Marino }
6524e4b17023SJohn Marino else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
6525e4b17023SJohn Marino {
6526e4b17023SJohn Marino /* For a numeric range [VAL1, VAL2] and an anti-range ~[VAL3, VAL4],
6527e4b17023SJohn Marino only handle the case where the ranges have an empty intersection.
6528e4b17023SJohn Marino The result of the meet operation is the anti-range. */
6529e4b17023SJohn Marino if (!symbolic_range_p (vr0)
6530e4b17023SJohn Marino && !symbolic_range_p (vr1)
6531e4b17023SJohn Marino && !value_ranges_intersect_p (vr0, vr1))
6532e4b17023SJohn Marino {
6533e4b17023SJohn Marino /* Copy most of VR1 into VR0. Don't copy VR1's equivalence
6534e4b17023SJohn Marino set. We need to compute the intersection of the two
6535e4b17023SJohn Marino equivalence sets. */
6536e4b17023SJohn Marino if (vr1->type == VR_ANTI_RANGE)
6537e4b17023SJohn Marino set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);
6538e4b17023SJohn Marino
6539e4b17023SJohn Marino /* The resulting set of equivalences is the intersection of
6540e4b17023SJohn Marino the two sets. */
6541e4b17023SJohn Marino if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
6542e4b17023SJohn Marino bitmap_and_into (vr0->equiv, vr1->equiv);
6543e4b17023SJohn Marino else if (vr0->equiv && !vr1->equiv)
6544e4b17023SJohn Marino bitmap_clear (vr0->equiv);
6545e4b17023SJohn Marino }
6546e4b17023SJohn Marino else
6547e4b17023SJohn Marino goto give_up;
6548e4b17023SJohn Marino }
6549e4b17023SJohn Marino else
6550e4b17023SJohn Marino gcc_unreachable ();
6551e4b17023SJohn Marino
6552e4b17023SJohn Marino return;
6553e4b17023SJohn Marino
6554e4b17023SJohn Marino give_up:
6555e4b17023SJohn Marino /* Failed to find an efficient meet. Before giving up and setting
6556e4b17023SJohn Marino the result to VARYING, see if we can at least derive a useful
6557e4b17023SJohn Marino anti-range. FIXME, all this nonsense about distinguishing
6558e4b17023SJohn Marino anti-ranges from ranges is necessary because of the odd
6559e4b17023SJohn Marino semantics of range_includes_zero_p and friends. */
6560e4b17023SJohn Marino if (!symbolic_range_p (vr0)
6561e4b17023SJohn Marino && ((vr0->type == VR_RANGE
6562e4b17023SJohn Marino && range_includes_zero_p (vr0->min, vr0->max) == 0)
6563e4b17023SJohn Marino || (vr0->type == VR_ANTI_RANGE
6564e4b17023SJohn Marino && range_includes_zero_p (vr0->min, vr0->max) == 1))
6565e4b17023SJohn Marino && !symbolic_range_p (vr1)
6566e4b17023SJohn Marino && ((vr1->type == VR_RANGE
6567e4b17023SJohn Marino && range_includes_zero_p (vr1->min, vr1->max) == 0)
6568e4b17023SJohn Marino || (vr1->type == VR_ANTI_RANGE
6569e4b17023SJohn Marino && range_includes_zero_p (vr1->min, vr1->max) == 1)))
6570e4b17023SJohn Marino {
6571e4b17023SJohn Marino set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
6572e4b17023SJohn Marino
6573e4b17023SJohn Marino /* Since this meet operation did not result from the meeting of
6574e4b17023SJohn Marino two equivalent names, VR0 cannot have any equivalences. */
6575e4b17023SJohn Marino if (vr0->equiv)
6576e4b17023SJohn Marino bitmap_clear (vr0->equiv);
6577e4b17023SJohn Marino }
6578e4b17023SJohn Marino else
6579e4b17023SJohn Marino set_value_range_to_varying (vr0);
6580e4b17023SJohn Marino }
6581e4b17023SJohn Marino
6582e4b17023SJohn Marino
6583e4b17023SJohn Marino /* Visit all arguments for PHI node PHI that flow through executable
6584e4b17023SJohn Marino edges. If a valid value range can be derived from all the incoming
6585e4b17023SJohn Marino value ranges, set a new range for the LHS of PHI. */
6586e4b17023SJohn Marino
6587e4b17023SJohn Marino static enum ssa_prop_result
vrp_visit_phi_node(gimple phi)6588e4b17023SJohn Marino vrp_visit_phi_node (gimple phi)
6589e4b17023SJohn Marino {
6590e4b17023SJohn Marino size_t i;
6591e4b17023SJohn Marino tree lhs = PHI_RESULT (phi);
6592e4b17023SJohn Marino value_range_t *lhs_vr = get_value_range (lhs);
6593e4b17023SJohn Marino value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6594e4b17023SJohn Marino bool first = true;
6595e4b17023SJohn Marino int edges, old_edges;
6596e4b17023SJohn Marino struct loop *l;
6597e4b17023SJohn Marino
6598e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6599e4b17023SJohn Marino {
6600e4b17023SJohn Marino fprintf (dump_file, "\nVisiting PHI node: ");
6601e4b17023SJohn Marino print_gimple_stmt (dump_file, phi, 0, dump_flags);
6602e4b17023SJohn Marino }
6603e4b17023SJohn Marino
6604e4b17023SJohn Marino edges = 0;
6605e4b17023SJohn Marino for (i = 0; i < gimple_phi_num_args (phi); i++)
6606e4b17023SJohn Marino {
6607e4b17023SJohn Marino edge e = gimple_phi_arg_edge (phi, i);
6608e4b17023SJohn Marino
6609e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6610e4b17023SJohn Marino {
6611e4b17023SJohn Marino fprintf (dump_file,
6612e4b17023SJohn Marino "\n Argument #%d (%d -> %d %sexecutable)\n",
6613e4b17023SJohn Marino (int) i, e->src->index, e->dest->index,
6614e4b17023SJohn Marino (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
6615e4b17023SJohn Marino }
6616e4b17023SJohn Marino
6617e4b17023SJohn Marino if (e->flags & EDGE_EXECUTABLE)
6618e4b17023SJohn Marino {
6619e4b17023SJohn Marino tree arg = PHI_ARG_DEF (phi, i);
6620e4b17023SJohn Marino value_range_t vr_arg;
6621e4b17023SJohn Marino
6622e4b17023SJohn Marino ++edges;
6623e4b17023SJohn Marino
6624e4b17023SJohn Marino if (TREE_CODE (arg) == SSA_NAME)
6625e4b17023SJohn Marino {
6626e4b17023SJohn Marino vr_arg = *(get_value_range (arg));
66275ce9237cSJohn Marino /* Do not allow equivalences or symbolic ranges to leak in from
66285ce9237cSJohn Marino backedges. That creates invalid equivalencies. */
66295ce9237cSJohn Marino if (e->flags & EDGE_DFS_BACK
66305ce9237cSJohn Marino && (vr_arg.type == VR_RANGE
66315ce9237cSJohn Marino || vr_arg.type == VR_ANTI_RANGE))
66325ce9237cSJohn Marino {
66335ce9237cSJohn Marino vr_arg.equiv = NULL;
66345ce9237cSJohn Marino if (symbolic_range_p (&vr_arg))
66355ce9237cSJohn Marino {
66365ce9237cSJohn Marino vr_arg.type = VR_VARYING;
66375ce9237cSJohn Marino vr_arg.min = NULL_TREE;
66385ce9237cSJohn Marino vr_arg.max = NULL_TREE;
66395ce9237cSJohn Marino }
66405ce9237cSJohn Marino }
6641e4b17023SJohn Marino }
6642e4b17023SJohn Marino else
6643e4b17023SJohn Marino {
6644e4b17023SJohn Marino if (is_overflow_infinity (arg))
6645e4b17023SJohn Marino {
6646e4b17023SJohn Marino arg = copy_node (arg);
6647e4b17023SJohn Marino TREE_OVERFLOW (arg) = 0;
6648e4b17023SJohn Marino }
6649e4b17023SJohn Marino
6650e4b17023SJohn Marino vr_arg.type = VR_RANGE;
6651e4b17023SJohn Marino vr_arg.min = arg;
6652e4b17023SJohn Marino vr_arg.max = arg;
6653e4b17023SJohn Marino vr_arg.equiv = NULL;
6654e4b17023SJohn Marino }
6655e4b17023SJohn Marino
6656e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6657e4b17023SJohn Marino {
6658e4b17023SJohn Marino fprintf (dump_file, "\t");
6659e4b17023SJohn Marino print_generic_expr (dump_file, arg, dump_flags);
6660e4b17023SJohn Marino fprintf (dump_file, "\n\tValue: ");
6661e4b17023SJohn Marino dump_value_range (dump_file, &vr_arg);
6662e4b17023SJohn Marino fprintf (dump_file, "\n");
6663e4b17023SJohn Marino }
6664e4b17023SJohn Marino
6665e4b17023SJohn Marino if (first)
6666e4b17023SJohn Marino copy_value_range (&vr_result, &vr_arg);
6667e4b17023SJohn Marino else
6668e4b17023SJohn Marino vrp_meet (&vr_result, &vr_arg);
6669e4b17023SJohn Marino first = false;
6670e4b17023SJohn Marino
6671e4b17023SJohn Marino if (vr_result.type == VR_VARYING)
6672e4b17023SJohn Marino break;
6673e4b17023SJohn Marino }
6674e4b17023SJohn Marino }
6675e4b17023SJohn Marino
6676e4b17023SJohn Marino if (vr_result.type == VR_VARYING)
6677e4b17023SJohn Marino goto varying;
6678e4b17023SJohn Marino else if (vr_result.type == VR_UNDEFINED)
6679e4b17023SJohn Marino goto update_range;
6680e4b17023SJohn Marino
6681e4b17023SJohn Marino old_edges = vr_phi_edge_counts[SSA_NAME_VERSION (lhs)];
6682e4b17023SJohn Marino vr_phi_edge_counts[SSA_NAME_VERSION (lhs)] = edges;
6683e4b17023SJohn Marino
6684e4b17023SJohn Marino /* To prevent infinite iterations in the algorithm, derive ranges
6685e4b17023SJohn Marino when the new value is slightly bigger or smaller than the
6686e4b17023SJohn Marino previous one. We don't do this if we have seen a new executable
6687e4b17023SJohn Marino edge; this helps us avoid an overflow infinity for conditionals
6688e4b17023SJohn Marino which are not in a loop. */
6689e4b17023SJohn Marino if (edges > 0
6690e4b17023SJohn Marino && gimple_phi_num_args (phi) > 1
6691e4b17023SJohn Marino && edges == old_edges)
6692e4b17023SJohn Marino {
6693e4b17023SJohn Marino int cmp_min = compare_values (lhs_vr->min, vr_result.min);
6694e4b17023SJohn Marino int cmp_max = compare_values (lhs_vr->max, vr_result.max);
6695e4b17023SJohn Marino
6696e4b17023SJohn Marino /* For non VR_RANGE or for pointers fall back to varying if
6697e4b17023SJohn Marino the range changed. */
6698e4b17023SJohn Marino if ((lhs_vr->type != VR_RANGE || vr_result.type != VR_RANGE
6699e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (lhs)))
6700e4b17023SJohn Marino && (cmp_min != 0 || cmp_max != 0))
6701e4b17023SJohn Marino goto varying;
6702e4b17023SJohn Marino
6703e4b17023SJohn Marino /* If the new minimum is smaller or larger than the previous
6704e4b17023SJohn Marino one, go all the way to -INF. In the first case, to avoid
6705e4b17023SJohn Marino iterating millions of times to reach -INF, and in the
6706e4b17023SJohn Marino other case to avoid infinite bouncing between different
6707e4b17023SJohn Marino minimums. */
6708e4b17023SJohn Marino if (cmp_min > 0 || cmp_min < 0)
6709e4b17023SJohn Marino {
6710e4b17023SJohn Marino if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
6711e4b17023SJohn Marino || !vrp_var_may_overflow (lhs, phi))
6712e4b17023SJohn Marino vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
6713e4b17023SJohn Marino else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
6714e4b17023SJohn Marino vr_result.min =
6715e4b17023SJohn Marino negative_overflow_infinity (TREE_TYPE (vr_result.min));
6716e4b17023SJohn Marino }
6717e4b17023SJohn Marino
6718e4b17023SJohn Marino /* Similarly, if the new maximum is smaller or larger than
6719e4b17023SJohn Marino the previous one, go all the way to +INF. */
6720e4b17023SJohn Marino if (cmp_max < 0 || cmp_max > 0)
6721e4b17023SJohn Marino {
6722e4b17023SJohn Marino if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
6723e4b17023SJohn Marino || !vrp_var_may_overflow (lhs, phi))
6724e4b17023SJohn Marino vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
6725e4b17023SJohn Marino else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
6726e4b17023SJohn Marino vr_result.max =
6727e4b17023SJohn Marino positive_overflow_infinity (TREE_TYPE (vr_result.max));
6728e4b17023SJohn Marino }
6729e4b17023SJohn Marino
6730e4b17023SJohn Marino /* If we dropped either bound to +-INF then if this is a loop
6731e4b17023SJohn Marino PHI node SCEV may known more about its value-range. */
6732e4b17023SJohn Marino if ((cmp_min > 0 || cmp_min < 0
6733e4b17023SJohn Marino || cmp_max < 0 || cmp_max > 0)
6734e4b17023SJohn Marino && current_loops
6735e4b17023SJohn Marino && (l = loop_containing_stmt (phi))
6736e4b17023SJohn Marino && l->header == gimple_bb (phi))
6737e4b17023SJohn Marino adjust_range_with_scev (&vr_result, l, phi, lhs);
6738e4b17023SJohn Marino
6739e4b17023SJohn Marino /* If we will end up with a (-INF, +INF) range, set it to
6740e4b17023SJohn Marino VARYING. Same if the previous max value was invalid for
6741e4b17023SJohn Marino the type and we end up with vr_result.min > vr_result.max. */
6742e4b17023SJohn Marino if ((vrp_val_is_max (vr_result.max)
6743e4b17023SJohn Marino && vrp_val_is_min (vr_result.min))
6744e4b17023SJohn Marino || compare_values (vr_result.min,
6745e4b17023SJohn Marino vr_result.max) > 0)
6746e4b17023SJohn Marino goto varying;
6747e4b17023SJohn Marino }
6748e4b17023SJohn Marino
6749e4b17023SJohn Marino /* If the new range is different than the previous value, keep
6750e4b17023SJohn Marino iterating. */
6751e4b17023SJohn Marino update_range:
6752e4b17023SJohn Marino if (update_value_range (lhs, &vr_result))
6753e4b17023SJohn Marino {
6754e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
6755e4b17023SJohn Marino {
6756e4b17023SJohn Marino fprintf (dump_file, "Found new range for ");
6757e4b17023SJohn Marino print_generic_expr (dump_file, lhs, 0);
6758e4b17023SJohn Marino fprintf (dump_file, ": ");
6759e4b17023SJohn Marino dump_value_range (dump_file, &vr_result);
6760e4b17023SJohn Marino fprintf (dump_file, "\n\n");
6761e4b17023SJohn Marino }
6762e4b17023SJohn Marino
6763e4b17023SJohn Marino return SSA_PROP_INTERESTING;
6764e4b17023SJohn Marino }
6765e4b17023SJohn Marino
6766e4b17023SJohn Marino /* Nothing changed, don't add outgoing edges. */
6767e4b17023SJohn Marino return SSA_PROP_NOT_INTERESTING;
6768e4b17023SJohn Marino
6769e4b17023SJohn Marino /* No match found. Set the LHS to VARYING. */
6770e4b17023SJohn Marino varying:
6771e4b17023SJohn Marino set_value_range_to_varying (lhs_vr);
6772e4b17023SJohn Marino return SSA_PROP_VARYING;
6773e4b17023SJohn Marino }
6774e4b17023SJohn Marino
6775e4b17023SJohn Marino /* Simplify boolean operations if the source is known
6776e4b17023SJohn Marino to be already a boolean. */
6777e4b17023SJohn Marino static bool
simplify_truth_ops_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)6778e4b17023SJohn Marino simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
6779e4b17023SJohn Marino {
6780e4b17023SJohn Marino enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
6781e4b17023SJohn Marino tree lhs, op0, op1;
6782e4b17023SJohn Marino bool need_conversion;
6783e4b17023SJohn Marino
6784e4b17023SJohn Marino /* We handle only !=/== case here. */
6785e4b17023SJohn Marino gcc_assert (rhs_code == EQ_EXPR || rhs_code == NE_EXPR);
6786e4b17023SJohn Marino
6787e4b17023SJohn Marino op0 = gimple_assign_rhs1 (stmt);
6788e4b17023SJohn Marino if (!op_with_boolean_value_range_p (op0))
6789e4b17023SJohn Marino return false;
6790e4b17023SJohn Marino
6791e4b17023SJohn Marino op1 = gimple_assign_rhs2 (stmt);
6792e4b17023SJohn Marino if (!op_with_boolean_value_range_p (op1))
6793e4b17023SJohn Marino return false;
6794e4b17023SJohn Marino
6795e4b17023SJohn Marino /* Reduce number of cases to handle to NE_EXPR. As there is no
6796e4b17023SJohn Marino BIT_XNOR_EXPR we cannot replace A == B with a single statement. */
6797e4b17023SJohn Marino if (rhs_code == EQ_EXPR)
6798e4b17023SJohn Marino {
6799e4b17023SJohn Marino if (TREE_CODE (op1) == INTEGER_CST)
6800e4b17023SJohn Marino op1 = int_const_binop (BIT_XOR_EXPR, op1, integer_one_node);
6801e4b17023SJohn Marino else
6802e4b17023SJohn Marino return false;
6803e4b17023SJohn Marino }
6804e4b17023SJohn Marino
6805e4b17023SJohn Marino lhs = gimple_assign_lhs (stmt);
6806e4b17023SJohn Marino need_conversion
6807e4b17023SJohn Marino = !useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (op0));
6808e4b17023SJohn Marino
6809e4b17023SJohn Marino /* Make sure to not sign-extend a 1-bit 1 when converting the result. */
6810e4b17023SJohn Marino if (need_conversion
6811e4b17023SJohn Marino && !TYPE_UNSIGNED (TREE_TYPE (op0))
6812e4b17023SJohn Marino && TYPE_PRECISION (TREE_TYPE (op0)) == 1
6813e4b17023SJohn Marino && TYPE_PRECISION (TREE_TYPE (lhs)) > 1)
6814e4b17023SJohn Marino return false;
6815e4b17023SJohn Marino
6816e4b17023SJohn Marino /* For A != 0 we can substitute A itself. */
6817e4b17023SJohn Marino if (integer_zerop (op1))
6818e4b17023SJohn Marino gimple_assign_set_rhs_with_ops (gsi,
6819e4b17023SJohn Marino need_conversion
6820e4b17023SJohn Marino ? NOP_EXPR : TREE_CODE (op0),
6821e4b17023SJohn Marino op0, NULL_TREE);
6822e4b17023SJohn Marino /* For A != B we substitute A ^ B. Either with conversion. */
6823e4b17023SJohn Marino else if (need_conversion)
6824e4b17023SJohn Marino {
6825e4b17023SJohn Marino gimple newop;
6826e4b17023SJohn Marino tree tem = create_tmp_reg (TREE_TYPE (op0), NULL);
6827e4b17023SJohn Marino newop = gimple_build_assign_with_ops (BIT_XOR_EXPR, tem, op0, op1);
6828e4b17023SJohn Marino tem = make_ssa_name (tem, newop);
6829e4b17023SJohn Marino gimple_assign_set_lhs (newop, tem);
6830e4b17023SJohn Marino gsi_insert_before (gsi, newop, GSI_SAME_STMT);
6831e4b17023SJohn Marino update_stmt (newop);
6832e4b17023SJohn Marino gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem, NULL_TREE);
6833e4b17023SJohn Marino }
6834e4b17023SJohn Marino /* Or without. */
6835e4b17023SJohn Marino else
6836e4b17023SJohn Marino gimple_assign_set_rhs_with_ops (gsi, BIT_XOR_EXPR, op0, op1);
6837e4b17023SJohn Marino update_stmt (gsi_stmt (*gsi));
6838e4b17023SJohn Marino
6839e4b17023SJohn Marino return true;
6840e4b17023SJohn Marino }
6841e4b17023SJohn Marino
6842e4b17023SJohn Marino /* Simplify a division or modulo operator to a right shift or
6843e4b17023SJohn Marino bitwise and if the first operand is unsigned or is greater
6844e4b17023SJohn Marino than zero and the second operand is an exact power of two. */
6845e4b17023SJohn Marino
6846e4b17023SJohn Marino static bool
simplify_div_or_mod_using_ranges(gimple stmt)6847e4b17023SJohn Marino simplify_div_or_mod_using_ranges (gimple stmt)
6848e4b17023SJohn Marino {
6849e4b17023SJohn Marino enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
6850e4b17023SJohn Marino tree val = NULL;
6851e4b17023SJohn Marino tree op0 = gimple_assign_rhs1 (stmt);
6852e4b17023SJohn Marino tree op1 = gimple_assign_rhs2 (stmt);
6853e4b17023SJohn Marino value_range_t *vr = get_value_range (gimple_assign_rhs1 (stmt));
6854e4b17023SJohn Marino
6855e4b17023SJohn Marino if (TYPE_UNSIGNED (TREE_TYPE (op0)))
6856e4b17023SJohn Marino {
6857e4b17023SJohn Marino val = integer_one_node;
6858e4b17023SJohn Marino }
6859e4b17023SJohn Marino else
6860e4b17023SJohn Marino {
6861e4b17023SJohn Marino bool sop = false;
6862e4b17023SJohn Marino
6863e4b17023SJohn Marino val = compare_range_with_value (GE_EXPR, vr, integer_zero_node, &sop);
6864e4b17023SJohn Marino
6865e4b17023SJohn Marino if (val
6866e4b17023SJohn Marino && sop
6867e4b17023SJohn Marino && integer_onep (val)
6868e4b17023SJohn Marino && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
6869e4b17023SJohn Marino {
6870e4b17023SJohn Marino location_t location;
6871e4b17023SJohn Marino
6872e4b17023SJohn Marino if (!gimple_has_location (stmt))
6873e4b17023SJohn Marino location = input_location;
6874e4b17023SJohn Marino else
6875e4b17023SJohn Marino location = gimple_location (stmt);
6876e4b17023SJohn Marino warning_at (location, OPT_Wstrict_overflow,
6877e4b17023SJohn Marino "assuming signed overflow does not occur when "
6878e4b17023SJohn Marino "simplifying %</%> or %<%%%> to %<>>%> or %<&%>");
6879e4b17023SJohn Marino }
6880e4b17023SJohn Marino }
6881e4b17023SJohn Marino
6882e4b17023SJohn Marino if (val && integer_onep (val))
6883e4b17023SJohn Marino {
6884e4b17023SJohn Marino tree t;
6885e4b17023SJohn Marino
6886e4b17023SJohn Marino if (rhs_code == TRUNC_DIV_EXPR)
6887e4b17023SJohn Marino {
6888e4b17023SJohn Marino t = build_int_cst (integer_type_node, tree_log2 (op1));
6889e4b17023SJohn Marino gimple_assign_set_rhs_code (stmt, RSHIFT_EXPR);
6890e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, op0);
6891e4b17023SJohn Marino gimple_assign_set_rhs2 (stmt, t);
6892e4b17023SJohn Marino }
6893e4b17023SJohn Marino else
6894e4b17023SJohn Marino {
6895e4b17023SJohn Marino t = build_int_cst (TREE_TYPE (op1), 1);
6896e4b17023SJohn Marino t = int_const_binop (MINUS_EXPR, op1, t);
6897e4b17023SJohn Marino t = fold_convert (TREE_TYPE (op0), t);
6898e4b17023SJohn Marino
6899e4b17023SJohn Marino gimple_assign_set_rhs_code (stmt, BIT_AND_EXPR);
6900e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, op0);
6901e4b17023SJohn Marino gimple_assign_set_rhs2 (stmt, t);
6902e4b17023SJohn Marino }
6903e4b17023SJohn Marino
6904e4b17023SJohn Marino update_stmt (stmt);
6905e4b17023SJohn Marino return true;
6906e4b17023SJohn Marino }
6907e4b17023SJohn Marino
6908e4b17023SJohn Marino return false;
6909e4b17023SJohn Marino }
6910e4b17023SJohn Marino
6911e4b17023SJohn Marino /* If the operand to an ABS_EXPR is >= 0, then eliminate the
6912e4b17023SJohn Marino ABS_EXPR. If the operand is <= 0, then simplify the
6913e4b17023SJohn Marino ABS_EXPR into a NEGATE_EXPR. */
6914e4b17023SJohn Marino
6915e4b17023SJohn Marino static bool
simplify_abs_using_ranges(gimple stmt)6916e4b17023SJohn Marino simplify_abs_using_ranges (gimple stmt)
6917e4b17023SJohn Marino {
6918e4b17023SJohn Marino tree val = NULL;
6919e4b17023SJohn Marino tree op = gimple_assign_rhs1 (stmt);
6920e4b17023SJohn Marino tree type = TREE_TYPE (op);
6921e4b17023SJohn Marino value_range_t *vr = get_value_range (op);
6922e4b17023SJohn Marino
6923e4b17023SJohn Marino if (TYPE_UNSIGNED (type))
6924e4b17023SJohn Marino {
6925e4b17023SJohn Marino val = integer_zero_node;
6926e4b17023SJohn Marino }
6927e4b17023SJohn Marino else if (vr)
6928e4b17023SJohn Marino {
6929e4b17023SJohn Marino bool sop = false;
6930e4b17023SJohn Marino
6931e4b17023SJohn Marino val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
6932e4b17023SJohn Marino if (!val)
6933e4b17023SJohn Marino {
6934e4b17023SJohn Marino sop = false;
6935e4b17023SJohn Marino val = compare_range_with_value (GE_EXPR, vr, integer_zero_node,
6936e4b17023SJohn Marino &sop);
6937e4b17023SJohn Marino
6938e4b17023SJohn Marino if (val)
6939e4b17023SJohn Marino {
6940e4b17023SJohn Marino if (integer_zerop (val))
6941e4b17023SJohn Marino val = integer_one_node;
6942e4b17023SJohn Marino else if (integer_onep (val))
6943e4b17023SJohn Marino val = integer_zero_node;
6944e4b17023SJohn Marino }
6945e4b17023SJohn Marino }
6946e4b17023SJohn Marino
6947e4b17023SJohn Marino if (val
6948e4b17023SJohn Marino && (integer_onep (val) || integer_zerop (val)))
6949e4b17023SJohn Marino {
6950e4b17023SJohn Marino if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
6951e4b17023SJohn Marino {
6952e4b17023SJohn Marino location_t location;
6953e4b17023SJohn Marino
6954e4b17023SJohn Marino if (!gimple_has_location (stmt))
6955e4b17023SJohn Marino location = input_location;
6956e4b17023SJohn Marino else
6957e4b17023SJohn Marino location = gimple_location (stmt);
6958e4b17023SJohn Marino warning_at (location, OPT_Wstrict_overflow,
6959e4b17023SJohn Marino "assuming signed overflow does not occur when "
6960e4b17023SJohn Marino "simplifying %<abs (X)%> to %<X%> or %<-X%>");
6961e4b17023SJohn Marino }
6962e4b17023SJohn Marino
6963e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, op);
6964e4b17023SJohn Marino if (integer_onep (val))
6965e4b17023SJohn Marino gimple_assign_set_rhs_code (stmt, NEGATE_EXPR);
6966e4b17023SJohn Marino else
6967e4b17023SJohn Marino gimple_assign_set_rhs_code (stmt, SSA_NAME);
6968e4b17023SJohn Marino update_stmt (stmt);
6969e4b17023SJohn Marino return true;
6970e4b17023SJohn Marino }
6971e4b17023SJohn Marino }
6972e4b17023SJohn Marino
6973e4b17023SJohn Marino return false;
6974e4b17023SJohn Marino }
6975e4b17023SJohn Marino
6976e4b17023SJohn Marino /* Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
6977e4b17023SJohn Marino If all the bits that are being cleared by & are already
6978e4b17023SJohn Marino known to be zero from VR, or all the bits that are being
6979e4b17023SJohn Marino set by | are already known to be one from VR, the bit
6980e4b17023SJohn Marino operation is redundant. */
6981e4b17023SJohn Marino
6982e4b17023SJohn Marino static bool
simplify_bit_ops_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)6983e4b17023SJohn Marino simplify_bit_ops_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
6984e4b17023SJohn Marino {
6985e4b17023SJohn Marino tree op0 = gimple_assign_rhs1 (stmt);
6986e4b17023SJohn Marino tree op1 = gimple_assign_rhs2 (stmt);
6987e4b17023SJohn Marino tree op = NULL_TREE;
6988e4b17023SJohn Marino value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6989e4b17023SJohn Marino value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
6990e4b17023SJohn Marino double_int may_be_nonzero0, may_be_nonzero1;
6991e4b17023SJohn Marino double_int must_be_nonzero0, must_be_nonzero1;
6992e4b17023SJohn Marino double_int mask;
6993e4b17023SJohn Marino
6994e4b17023SJohn Marino if (TREE_CODE (op0) == SSA_NAME)
6995e4b17023SJohn Marino vr0 = *(get_value_range (op0));
6996e4b17023SJohn Marino else if (is_gimple_min_invariant (op0))
6997e4b17023SJohn Marino set_value_range_to_value (&vr0, op0, NULL);
6998e4b17023SJohn Marino else
6999e4b17023SJohn Marino return false;
7000e4b17023SJohn Marino
7001e4b17023SJohn Marino if (TREE_CODE (op1) == SSA_NAME)
7002e4b17023SJohn Marino vr1 = *(get_value_range (op1));
7003e4b17023SJohn Marino else if (is_gimple_min_invariant (op1))
7004e4b17023SJohn Marino set_value_range_to_value (&vr1, op1, NULL);
7005e4b17023SJohn Marino else
7006e4b17023SJohn Marino return false;
7007e4b17023SJohn Marino
7008e4b17023SJohn Marino if (!zero_nonzero_bits_from_vr (&vr0, &may_be_nonzero0, &must_be_nonzero0))
7009e4b17023SJohn Marino return false;
7010e4b17023SJohn Marino if (!zero_nonzero_bits_from_vr (&vr1, &may_be_nonzero1, &must_be_nonzero1))
7011e4b17023SJohn Marino return false;
7012e4b17023SJohn Marino
7013e4b17023SJohn Marino switch (gimple_assign_rhs_code (stmt))
7014e4b17023SJohn Marino {
7015e4b17023SJohn Marino case BIT_AND_EXPR:
7016e4b17023SJohn Marino mask = double_int_and_not (may_be_nonzero0, must_be_nonzero1);
7017e4b17023SJohn Marino if (double_int_zero_p (mask))
7018e4b17023SJohn Marino {
7019e4b17023SJohn Marino op = op0;
7020e4b17023SJohn Marino break;
7021e4b17023SJohn Marino }
7022e4b17023SJohn Marino mask = double_int_and_not (may_be_nonzero1, must_be_nonzero0);
7023e4b17023SJohn Marino if (double_int_zero_p (mask))
7024e4b17023SJohn Marino {
7025e4b17023SJohn Marino op = op1;
7026e4b17023SJohn Marino break;
7027e4b17023SJohn Marino }
7028e4b17023SJohn Marino break;
7029e4b17023SJohn Marino case BIT_IOR_EXPR:
7030e4b17023SJohn Marino mask = double_int_and_not (may_be_nonzero0, must_be_nonzero1);
7031e4b17023SJohn Marino if (double_int_zero_p (mask))
7032e4b17023SJohn Marino {
7033e4b17023SJohn Marino op = op1;
7034e4b17023SJohn Marino break;
7035e4b17023SJohn Marino }
7036e4b17023SJohn Marino mask = double_int_and_not (may_be_nonzero1, must_be_nonzero0);
7037e4b17023SJohn Marino if (double_int_zero_p (mask))
7038e4b17023SJohn Marino {
7039e4b17023SJohn Marino op = op0;
7040e4b17023SJohn Marino break;
7041e4b17023SJohn Marino }
7042e4b17023SJohn Marino break;
7043e4b17023SJohn Marino default:
7044e4b17023SJohn Marino gcc_unreachable ();
7045e4b17023SJohn Marino }
7046e4b17023SJohn Marino
7047e4b17023SJohn Marino if (op == NULL_TREE)
7048e4b17023SJohn Marino return false;
7049e4b17023SJohn Marino
7050e4b17023SJohn Marino gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (op), op, NULL);
7051e4b17023SJohn Marino update_stmt (gsi_stmt (*gsi));
7052e4b17023SJohn Marino return true;
7053e4b17023SJohn Marino }
7054e4b17023SJohn Marino
7055e4b17023SJohn Marino /* We are comparing trees OP0 and OP1 using COND_CODE. OP0 has
7056e4b17023SJohn Marino a known value range VR.
7057e4b17023SJohn Marino
7058e4b17023SJohn Marino If there is one and only one value which will satisfy the
7059e4b17023SJohn Marino conditional, then return that value. Else return NULL. */
7060e4b17023SJohn Marino
7061e4b17023SJohn Marino static tree
test_for_singularity(enum tree_code cond_code,tree op0,tree op1,value_range_t * vr)7062e4b17023SJohn Marino test_for_singularity (enum tree_code cond_code, tree op0,
7063e4b17023SJohn Marino tree op1, value_range_t *vr)
7064e4b17023SJohn Marino {
7065e4b17023SJohn Marino tree min = NULL;
7066e4b17023SJohn Marino tree max = NULL;
7067e4b17023SJohn Marino
7068e4b17023SJohn Marino /* Extract minimum/maximum values which satisfy the
7069e4b17023SJohn Marino the conditional as it was written. */
7070e4b17023SJohn Marino if (cond_code == LE_EXPR || cond_code == LT_EXPR)
7071e4b17023SJohn Marino {
7072e4b17023SJohn Marino /* This should not be negative infinity; there is no overflow
7073e4b17023SJohn Marino here. */
7074e4b17023SJohn Marino min = TYPE_MIN_VALUE (TREE_TYPE (op0));
7075e4b17023SJohn Marino
7076e4b17023SJohn Marino max = op1;
7077e4b17023SJohn Marino if (cond_code == LT_EXPR && !is_overflow_infinity (max))
7078e4b17023SJohn Marino {
7079e4b17023SJohn Marino tree one = build_int_cst (TREE_TYPE (op0), 1);
7080e4b17023SJohn Marino max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
7081e4b17023SJohn Marino if (EXPR_P (max))
7082e4b17023SJohn Marino TREE_NO_WARNING (max) = 1;
7083e4b17023SJohn Marino }
7084e4b17023SJohn Marino }
7085e4b17023SJohn Marino else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
7086e4b17023SJohn Marino {
7087e4b17023SJohn Marino /* This should not be positive infinity; there is no overflow
7088e4b17023SJohn Marino here. */
7089e4b17023SJohn Marino max = TYPE_MAX_VALUE (TREE_TYPE (op0));
7090e4b17023SJohn Marino
7091e4b17023SJohn Marino min = op1;
7092e4b17023SJohn Marino if (cond_code == GT_EXPR && !is_overflow_infinity (min))
7093e4b17023SJohn Marino {
7094e4b17023SJohn Marino tree one = build_int_cst (TREE_TYPE (op0), 1);
7095e4b17023SJohn Marino min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
7096e4b17023SJohn Marino if (EXPR_P (min))
7097e4b17023SJohn Marino TREE_NO_WARNING (min) = 1;
7098e4b17023SJohn Marino }
7099e4b17023SJohn Marino }
7100e4b17023SJohn Marino
7101e4b17023SJohn Marino /* Now refine the minimum and maximum values using any
7102e4b17023SJohn Marino value range information we have for op0. */
7103e4b17023SJohn Marino if (min && max)
7104e4b17023SJohn Marino {
7105e4b17023SJohn Marino if (compare_values (vr->min, min) == 1)
7106e4b17023SJohn Marino min = vr->min;
7107e4b17023SJohn Marino if (compare_values (vr->max, max) == -1)
7108e4b17023SJohn Marino max = vr->max;
7109e4b17023SJohn Marino
7110e4b17023SJohn Marino /* If the new min/max values have converged to a single value,
7111e4b17023SJohn Marino then there is only one value which can satisfy the condition,
7112e4b17023SJohn Marino return that value. */
7113e4b17023SJohn Marino if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
7114e4b17023SJohn Marino return min;
7115e4b17023SJohn Marino }
7116e4b17023SJohn Marino return NULL;
7117e4b17023SJohn Marino }
7118e4b17023SJohn Marino
7119e4b17023SJohn Marino /* Simplify a conditional using a relational operator to an equality
7120e4b17023SJohn Marino test if the range information indicates only one value can satisfy
7121e4b17023SJohn Marino the original conditional. */
7122e4b17023SJohn Marino
7123e4b17023SJohn Marino static bool
simplify_cond_using_ranges(gimple stmt)7124e4b17023SJohn Marino simplify_cond_using_ranges (gimple stmt)
7125e4b17023SJohn Marino {
7126e4b17023SJohn Marino tree op0 = gimple_cond_lhs (stmt);
7127e4b17023SJohn Marino tree op1 = gimple_cond_rhs (stmt);
7128e4b17023SJohn Marino enum tree_code cond_code = gimple_cond_code (stmt);
7129e4b17023SJohn Marino
7130e4b17023SJohn Marino if (cond_code != NE_EXPR
7131e4b17023SJohn Marino && cond_code != EQ_EXPR
7132e4b17023SJohn Marino && TREE_CODE (op0) == SSA_NAME
7133e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (op0))
7134e4b17023SJohn Marino && is_gimple_min_invariant (op1))
7135e4b17023SJohn Marino {
7136e4b17023SJohn Marino value_range_t *vr = get_value_range (op0);
7137e4b17023SJohn Marino
7138e4b17023SJohn Marino /* If we have range information for OP0, then we might be
7139e4b17023SJohn Marino able to simplify this conditional. */
7140e4b17023SJohn Marino if (vr->type == VR_RANGE)
7141e4b17023SJohn Marino {
7142e4b17023SJohn Marino tree new_tree = test_for_singularity (cond_code, op0, op1, vr);
7143e4b17023SJohn Marino
7144e4b17023SJohn Marino if (new_tree)
7145e4b17023SJohn Marino {
7146e4b17023SJohn Marino if (dump_file)
7147e4b17023SJohn Marino {
7148e4b17023SJohn Marino fprintf (dump_file, "Simplified relational ");
7149e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, 0);
7150e4b17023SJohn Marino fprintf (dump_file, " into ");
7151e4b17023SJohn Marino }
7152e4b17023SJohn Marino
7153e4b17023SJohn Marino gimple_cond_set_code (stmt, EQ_EXPR);
7154e4b17023SJohn Marino gimple_cond_set_lhs (stmt, op0);
7155e4b17023SJohn Marino gimple_cond_set_rhs (stmt, new_tree);
7156e4b17023SJohn Marino
7157e4b17023SJohn Marino update_stmt (stmt);
7158e4b17023SJohn Marino
7159e4b17023SJohn Marino if (dump_file)
7160e4b17023SJohn Marino {
7161e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, 0);
7162e4b17023SJohn Marino fprintf (dump_file, "\n");
7163e4b17023SJohn Marino }
7164e4b17023SJohn Marino
7165e4b17023SJohn Marino return true;
7166e4b17023SJohn Marino }
7167e4b17023SJohn Marino
7168e4b17023SJohn Marino /* Try again after inverting the condition. We only deal
7169e4b17023SJohn Marino with integral types here, so no need to worry about
7170e4b17023SJohn Marino issues with inverting FP comparisons. */
7171e4b17023SJohn Marino cond_code = invert_tree_comparison (cond_code, false);
7172e4b17023SJohn Marino new_tree = test_for_singularity (cond_code, op0, op1, vr);
7173e4b17023SJohn Marino
7174e4b17023SJohn Marino if (new_tree)
7175e4b17023SJohn Marino {
7176e4b17023SJohn Marino if (dump_file)
7177e4b17023SJohn Marino {
7178e4b17023SJohn Marino fprintf (dump_file, "Simplified relational ");
7179e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, 0);
7180e4b17023SJohn Marino fprintf (dump_file, " into ");
7181e4b17023SJohn Marino }
7182e4b17023SJohn Marino
7183e4b17023SJohn Marino gimple_cond_set_code (stmt, NE_EXPR);
7184e4b17023SJohn Marino gimple_cond_set_lhs (stmt, op0);
7185e4b17023SJohn Marino gimple_cond_set_rhs (stmt, new_tree);
7186e4b17023SJohn Marino
7187e4b17023SJohn Marino update_stmt (stmt);
7188e4b17023SJohn Marino
7189e4b17023SJohn Marino if (dump_file)
7190e4b17023SJohn Marino {
7191e4b17023SJohn Marino print_gimple_stmt (dump_file, stmt, 0, 0);
7192e4b17023SJohn Marino fprintf (dump_file, "\n");
7193e4b17023SJohn Marino }
7194e4b17023SJohn Marino
7195e4b17023SJohn Marino return true;
7196e4b17023SJohn Marino }
7197e4b17023SJohn Marino }
7198e4b17023SJohn Marino }
7199e4b17023SJohn Marino
7200e4b17023SJohn Marino return false;
7201e4b17023SJohn Marino }
7202e4b17023SJohn Marino
7203e4b17023SJohn Marino /* Simplify a switch statement using the value range of the switch
7204e4b17023SJohn Marino argument. */
7205e4b17023SJohn Marino
7206e4b17023SJohn Marino static bool
simplify_switch_using_ranges(gimple stmt)7207e4b17023SJohn Marino simplify_switch_using_ranges (gimple stmt)
7208e4b17023SJohn Marino {
7209e4b17023SJohn Marino tree op = gimple_switch_index (stmt);
7210e4b17023SJohn Marino value_range_t *vr;
7211e4b17023SJohn Marino bool take_default;
7212e4b17023SJohn Marino edge e;
7213e4b17023SJohn Marino edge_iterator ei;
7214e4b17023SJohn Marino size_t i = 0, j = 0, n, n2;
7215e4b17023SJohn Marino tree vec2;
7216e4b17023SJohn Marino switch_update su;
7217e4b17023SJohn Marino
7218e4b17023SJohn Marino if (TREE_CODE (op) == SSA_NAME)
7219e4b17023SJohn Marino {
7220e4b17023SJohn Marino vr = get_value_range (op);
7221e4b17023SJohn Marino
7222e4b17023SJohn Marino /* We can only handle integer ranges. */
7223e4b17023SJohn Marino if (vr->type != VR_RANGE
7224e4b17023SJohn Marino || symbolic_range_p (vr))
7225e4b17023SJohn Marino return false;
7226e4b17023SJohn Marino
7227e4b17023SJohn Marino /* Find case label for min/max of the value range. */
7228e4b17023SJohn Marino take_default = !find_case_label_range (stmt, vr->min, vr->max, &i, &j);
7229e4b17023SJohn Marino }
7230e4b17023SJohn Marino else if (TREE_CODE (op) == INTEGER_CST)
7231e4b17023SJohn Marino {
7232e4b17023SJohn Marino take_default = !find_case_label_index (stmt, 1, op, &i);
7233e4b17023SJohn Marino if (take_default)
7234e4b17023SJohn Marino {
7235e4b17023SJohn Marino i = 1;
7236e4b17023SJohn Marino j = 0;
7237e4b17023SJohn Marino }
7238e4b17023SJohn Marino else
7239e4b17023SJohn Marino {
7240e4b17023SJohn Marino j = i;
7241e4b17023SJohn Marino }
7242e4b17023SJohn Marino }
7243e4b17023SJohn Marino else
7244e4b17023SJohn Marino return false;
7245e4b17023SJohn Marino
7246e4b17023SJohn Marino n = gimple_switch_num_labels (stmt);
7247e4b17023SJohn Marino
7248e4b17023SJohn Marino /* Bail out if this is just all edges taken. */
7249e4b17023SJohn Marino if (i == 1
7250e4b17023SJohn Marino && j == n - 1
7251e4b17023SJohn Marino && take_default)
7252e4b17023SJohn Marino return false;
7253e4b17023SJohn Marino
7254e4b17023SJohn Marino /* Build a new vector of taken case labels. */
7255e4b17023SJohn Marino vec2 = make_tree_vec (j - i + 1 + (int)take_default);
7256e4b17023SJohn Marino n2 = 0;
7257e4b17023SJohn Marino
7258e4b17023SJohn Marino /* Add the default edge, if necessary. */
7259e4b17023SJohn Marino if (take_default)
7260e4b17023SJohn Marino TREE_VEC_ELT (vec2, n2++) = gimple_switch_default_label (stmt);
7261e4b17023SJohn Marino
7262e4b17023SJohn Marino for (; i <= j; ++i, ++n2)
7263e4b17023SJohn Marino TREE_VEC_ELT (vec2, n2) = gimple_switch_label (stmt, i);
7264e4b17023SJohn Marino
7265e4b17023SJohn Marino /* Mark needed edges. */
7266e4b17023SJohn Marino for (i = 0; i < n2; ++i)
7267e4b17023SJohn Marino {
7268e4b17023SJohn Marino e = find_edge (gimple_bb (stmt),
7269e4b17023SJohn Marino label_to_block (CASE_LABEL (TREE_VEC_ELT (vec2, i))));
7270e4b17023SJohn Marino e->aux = (void *)-1;
7271e4b17023SJohn Marino }
7272e4b17023SJohn Marino
7273e4b17023SJohn Marino /* Queue not needed edges for later removal. */
7274e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->succs)
7275e4b17023SJohn Marino {
7276e4b17023SJohn Marino if (e->aux == (void *)-1)
7277e4b17023SJohn Marino {
7278e4b17023SJohn Marino e->aux = NULL;
7279e4b17023SJohn Marino continue;
7280e4b17023SJohn Marino }
7281e4b17023SJohn Marino
7282e4b17023SJohn Marino if (dump_file && (dump_flags & TDF_DETAILS))
7283e4b17023SJohn Marino {
7284e4b17023SJohn Marino fprintf (dump_file, "removing unreachable case label\n");
7285e4b17023SJohn Marino }
7286e4b17023SJohn Marino VEC_safe_push (edge, heap, to_remove_edges, e);
7287e4b17023SJohn Marino e->flags &= ~EDGE_EXECUTABLE;
7288e4b17023SJohn Marino }
7289e4b17023SJohn Marino
7290e4b17023SJohn Marino /* And queue an update for the stmt. */
7291e4b17023SJohn Marino su.stmt = stmt;
7292e4b17023SJohn Marino su.vec = vec2;
7293e4b17023SJohn Marino VEC_safe_push (switch_update, heap, to_update_switch_stmts, &su);
7294e4b17023SJohn Marino return false;
7295e4b17023SJohn Marino }
7296e4b17023SJohn Marino
7297e4b17023SJohn Marino /* Simplify an integral conversion from an SSA name in STMT. */
7298e4b17023SJohn Marino
7299e4b17023SJohn Marino static bool
simplify_conversion_using_ranges(gimple stmt)7300e4b17023SJohn Marino simplify_conversion_using_ranges (gimple stmt)
7301e4b17023SJohn Marino {
7302e4b17023SJohn Marino tree innerop, middleop, finaltype;
7303e4b17023SJohn Marino gimple def_stmt;
7304e4b17023SJohn Marino value_range_t *innervr;
7305e4b17023SJohn Marino bool inner_unsigned_p, middle_unsigned_p, final_unsigned_p;
7306e4b17023SJohn Marino unsigned inner_prec, middle_prec, final_prec;
7307e4b17023SJohn Marino double_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
7308e4b17023SJohn Marino
7309e4b17023SJohn Marino finaltype = TREE_TYPE (gimple_assign_lhs (stmt));
7310e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (finaltype))
7311e4b17023SJohn Marino return false;
7312e4b17023SJohn Marino middleop = gimple_assign_rhs1 (stmt);
7313e4b17023SJohn Marino def_stmt = SSA_NAME_DEF_STMT (middleop);
7314e4b17023SJohn Marino if (!is_gimple_assign (def_stmt)
7315e4b17023SJohn Marino || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
7316e4b17023SJohn Marino return false;
7317e4b17023SJohn Marino innerop = gimple_assign_rhs1 (def_stmt);
7318e4b17023SJohn Marino if (TREE_CODE (innerop) != SSA_NAME)
7319e4b17023SJohn Marino return false;
7320e4b17023SJohn Marino
7321e4b17023SJohn Marino /* Get the value-range of the inner operand. */
7322e4b17023SJohn Marino innervr = get_value_range (innerop);
7323e4b17023SJohn Marino if (innervr->type != VR_RANGE
7324e4b17023SJohn Marino || TREE_CODE (innervr->min) != INTEGER_CST
7325e4b17023SJohn Marino || TREE_CODE (innervr->max) != INTEGER_CST)
7326e4b17023SJohn Marino return false;
7327e4b17023SJohn Marino
7328e4b17023SJohn Marino /* Simulate the conversion chain to check if the result is equal if
7329e4b17023SJohn Marino the middle conversion is removed. */
7330e4b17023SJohn Marino innermin = tree_to_double_int (innervr->min);
7331e4b17023SJohn Marino innermax = tree_to_double_int (innervr->max);
7332e4b17023SJohn Marino
7333e4b17023SJohn Marino inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
7334e4b17023SJohn Marino middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
7335e4b17023SJohn Marino final_prec = TYPE_PRECISION (finaltype);
7336e4b17023SJohn Marino
7337e4b17023SJohn Marino /* If the first conversion is not injective, the second must not
7338e4b17023SJohn Marino be widening. */
7339e4b17023SJohn Marino if (double_int_cmp (double_int_sub (innermax, innermin),
7340e4b17023SJohn Marino double_int_mask (middle_prec), true) > 0
7341e4b17023SJohn Marino && middle_prec < final_prec)
7342e4b17023SJohn Marino return false;
7343e4b17023SJohn Marino /* We also want a medium value so that we can track the effect that
7344e4b17023SJohn Marino narrowing conversions with sign change have. */
7345e4b17023SJohn Marino inner_unsigned_p = TYPE_UNSIGNED (TREE_TYPE (innerop));
7346e4b17023SJohn Marino if (inner_unsigned_p)
7347e4b17023SJohn Marino innermed = double_int_rshift (double_int_mask (inner_prec),
7348e4b17023SJohn Marino 1, inner_prec, false);
7349e4b17023SJohn Marino else
7350e4b17023SJohn Marino innermed = double_int_zero;
7351e4b17023SJohn Marino if (double_int_cmp (innermin, innermed, inner_unsigned_p) >= 0
7352e4b17023SJohn Marino || double_int_cmp (innermed, innermax, inner_unsigned_p) >= 0)
7353e4b17023SJohn Marino innermed = innermin;
7354e4b17023SJohn Marino
7355e4b17023SJohn Marino middle_unsigned_p = TYPE_UNSIGNED (TREE_TYPE (middleop));
7356e4b17023SJohn Marino middlemin = double_int_ext (innermin, middle_prec, middle_unsigned_p);
7357e4b17023SJohn Marino middlemed = double_int_ext (innermed, middle_prec, middle_unsigned_p);
7358e4b17023SJohn Marino middlemax = double_int_ext (innermax, middle_prec, middle_unsigned_p);
7359e4b17023SJohn Marino
7360e4b17023SJohn Marino /* Require that the final conversion applied to both the original
7361e4b17023SJohn Marino and the intermediate range produces the same result. */
7362e4b17023SJohn Marino final_unsigned_p = TYPE_UNSIGNED (finaltype);
7363e4b17023SJohn Marino if (!double_int_equal_p (double_int_ext (middlemin,
7364e4b17023SJohn Marino final_prec, final_unsigned_p),
7365e4b17023SJohn Marino double_int_ext (innermin,
7366e4b17023SJohn Marino final_prec, final_unsigned_p))
7367e4b17023SJohn Marino || !double_int_equal_p (double_int_ext (middlemed,
7368e4b17023SJohn Marino final_prec, final_unsigned_p),
7369e4b17023SJohn Marino double_int_ext (innermed,
7370e4b17023SJohn Marino final_prec, final_unsigned_p))
7371e4b17023SJohn Marino || !double_int_equal_p (double_int_ext (middlemax,
7372e4b17023SJohn Marino final_prec, final_unsigned_p),
7373e4b17023SJohn Marino double_int_ext (innermax,
7374e4b17023SJohn Marino final_prec, final_unsigned_p)))
7375e4b17023SJohn Marino return false;
7376e4b17023SJohn Marino
7377e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, innerop);
7378e4b17023SJohn Marino update_stmt (stmt);
7379e4b17023SJohn Marino return true;
7380e4b17023SJohn Marino }
7381e4b17023SJohn Marino
7382e4b17023SJohn Marino /* Return whether the value range *VR fits in an integer type specified
7383e4b17023SJohn Marino by PRECISION and UNSIGNED_P. */
7384e4b17023SJohn Marino
7385e4b17023SJohn Marino static bool
range_fits_type_p(value_range_t * vr,unsigned precision,bool unsigned_p)7386e4b17023SJohn Marino range_fits_type_p (value_range_t *vr, unsigned precision, bool unsigned_p)
7387e4b17023SJohn Marino {
7388e4b17023SJohn Marino tree src_type;
7389e4b17023SJohn Marino unsigned src_precision;
7390e4b17023SJohn Marino double_int tem;
7391e4b17023SJohn Marino
7392e4b17023SJohn Marino /* We can only handle integral and pointer types. */
7393e4b17023SJohn Marino src_type = TREE_TYPE (vr->min);
7394e4b17023SJohn Marino if (!INTEGRAL_TYPE_P (src_type)
7395e4b17023SJohn Marino && !POINTER_TYPE_P (src_type))
7396e4b17023SJohn Marino return false;
7397e4b17023SJohn Marino
7398e4b17023SJohn Marino /* An extension is always fine, so is an identity transform. */
7399e4b17023SJohn Marino src_precision = TYPE_PRECISION (TREE_TYPE (vr->min));
7400e4b17023SJohn Marino if (src_precision < precision
7401e4b17023SJohn Marino || (src_precision == precision
7402e4b17023SJohn Marino && TYPE_UNSIGNED (src_type) == unsigned_p))
7403e4b17023SJohn Marino return true;
7404e4b17023SJohn Marino
7405e4b17023SJohn Marino /* Now we can only handle ranges with constant bounds. */
7406e4b17023SJohn Marino if (vr->type != VR_RANGE
7407e4b17023SJohn Marino || TREE_CODE (vr->min) != INTEGER_CST
7408e4b17023SJohn Marino || TREE_CODE (vr->max) != INTEGER_CST)
7409e4b17023SJohn Marino return false;
7410e4b17023SJohn Marino
7411e4b17023SJohn Marino /* For precision-preserving sign-changes the MSB of the double-int
7412e4b17023SJohn Marino has to be clear. */
7413e4b17023SJohn Marino if (src_precision == precision
7414e4b17023SJohn Marino && (TREE_INT_CST_HIGH (vr->min) | TREE_INT_CST_HIGH (vr->max)) < 0)
7415e4b17023SJohn Marino return false;
7416e4b17023SJohn Marino
7417e4b17023SJohn Marino /* Then we can perform the conversion on both ends and compare
7418e4b17023SJohn Marino the result for equality. */
7419e4b17023SJohn Marino tem = double_int_ext (tree_to_double_int (vr->min), precision, unsigned_p);
7420e4b17023SJohn Marino if (!double_int_equal_p (tree_to_double_int (vr->min), tem))
7421e4b17023SJohn Marino return false;
7422e4b17023SJohn Marino tem = double_int_ext (tree_to_double_int (vr->max), precision, unsigned_p);
7423e4b17023SJohn Marino if (!double_int_equal_p (tree_to_double_int (vr->max), tem))
7424e4b17023SJohn Marino return false;
7425e4b17023SJohn Marino
7426e4b17023SJohn Marino return true;
7427e4b17023SJohn Marino }
7428e4b17023SJohn Marino
7429e4b17023SJohn Marino /* Simplify a conversion from integral SSA name to float in STMT. */
7430e4b17023SJohn Marino
7431e4b17023SJohn Marino static bool
simplify_float_conversion_using_ranges(gimple_stmt_iterator * gsi,gimple stmt)7432e4b17023SJohn Marino simplify_float_conversion_using_ranges (gimple_stmt_iterator *gsi, gimple stmt)
7433e4b17023SJohn Marino {
7434e4b17023SJohn Marino tree rhs1 = gimple_assign_rhs1 (stmt);
7435e4b17023SJohn Marino value_range_t *vr = get_value_range (rhs1);
7436e4b17023SJohn Marino enum machine_mode fltmode = TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt)));
7437e4b17023SJohn Marino enum machine_mode mode;
7438e4b17023SJohn Marino tree tem;
7439e4b17023SJohn Marino gimple conv;
7440e4b17023SJohn Marino
7441e4b17023SJohn Marino /* We can only handle constant ranges. */
7442e4b17023SJohn Marino if (vr->type != VR_RANGE
7443e4b17023SJohn Marino || TREE_CODE (vr->min) != INTEGER_CST
7444e4b17023SJohn Marino || TREE_CODE (vr->max) != INTEGER_CST)
7445e4b17023SJohn Marino return false;
7446e4b17023SJohn Marino
7447e4b17023SJohn Marino /* First check if we can use a signed type in place of an unsigned. */
7448e4b17023SJohn Marino if (TYPE_UNSIGNED (TREE_TYPE (rhs1))
7449e4b17023SJohn Marino && (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)), 0)
7450e4b17023SJohn Marino != CODE_FOR_nothing)
7451e4b17023SJohn Marino && range_fits_type_p (vr, GET_MODE_PRECISION
7452e4b17023SJohn Marino (TYPE_MODE (TREE_TYPE (rhs1))), 0))
7453e4b17023SJohn Marino mode = TYPE_MODE (TREE_TYPE (rhs1));
7454e4b17023SJohn Marino /* If we can do the conversion in the current input mode do nothing. */
7455e4b17023SJohn Marino else if (can_float_p (fltmode, TYPE_MODE (TREE_TYPE (rhs1)),
7456e4b17023SJohn Marino TYPE_UNSIGNED (TREE_TYPE (rhs1))))
7457e4b17023SJohn Marino return false;
7458e4b17023SJohn Marino /* Otherwise search for a mode we can use, starting from the narrowest
7459e4b17023SJohn Marino integer mode available. */
7460e4b17023SJohn Marino else
7461e4b17023SJohn Marino {
7462e4b17023SJohn Marino mode = GET_CLASS_NARROWEST_MODE (MODE_INT);
7463e4b17023SJohn Marino do
7464e4b17023SJohn Marino {
7465e4b17023SJohn Marino /* If we cannot do a signed conversion to float from mode
7466e4b17023SJohn Marino or if the value-range does not fit in the signed type
7467e4b17023SJohn Marino try with a wider mode. */
7468e4b17023SJohn Marino if (can_float_p (fltmode, mode, 0) != CODE_FOR_nothing
7469e4b17023SJohn Marino && range_fits_type_p (vr, GET_MODE_PRECISION (mode), 0))
7470e4b17023SJohn Marino break;
7471e4b17023SJohn Marino
7472e4b17023SJohn Marino mode = GET_MODE_WIDER_MODE (mode);
7473e4b17023SJohn Marino /* But do not widen the input. Instead leave that to the
7474e4b17023SJohn Marino optabs expansion code. */
7475e4b17023SJohn Marino if (GET_MODE_PRECISION (mode) > TYPE_PRECISION (TREE_TYPE (rhs1)))
7476e4b17023SJohn Marino return false;
7477e4b17023SJohn Marino }
7478e4b17023SJohn Marino while (mode != VOIDmode);
7479e4b17023SJohn Marino if (mode == VOIDmode)
7480e4b17023SJohn Marino return false;
7481e4b17023SJohn Marino }
7482e4b17023SJohn Marino
7483e4b17023SJohn Marino /* It works, insert a truncation or sign-change before the
7484e4b17023SJohn Marino float conversion. */
7485e4b17023SJohn Marino tem = create_tmp_var (build_nonstandard_integer_type
7486e4b17023SJohn Marino (GET_MODE_PRECISION (mode), 0), NULL);
7487e4b17023SJohn Marino conv = gimple_build_assign_with_ops (NOP_EXPR, tem, rhs1, NULL_TREE);
7488e4b17023SJohn Marino tem = make_ssa_name (tem, conv);
7489e4b17023SJohn Marino gimple_assign_set_lhs (conv, tem);
7490e4b17023SJohn Marino gsi_insert_before (gsi, conv, GSI_SAME_STMT);
7491e4b17023SJohn Marino gimple_assign_set_rhs1 (stmt, tem);
7492e4b17023SJohn Marino update_stmt (stmt);
7493e4b17023SJohn Marino
7494e4b17023SJohn Marino return true;
7495e4b17023SJohn Marino }
7496e4b17023SJohn Marino
7497e4b17023SJohn Marino /* Simplify STMT using ranges if possible. */
7498e4b17023SJohn Marino
7499e4b17023SJohn Marino static bool
simplify_stmt_using_ranges(gimple_stmt_iterator * gsi)7500e4b17023SJohn Marino simplify_stmt_using_ranges (gimple_stmt_iterator *gsi)
7501e4b17023SJohn Marino {
7502e4b17023SJohn Marino gimple stmt = gsi_stmt (*gsi);
7503e4b17023SJohn Marino if (is_gimple_assign (stmt))
7504e4b17023SJohn Marino {
7505e4b17023SJohn Marino enum tree_code rhs_code = gimple_assign_rhs_code (stmt);
7506e4b17023SJohn Marino tree rhs1 = gimple_assign_rhs1 (stmt);
7507e4b17023SJohn Marino
7508e4b17023SJohn Marino switch (rhs_code)
7509e4b17023SJohn Marino {
7510e4b17023SJohn Marino case EQ_EXPR:
7511e4b17023SJohn Marino case NE_EXPR:
7512e4b17023SJohn Marino /* Transform EQ_EXPR, NE_EXPR into BIT_XOR_EXPR or identity
7513e4b17023SJohn Marino if the RHS is zero or one, and the LHS are known to be boolean
7514e4b17023SJohn Marino values. */
7515e4b17023SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7516e4b17023SJohn Marino return simplify_truth_ops_using_ranges (gsi, stmt);
7517e4b17023SJohn Marino break;
7518e4b17023SJohn Marino
7519e4b17023SJohn Marino /* Transform TRUNC_DIV_EXPR and TRUNC_MOD_EXPR into RSHIFT_EXPR
7520e4b17023SJohn Marino and BIT_AND_EXPR respectively if the first operand is greater
7521e4b17023SJohn Marino than zero and the second operand is an exact power of two. */
7522e4b17023SJohn Marino case TRUNC_DIV_EXPR:
7523e4b17023SJohn Marino case TRUNC_MOD_EXPR:
7524e4b17023SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1))
7525e4b17023SJohn Marino && integer_pow2p (gimple_assign_rhs2 (stmt)))
7526e4b17023SJohn Marino return simplify_div_or_mod_using_ranges (stmt);
7527e4b17023SJohn Marino break;
7528e4b17023SJohn Marino
7529e4b17023SJohn Marino /* Transform ABS (X) into X or -X as appropriate. */
7530e4b17023SJohn Marino case ABS_EXPR:
7531e4b17023SJohn Marino if (TREE_CODE (rhs1) == SSA_NAME
7532e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7533e4b17023SJohn Marino return simplify_abs_using_ranges (stmt);
7534e4b17023SJohn Marino break;
7535e4b17023SJohn Marino
7536e4b17023SJohn Marino case BIT_AND_EXPR:
7537e4b17023SJohn Marino case BIT_IOR_EXPR:
7538e4b17023SJohn Marino /* Optimize away BIT_AND_EXPR and BIT_IOR_EXPR
7539e4b17023SJohn Marino if all the bits being cleared are already cleared or
7540e4b17023SJohn Marino all the bits being set are already set. */
7541e4b17023SJohn Marino if (INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7542e4b17023SJohn Marino return simplify_bit_ops_using_ranges (gsi, stmt);
7543e4b17023SJohn Marino break;
7544e4b17023SJohn Marino
7545e4b17023SJohn Marino CASE_CONVERT:
7546e4b17023SJohn Marino if (TREE_CODE (rhs1) == SSA_NAME
7547e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7548e4b17023SJohn Marino return simplify_conversion_using_ranges (stmt);
7549e4b17023SJohn Marino break;
7550e4b17023SJohn Marino
7551e4b17023SJohn Marino case FLOAT_EXPR:
7552e4b17023SJohn Marino if (TREE_CODE (rhs1) == SSA_NAME
7553e4b17023SJohn Marino && INTEGRAL_TYPE_P (TREE_TYPE (rhs1)))
7554e4b17023SJohn Marino return simplify_float_conversion_using_ranges (gsi, stmt);
7555e4b17023SJohn Marino break;
7556e4b17023SJohn Marino
7557e4b17023SJohn Marino default:
7558e4b17023SJohn Marino break;
7559e4b17023SJohn Marino }
7560e4b17023SJohn Marino }
7561e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_COND)
7562e4b17023SJohn Marino return simplify_cond_using_ranges (stmt);
7563e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_SWITCH)
7564e4b17023SJohn Marino return simplify_switch_using_ranges (stmt);
7565e4b17023SJohn Marino
7566e4b17023SJohn Marino return false;
7567e4b17023SJohn Marino }
7568e4b17023SJohn Marino
7569e4b17023SJohn Marino /* If the statement pointed by SI has a predicate whose value can be
7570e4b17023SJohn Marino computed using the value range information computed by VRP, compute
7571e4b17023SJohn Marino its value and return true. Otherwise, return false. */
7572e4b17023SJohn Marino
7573e4b17023SJohn Marino static bool
fold_predicate_in(gimple_stmt_iterator * si)7574e4b17023SJohn Marino fold_predicate_in (gimple_stmt_iterator *si)
7575e4b17023SJohn Marino {
7576e4b17023SJohn Marino bool assignment_p = false;
7577e4b17023SJohn Marino tree val;
7578e4b17023SJohn Marino gimple stmt = gsi_stmt (*si);
7579e4b17023SJohn Marino
7580e4b17023SJohn Marino if (is_gimple_assign (stmt)
7581e4b17023SJohn Marino && TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) == tcc_comparison)
7582e4b17023SJohn Marino {
7583e4b17023SJohn Marino assignment_p = true;
7584e4b17023SJohn Marino val = vrp_evaluate_conditional (gimple_assign_rhs_code (stmt),
7585e4b17023SJohn Marino gimple_assign_rhs1 (stmt),
7586e4b17023SJohn Marino gimple_assign_rhs2 (stmt),
7587e4b17023SJohn Marino stmt);
7588e4b17023SJohn Marino }
7589e4b17023SJohn Marino else if (gimple_code (stmt) == GIMPLE_COND)
7590e4b17023SJohn Marino val = vrp_evaluate_conditional (gimple_cond_code (stmt),
7591e4b17023SJohn Marino gimple_cond_lhs (stmt),
7592e4b17023SJohn Marino gimple_cond_rhs (stmt),
7593e4b17023SJohn Marino stmt);
7594e4b17023SJohn Marino else
7595e4b17023SJohn Marino return false;
7596e4b17023SJohn Marino
7597e4b17023SJohn Marino if (val)
7598e4b17023SJohn Marino {
7599e4b17023SJohn Marino if (assignment_p)
7600e4b17023SJohn Marino val = fold_convert (gimple_expr_type (stmt), val);
7601e4b17023SJohn Marino
7602e4b17023SJohn Marino if (dump_file)
7603e4b17023SJohn Marino {
7604e4b17023SJohn Marino fprintf (dump_file, "Folding predicate ");
7605e4b17023SJohn Marino print_gimple_expr (dump_file, stmt, 0, 0);
7606e4b17023SJohn Marino fprintf (dump_file, " to ");
7607e4b17023SJohn Marino print_generic_expr (dump_file, val, 0);
7608e4b17023SJohn Marino fprintf (dump_file, "\n");
7609e4b17023SJohn Marino }
7610e4b17023SJohn Marino
7611e4b17023SJohn Marino if (is_gimple_assign (stmt))
7612e4b17023SJohn Marino gimple_assign_set_rhs_from_tree (si, val);
7613e4b17023SJohn Marino else
7614e4b17023SJohn Marino {
7615e4b17023SJohn Marino gcc_assert (gimple_code (stmt) == GIMPLE_COND);
7616e4b17023SJohn Marino if (integer_zerop (val))
7617e4b17023SJohn Marino gimple_cond_make_false (stmt);
7618e4b17023SJohn Marino else if (integer_onep (val))
7619e4b17023SJohn Marino gimple_cond_make_true (stmt);
7620e4b17023SJohn Marino else
7621e4b17023SJohn Marino gcc_unreachable ();
7622e4b17023SJohn Marino }
7623e4b17023SJohn Marino
7624e4b17023SJohn Marino return true;
7625e4b17023SJohn Marino }
7626e4b17023SJohn Marino
7627e4b17023SJohn Marino return false;
7628e4b17023SJohn Marino }
7629e4b17023SJohn Marino
7630e4b17023SJohn Marino /* Callback for substitute_and_fold folding the stmt at *SI. */
7631e4b17023SJohn Marino
7632e4b17023SJohn Marino static bool
vrp_fold_stmt(gimple_stmt_iterator * si)7633e4b17023SJohn Marino vrp_fold_stmt (gimple_stmt_iterator *si)
7634e4b17023SJohn Marino {
7635e4b17023SJohn Marino if (fold_predicate_in (si))
7636e4b17023SJohn Marino return true;
7637e4b17023SJohn Marino
7638e4b17023SJohn Marino return simplify_stmt_using_ranges (si);
7639e4b17023SJohn Marino }
7640e4b17023SJohn Marino
7641e4b17023SJohn Marino /* Stack of dest,src equivalency pairs that need to be restored after
7642e4b17023SJohn Marino each attempt to thread a block's incoming edge to an outgoing edge.
7643e4b17023SJohn Marino
7644e4b17023SJohn Marino A NULL entry is used to mark the end of pairs which need to be
7645e4b17023SJohn Marino restored. */
VEC(tree,heap)7646e4b17023SJohn Marino static VEC(tree,heap) *stack;
7647e4b17023SJohn Marino
7648e4b17023SJohn Marino /* A trivial wrapper so that we can present the generic jump threading
7649e4b17023SJohn Marino code with a simple API for simplifying statements. STMT is the
7650e4b17023SJohn Marino statement we want to simplify, WITHIN_STMT provides the location
7651e4b17023SJohn Marino for any overflow warnings. */
7652e4b17023SJohn Marino
7653e4b17023SJohn Marino static tree
7654e4b17023SJohn Marino simplify_stmt_for_jump_threading (gimple stmt, gimple within_stmt)
7655e4b17023SJohn Marino {
7656e4b17023SJohn Marino /* We only use VRP information to simplify conditionals. This is
7657e4b17023SJohn Marino overly conservative, but it's unclear if doing more would be
7658e4b17023SJohn Marino worth the compile time cost. */
7659e4b17023SJohn Marino if (gimple_code (stmt) != GIMPLE_COND)
7660e4b17023SJohn Marino return NULL;
7661e4b17023SJohn Marino
7662e4b17023SJohn Marino return vrp_evaluate_conditional (gimple_cond_code (stmt),
7663e4b17023SJohn Marino gimple_cond_lhs (stmt),
7664e4b17023SJohn Marino gimple_cond_rhs (stmt), within_stmt);
7665e4b17023SJohn Marino }
7666e4b17023SJohn Marino
7667e4b17023SJohn Marino /* Blocks which have more than one predecessor and more than
7668e4b17023SJohn Marino one successor present jump threading opportunities, i.e.,
7669e4b17023SJohn Marino when the block is reached from a specific predecessor, we
7670e4b17023SJohn Marino may be able to determine which of the outgoing edges will
7671e4b17023SJohn Marino be traversed. When this optimization applies, we are able
7672e4b17023SJohn Marino to avoid conditionals at runtime and we may expose secondary
7673e4b17023SJohn Marino optimization opportunities.
7674e4b17023SJohn Marino
7675e4b17023SJohn Marino This routine is effectively a driver for the generic jump
7676e4b17023SJohn Marino threading code. It basically just presents the generic code
7677e4b17023SJohn Marino with edges that may be suitable for jump threading.
7678e4b17023SJohn Marino
7679e4b17023SJohn Marino Unlike DOM, we do not iterate VRP if jump threading was successful.
7680e4b17023SJohn Marino While iterating may expose new opportunities for VRP, it is expected
7681e4b17023SJohn Marino those opportunities would be very limited and the compile time cost
7682e4b17023SJohn Marino to expose those opportunities would be significant.
7683e4b17023SJohn Marino
7684e4b17023SJohn Marino As jump threading opportunities are discovered, they are registered
7685e4b17023SJohn Marino for later realization. */
7686e4b17023SJohn Marino
7687e4b17023SJohn Marino static void
identify_jump_threads(void)7688e4b17023SJohn Marino identify_jump_threads (void)
7689e4b17023SJohn Marino {
7690e4b17023SJohn Marino basic_block bb;
7691e4b17023SJohn Marino gimple dummy;
7692e4b17023SJohn Marino int i;
7693e4b17023SJohn Marino edge e;
7694e4b17023SJohn Marino
7695e4b17023SJohn Marino /* Ugh. When substituting values earlier in this pass we can
7696e4b17023SJohn Marino wipe the dominance information. So rebuild the dominator
7697e4b17023SJohn Marino information as we need it within the jump threading code. */
7698e4b17023SJohn Marino calculate_dominance_info (CDI_DOMINATORS);
7699e4b17023SJohn Marino
7700e4b17023SJohn Marino /* We do not allow VRP information to be used for jump threading
7701e4b17023SJohn Marino across a back edge in the CFG. Otherwise it becomes too
7702e4b17023SJohn Marino difficult to avoid eliminating loop exit tests. Of course
7703e4b17023SJohn Marino EDGE_DFS_BACK is not accurate at this time so we have to
7704e4b17023SJohn Marino recompute it. */
7705e4b17023SJohn Marino mark_dfs_back_edges ();
7706e4b17023SJohn Marino
7707e4b17023SJohn Marino /* Do not thread across edges we are about to remove. Just marking
7708e4b17023SJohn Marino them as EDGE_DFS_BACK will do. */
7709e4b17023SJohn Marino FOR_EACH_VEC_ELT (edge, to_remove_edges, i, e)
7710e4b17023SJohn Marino e->flags |= EDGE_DFS_BACK;
7711e4b17023SJohn Marino
7712e4b17023SJohn Marino /* Allocate our unwinder stack to unwind any temporary equivalences
7713e4b17023SJohn Marino that might be recorded. */
7714e4b17023SJohn Marino stack = VEC_alloc (tree, heap, 20);
7715e4b17023SJohn Marino
7716e4b17023SJohn Marino /* To avoid lots of silly node creation, we create a single
7717e4b17023SJohn Marino conditional and just modify it in-place when attempting to
7718e4b17023SJohn Marino thread jumps. */
7719e4b17023SJohn Marino dummy = gimple_build_cond (EQ_EXPR,
7720e4b17023SJohn Marino integer_zero_node, integer_zero_node,
7721e4b17023SJohn Marino NULL, NULL);
7722e4b17023SJohn Marino
7723e4b17023SJohn Marino /* Walk through all the blocks finding those which present a
7724e4b17023SJohn Marino potential jump threading opportunity. We could set this up
7725e4b17023SJohn Marino as a dominator walker and record data during the walk, but
7726e4b17023SJohn Marino I doubt it's worth the effort for the classes of jump
7727e4b17023SJohn Marino threading opportunities we are trying to identify at this
7728e4b17023SJohn Marino point in compilation. */
7729e4b17023SJohn Marino FOR_EACH_BB (bb)
7730e4b17023SJohn Marino {
7731e4b17023SJohn Marino gimple last;
7732e4b17023SJohn Marino
7733e4b17023SJohn Marino /* If the generic jump threading code does not find this block
7734e4b17023SJohn Marino interesting, then there is nothing to do. */
7735e4b17023SJohn Marino if (! potentially_threadable_block (bb))
7736e4b17023SJohn Marino continue;
7737e4b17023SJohn Marino
7738e4b17023SJohn Marino /* We only care about blocks ending in a COND_EXPR. While there
7739e4b17023SJohn Marino may be some value in handling SWITCH_EXPR here, I doubt it's
7740e4b17023SJohn Marino terribly important. */
7741e4b17023SJohn Marino last = gsi_stmt (gsi_last_bb (bb));
7742e4b17023SJohn Marino
7743e4b17023SJohn Marino /* We're basically looking for a switch or any kind of conditional with
7744e4b17023SJohn Marino integral or pointer type arguments. Note the type of the second
7745e4b17023SJohn Marino argument will be the same as the first argument, so no need to
7746e4b17023SJohn Marino check it explicitly. */
7747e4b17023SJohn Marino if (gimple_code (last) == GIMPLE_SWITCH
7748e4b17023SJohn Marino || (gimple_code (last) == GIMPLE_COND
7749e4b17023SJohn Marino && TREE_CODE (gimple_cond_lhs (last)) == SSA_NAME
7750e4b17023SJohn Marino && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (last)))
7751e4b17023SJohn Marino || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (last))))
7752e4b17023SJohn Marino && (TREE_CODE (gimple_cond_rhs (last)) == SSA_NAME
7753e4b17023SJohn Marino || is_gimple_min_invariant (gimple_cond_rhs (last)))))
7754e4b17023SJohn Marino {
7755e4b17023SJohn Marino edge_iterator ei;
7756e4b17023SJohn Marino
7757e4b17023SJohn Marino /* We've got a block with multiple predecessors and multiple
7758e4b17023SJohn Marino successors which also ends in a suitable conditional or
7759e4b17023SJohn Marino switch statement. For each predecessor, see if we can thread
7760e4b17023SJohn Marino it to a specific successor. */
7761e4b17023SJohn Marino FOR_EACH_EDGE (e, ei, bb->preds)
7762e4b17023SJohn Marino {
7763e4b17023SJohn Marino /* Do not thread across back edges or abnormal edges
7764e4b17023SJohn Marino in the CFG. */
7765e4b17023SJohn Marino if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
7766e4b17023SJohn Marino continue;
7767e4b17023SJohn Marino
7768e4b17023SJohn Marino thread_across_edge (dummy, e, true, &stack,
7769e4b17023SJohn Marino simplify_stmt_for_jump_threading);
7770e4b17023SJohn Marino }
7771e4b17023SJohn Marino }
7772e4b17023SJohn Marino }
7773e4b17023SJohn Marino
7774e4b17023SJohn Marino /* We do not actually update the CFG or SSA graphs at this point as
7775e4b17023SJohn Marino ASSERT_EXPRs are still in the IL and cfg cleanup code does not yet
7776e4b17023SJohn Marino handle ASSERT_EXPRs gracefully. */
7777e4b17023SJohn Marino }
7778e4b17023SJohn Marino
7779e4b17023SJohn Marino /* We identified all the jump threading opportunities earlier, but could
7780e4b17023SJohn Marino not transform the CFG at that time. This routine transforms the
7781e4b17023SJohn Marino CFG and arranges for the dominator tree to be rebuilt if necessary.
7782e4b17023SJohn Marino
7783e4b17023SJohn Marino Note the SSA graph update will occur during the normal TODO
7784e4b17023SJohn Marino processing by the pass manager. */
7785e4b17023SJohn Marino static void
finalize_jump_threads(void)7786e4b17023SJohn Marino finalize_jump_threads (void)
7787e4b17023SJohn Marino {
7788e4b17023SJohn Marino thread_through_all_blocks (false);
7789e4b17023SJohn Marino VEC_free (tree, heap, stack);
7790e4b17023SJohn Marino }
7791e4b17023SJohn Marino
7792e4b17023SJohn Marino
7793e4b17023SJohn Marino /* Traverse all the blocks folding conditionals with known ranges. */
7794e4b17023SJohn Marino
7795e4b17023SJohn Marino static void
vrp_finalize(void)7796e4b17023SJohn Marino vrp_finalize (void)
7797e4b17023SJohn Marino {
7798e4b17023SJohn Marino size_t i;
7799e4b17023SJohn Marino
7800e4b17023SJohn Marino values_propagated = true;
7801e4b17023SJohn Marino
7802e4b17023SJohn Marino if (dump_file)
7803e4b17023SJohn Marino {
7804e4b17023SJohn Marino fprintf (dump_file, "\nValue ranges after VRP:\n\n");
7805e4b17023SJohn Marino dump_all_value_ranges (dump_file);
7806e4b17023SJohn Marino fprintf (dump_file, "\n");
7807e4b17023SJohn Marino }
7808e4b17023SJohn Marino
7809e4b17023SJohn Marino substitute_and_fold (op_with_constant_singleton_value_range,
7810e4b17023SJohn Marino vrp_fold_stmt, false);
7811e4b17023SJohn Marino
7812e4b17023SJohn Marino if (warn_array_bounds)
7813e4b17023SJohn Marino check_all_array_refs ();
7814e4b17023SJohn Marino
7815e4b17023SJohn Marino /* We must identify jump threading opportunities before we release
7816e4b17023SJohn Marino the datastructures built by VRP. */
7817e4b17023SJohn Marino identify_jump_threads ();
7818e4b17023SJohn Marino
7819e4b17023SJohn Marino /* Free allocated memory. */
7820e4b17023SJohn Marino for (i = 0; i < num_vr_values; i++)
7821e4b17023SJohn Marino if (vr_value[i])
7822e4b17023SJohn Marino {
7823e4b17023SJohn Marino BITMAP_FREE (vr_value[i]->equiv);
7824e4b17023SJohn Marino free (vr_value[i]);
7825e4b17023SJohn Marino }
7826e4b17023SJohn Marino
7827e4b17023SJohn Marino free (vr_value);
7828e4b17023SJohn Marino free (vr_phi_edge_counts);
7829e4b17023SJohn Marino
7830e4b17023SJohn Marino /* So that we can distinguish between VRP data being available
7831e4b17023SJohn Marino and not available. */
7832e4b17023SJohn Marino vr_value = NULL;
7833e4b17023SJohn Marino vr_phi_edge_counts = NULL;
7834e4b17023SJohn Marino }
7835e4b17023SJohn Marino
7836e4b17023SJohn Marino
7837e4b17023SJohn Marino /* Main entry point to VRP (Value Range Propagation). This pass is
7838e4b17023SJohn Marino loosely based on J. R. C. Patterson, ``Accurate Static Branch
7839e4b17023SJohn Marino Prediction by Value Range Propagation,'' in SIGPLAN Conference on
7840e4b17023SJohn Marino Programming Language Design and Implementation, pp. 67-78, 1995.
7841e4b17023SJohn Marino Also available at http://citeseer.ist.psu.edu/patterson95accurate.html
7842e4b17023SJohn Marino
7843e4b17023SJohn Marino This is essentially an SSA-CCP pass modified to deal with ranges
7844e4b17023SJohn Marino instead of constants.
7845e4b17023SJohn Marino
7846e4b17023SJohn Marino While propagating ranges, we may find that two or more SSA name
7847e4b17023SJohn Marino have equivalent, though distinct ranges. For instance,
7848e4b17023SJohn Marino
7849e4b17023SJohn Marino 1 x_9 = p_3->a;
7850e4b17023SJohn Marino 2 p_4 = ASSERT_EXPR <p_3, p_3 != 0>
7851e4b17023SJohn Marino 3 if (p_4 == q_2)
7852e4b17023SJohn Marino 4 p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
7853e4b17023SJohn Marino 5 endif
7854e4b17023SJohn Marino 6 if (q_2)
7855e4b17023SJohn Marino
7856e4b17023SJohn Marino In the code above, pointer p_5 has range [q_2, q_2], but from the
7857e4b17023SJohn Marino code we can also determine that p_5 cannot be NULL and, if q_2 had
7858e4b17023SJohn Marino a non-varying range, p_5's range should also be compatible with it.
7859e4b17023SJohn Marino
7860e4b17023SJohn Marino These equivalences are created by two expressions: ASSERT_EXPR and
7861e4b17023SJohn Marino copy operations. Since p_5 is an assertion on p_4, and p_4 was the
7862e4b17023SJohn Marino result of another assertion, then we can use the fact that p_5 and
7863e4b17023SJohn Marino p_4 are equivalent when evaluating p_5's range.
7864e4b17023SJohn Marino
7865e4b17023SJohn Marino Together with value ranges, we also propagate these equivalences
7866e4b17023SJohn Marino between names so that we can take advantage of information from
7867e4b17023SJohn Marino multiple ranges when doing final replacement. Note that this
7868e4b17023SJohn Marino equivalency relation is transitive but not symmetric.
7869e4b17023SJohn Marino
7870e4b17023SJohn Marino In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
7871e4b17023SJohn Marino cannot assert that q_2 is equivalent to p_5 because q_2 may be used
7872e4b17023SJohn Marino in contexts where that assertion does not hold (e.g., in line 6).
7873e4b17023SJohn Marino
7874e4b17023SJohn Marino TODO, the main difference between this pass and Patterson's is that
7875e4b17023SJohn Marino we do not propagate edge probabilities. We only compute whether
7876e4b17023SJohn Marino edges can be taken or not. That is, instead of having a spectrum
7877e4b17023SJohn Marino of jump probabilities between 0 and 1, we only deal with 0, 1 and
7878e4b17023SJohn Marino DON'T KNOW. In the future, it may be worthwhile to propagate
7879e4b17023SJohn Marino probabilities to aid branch prediction. */
7880e4b17023SJohn Marino
7881e4b17023SJohn Marino static unsigned int
execute_vrp(void)7882e4b17023SJohn Marino execute_vrp (void)
7883e4b17023SJohn Marino {
7884e4b17023SJohn Marino int i;
7885e4b17023SJohn Marino edge e;
7886e4b17023SJohn Marino switch_update *su;
7887e4b17023SJohn Marino
7888e4b17023SJohn Marino loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
7889e4b17023SJohn Marino rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa);
7890e4b17023SJohn Marino scev_initialize ();
7891e4b17023SJohn Marino
78925ce9237cSJohn Marino /* ??? This ends up using stale EDGE_DFS_BACK for liveness computation.
78935ce9237cSJohn Marino Inserting assertions may split edges which will invalidate
78945ce9237cSJohn Marino EDGE_DFS_BACK. */
7895e4b17023SJohn Marino insert_range_assertions ();
7896e4b17023SJohn Marino
7897e4b17023SJohn Marino /* Estimate number of iterations - but do not use undefined behavior
7898e4b17023SJohn Marino for this. We can't do this lazily as other functions may compute
7899e4b17023SJohn Marino this using undefined behavior. */
7900e4b17023SJohn Marino free_numbers_of_iterations_estimates ();
7901e4b17023SJohn Marino estimate_numbers_of_iterations (false);
7902e4b17023SJohn Marino
7903e4b17023SJohn Marino to_remove_edges = VEC_alloc (edge, heap, 10);
7904e4b17023SJohn Marino to_update_switch_stmts = VEC_alloc (switch_update, heap, 5);
7905e4b17023SJohn Marino threadedge_initialize_values ();
7906e4b17023SJohn Marino
79075ce9237cSJohn Marino /* For visiting PHI nodes we need EDGE_DFS_BACK computed. */
79085ce9237cSJohn Marino mark_dfs_back_edges ();
79095ce9237cSJohn Marino
7910e4b17023SJohn Marino vrp_initialize ();
7911e4b17023SJohn Marino ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
7912e4b17023SJohn Marino vrp_finalize ();
7913e4b17023SJohn Marino
7914e4b17023SJohn Marino free_numbers_of_iterations_estimates ();
7915e4b17023SJohn Marino
7916e4b17023SJohn Marino /* ASSERT_EXPRs must be removed before finalizing jump threads
7917e4b17023SJohn Marino as finalizing jump threads calls the CFG cleanup code which
7918e4b17023SJohn Marino does not properly handle ASSERT_EXPRs. */
7919e4b17023SJohn Marino remove_range_assertions ();
7920e4b17023SJohn Marino
7921e4b17023SJohn Marino /* If we exposed any new variables, go ahead and put them into
7922e4b17023SJohn Marino SSA form now, before we handle jump threading. This simplifies
7923e4b17023SJohn Marino interactions between rewriting of _DECL nodes into SSA form
7924e4b17023SJohn Marino and rewriting SSA_NAME nodes into SSA form after block
7925e4b17023SJohn Marino duplication and CFG manipulation. */
7926e4b17023SJohn Marino update_ssa (TODO_update_ssa);
7927e4b17023SJohn Marino
7928e4b17023SJohn Marino finalize_jump_threads ();
7929e4b17023SJohn Marino
7930e4b17023SJohn Marino /* Remove dead edges from SWITCH_EXPR optimization. This leaves the
7931e4b17023SJohn Marino CFG in a broken state and requires a cfg_cleanup run. */
7932e4b17023SJohn Marino FOR_EACH_VEC_ELT (edge, to_remove_edges, i, e)
7933e4b17023SJohn Marino remove_edge (e);
7934e4b17023SJohn Marino /* Update SWITCH_EXPR case label vector. */
7935e4b17023SJohn Marino FOR_EACH_VEC_ELT (switch_update, to_update_switch_stmts, i, su)
7936e4b17023SJohn Marino {
7937e4b17023SJohn Marino size_t j;
7938e4b17023SJohn Marino size_t n = TREE_VEC_LENGTH (su->vec);
7939e4b17023SJohn Marino tree label;
7940e4b17023SJohn Marino gimple_switch_set_num_labels (su->stmt, n);
7941e4b17023SJohn Marino for (j = 0; j < n; j++)
7942e4b17023SJohn Marino gimple_switch_set_label (su->stmt, j, TREE_VEC_ELT (su->vec, j));
7943e4b17023SJohn Marino /* As we may have replaced the default label with a regular one
7944e4b17023SJohn Marino make sure to make it a real default label again. This ensures
7945e4b17023SJohn Marino optimal expansion. */
7946e4b17023SJohn Marino label = gimple_switch_default_label (su->stmt);
7947e4b17023SJohn Marino CASE_LOW (label) = NULL_TREE;
7948e4b17023SJohn Marino CASE_HIGH (label) = NULL_TREE;
7949e4b17023SJohn Marino }
7950e4b17023SJohn Marino
7951e4b17023SJohn Marino if (VEC_length (edge, to_remove_edges) > 0)
7952e4b17023SJohn Marino free_dominance_info (CDI_DOMINATORS);
7953e4b17023SJohn Marino
7954e4b17023SJohn Marino VEC_free (edge, heap, to_remove_edges);
7955e4b17023SJohn Marino VEC_free (switch_update, heap, to_update_switch_stmts);
7956e4b17023SJohn Marino threadedge_finalize_values ();
7957e4b17023SJohn Marino
7958e4b17023SJohn Marino scev_finalize ();
7959e4b17023SJohn Marino loop_optimizer_finalize ();
7960e4b17023SJohn Marino return 0;
7961e4b17023SJohn Marino }
7962e4b17023SJohn Marino
7963e4b17023SJohn Marino static bool
gate_vrp(void)7964e4b17023SJohn Marino gate_vrp (void)
7965e4b17023SJohn Marino {
7966e4b17023SJohn Marino return flag_tree_vrp != 0;
7967e4b17023SJohn Marino }
7968e4b17023SJohn Marino
7969e4b17023SJohn Marino struct gimple_opt_pass pass_vrp =
7970e4b17023SJohn Marino {
7971e4b17023SJohn Marino {
7972e4b17023SJohn Marino GIMPLE_PASS,
7973e4b17023SJohn Marino "vrp", /* name */
7974e4b17023SJohn Marino gate_vrp, /* gate */
7975e4b17023SJohn Marino execute_vrp, /* execute */
7976e4b17023SJohn Marino NULL, /* sub */
7977e4b17023SJohn Marino NULL, /* next */
7978e4b17023SJohn Marino 0, /* static_pass_number */
7979e4b17023SJohn Marino TV_TREE_VRP, /* tv_id */
7980e4b17023SJohn Marino PROP_ssa, /* properties_required */
7981e4b17023SJohn Marino 0, /* properties_provided */
7982e4b17023SJohn Marino 0, /* properties_destroyed */
7983e4b17023SJohn Marino 0, /* todo_flags_start */
7984e4b17023SJohn Marino TODO_cleanup_cfg
7985e4b17023SJohn Marino | TODO_update_ssa
7986e4b17023SJohn Marino | TODO_verify_ssa
7987e4b17023SJohn Marino | TODO_verify_flow
7988e4b17023SJohn Marino | TODO_ggc_collect /* todo_flags_finish */
7989e4b17023SJohn Marino }
7990e4b17023SJohn Marino };
7991