From: Jan Hubicka <hubicka@ucw.cz>
To: Martin Jambor <mjambor@suse.cz>
Cc: GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH 1/2] ipa-cp: Better representation of aggregate values we clone for
Date: Fri, 14 Oct 2022 19:17:34 +0200 [thread overview]
Message-ID: <Y0mZrn8sDbFv8scn@kam.mff.cuni.cz> (raw)
In-Reply-To: <ri6ilm9k6fh.fsf@suse.cz>
> gcc/ChangeLog:
>
> 2022-08-26 Martin Jambor <mjambor@suse.cz>
>
> * ipa-prop.h (IPA_PROP_ARG_INDEX_LIMIT_BITS): New.
> (ipcp_transformation): Added forward declaration.
> (ipa_argagg_value): New type.
> (ipa_argagg_value_list): New type.
> (ipa_agg_replacement_value): Removed type.
> (ipcp_transformation): Switch from using ipa_agg_replacement_value
> to ipa_argagg_value_list.
> (ipa_get_agg_replacements_for_node): Removed.
> (ipa_dump_agg_replacement_values): Removed declaration.
> * ipa-cp.cc: Include <algorithm>.
> (values_equal_for_ipcp_p): Moved up in the file.
> (ipa_argagg_value_list::dump): Likewise.
> (ipa_argagg_value_list::debug): Likewise.
> (ipa_argagg_value_list::get_elt): Likewise.
> (ipa_argagg_value_list::get_elt_for_index): Likewise.
> (ipa_argagg_value_list::get_value): New overloaded functions.
> (ipa_argagg_value_list::superset_of_p): New function.
> (new ipa_argagg_value_list::push_adjusted_values): Likewise.
> (push_agg_values_from_plats): Likewise.
> (intersect_argaggs_with): Likewise.
> (get_clone_agg_value): Removed.
> (ipa_agg_value_from_node): Make last parameter const, use
> ipa_argagg_value_list to search values coming from clones.
> (ipa_get_indirect_edge_target_1): Use ipa_argagg_value_list to search
> values coming from clones.
> (ipcp_discover_new_direct_edges): Pass around a vector of
> ipa_argagg_values rather than a link list of replacement values.
> (cgraph_edge_brings_value_p): Use ipa_argagg_value_list to search
> values coming from clones.
> (create_specialized_node): Work with a vector of ipa_argagg_values
> rather than a link list of replacement values.
> (self_recursive_agg_pass_through_p): Make the pointer parameters
> const.
> (copy_plats_to_inter): Removed.
> (intersect_with_plats): Likewise.
> (agg_replacements_to_vector): Likewise.
> (intersect_with_agg_replacements): Likewise.
> (intersect_aggregates_with_edge): Likewise.
> (push_agg_values_for_index_from_edge): Likewise.
> (push_agg_values_from_edge): Likewise.
> (find_aggregate_values_for_callers_subset): Rewrite.
> (cgraph_edge_brings_all_agg_vals_for_node): Likewise.
> (ipcp_val_agg_replacement_ok_p): Use ipa_argagg_value_list to search
> aggregate values.
> (decide_about_value): Work with a vector of ipa_argagg_values rather
> than a link list of replacement values.
> (decide_whether_version_node): Likewise.
> (ipa_analyze_node): Check number of parameters, assert that there
> are no descriptors when bailing out.
> * ipa-prop.cc (ipa_set_node_agg_value_chain): Switch to a vector of
> ipa_argagg_value.
> (ipa_node_params_t::duplicate): Removed superfluous handling of
> ipa_agg_replacement_values. Name of src parameter removed because
> it is no longer used.
> (ipcp_transformation_t::duplicate): Replaced duplication of
> ipa_agg_replacement_values with copying vector m_agg_values.
> (ipa_dump_agg_replacement_values): Removed.
> (write_ipcp_transformation_info): Stream the new data-structure
> instead of the old.
> (read_ipcp_transformation_info): Likewise.
> (adjust_agg_replacement_values): Work with ipa_argagg_values instead
> of linked lists of ipa_agg_replacement_values, copy the items and
> truncate the vector as necessary to keep it sorted instead of marking
> items as invalid. Return one bool if CFG should be updated.
> (ipcp_modif_dom_walker): Store ipcp_transformation instead of
> linked list of ipa_agg_replacement_values.
> (ipcp_modif_dom_walker::before_dom_children): Use
> ipa_argagg_value_list instead of walking a list of
> ipa_agg_replacement_values.
> (ipcp_transform_function): Switch to the new data structure, adjust
> dumping.
>
> gcc/testsuite/ChangeLog:
>
> 2022-08-15 Martin Jambor <mjambor@suse.cz>
>
> * gcc.dg/ipa/ipcp-agg-11.c: Adjust dumps.
> * gcc.dg/ipa/ipcp-agg-8.c: Likewise.
> ---
> gcc/ipa-cp.cc | 1010 ++++++++++++------------
> gcc/ipa-prop.cc | 254 +++---
> gcc/ipa-prop.h | 139 +++-
> gcc/testsuite/gcc.dg/ipa/ipcp-agg-11.c | 4 +-
> gcc/testsuite/gcc.dg/ipa/ipcp-agg-8.c | 4 +-
> 5 files changed, 736 insertions(+), 675 deletions(-)
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index 543a9334e2c..024f8c06b5d 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -127,6 +127,7 @@ along with GCC; see the file COPYING3. If not see
> #include "attribs.h"
> #include "dbgcnt.h"
> #include "symtab-clones.h"
> +#include <algorithm>
>
> template <typename valtype> class ipcp_value;
>
> @@ -455,6 +456,26 @@ ipcp_lattice<valtype>::is_single_const ()
> return true;
> }
>
> +/* Return true iff X and Y should be considered equal values by IPA-CP. */
> +
> +static bool
> +values_equal_for_ipcp_p (tree x, tree y)
> +{
> + gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
> +
> + if (x == y)
> + return true;
> +
> + if (TREE_CODE (x) == ADDR_EXPR
> + && TREE_CODE (y) == ADDR_EXPR
> + && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
> + && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
> + return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
> + DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
I wonder if we want to handle MEM_REFs here too? They get quite common
in IPA mode and I think we miss the fixup removing them here.
> + else
> + return operand_equal_p (x, y, 0);
> +/* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
> + NULL if there is no such constant. */
> +
> +const ipa_argagg_value *
> +ipa_argagg_value_list::get_elt (int index, unsigned unit_offset) const
> +{
> + ipa_argagg_value key;
> + key.index = index;
> + key.unit_offset = unit_offset;
> + const ipa_argagg_value *res
> + = std::lower_bound (m_elts.begin (), m_elts.end (), key,
> + [] (const ipa_argagg_value &elt,
> + const ipa_argagg_value &val)
> + {
> + if (elt.index < val.index)
> + return true;
> + if (elt.index > val.index)
> + return false;
> + if (elt.unit_offset < val.unit_offset)
> + return true;
> + return false;
> + });
> +
> + if (res == m_elts.end ()
> + || res->index != index
> + || res->unit_offset != unit_offset)
> + res = nullptr;
> +
> + /* TODO: perhaps remove after some extensive testing? */
> + if (!flag_checking)
> + return res;
> +
> + const ipa_argagg_value *slow_res = NULL;
> + int prev_index = -1;
> + unsigned prev_unit_offset = 0;
> + for (const ipa_argagg_value &av : m_elts)
> + {
> + gcc_assert (prev_index < 0
> + || prev_index < av.index
> + || prev_unit_offset < av.unit_offset);
> + prev_index = av.index;
> + prev_unit_offset = av.unit_offset;
> + if (av.index == index
> + && av.unit_offset == unit_offset)
> + slow_res = &av;
> + }
> + gcc_assert (res == slow_res);
So this is just checking that the std::lower_bound works as expected?
I am just curious if you expect it to break?
> +/* Turn all values that are not present in OTHER into NULL_TREEs. Return the
> + number of remaining valid entries. */
> +
> +bool
> +ipa_argagg_value_list::superset_of_p (const ipa_argagg_value_list &other) const
It returns bool, so not number of entries.
> +/* Push into RES aggregate all stored aggregate values relating to parameter
> + with SRC_INDEX as those relating to of DST_INDEX while subtracting
> + UNIT_DELTA from the individual unit offsets. */
> +
> +void
> +ipa_argagg_value_list::push_adjusted_values (unsigned src_index,
> + unsigned dest_index,
> + unsigned unit_delta,
> + vec<ipa_argagg_value> *res) const
> +{
> + const ipa_argagg_value *av = get_elt_for_index (src_index);
> + if (!av)
> + return;
> + unsigned prev_unit_offset = 0;
> + bool first = true;
> + for (; av < m_elts.end (); ++av)
> + {
> + if (av->index > src_index)
> + return;
> + if (av->index == src_index
> + && (av->unit_offset >= unit_delta)
> + && av->value)
> + {
> + ipa_argagg_value new_av;
> + gcc_checking_assert (av->value);
> + new_av.value = av->value;
> + new_av.unit_offset = av->unit_offset - unit_delta;
> + new_av.index = dest_index;
> + new_av.by_ref = av->by_ref;
I am bit lost on what is going here, so perhaps a comment would help.
>
> +class ipcp_transformation;
> +
> +/* 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
> + specialized for. */
> +
> +struct GTY(()) ipa_argagg_value
> +{
> + /* The constant value. In the contexts where the list of known values is
> + being pruned, NULL means a variable value. */
> + tree value;
> + /* Unit offset within the aggregate. */
> + unsigned unit_offset;
since this is 32bit, it makes me wonder if we have overflow checks (even
though greater than 4GB structures on stack are likely rare even today)
> + /* Index of the parameter, as it was in the original function (i.e. needs
> + remapping after parameter modification is carried out as part of clone
> + materialization). */
> + unsigned index : IPA_PROP_ARG_INDEX_LIMIT_BITS;
> + /* Whether the value was passed by reference. */
> + unsigned by_ref : 1;
> +};
> +
> +/* A view into a sorted list of aggregate values in a particular context, be it
> + a call or the aggregate constants that a node is specialized for. The
> + actual data is stored in the vector this has been constructed from. */
> +
> +class ipa_argagg_value_list
> +{
> +public:
> + ipa_argagg_value_list () = delete;
> + ipa_argagg_value_list (const vec<ipa_argagg_value, va_gc> *values)
> + : m_elts (values)
> + {}
> + ipa_argagg_value_list (const vec<ipa_argagg_value> *values)
> + : m_elts (*values)
> + {}
> + ipa_argagg_value_list (const ipcp_transformation *tinfo);
> +
> + /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, if it is
> + passed by reference or not according to BY_REF, or NULL_TREE
> + otherwise. */
> +
> + tree get_value (int index, unsigned unit_offset, bool by_ref) const;
> +
> + /* Return the aggregate constant stored for INDEX at UNIT_OFFSET, not
> + performing any check of whether value is passed by reference. Return
> + NULL_TREE if there is no such constant. */
> +
> + tree get_value (int index, unsigned unit_offset) const;
> +
> + /* Return the item describing a constant stored for INDEX at UNIT_OFFSET or
> + NULL if there is no such constant. */
> +
> + 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 all elements present in OTHER are also present in this
> + class. */
> +
> + bool superset_of_p (const ipa_argagg_value_list &other) const;
> +
> + /* Push into RES aggregate all stored aggregate values relating to parameter
> + with SRC_INDEX as those relating to of DST_INDEX while subtracting
> + UNIT_DELTA from the individual unit offsets. */
> +
> + void push_adjusted_values (unsigned src_index, unsigned dest_index,
> + unsigned unit_delta,
> + vec<ipa_argagg_value> *res) const;
> +
> + /* Dump aggregate constants to FILE. */
> +
> + void dump (FILE *f);
> +
> + /* Dump aggregate constants to stderr. */
> +
DEBUG_FUNCTION here.
> + void debug ();
> +
> + /* Array slice pointing to the actual storage. */
> +
> + array_slice<const ipa_argagg_value> m_elts;
> +};
> +
Patch is OK with those changes.
Thanks,
Honza
next prev parent reply other threads:[~2022-10-14 17:17 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-30 17:05 Martin Jambor
2022-10-14 17:17 ` Jan Hubicka [this message]
2022-10-17 17:42 ` Martin Jambor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y0mZrn8sDbFv8scn@kam.mff.cuni.cz \
--to=hubicka@ucw.cz \
--cc=gcc-patches@gcc.gnu.org \
--cc=mjambor@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).