1 /* Support routines for value queries.
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 Contributed by Aldy Hernandez <aldyh@redhat.com> and
4 Andrew MacLeod <amacleod@redhat.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
29 #include "tree-pretty-print.h"
30 #include "fold-const.h"
31 #include "value-query.h"
32 #include "alloc-pool.h"
33 #include "gimple-range.h"
34 #include "value-range-storage.h"
36 // value_query default methods.
39 value_query::value_on_edge (edge
, tree expr
)
41 return value_of_expr (expr
);
45 value_query::value_of_stmt (gimple
*stmt
, tree name
)
48 name
= gimple_get_lhs (stmt
);
50 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
53 return value_of_expr (name
);
57 // range_query default methods.
60 range_query::range_on_edge (vrange
&r
, edge
, tree expr
)
62 return range_of_expr (r
, expr
);
66 range_query::range_of_stmt (vrange
&r
, gimple
*stmt
, tree name
)
69 name
= gimple_get_lhs (stmt
);
71 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
74 return range_of_expr (r
, name
);
79 range_query::value_of_expr (tree expr
, gimple
*stmt
)
83 if (!Value_Range::supports_type_p (TREE_TYPE (expr
)))
86 Value_Range
r (TREE_TYPE (expr
));
88 if (range_of_expr (r
, expr
, stmt
))
90 // A constant used in an unreachable block often returns as UNDEFINED.
91 // If the result is undefined, check the global value for a constant.
93 range_of_expr (r
, expr
);
94 if (r
.singleton_p (&t
))
101 range_query::value_on_edge (edge e
, tree expr
)
105 if (!Value_Range::supports_type_p (TREE_TYPE (expr
)))
107 Value_Range
r (TREE_TYPE (expr
));
108 if (range_on_edge (r
, e
, expr
))
110 // A constant used in an unreachable block often returns as UNDEFINED.
111 // If the result is undefined, check the global value for a constant.
112 if (r
.undefined_p ())
113 range_of_expr (r
, expr
);
114 if (r
.singleton_p (&t
))
122 range_query::value_of_stmt (gimple
*stmt
, tree name
)
127 name
= gimple_get_lhs (stmt
);
129 gcc_checking_assert (!name
|| name
== gimple_get_lhs (stmt
));
131 if (!name
|| !Value_Range::supports_type_p (TREE_TYPE (name
)))
133 Value_Range
r (TREE_TYPE (name
));
134 if (range_of_stmt (r
, stmt
, name
) && r
.singleton_p (&t
))
141 range_query::dump (FILE *)
145 range_query::range_query ()
150 range_query::~range_query ()
154 // Return a range in R for the tree EXPR. Return true if a range is
155 // representable, and UNDEFINED/false if not.
158 range_query::get_tree_range (vrange
&r
, tree expr
, gimple
*stmt
)
164 type
= TREE_TYPE (expr
);
166 if (!Value_Range::supports_type_p (type
))
173 r
.set_varying (type
);
176 switch (TREE_CODE (expr
))
180 irange
&i
= as_a
<irange
> (r
);
181 if (TREE_OVERFLOW_P (expr
))
182 expr
= drop_tree_overflow (expr
);
183 wide_int w
= wi::to_wide (expr
);
184 i
.set (TREE_TYPE (expr
), w
, w
);
190 frange
&f
= as_a
<frange
> (r
);
191 REAL_VALUE_TYPE
*rv
= TREE_REAL_CST_PTR (expr
);
194 bool sign
= real_isneg (rv
);
195 f
.set_nan (TREE_TYPE (expr
), sign
);
199 nan_state
nan (false);
200 f
.set (TREE_TYPE (expr
), *rv
, *rv
, nan
);
206 gimple_range_global (r
, expr
);
211 // Handle &var which can show up in phi arguments.
213 if (tree_single_nonzero_warnv_p (expr
, &ov
))
215 r
.set_nonzero (type
);
224 if (BINARY_CLASS_P (expr
) || COMPARISON_CLASS_P (expr
))
226 tree op0
= TREE_OPERAND (expr
, 0);
227 tree op1
= TREE_OPERAND (expr
, 1);
228 if (COMPARISON_CLASS_P (expr
)
229 && !Value_Range::supports_type_p (TREE_TYPE (op0
)))
231 range_op_handler
op (TREE_CODE (expr
));
234 Value_Range
r0 (TREE_TYPE (op0
));
235 Value_Range
r1 (TREE_TYPE (op1
));
236 range_of_expr (r0
, op0
, stmt
);
237 range_of_expr (r1
, op1
, stmt
);
238 if (!op
.fold_range (r
, type
, r0
, r1
))
239 r
.set_varying (type
);
242 r
.set_varying (type
);
245 if (UNARY_CLASS_P (expr
))
247 range_op_handler
op (TREE_CODE (expr
));
248 tree op0_type
= TREE_TYPE (TREE_OPERAND (expr
, 0));
249 if (op
&& Value_Range::supports_type_p (op0_type
))
251 Value_Range
r0 (TREE_TYPE (TREE_OPERAND (expr
, 0)));
252 Value_Range
r1 (type
);
253 r1
.set_varying (type
);
254 range_of_expr (r0
, TREE_OPERAND (expr
, 0), stmt
);
255 if (!op
.fold_range (r
, type
, r0
, r1
))
256 r
.set_varying (type
);
259 r
.set_varying (type
);
262 r
.set_varying (type
);
266 // Return the range for NAME from SSA_NAME_RANGE_INFO.
269 get_ssa_name_range_info (vrange
&r
, const_tree name
)
271 tree type
= TREE_TYPE (name
);
272 gcc_checking_assert (!POINTER_TYPE_P (type
));
273 gcc_checking_assert (TREE_CODE (name
) == SSA_NAME
);
275 vrange_storage
*ri
= SSA_NAME_RANGE_INFO (name
);
278 ri
->get_vrange (r
, TREE_TYPE (name
));
280 r
.set_varying (type
);
283 // Return nonnull attribute of pointer NAME from SSA_NAME_PTR_INFO.
286 get_ssa_name_ptr_info_nonnull (const_tree name
)
288 gcc_assert (POINTER_TYPE_P (TREE_TYPE (name
)));
289 struct ptr_info_def
*pi
= SSA_NAME_PTR_INFO (name
);
292 /* TODO Now pt->null is conservatively set to true in PTA
293 analysis. vrp is the only pass (including ipa-vrp)
294 that clears pt.null via set_ptr_nonnull when it knows
295 for sure. PTA will preserves the pt.null value set by VRP.
297 When PTA analysis is improved, pt.anything, pt.nonlocal
298 and pt.escaped may also has to be considered before
299 deciding that pointer cannot point to NULL. */
303 // Update the global range for NAME into the SSA_RANGE_NAME_INFO and
304 // Return the legacy global range for NAME if it has one, otherwise
308 get_range_global (vrange
&r
, tree name
, struct function
*fun
= cfun
)
310 tree type
= TREE_TYPE (name
);
312 if (SSA_NAME_IS_DEFAULT_DEF (name
))
314 tree sym
= SSA_NAME_VAR (name
);
315 // Adapted from vr_values::get_lattice_entry().
316 // Use a range from an SSA_NAME's available range.
317 if (TREE_CODE (sym
) == PARM_DECL
)
319 // Try to use the "nonnull" attribute to create ~[0, 0]
320 // anti-ranges for pointers. Note that this is only valid with
321 // default definitions of PARM_DECLs.
322 if (POINTER_TYPE_P (type
)
323 && ((cfun
&& fun
== cfun
&& nonnull_arg_p (sym
))
324 || get_ssa_name_ptr_info_nonnull (name
)))
325 r
.set_nonzero (type
);
326 else if (!POINTER_TYPE_P (type
))
328 get_ssa_name_range_info (r
, name
);
329 if (r
.undefined_p ())
330 r
.set_varying (type
);
333 r
.set_varying (type
);
335 // If this is a local automatic with no definition, use undefined.
336 else if (TREE_CODE (sym
) != RESULT_DECL
)
339 r
.set_varying (type
);
341 else if (!POINTER_TYPE_P (type
) && SSA_NAME_RANGE_INFO (name
))
343 get_ssa_name_range_info (r
, name
);
344 if (r
.undefined_p ())
345 r
.set_varying (type
);
347 else if (POINTER_TYPE_P (type
) && SSA_NAME_PTR_INFO (name
))
349 if (get_ssa_name_ptr_info_nonnull (name
))
350 r
.set_nonzero (type
);
352 r
.set_varying (type
);
355 r
.set_varying (type
);
358 // This is where the ranger picks up global info to seed initial
359 // requests. It is a slightly restricted version of
360 // get_range_global() above.
362 // The reason for the difference is that we can always pick the
363 // default definition of an SSA with no adverse effects, but for other
364 // SSAs, if we pick things up to early, we may prematurely eliminate
365 // builtin_unreachables.
367 // Without this restriction, the test in g++.dg/tree-ssa/pr61034.C has
368 // all of its unreachable calls removed too early.
370 // See discussion here:
371 // https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571709.html
374 gimple_range_global (vrange
&r
, tree name
, struct function
*fun
)
376 tree type
= TREE_TYPE (name
);
377 gcc_checking_assert (TREE_CODE (name
) == SSA_NAME
);
379 if (SSA_NAME_IS_DEFAULT_DEF (name
) || (fun
&& fun
->after_inlining
)
380 || is_a
<gphi
*> (SSA_NAME_DEF_STMT (name
)))
382 get_range_global (r
, name
, fun
);
385 r
.set_varying (type
);
388 // ----------------------------------------------
389 // global_range_query implementation.
391 global_range_query global_ranges
;
394 global_range_query::range_of_expr (vrange
&r
, tree expr
, gimple
*stmt
)
396 if (!gimple_range_ssa_p (expr
))
397 return get_tree_range (r
, expr
, stmt
);
399 get_range_global (r
, expr
);
404 // Return any known relation between SSA1 and SSA2 before stmt S is executed.
405 // If GET_RANGE is true, query the range of both operands first to ensure
406 // the definitions have been processed and any relations have be created.
409 range_query::query_relation (gimple
*s
, tree ssa1
, tree ssa2
, bool get_range
)
411 if (!m_oracle
|| TREE_CODE (ssa1
) != SSA_NAME
|| TREE_CODE (ssa2
) != SSA_NAME
)
414 // Ensure ssa1 and ssa2 have both been evaluated.
417 Value_Range
tmp1 (TREE_TYPE (ssa1
));
418 Value_Range
tmp2 (TREE_TYPE (ssa2
));
419 range_of_expr (tmp1
, ssa1
, s
);
420 range_of_expr (tmp2
, ssa2
, s
);
422 return m_oracle
->query_relation (gimple_bb (s
), ssa1
, ssa2
);
425 // Return any known relation between SSA1 and SSA2 on edge E.
426 // If GET_RANGE is true, query the range of both operands first to ensure
427 // the definitions have been processed and any relations have be created.
430 range_query::query_relation (edge e
, tree ssa1
, tree ssa2
, bool get_range
)
433 if (!m_oracle
|| TREE_CODE (ssa1
) != SSA_NAME
|| TREE_CODE (ssa2
) != SSA_NAME
)
436 // Use destination block if it has a single predecessor, and this picks
437 // up any relation on the edge.
438 // Otherwise choose the src edge and the result is the same as on-exit.
439 if (!single_pred_p (e
->dest
))
444 // Ensure ssa1 and ssa2 have both been evaluated.
447 Value_Range
tmp (TREE_TYPE (ssa1
));
448 range_on_edge (tmp
, e
, ssa1
);
449 range_on_edge (tmp
, e
, ssa2
);
451 return m_oracle
->query_relation (bb
, ssa1
, ssa2
);