From 586d6f7aee0ba9faf3d9b7afd6ff89d57763a775 Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Wed, 19 May 2021 18:27:05 +0200 Subject: Common API for accessing global and on-demand ranges. This patch provides a generic API for accessing global ranges. It is meant to replace get_range_info() and get_ptr_nonnull() with one common interface. It uses the same API as the ranger (class range_query), so there will now be one API for accessing local and global ranges alike. Follow-up patches will convert all users of get_range_info and get_ptr_nonnull to this API. For get_range_info, instead of: if (!POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_RANGE_INFO (name)) get_range_info (name, vr); You can now do: get_range_query (cfun)->range_of_expr (vr, name, [stmt]); ...as well as any other of the range_query methods (range_on_edge, range_of_stmt, value_of_expr, value_on_edge, value_on_stmt, etc). As per the API, range_of_expr will work on constants, SSA names, and anything we support in irange::supports_type_p(). For pointers, the interface is the same, so instead of: else if (POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_PTR_INFO (name)) { if (get_ptr_nonnull (name)) stuff(); } One can do: get_range_query (cfun)->range_of_expr (vr, name, [stmt]); if (vr.nonzero_p ()) stuff (); Along with this interface, we are providing a mechanism by which a pass can use an on-demand ranger transparently, without having to change its code. Of course, this assumes all get_range_info() and get_ptr_nonnull() users have been converted to the new API, which follow-up patches will do. If a pass would prefer to use an on-demand ranger with finer grained and context aware ranges, all it would have to do is call enable_ranger() at the beginning of the pass, and disable_ranger() at the end of the pass. Note, that to use context aware ranges, any user of range_of_expr() would need to pass additional context. For example, the optional gimple statement (or perhaps use range_on_edge or range_of_stmt). The observant reader will note that get_range_query is tied to a struct function, which may not be available in certain contexts, such as at RTL time, gimple-fold, or some other places where we may or may not have cfun set. For cases where we are sure there is no function, you can use get_global_range_query() instead of get_range_query(fun). The API is the same. For cases where a function may be called with or without a function, you could use the following idiom: range_query *query = cfun ? get_range_query (cfun) : get_global_range_query (); query->range_of_expr (range, expr, [stmt]); The default range query obtained by get_range_query() is the global range query, unless the user has enabled an on-demand ranger with enable_ranger(), in which case it will use the currently active ranger. That is, until disable_ranger() is called, at which point, we revert back to global ranges. We think this provides a generic way of accessing ranges, both globally and locally, without having to keep track of types, SSA_NAME_RANGE_INFO, and SSA_NAME_PTR_INFO. We also hope this can be used to transition passes from global to on-demand ranges when appropriate. gcc/ChangeLog: * function.c (allocate_struct_function): Set cfun->x_range_query. * function.h (struct function): Declare x_range_query. (get_range_query): New. (get_global_range_query): New. * gimple-range-cache.cc (ssa_global_cache::ssa_global_cache): Remove call to safe_grow_cleared. * gimple-range.cc (get_range_global): New. (gimple_range_global): Move from gimple-range.h. (get_global_range_query): New. (global_range_query::range_of_expr): New. (enable_ranger): New. (disable_ranger): New. * gimple-range.h (gimple_range_global): Move to gimple-range.cc. (class global_range_query): New. (enable_ranger): New. (disable_ranger): New. * gimple-ssa-evrp.c (evrp_folder::~evrp_folder): Rename dump_all_value_ranges to dump. * tree-vrp.c (vrp_prop::finalize): Same. * value-query.cc (range_query::dump): New. * value-query.h (range_query::dump): New. * vr-values.c (vr_values::dump_all_value_ranges): Rename to... (vr_values::dump): ...this. * vr-values.h (class vr_values): Rename dump_all_value_ranges to dump and make virtual. --- gcc/function.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'gcc/function.h') diff --git a/gcc/function.h b/gcc/function.h index 66cfa97..0db5177 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -157,6 +157,7 @@ struct GTY(()) rtl_eh { struct gimple_df; struct call_site_record_d; struct dw_fde_node; +class range_query; struct GTY(()) varasm_status { /* If we're using a per-function constant pool, this is it. */ @@ -309,6 +310,11 @@ struct GTY(()) function { debugging is enabled. */ struct dw_fde_node *fde; + /* Range query mechanism for functions. The default is to pick up + global ranges. If a pass wants on-demand ranges OTOH, it must + call enable/disable_ranger(). */ + range_query * GTY ((skip)) x_range_query; + /* Last statement uid. */ int last_stmt_uid; @@ -712,4 +718,15 @@ extern const char *current_function_name (void); extern void used_types_insert (tree); +/* Returns the currently active range access class. When there is no active + range class, global ranges are used. */ + +inline range_query * +get_range_query (struct function *fun) +{ + return fun->x_range_query; +} + +extern range_query *get_global_range_query (); + #endif /* GCC_FUNCTION_H */ -- cgit v1.1 From e45d5b6bf1bcf9fd16c3ecfadb9bde69f890b28d Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Tue, 31 Aug 2021 11:13:29 -0600 Subject: Add attribute returns nonnull to get_range_query. gcc/ChangeLog: * function.h (function): Add comments. (get_range_query): Same. Add attribute returns nonnull. --- gcc/function.h | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'gcc/function.h') diff --git a/gcc/function.h b/gcc/function.h index 0db5177..36003e7 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -312,7 +312,8 @@ struct GTY(()) function { /* Range query mechanism for functions. The default is to pick up global ranges. If a pass wants on-demand ranges OTOH, it must - call enable/disable_ranger(). */ + call enable/disable_ranger(). The pointer is never null. It + should be queried by calling get_range_query(). */ range_query * GTY ((skip)) x_range_query; /* Last statement uid. */ @@ -719,10 +720,10 @@ extern const char *current_function_name (void); extern void used_types_insert (tree); /* Returns the currently active range access class. When there is no active - range class, global ranges are used. */ + range class, global ranges are used. Never returns null. */ -inline range_query * -get_range_query (struct function *fun) +ATTRIBUTE_RETURNS_NONNULL inline range_query * +get_range_query (const struct function *fun) { return fun->x_range_query; } -- cgit v1.1