aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-prop.h
diff options
context:
space:
mode:
authorMartin Jambor <mjambor@suse.cz>2022-10-18 14:14:26 +0200
committerMartin Jambor <mjambor@suse.cz>2022-10-18 14:14:26 +0200
commit656b2338c8f248d9205b6e9d5e4d9cc43228dd5e (patch)
tree09d8d400677fa1521a05d9081e4dd59b2755d5eb /gcc/ipa-prop.h
parente0403e95689af7d562c7d04f706e9e25115747ff (diff)
downloadgcc-656b2338c8f248d9205b6e9d5e4d9cc43228dd5e.zip
gcc-656b2338c8f248d9205b6e9d5e4d9cc43228dd5e.tar.gz
gcc-656b2338c8f248d9205b6e9d5e4d9cc43228dd5e.tar.bz2
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 <mjambor@suse.cz> * 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.
Diffstat (limited to 'gcc/ipa-prop.h')
-rw-r--r--gcc/ipa-prop.h172
1 files changed, 37 insertions, 135 deletions
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<ipa_argagg_value> *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<const ipa_argagg_value> 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<ipa_agg_value> 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<ipa_agg_value_set>. */
-
-static inline vec<ipa_agg_value_set>
-ipa_copy_agg_values (const vec<ipa_agg_value_set> &aggs)
-{
- vec<ipa_agg_value_set> 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<ipa_agg_value_set>, 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<ipa_agg_value_set> &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<tree, 32> m_known_vals;
@@ -580,15 +482,22 @@ public:
auto_vec<ipa_polymorphic_call_context, 32> m_known_contexts;
/* Vector describing known aggregate values. */
- auto_vec<ipa_agg_value_set, 32> m_known_aggs;
+ auto_vec<ipa_argagg_value, 32> m_known_aggs;
/* Vector describing known value ranges of arguments. */
auto_vec<value_range, 32> 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<tree> m_known_vals = vNULL;
@@ -636,12 +534,17 @@ public:
vec<ipa_polymorphic_call_context> m_known_contexts = vNULL;
/* Vector describing known aggregate values. */
- vec<ipa_agg_value_set> m_known_aggs = vNULL;
+ vec<ipa_argagg_value> m_known_aggs = vNULL;
/* Vector describing known value ranges of arguments. */
vec<value_range> 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<ipa_param_descriptor, va_gc> *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<ipa_argagg_value> *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);