From 656b2338c8f248d9205b6e9d5e4d9cc43228dd5e Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Tue, 18 Oct 2022 14:14:26 +0200 Subject: ipa-cp: Better representation of aggregate values in call contexts This patch extends the previous one by using the same data structure to represent aggregate values in classes ipa_auto_call_arg_values and ipa_call_arg_values. This usually simplifies handling and makes allocations of memory much cheaper because only a single vectore is needed, as opposed to vectors with each element pointing at other vecs. The only functions which unfortunately are a bit more complec are estimate_local_effects in ipa-cp.cc and ipa_call_context::equal_to but I hope not too much - the latter could probably be shorteneed at the expense of readability. The patch removes types ipa_agg_value ipa_agg_value_set which is no longer used with it. This means that we could replace the "_argagg_" part of the types introduced by the previous patches with more reasonable "_agg_" - possibly as a follow-up patch. gcc/ChangeLog: 2022-08-26 Martin Jambor * ipa-prop.h (ipa_agg_value): Remove type. (ipa_agg_value_set): Likewise. (ipa_copy_agg_values): Remove function. (ipa_release_agg_values): Likewise. (ipa_auto_call_arg_values) Add a forward declaration. (ipa_call_arg_values): Likewise. (class ipa_argagg_value_list): New constructors, added member function value_for_index_p. (class ipa_auto_call_arg_values): Removed the destructor and member function safe_aggval_at. Use ipa_argagg_values for m_known_aggs. (class ipa_call_arg_values): Removed member function safe_aggval_at. Use ipa_argagg_values for m_known_aggs. (ipa_get_indirect_edge_target): Removed declaration. (ipa_find_agg_cst_for_param): Likewise. (ipa_find_agg_cst_from_init): New declaration. (ipa_agg_value_from_jfunc): Likewise. (ipa_agg_value_set_from_jfunc): Removed declaration. (ipa_push_agg_values_from_jfunc): New declaration. * ipa-cp.cc (ipa_agg_value_from_node): Renamed to ipa_agg_value_from_jfunc, made public. (ipa_agg_value_set_from_jfunc): Removed. (ipa_push_agg_values_from_jfunc): New function. (ipa_get_indirect_edge_target_1): Removed known_aggs parameter, use avs for this purpose too. (ipa_get_indirect_edge_target): Removed the overload working on ipa_auto_call_arg_values, use ipa_argagg_value_list in the remaining one. (devirtualization_time_bonus): Use ipa_argagg_value_list and ipa_get_indirect_edge_target_1 instead of ipa_get_indirect_edge_target. (context_independent_aggregate_values): Removed function. (gather_context_independent_values): Work on ipa_argagg_value_list. (estimate_local_effects): Likewise, define some iterator variables only in the construct where necessary. (ipcp_discover_new_direct_edges): Adjust the call to ipa_get_indirect_edge_target_1. (push_agg_values_for_index_from_edge): Adjust the call ipa_agg_value_from_node which has been renamed to ipa_agg_value_from_jfunc. * ipa-fnsummary.cc (evaluate_conditions_for_known_args): Work on ipa_argagg_value_list. (evaluate_properties_for_edge): Replace manual filling in aggregate values with call to ipa_push_agg_values_from_jfunc. (estimate_calls_size_and_time): Work on ipa_argagg_value_list. (ipa_cached_call_context::duplicate_from): Likewise. (ipa_cached_call_context::release): Likewise. (ipa_call_context::equal_to): Likewise. * ipa-prop.cc (ipa_find_agg_cst_from_init): Make public. (ipa_find_agg_cst_for_param): Removed function. (ipa_find_agg_cst_from_jfunc_items): New function. (try_make_edge_direct_simple_call): Replace calls to ipa_agg_value_set_from_jfunc and ipa_find_agg_cst_for_param with ipa_find_agg_cst_from_init and ipa_find_agg_cst_from_jfunc_items. (try_make_edge_direct_virtual_call): Replace calls to ipa_agg_value_set_from_jfunc and ipa_find_agg_cst_for_param with simple query of constant jump function and a call to ipa_find_agg_cst_from_jfunc_items. (ipa_auto_call_arg_values::~ipa_auto_call_arg_values): Removed. --- gcc/ipa-prop.h | 172 +++++++++++++-------------------------------------------- 1 file changed, 37 insertions(+), 135 deletions(-) (limited to 'gcc/ipa-prop.h') diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h index 008d34d..0ba6ded 100644 --- a/gcc/ipa-prop.h +++ b/gcc/ipa-prop.h @@ -190,6 +190,8 @@ struct GTY(()) ipa_agg_jump_function }; class ipcp_transformation; +class ipa_auto_call_arg_values; +class ipa_call_arg_values; /* Element of a vector describing aggregate values for a number of arguments in a particular context, be it a call or the aggregate constants that a node is @@ -224,6 +226,8 @@ public: ipa_argagg_value_list (const vec *values) : m_elts (*values) {} + ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals); + ipa_argagg_value_list (const ipa_call_arg_values *gavals); ipa_argagg_value_list (const ipcp_transformation *tinfo); /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is @@ -243,12 +247,22 @@ public: const ipa_argagg_value *get_elt (int index, unsigned unit_offset) const; + /* Return the first item describing a constant stored for parameter with INDEX, regardless of offset or reference, or NULL if there is no such constant. */ const ipa_argagg_value *get_elt_for_index (int index) const; + /* Return true if there is an aggregate constant referring to a value passed + in or by parameter with INDEX (at any offset, whether by reference or + not). */ + + bool value_for_index_p (int index) const + { + return !!get_elt_for_index (index); + } + /* Return true if all elements present in OTHER are also present in this list. */ @@ -275,105 +289,6 @@ public: array_slice m_elts; }; -/* An element in an aggregate part describing a known value at a given offset. - All unlisted positions are assumed to be unknown and all listed values must - fulfill is_gimple_ip_invariant. */ - -struct ipa_agg_value -{ - /* The offset at which the known value is located within the aggregate. */ - HOST_WIDE_INT offset; - - /* The known constant. */ - tree value; - - /* Return true if OTHER describes same agg value. */ - bool equal_to (const ipa_agg_value &other); -}; - -/* Structure describing a set of known offset/value for aggregate. */ - -struct ipa_agg_value_set -{ - /* Description of the individual item. */ - vec items; - /* True if the data was passed by reference (as opposed to by value). */ - bool by_ref; - - /* Return true if OTHER describes same agg values. */ - bool equal_to (const ipa_agg_value_set &other) - { - if (by_ref != other.by_ref) - return false; - if (items.length () != other.items.length ()) - return false; - for (unsigned int i = 0; i < items.length (); i++) - if (!items[i].equal_to (other.items[i])) - return false; - return true; - } - - /* Return true if there is any value for aggregate. */ - bool is_empty () const - { - return items.is_empty (); - } - - ipa_agg_value_set copy () const - { - ipa_agg_value_set new_copy; - - new_copy.items = items.copy (); - new_copy.by_ref = by_ref; - - return new_copy; - } - - void release () - { - items.release (); - } -}; - -/* Return copy of a vec. */ - -static inline vec -ipa_copy_agg_values (const vec &aggs) -{ - vec aggs_copy = vNULL; - - if (!aggs.is_empty ()) - { - ipa_agg_value_set *agg; - int i; - - aggs_copy.reserve_exact (aggs.length ()); - - FOR_EACH_VEC_ELT (aggs, i, agg) - aggs_copy.quick_push (agg->copy ()); - } - - return aggs_copy; -} - -/* For vec, DO NOT call release(), use below function - instead. Because ipa_agg_value_set contains a field of vector type, we - should release this child vector in each element before reclaiming the - whole vector. */ - -static inline void -ipa_release_agg_values (vec &aggs, - bool release_vector = true) -{ - ipa_agg_value_set *agg; - int i; - - FOR_EACH_VEC_ELT (aggs, i, agg) - agg->release (); - if (release_vector) - aggs.release (); -} - /* Information about zero/non-zero bits. */ class GTY(()) ipa_bits { @@ -551,28 +466,15 @@ ipa_get_jf_ancestor_keep_null (struct ipa_jump_func *jfunc) class ipa_auto_call_arg_values { public: - ~ipa_auto_call_arg_values (); - /* If m_known_vals (vector of known "scalar" values) is sufficiantly long, return its element at INDEX, otherwise return NULL. */ tree safe_sval_at (int index) { - /* TODO: Assert non-negative index here and test. */ if ((unsigned) index < m_known_vals.length ()) return m_known_vals[index]; return NULL; } - /* If m_known_aggs is sufficiantly long, return the pointer rto its element - at INDEX, otherwise return NULL. */ - ipa_agg_value_set *safe_aggval_at (int index) - { - /* TODO: Assert non-negative index here and test. */ - if ((unsigned) index < m_known_aggs.length ()) - return &m_known_aggs[index]; - return NULL; - } - /* Vector describing known values of parameters. */ auto_vec m_known_vals; @@ -580,15 +482,22 @@ public: auto_vec m_known_contexts; /* Vector describing known aggregate values. */ - auto_vec m_known_aggs; + auto_vec m_known_aggs; /* Vector describing known value ranges of arguments. */ auto_vec m_known_value_ranges; }; +inline +ipa_argagg_value_list +::ipa_argagg_value_list (const ipa_auto_call_arg_values *aavals) + : m_elts (aavals->m_known_aggs) +{} + /* Class bundling the various potentially known properties about actual arguments of a particular call. This variant does not deallocate the - bundled data in any way. */ + bundled data in any way as the vectors can either be pointing to vectors in + ipa_auto_call_arg_values or be allocated independently. */ class ipa_call_arg_values { @@ -613,22 +522,11 @@ public: return its element at INDEX, otherwise return NULL. */ tree safe_sval_at (int index) { - /* TODO: Assert non-negative index here and test. */ if ((unsigned) index < m_known_vals.length ()) return m_known_vals[index]; return NULL; } - /* If m_known_aggs is sufficiantly long, return the pointer rto its element - at INDEX, otherwise return NULL. */ - ipa_agg_value_set *safe_aggval_at (int index) - { - /* TODO: Assert non-negative index here and test. */ - if ((unsigned) index < m_known_aggs.length ()) - return &m_known_aggs[index]; - return NULL; - } - /* Vector describing known values of parameters. */ vec m_known_vals = vNULL; @@ -636,12 +534,17 @@ public: vec m_known_contexts = vNULL; /* Vector describing known aggregate values. */ - vec m_known_aggs = vNULL; + vec m_known_aggs = vNULL; /* Vector describing known value ranges of arguments. */ vec m_known_value_ranges = vNULL; }; +inline +ipa_argagg_value_list +::ipa_argagg_value_list (const ipa_call_arg_values *gavals) + : m_elts (gavals->m_known_aggs) +{} /* Summary describing a single formal parameter. */ @@ -1190,9 +1093,6 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, ipa_call_arg_values *avals, bool *speculative); -tree ipa_get_indirect_edge_target (struct cgraph_edge *ie, - ipa_auto_call_arg_values *avals, - bool *speculative); struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree, bool speculative = false); tree ipa_impossible_devirt_target (struct cgraph_edge *, tree); @@ -1204,9 +1104,8 @@ ipa_bits *ipa_get_ipa_bits_for_value (const widest_int &value, void ipa_analyze_node (struct cgraph_node *); /* Aggregate jump function related functions. */ -tree ipa_find_agg_cst_for_param (const ipa_agg_value_set *agg, tree scalar, - HOST_WIDE_INT offset, bool by_ref, - bool *from_global_constant = NULL); +tree ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, + bool by_ref); bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi, vec *descriptors, gimple *stmt, tree op, int *index_p, @@ -1243,6 +1142,8 @@ void ipcp_read_transformation_summaries (void); int ipa_get_param_decl_index (class ipa_node_params *, tree); tree ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc, tree type); +tree ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node, + const ipa_agg_jf_item *item); unsigned int ipcp_transform_function (struct cgraph_node *node); ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *, cgraph_edge *, @@ -1250,9 +1151,10 @@ ipa_polymorphic_call_context ipa_context_from_jfunc (ipa_node_params *, ipa_jump_func *); value_range ipa_value_range_from_jfunc (ipa_node_params *, cgraph_edge *, ipa_jump_func *, tree); -ipa_agg_value_set ipa_agg_value_set_from_jfunc (ipa_node_params *, - cgraph_node *, - ipa_agg_jump_function *); +void ipa_push_agg_values_from_jfunc (ipa_node_params *info, cgraph_node *node, + ipa_agg_jump_function *agg_jfunc, + unsigned dst_index, + vec *res); void ipa_dump_param (FILE *, class ipa_node_params *info, int i); void ipa_release_body_info (struct ipa_func_body_info *); tree ipa_get_callee_param_type (struct cgraph_edge *e, int i); -- cgit v1.1