* Re: [PATCH] ipa: Convert lattices from pure array to vector (PR 113476)
2024-02-19 15:04 ` [PATCH] ipa: Convert lattices from pure array to vector " Martin Jambor
@ 2024-02-20 7:11 ` Richard Biener
2024-02-20 10:20 ` Jan Hubicka
1 sibling, 0 replies; 9+ messages in thread
From: Richard Biener @ 2024-02-20 7:11 UTC (permalink / raw)
To: Martin Jambor; +Cc: Jan Hubicka, GCC Patches
On Mon, 19 Feb 2024, Martin Jambor wrote:
> On Tue, Feb 13 2024, Martin Jambor wrote:
> > On Mon, Feb 12 2024, Jan Hubicka wrote:
> >>> Believe it or not, even though I have re-worked the internals of the
> >>> lattices completely, the array itself is older than my involvement with
> >>> GCC (or at least with ipa-cp.c ;-).
> >>>
> >>> So it being an array and not a vector is historical coincidence, as far
> >>> as I am concerned :-). But that may be the reason, or because vector
> >>> macros at that time looked scary, or perhaps the initialization by
> >>> XCNEWVEC zeroing everything out was considered attractive (I kind of
> >>> like that but constructors would probably be cleaner), I don't know.
> >>
> >> If your class is no longer a POD, then the clearing before construcion
> >> is dead and GCC may optimize it out. So fixing this may solve some
> >> surprised in foreseable future when we will try to compile older GCC's
> >> with newer ones.
> >>
> >
> > That's a good point. I'll prepare a patch converting the whole thing to
> > use constructors and vectors.
> >
>
> In PR 113476 we have discovered that ipcp_param_lattices is no longer
> a POD and should be destructed. In a follow-up discussion it
> transpired that their initialization done by memsetting their backing
> memory to zero is also invalid because now any write there before
> construction can be considered dead. Plus that having them in an
> array is a little bit old-school and does not get the extra checking
> offered by vector along with automatic construction and destruction
> when necessary.
>
> So this patch converts the array to a vector. That however means that
> ipcp_param_lattices cannot be just a forward declared type but must be
> known to all code that deal with ipa_node_params and thus to all code
> that includes ipa-prop.h. Therefore I have moved ipcp_param_lattices
> and the type it depends on to a new header ipa-cp.h which now
> ipa-prop.h depends on. Because we have the (IMHO not a very wise)
> rule that headers don't include what they need themselves, I had to
> add inclusions of ipa-cp.h and sreal.h (on which it depends) to very
> many files, which made the patch rather ugly.
>
> Bootstrapped and tested on x86_64-linux. I also had it checked by our
> script which builds more than a hundred of cross-compilers, so other
> targets are hopefully also fine.
>
> OK for master?
LGTM.
Thanks,
Richard.
> Martin
>
>
> gcc/lto/ChangeLog:
>
> 2024-02-16 Martin Jambor <mjambor@suse.cz>
>
> * lto-common.cc: Include sreal.h and ipa-cp.h.
> * lto-partition.cc: Include ipa-cp.h, move inclusion of sreal higher.
> * lto.cc: Include sreal.h and ipa-cp.h.
>
> gcc/ChangeLog:
>
> 2024-02-16 Martin Jambor <mjambor@suse.cz>
>
> * ipa-prop.h (ipa_node_params): Convert lattices to a vector, adjust
> initializers in the contructor.
> (ipa_node_params::~ipa_node_params): Release lattices as a vector.
> * ipa-cp.h: New file.
> * ipa-cp.cc: Include sreal.h and ipa-cp.h.
> (ipcp_value_source): Move to ipa-cp.h.
> (ipcp_value_base): Likewise.
> (ipcp_value): Likewise.
> (ipcp_lattice): Likewise.
> (ipcp_agg_lattice): Likewise.
> (ipcp_bits_lattice): Likewise.
> (ipcp_vr_lattice): Likewise.
> (ipcp_param_lattices): Likewise.
> (ipa_get_parm_lattices): Remove assert latticess is non-NULL).
> (ipa_value_from_jfunc): Adjust a check for empty lattices.
> (ipa_context_from_jfunc): Likewise.
> (ipa_agg_value_from_jfunc): Likewise.
> (merge_agg_lats_step): Do not memset new aggregate lattices to zero.
> (ipcp_propagate_stage): Allocate lattices in a vector as opposed to
> just in contiguous memory.
> (ipcp_store_vr_results): Adjust a check for empty lattices.
> * auto-profile.cc: Include sreal.h and ipa-cp.h.
> * cgraph.cc: Likewise.
> * cgraphclones.cc: Likewise.
> * cgraphunit.cc: Likewise.
> * config/aarch64/aarch64.cc: Likewise.
> * config/i386/i386-builtins.cc: Likewise.
> * config/i386/i386-expand.cc: Likewise.
> * config/i386/i386-features.cc: Likewise.
> * config/i386/i386-options.cc: Likewise.
> * config/i386/i386.cc: Likewise.
> * config/rs6000/rs6000.cc: Likewise.
> * config/s390/s390.cc: Likewise.
> * gengtype.cc (open_base_files): Added sreal.h and ipa-cp.h to the
> files to be included in gtype-desc.cc.
> * gimple-range-fold.cc: Include sreal.h and ipa-cp.h.
> * ipa-devirt.cc: Likewise.
> * ipa-fnsummary.cc: Likewise.
> * ipa-icf.cc: Likewise.
> * ipa-inline-analysis.cc: Likewise.
> * ipa-inline-transform.cc: Likewise.
> * ipa-inline.cc: Include ipa-cp.h, move inclusion of sreal.h higher.
> * ipa-modref.cc: Include sreal.h and ipa-cp.h.
> * ipa-param-manipulation.cc: Likewise.
> * ipa-predicate.cc: Likewise.
> * ipa-profile.cc: Likewise.
> * ipa-prop.cc: Likewise.
> (ipa_node_params_t::duplicate): Assert new lattices remain empty
> instead of setting them to NULL.
> * ipa-pure-const.cc: Include sreal.h and ipa-cp.h.
> * ipa-split.cc: Likewise.
> * ipa-sra.cc: Likewise.
> * ipa-strub.cc: Likewise.
> * ipa-utils.cc: Likewise.
> * ipa.cc: Likewise.
> * toplev.cc: Likewise.
> * tree-ssa-ccp.cc: Likewise.
> * tree-ssa-sccvn.cc: Likewise.
> * tree-vrp.cc: Likewise.
> ---
> gcc/auto-profile.cc | 2 +
> gcc/cgraph.cc | 2 +
> gcc/cgraphclones.cc | 2 +
> gcc/cgraphunit.cc | 2 +
> gcc/config/aarch64/aarch64.cc | 2 +
> gcc/config/i386/i386-builtins.cc | 2 +
> gcc/config/i386/i386-expand.cc | 2 +
> gcc/config/i386/i386-features.cc | 2 +
> gcc/config/i386/i386-options.cc | 2 +
> gcc/config/i386/i386.cc | 2 +
> gcc/config/rs6000/rs6000.cc | 2 +
> gcc/config/s390/s390.cc | 2 +
> gcc/gengtype.cc | 6 +-
> gcc/gimple-range-fold.cc | 2 +
> gcc/ipa-cp.cc | 283 +-----------------------------
> gcc/ipa-cp.h | 292 +++++++++++++++++++++++++++++++
> gcc/ipa-devirt.cc | 2 +
> gcc/ipa-fnsummary.cc | 2 +
> gcc/ipa-icf.cc | 2 +
> gcc/ipa-inline-analysis.cc | 2 +
> gcc/ipa-inline-transform.cc | 2 +
> gcc/ipa-inline.cc | 3 +-
> gcc/ipa-modref.cc | 2 +
> gcc/ipa-param-manipulation.cc | 2 +
> gcc/ipa-predicate.cc | 2 +
> gcc/ipa-profile.cc | 2 +
> gcc/ipa-prop.cc | 4 +-
> gcc/ipa-prop.h | 6 +-
> gcc/ipa-pure-const.cc | 2 +
> gcc/ipa-split.cc | 2 +
> gcc/ipa-sra.cc | 2 +
> gcc/ipa-strub.cc | 2 +
> gcc/ipa-utils.cc | 2 +
> gcc/ipa.cc | 2 +
> gcc/lto/lto-common.cc | 2 +
> gcc/lto/lto-partition.cc | 3 +-
> gcc/lto/lto.cc | 2 +
> gcc/toplev.cc | 2 +
> gcc/tree-ssa-ccp.cc | 2 +
> gcc/tree-ssa-sccvn.cc | 2 +
> gcc/tree-vrp.cc | 2 +
> 41 files changed, 380 insertions(+), 285 deletions(-)
> create mode 100644 gcc/ipa-cp.h
>
> diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
> index 63d0c3dc36d..e5407d32fbb 100644
> --- a/gcc/auto-profile.cc
> +++ b/gcc/auto-profile.cc
> @@ -42,6 +42,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-iterator.h"
> #include "value-prof.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index 0ac8f73204b..473d8410bc9 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "cfgloop.h"
> diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
> index 6d7bc402a29..4fff6873a36 100644
> --- a/gcc/cgraphclones.cc
> +++ b/gcc/cgraphclones.cc
> @@ -84,6 +84,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "symtab-thunks.h"
> diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
> index 5c405258ec3..d200166f7e9 100644
> --- a/gcc/cgraphunit.cc
> +++ b/gcc/cgraphunit.cc
> @@ -191,6 +191,8 @@ along with GCC; see the file COPYING3. If not see
> #include "debug.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "gimple-pretty-print.h"
> #include "plugin.h"
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 32eae49d4e9..29c899157e1 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -91,6 +91,8 @@
> #include "tree-pass.h"
> #include "cfgbuild.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "hash-map.h"
> diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
> index d5b83e9d90f..8b79d335c88 100644
> --- a/gcc/config/i386/i386-builtins.cc
> +++ b/gcc/config/i386/i386-builtins.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index 50f9fe2c0d7..a4d3369f01b 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
> index f1b1cf24233..d3b9ae81025 100644
> --- a/gcc/config/i386/i386-features.cc
> +++ b/gcc/config/i386/i386-features.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
> index 8f5ce817630..93a01146db7 100644
> --- a/gcc/config/i386/i386-options.cc
> +++ b/gcc/config/i386/i386-options.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index dbb26e8f76a..53db72e95f9 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -86,6 +86,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 5d975dab921..a2a679d8eed 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -72,6 +72,8 @@
> #include "context.h"
> #include "tree-pass.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "except.h"
> diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
> index f182c26e78b..c857b2028f2 100644
> --- a/gcc/config/s390/s390.cc
> +++ b/gcc/config/s390/s390.cc
> @@ -83,6 +83,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tm-constrs.h"
> #include "tree-vrp.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "sched-int.h"
> diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc
> index b1db727b958..a72249eacf8 100644
> --- a/gcc/gengtype.cc
> +++ b/gcc/gengtype.cc
> @@ -1713,9 +1713,9 @@ open_base_files (void)
> "tree-dfa.h", "tree-ssa.h", "reload.h", "cpplib.h", "tree-chrec.h",
> "except.h", "output.h", "cfgloop.h", "target.h", "lto-streamer.h",
> "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
> - "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-general.h",
> - "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h", "symtab-thunks.h",
> - "symtab-clones.h", "diagnostic-spec.h", "ctfc.h",
> + "sreal.h", "ipa-cp.h", "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h",
> + "omp-general.h", "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h",
> + "symtab-thunks.h", "symtab-clones.h", "diagnostic-spec.h", "ctfc.h",
> NULL
> };
> const char *const *ifp;
> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> index 0cc53199963..9c4ad1ee7b9 100644
> --- a/gcc/gimple-range-fold.cc
> +++ b/gcc/gimple-range-fold.cc
> @@ -48,6 +48,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> // Construct a fur_source, and set the m_query field.
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index e85477df32d..2a1da631e9c 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -109,6 +109,7 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-expr.h"
> #include "gimple.h"
> #include "predict.h"
> +#include "sreal.h"
> #include "alloc-pool.h"
> #include "tree-pass.h"
> #include "cgraph.h"
> @@ -118,6 +119,7 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-fold.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-pretty-print.h"
> #include "tree-inline.h"
> @@ -130,274 +132,6 @@ along with GCC; see the file COPYING3. If not see
> #include "symtab-clones.h"
> #include "gimple-range.h"
>
> -template <typename valtype> class ipcp_value;
> -
> -/* Describes a particular source for an IPA-CP value. */
> -
> -template <typename valtype>
> -struct ipcp_value_source
> -{
> -public:
> - /* Aggregate offset of the source, negative if the source is scalar value of
> - the argument itself. */
> - HOST_WIDE_INT offset;
> - /* The incoming edge that brought the value. */
> - cgraph_edge *cs;
> - /* If the jump function that resulted into his value was a pass-through or an
> - ancestor, this is the ipcp_value of the caller from which the described
> - value has been derived. Otherwise it is NULL. */
> - ipcp_value<valtype> *val;
> - /* Next pointer in a linked list of sources of a value. */
> - ipcp_value_source *next;
> - /* If the jump function that resulted into his value was a pass-through or an
> - ancestor, this is the index of the parameter of the caller the jump
> - function references. */
> - int index;
> -};
> -
> -/* Common ancestor for all ipcp_value instantiations. */
> -
> -class ipcp_value_base
> -{
> -public:
> - /* Time benefit and that specializing the function for this value would bring
> - about in this function alone. */
> - sreal local_time_benefit;
> - /* Time benefit that specializing the function for this value can bring about
> - in it's callees. */
> - sreal prop_time_benefit;
> - /* Size cost that specializing the function for this value would bring about
> - in this function alone. */
> - int local_size_cost;
> - /* Size cost that specializing the function for this value can bring about in
> - it's callees. */
> - int prop_size_cost;
> -
> - ipcp_value_base ()
> - : local_time_benefit (0), prop_time_benefit (0),
> - local_size_cost (0), prop_size_cost (0) {}
> -};
> -
> -/* Describes one particular value stored in struct ipcp_lattice. */
> -
> -template <typename valtype>
> -class ipcp_value : public ipcp_value_base
> -{
> -public:
> - /* The actual value for the given parameter. */
> - valtype value;
> - /* The list of sources from which this value originates. */
> - ipcp_value_source <valtype> *sources = nullptr;
> - /* Next pointers in a linked list of all values in a lattice. */
> - ipcp_value *next = nullptr;
> - /* Next pointers in a linked list of values in a strongly connected component
> - of values. */
> - ipcp_value *scc_next = nullptr;
> - /* Next pointers in a linked list of SCCs of values sorted topologically
> - according their sources. */
> - ipcp_value *topo_next = nullptr;
> - /* A specialized node created for this value, NULL if none has been (so far)
> - created. */
> - cgraph_node *spec_node = nullptr;
> - /* Depth first search number and low link for topological sorting of
> - values. */
> - int dfs = 0;
> - int low_link = 0;
> - /* SCC number to identify values which recursively feed into each other.
> - Values in the same SCC have the same SCC number. */
> - int scc_no = 0;
> - /* Non zero if the value is generated from another value in the same lattice
> - for a self-recursive call, the actual number is how many times the
> - operation has been performed. In the unlikely event of the value being
> - present in two chains fo self-recursive value generation chains, it is the
> - maximum. */
> - unsigned self_recursion_generated_level = 0;
> - /* True if this value is currently on the topo-sort stack. */
> - bool on_stack = false;
> -
> - void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
> - HOST_WIDE_INT offset);
> -
> - /* Return true if both THIS value and O feed into each other. */
> -
> - bool same_scc (const ipcp_value<valtype> *o)
> - {
> - return o->scc_no == scc_no;
> - }
> -
> -/* Return true, if a this value has been generated for a self-recursive call as
> - a result of an arithmetic pass-through jump-function acting on a value in
> - the same lattice function. */
> -
> - bool self_recursion_generated_p ()
> - {
> - return self_recursion_generated_level > 0;
> - }
> -};
> -
> -/* Lattice describing potential values of a formal parameter of a function, or
> - a part of an aggregate. TOP is represented by a lattice with zero values
> - and with contains_variable and bottom flags cleared. BOTTOM is represented
> - by a lattice with the bottom flag set. In that case, values and
> - contains_variable flag should be disregarded. */
> -
> -template <typename valtype>
> -struct ipcp_lattice
> -{
> -public:
> - /* The list of known values and types in this lattice. Note that values are
> - not deallocated if a lattice is set to bottom because there may be value
> - sources referencing them. */
> - ipcp_value<valtype> *values;
> - /* Number of known values and types in this lattice. */
> - int values_count;
> - /* The lattice contains a variable component (in addition to values). */
> - bool contains_variable;
> - /* The value of the lattice is bottom (i.e. variable and unusable for any
> - propagation). */
> - bool bottom;
> -
> - inline bool is_single_const ();
> - inline bool set_to_bottom ();
> - inline bool set_contains_variable ();
> - bool add_value (valtype newval, cgraph_edge *cs,
> - ipcp_value<valtype> *src_val = NULL,
> - int src_idx = 0, HOST_WIDE_INT offset = -1,
> - ipcp_value<valtype> **val_p = NULL,
> - unsigned same_lat_gen_level = 0);
> - void print (FILE * f, bool dump_sources, bool dump_benefits);
> -};
> -
> -/* Lattice of tree values with an offset to describe a part of an
> - aggregate. */
> -
> -struct ipcp_agg_lattice : public ipcp_lattice<tree>
> -{
> -public:
> - /* Offset that is being described by this lattice. */
> - HOST_WIDE_INT offset;
> - /* Size so that we don't have to re-compute it every time we traverse the
> - list. Must correspond to TYPE_SIZE of all lat values. */
> - HOST_WIDE_INT size;
> - /* Next element of the linked list. */
> - struct ipcp_agg_lattice *next;
> -};
> -
> -/* Lattice of known bits, only capable of holding one value.
> - Bitwise constant propagation propagates which bits of a
> - value are constant.
> - For eg:
> - int f(int x)
> - {
> - return some_op (x);
> - }
> -
> - int f1(int y)
> - {
> - if (cond)
> - return f (y & 0xff);
> - else
> - return f (y & 0xf);
> - }
> -
> - In the above case, the param 'x' will always have all
> - the bits (except the bits in lsb) set to 0.
> - Hence the mask of 'x' would be 0xff. The mask
> - reflects that the bits in lsb are unknown.
> - The actual propagated value is given by m_value & ~m_mask. */
> -
> -class ipcp_bits_lattice
> -{
> -public:
> - bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
> - bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
> - bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
> - bool set_to_bottom ();
> - bool set_to_constant (widest_int, widest_int);
> - bool known_nonzero_p () const;
> -
> - widest_int get_value () const { return m_value; }
> - widest_int get_mask () const { return m_mask; }
> -
> - bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
> - enum tree_code, tree, bool);
> -
> - bool meet_with (widest_int, widest_int, unsigned);
> -
> - void print (FILE *);
> -
> -private:
> - enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
> -
> - /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
> - If a bit in mask is set to 0, then the corresponding bit in
> - value is known to be constant. */
> - widest_int m_value, m_mask;
> -
> - bool meet_with_1 (widest_int, widest_int, unsigned, bool);
> - void get_value_and_mask (tree, widest_int *, widest_int *);
> -};
> -
> -/* Lattice of value ranges. */
> -
> -class ipcp_vr_lattice
> -{
> -public:
> - Value_Range m_vr;
> -
> - inline bool bottom_p () const;
> - inline bool top_p () const;
> - inline bool set_to_bottom ();
> - bool meet_with (const vrange &p_vr);
> - bool meet_with (const ipcp_vr_lattice &other);
> - void init (tree type);
> - void print (FILE * f);
> -
> -private:
> - bool meet_with_1 (const vrange &other_vr);
> -};
> -
> -inline void
> -ipcp_vr_lattice::init (tree type)
> -{
> - if (type)
> - m_vr.set_type (type);
> -
> - // Otherwise m_vr will default to unsupported_range.
> -}
> -
> -/* Structure containing lattices for a parameter itself and for pieces of
> - aggregates that are passed in the parameter or by a reference in a parameter
> - plus some other useful flags. */
> -
> -class ipcp_param_lattices
> -{
> -public:
> - /* Lattice describing the value of the parameter itself. */
> - ipcp_lattice<tree> itself;
> - /* Lattice describing the polymorphic contexts of a parameter. */
> - ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
> - /* Lattices describing aggregate parts. */
> - ipcp_agg_lattice *aggs;
> - /* Lattice describing known bits. */
> - ipcp_bits_lattice bits_lattice;
> - /* Lattice describing value range. */
> - ipcp_vr_lattice m_value_range;
> - /* Number of aggregate lattices */
> - int aggs_count;
> - /* True if aggregate data were passed by reference (as opposed to by
> - value). */
> - bool aggs_by_ref;
> - /* All aggregate lattices contain a variable component (in addition to
> - values). */
> - bool aggs_contain_variable;
> - /* The value of all aggregate lattices is bottom (i.e. variable and unusable
> - for any propagation). */
> - bool aggs_bottom;
> -
> - /* There is a virtual call based on this parameter. */
> - bool virt_call;
> -};
>
> /* Allocation pools for values and their sources in ipa-cp. */
>
> @@ -431,7 +165,6 @@ ipa_get_parm_lattices (class ipa_node_params *info, int i)
> {
> gcc_assert (i >= 0 && i < ipa_get_param_count (info));
> gcc_checking_assert (!info->ipcp_orig_node);
> - gcc_checking_assert (info->lattices);
> return &(info->lattices[i]);
> }
>
> @@ -1821,7 +1554,7 @@ ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
> {
> ipcp_lattice<tree> *lat;
>
> - if (!info->lattices
> + if (info->lattices.is_empty ()
> || idx >= ipa_get_param_count (info))
> return NULL_TREE;
> lat = ipa_get_scalar_lat (info, idx);
> @@ -1884,7 +1617,7 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
> }
> else
> {
> - if (!info->lattices
> + if (info->lattices.is_empty ()
> || srcidx >= ipa_get_param_count (info))
> return ctx;
> ipcp_lattice<ipa_polymorphic_call_context> *lat;
> @@ -2056,7 +1789,7 @@ ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
> item->value.load_agg.by_ref);
> }
> }
> - else if (info->lattices)
> + else if (!info->lattices.is_empty ())
> {
> class ipcp_param_lattices *src_plats
> = ipa_get_parm_lattices (info, src_idx);
> @@ -2937,7 +2670,6 @@ merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
> return false;
> dest_plats->aggs_count++;
> new_al = ipcp_agg_lattice_pool.allocate ();
> - memset (new_al, 0, sizeof (*new_al));
>
> new_al->offset = offset;
> new_al->size = val_size;
> @@ -4295,8 +4027,7 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
> determine_versionability (node, info);
>
> unsigned nlattices = ipa_get_param_count (info);
> - void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
> - info->lattices = new (chunk) ipcp_param_lattices[nlattices];
> + info->lattices.safe_grow_cleared (nlattices, true);
> initialize_node_lattices (node);
> }
> ipa_size_summary *s = ipa_size_summaries->get (node);
> @@ -6568,7 +6299,7 @@ ipcp_store_vr_results (void)
>
> if (info->ipcp_orig_node)
> info = ipa_node_params_sum->get (info->ipcp_orig_node);
> - if (!info->lattices)
> + if (info->lattices.is_empty ())
> /* Newly expanded artificial thunks do not have lattices. */
> continue;
>
> diff --git a/gcc/ipa-cp.h b/gcc/ipa-cp.h
> new file mode 100644
> index 00000000000..0b3cfe4b526
> --- /dev/null
> +++ b/gcc/ipa-cp.h
> @@ -0,0 +1,292 @@
> +/* Interprocedural constant propagation
> + Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3. If not see
> +<http://www.gnu.org/licenses/>. */
> +
> +#ifndef IPA_CP_H
> +#define IPA_CP_H
> +
> +template <typename valtype> class ipcp_value;
> +
> +/* Describes a particular source for an IPA-CP value. */
> +
> +template <typename valtype>
> +struct ipcp_value_source
> +{
> +public:
> + /* Aggregate offset of the source, negative if the source is scalar value of
> + the argument itself. */
> + HOST_WIDE_INT offset;
> + /* The incoming edge that brought the value. */
> + cgraph_edge *cs;
> + /* If the jump function that resulted into his value was a pass-through or an
> + ancestor, this is the ipcp_value of the caller from which the described
> + value has been derived. Otherwise it is NULL. */
> + ipcp_value<valtype> *val;
> + /* Next pointer in a linked list of sources of a value. */
> + ipcp_value_source *next;
> + /* If the jump function that resulted into his value was a pass-through or an
> + ancestor, this is the index of the parameter of the caller the jump
> + function references. */
> + int index;
> +};
> +
> +/* Common ancestor for all ipcp_value instantiations. */
> +
> +class ipcp_value_base
> +{
> +public:
> + /* Time benefit and that specializing the function for this value would bring
> + about in this function alone. */
> + sreal local_time_benefit = 0;
> + /* Time benefit that specializing the function for this value can bring about
> + in it's callees. */
> + sreal prop_time_benefit = 0;
> + /* Size cost that specializing the function for this value would bring about
> + in this function alone. */
> + int local_size_cost = 0;
> + /* Size cost that specializing the function for this value can bring about in
> + it's callees. */
> + int prop_size_cost = 0;
> +};
> +
> +/* Describes one particular value stored in struct ipcp_lattice. */
> +
> +template <typename valtype>
> +class ipcp_value : public ipcp_value_base
> +{
> +public:
> + /* The actual value for the given parameter. */
> + valtype value;
> + /* The list of sources from which this value originates. */
> + ipcp_value_source <valtype> *sources = nullptr;
> + /* Next pointers in a linked list of all values in a lattice. */
> + ipcp_value *next = nullptr;
> + /* Next pointers in a linked list of values in a strongly connected component
> + of values. */
> + ipcp_value *scc_next = nullptr;
> + /* Next pointers in a linked list of SCCs of values sorted topologically
> + according their sources. */
> + ipcp_value *topo_next = nullptr;
> + /* A specialized node created for this value, NULL if none has been (so far)
> + created. */
> + cgraph_node *spec_node = nullptr;
> + /* Depth first search number and low link for topological sorting of
> + values. */
> + int dfs = 0;
> + int low_link = 0;
> + /* SCC number to identify values which recursively feed into each other.
> + Values in the same SCC have the same SCC number. */
> + int scc_no = 0;
> + /* Non zero if the value is generated from another value in the same lattice
> + for a self-recursive call, the actual number is how many times the
> + operation has been performed. In the unlikely event of the value being
> + present in two chains fo self-recursive value generation chains, it is the
> + maximum. */
> + unsigned self_recursion_generated_level = 0;
> + /* True if this value is currently on the topo-sort stack. */
> + bool on_stack = false;
> +
> + void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
> + HOST_WIDE_INT offset);
> +
> + /* Return true if both THIS value and O feed into each other. */
> +
> + bool same_scc (const ipcp_value<valtype> *o)
> + {
> + return o->scc_no == scc_no;
> + }
> +
> +/* Return true, if a this value has been generated for a self-recursive call as
> + a result of an arithmetic pass-through jump-function acting on a value in
> + the same lattice function. */
> +
> + bool self_recursion_generated_p ()
> + {
> + return self_recursion_generated_level > 0;
> + }
> +};
> +
> +/* Lattice describing potential values of a formal parameter of a function, or
> + a part of an aggregate. TOP is represented by a lattice with zero values
> + and with contains_variable and bottom flags cleared. BOTTOM is represented
> + by a lattice with the bottom flag set. In that case, values and
> + contains_variable flag should be disregarded. */
> +
> +template <typename valtype>
> +struct ipcp_lattice
> +{
> +public:
> + /* The list of known values and types in this lattice. Note that values are
> + not deallocated if a lattice is set to bottom because there may be value
> + sources referencing them. */
> + ipcp_value<valtype> *values = nullptr;
> + /* Number of known values and types in this lattice. */
> + int values_count = 0;
> + /* The lattice contains a variable component (in addition to values). */
> + bool contains_variable = false;
> + /* The value of the lattice is bottom (i.e. variable and unusable for any
> + propagation). */
> + bool bottom = false;
> +
> + inline bool is_single_const ();
> + inline bool set_to_bottom ();
> + inline bool set_contains_variable ();
> + bool add_value (valtype newval, cgraph_edge *cs,
> + ipcp_value<valtype> *src_val = NULL,
> + int src_idx = 0, HOST_WIDE_INT offset = -1,
> + ipcp_value<valtype> **val_p = NULL,
> + unsigned same_lat_gen_level = 0);
> + void print (FILE * f, bool dump_sources, bool dump_benefits);
> +};
> +
> +/* Lattice of tree values with an offset to describe a part of an
> + aggregate. */
> +
> +struct ipcp_agg_lattice : public ipcp_lattice<tree>
> +{
> +public:
> + /* Offset that is being described by this lattice. */
> + HOST_WIDE_INT offset = 0;
> + /* Size so that we don't have to re-compute it every time we traverse the
> + list. Must correspond to TYPE_SIZE of all lat values. */
> + HOST_WIDE_INT size = 0;
> + /* Next element of the linked list. */
> + struct ipcp_agg_lattice *next = nullptr;
> +};
> +
> +/* Lattice of known bits, only capable of holding one value.
> + Bitwise constant propagation propagates which bits of a
> + value are constant.
> + For eg:
> + int f(int x)
> + {
> + return some_op (x);
> + }
> +
> + int f1(int y)
> + {
> + if (cond)
> + return f (y & 0xff);
> + else
> + return f (y & 0xf);
> + }
> +
> + In the above case, the param 'x' will always have all
> + the bits (except the bits in lsb) set to 0.
> + Hence the mask of 'x' would be 0xff. The mask
> + reflects that the bits in lsb are unknown.
> + The actual propagated value is given by m_value & ~m_mask. */
> +
> +class ipcp_bits_lattice
> +{
> +public:
> + bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
> + bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
> + bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
> + bool set_to_bottom ();
> + bool set_to_constant (widest_int, widest_int);
> + bool known_nonzero_p () const;
> +
> + widest_int get_value () const { return m_value; }
> + widest_int get_mask () const { return m_mask; }
> +
> + bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
> + enum tree_code, tree, bool);
> +
> + bool meet_with (widest_int, widest_int, unsigned);
> +
> + void print (FILE *);
> +
> +private:
> + enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING }
> + m_lattice_val = IPA_BITS_UNDEFINED;
> +
> + /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
> + If a bit in mask is set to 0, then the corresponding bit in
> + value is known to be constant. */
> + widest_int m_value, m_mask;
> +
> + bool meet_with_1 (widest_int, widest_int, unsigned, bool);
> + void get_value_and_mask (tree, widest_int *, widest_int *);
> +};
> +
> +/* Lattice of value ranges. */
> +
> +class ipcp_vr_lattice
> +{
> +public:
> + Value_Range m_vr;
> +
> + inline bool bottom_p () const;
> + inline bool top_p () const;
> + inline bool set_to_bottom ();
> + bool meet_with (const vrange &p_vr);
> + bool meet_with (const ipcp_vr_lattice &other);
> + void init (tree type);
> + void print (FILE * f);
> +
> +private:
> + bool meet_with_1 (const vrange &other_vr);
> +};
> +
> +inline void
> +ipcp_vr_lattice::init (tree type)
> +{
> + if (type)
> + m_vr.set_type (type);
> +
> + // Otherwise m_vr will default to unsupported_range.
> +}
> +
> +/* Structure containing lattices for a parameter itself and for pieces of
> + aggregates that are passed in the parameter or by a reference in a parameter
> + plus some other useful flags.
> +
> + Even after construction, m_value_range parts still need to be initialized
> + with the type they represent with the init method. */
> +
> +class ipcp_param_lattices
> +{
> +public:
> + /* Lattice describing the value of the parameter itself. */
> + ipcp_lattice<tree> itself;
> + /* Lattice describing the polymorphic contexts of a parameter. */
> + ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
> + /* Lattices describing aggregate parts. */
> + ipcp_agg_lattice *aggs = nullptr;
> + /* Lattice describing known bits. */
> + ipcp_bits_lattice bits_lattice;
> + /* Lattice describing value range. */
> + ipcp_vr_lattice m_value_range;
> + /* Number of aggregate lattices */
> + int aggs_count = 0;
> + /* True if aggregate data were passed by reference (as opposed to by
> + value). */
> + bool aggs_by_ref = false;
> + /* All aggregate lattices contain a variable component (in addition to
> + values). */
> + bool aggs_contain_variable = false;
> + /* The value of all aggregate lattices is bottom (i.e. variable and unusable
> + for any propagation). */
> + bool aggs_bottom = false;
> +
> + /* There is a virtual call based on this parameter. */
> + bool virt_call = false;
> +};
> +
> +#endif /* IPA_CP_H */
> diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
> index caf8548fbc9..a7ce434bffb 100644
> --- a/gcc/ipa-devirt.cc
> +++ b/gcc/ipa-devirt.cc
> @@ -124,6 +124,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-fold.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "demangle.h"
> diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
> index 74c9b4e1d1e..dff40cd8aa5 100644
> --- a/gcc/ipa-fnsummary.cc
> +++ b/gcc/ipa-fnsummary.cc
> @@ -75,6 +75,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-loop-niter.h"
> #include "tree-ssa-loop.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "cfgloop.h"
> diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
> index f56891325f3..5d5a42f9c6c 100644
> --- a/gcc/ipa-icf.cc
> +++ b/gcc/ipa-icf.cc
> @@ -73,6 +73,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-iterator.h"
> #include "tree-cfg.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "except.h"
> diff --git a/gcc/ipa-inline-analysis.cc b/gcc/ipa-inline-analysis.cc
> index 24ac4cbafc0..a190cb6501b 100644
> --- a/gcc/ipa-inline-analysis.cc
> +++ b/gcc/ipa-inline-analysis.cc
> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-loop-niter.h"
> #include "tree-ssa-loop.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/ipa-inline-transform.cc b/gcc/ipa-inline-transform.cc
> index a05631a085d..73ae4e68ef3 100644
> --- a/gcc/ipa-inline-transform.cc
> +++ b/gcc/ipa-inline-transform.cc
> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-cfg.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
> index be2ca58c7dd..cc509b0c4a4 100644
> --- a/gcc/ipa-inline.cc
> +++ b/gcc/ipa-inline.cc
> @@ -108,11 +108,12 @@ along with GCC; see the file COPYING3. If not see
> #include "profile.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> #include "ipa-utils.h"
> -#include "sreal.h"
> #include "auto-profile.h"
> #include "builtins.h"
> #include "fibonacci_heap.h"
> diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
> index cec730dfa4b..a5adce8ea39 100644
> --- a/gcc/ipa-modref.cc
> +++ b/gcc/ipa-modref.cc
> @@ -75,6 +75,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-modref-tree.h"
> #include "ipa-modref.h"
> #include "value-range.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "attr-fnspec.h"
> diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
> index 02f71a42237..3e0df6a6f77 100644
> --- a/gcc/ipa-param-manipulation.cc
> +++ b/gcc/ipa-param-manipulation.cc
> @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-phinodes.h"
> #include "cfgexpand.h"
> #include "attribs.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
>
> /* Actual prefixes of different newly synthetized parameters. Keep in sync
> diff --git a/gcc/ipa-predicate.cc b/gcc/ipa-predicate.cc
> index d3b3227b0fe..164aba4a126 100644
> --- a/gcc/ipa-predicate.cc
> +++ b/gcc/ipa-predicate.cc
> @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-vrp.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "real.h"
> diff --git a/gcc/ipa-profile.cc b/gcc/ipa-profile.cc
> index 5e89f677c3e..27f411ce81a 100644
> --- a/gcc/ipa-profile.cc
> +++ b/gcc/ipa-profile.cc
> @@ -55,6 +55,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-inline.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
>
> diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
> index bec0ebd210c..e22c4f78405 100644
> --- a/gcc/ipa-prop.cc
> +++ b/gcc/ipa-prop.cc
> @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimplify-me.h"
> #include "gimple-walk.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-cfg.h"
> #include "tree-dfa.h"
> @@ -4561,7 +4563,7 @@ ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
> ipa_node_params *new_info)
> {
> new_info->descriptors = vec_safe_copy (old_info->descriptors);
> - new_info->lattices = NULL;
> + gcc_assert (new_info->lattices.is_empty ());
> new_info->ipcp_orig_node = old_info->ipcp_orig_node;
> new_info->known_csts = old_info->known_csts.copy ();
> new_info->known_contexts = old_info->known_contexts.copy ();
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 9c78dc9f486..ee3c0006add 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -627,7 +627,7 @@ public:
> vec<ipa_param_descriptor, va_gc> *descriptors;
> /* Pointer to an array of structures describing individual formal
> parameters. */
> - class ipcp_param_lattices * GTY((skip)) lattices;
> + vec<ipcp_param_lattices> GTY((skip)) lattices;
> /* Only for versioned nodes this field would not be NULL,
> it points to the node that IPA cp cloned from. */
> struct cgraph_node * GTY((skip)) ipcp_orig_node;
> @@ -662,7 +662,7 @@ public:
>
> inline
> ipa_node_params::ipa_node_params ()
> -: descriptors (NULL), lattices (NULL), ipcp_orig_node (NULL),
> +: descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL),
> known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
> node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
> node_dead (0), node_within_scc (0), node_is_self_scc (0),
> @@ -673,8 +673,8 @@ ipa_node_params::ipa_node_params ()
> inline
> ipa_node_params::~ipa_node_params ()
> {
> - free (lattices);
> vec_free (descriptors);
> + lattices.release ();
> known_csts.release ();
> known_contexts.release ();
> }
> diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
> index 7e9ece21b22..d285462b6cf 100644
> --- a/gcc/ipa-pure-const.cc
> +++ b/gcc/ipa-pure-const.cc
> @@ -59,6 +59,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ssa.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "symtab-thunks.h"
> diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
> index 8e6aa018a7d..39ad822608b 100644
> --- a/gcc/ipa-split.cc
> +++ b/gcc/ipa-split.cc
> @@ -95,6 +95,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimplify-me.h"
> #include "gimple-walk.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-cfg.h"
> #include "tree-into-ssa.h"
> diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
> index 14c2a344e6d..6d6da408925 100644
> --- a/gcc/ipa-sra.cc
> +++ b/gcc/ipa-sra.cc
> @@ -84,6 +84,8 @@ along with GCC; see the file COPYING3. If not see
> #include "internal-fn.h"
> #include "symtab-clones.h"
> #include "attribs.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
>
> static void ipa_sra_summarize_function (cgraph_node *);
> diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
> index 0ee063c9edd..09db1e04431 100644
> --- a/gcc/ipa-strub.cc
> +++ b/gcc/ipa-strub.cc
> @@ -43,6 +43,8 @@ along with GCC; see the file COPYING3. If not see
> #include "cgraph.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "gimple-fold.h"
> diff --git a/gcc/ipa-utils.cc b/gcc/ipa-utils.cc
> index 1567874882f..3be0ddb8e96 100644
> --- a/gcc/ipa-utils.cc
> +++ b/gcc/ipa-utils.cc
> @@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "tree-eh.h"
> diff --git a/gcc/ipa.cc b/gcc/ipa.cc
> index 82d8c59d660..c453fca5d9b 100644
> --- a/gcc/ipa.cc
> +++ b/gcc/ipa.cc
> @@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "dbgcnt.h"
> diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
> index e54ddf2ca41..2ce94cc3282 100644
> --- a/gcc/lto/lto-common.cc
> +++ b/gcc/lto/lto-common.cc
> @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
> #include "stor-layout.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "common.h"
> #include "debug.h"
> diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
> index 7165747d57e..19f91e5d660 100644
> --- a/gcc/lto/lto-partition.cc
> +++ b/gcc/lto/lto-partition.cc
> @@ -31,10 +31,11 @@ along with GCC; see the file COPYING3. If not see
> #include "lto-streamer.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "lto-partition.h"
> -#include "sreal.h"
>
> vec<ltrans_partition> ltrans_partitions;
>
> diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
> index f7c0623f6b2..91aa2fbddb4 100644
> --- a/gcc/lto/lto.cc
> +++ b/gcc/lto/lto.cc
> @@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
> #include "stor-layout.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "debug.h"
> #include "lto.h"
> diff --git a/gcc/toplev.cc b/gcc/toplev.cc
> index 175d4cd18fa..2cd4096558e 100644
> --- a/gcc/toplev.cc
> +++ b/gcc/toplev.cc
> @@ -74,6 +74,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-reference.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-utils.h"
> #include "gcse.h"
> diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
> index ad3b9b87c9d..f6a5cd0ee6e 100644
> --- a/gcc/tree-ssa-ccp.cc
> +++ b/gcc/tree-ssa-ccp.cc
> @@ -150,6 +150,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "internal-fn.h"
>
> diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
> index 8792cd07901..97c6d5895f0 100644
> --- a/gcc/tree-ssa-sccvn.cc
> +++ b/gcc/tree-ssa-sccvn.cc
> @@ -76,6 +76,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-sccvn.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "target.h"
>
> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> index 978025b51de..b0f21e3aa60 100644
> --- a/gcc/tree-vrp.cc
> +++ b/gcc/tree-vrp.cc
> @@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see
> #include "cgraph.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "attribs.h"
>
>
--
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] ipa: Convert lattices from pure array to vector (PR 113476)
2024-02-19 15:04 ` [PATCH] ipa: Convert lattices from pure array to vector " Martin Jambor
2024-02-20 7:11 ` Richard Biener
@ 2024-02-20 10:20 ` Jan Hubicka
1 sibling, 0 replies; 9+ messages in thread
From: Jan Hubicka @ 2024-02-20 10:20 UTC (permalink / raw)
To: Martin Jambor; +Cc: GCC Patches, Richard Biener
> On Tue, Feb 13 2024, Martin Jambor wrote:
> > On Mon, Feb 12 2024, Jan Hubicka wrote:
> >>> Believe it or not, even though I have re-worked the internals of the
> >>> lattices completely, the array itself is older than my involvement with
> >>> GCC (or at least with ipa-cp.c ;-).
> >>>
> >>> So it being an array and not a vector is historical coincidence, as far
> >>> as I am concerned :-). But that may be the reason, or because vector
> >>> macros at that time looked scary, or perhaps the initialization by
> >>> XCNEWVEC zeroing everything out was considered attractive (I kind of
> >>> like that but constructors would probably be cleaner), I don't know.
> >>
> >> If your class is no longer a POD, then the clearing before construcion
> >> is dead and GCC may optimize it out. So fixing this may solve some
> >> surprised in foreseable future when we will try to compile older GCC's
> >> with newer ones.
> >>
> >
> > That's a good point. I'll prepare a patch converting the whole thing to
> > use constructors and vectors.
> >
>
> In PR 113476 we have discovered that ipcp_param_lattices is no longer
> a POD and should be destructed. In a follow-up discussion it
> transpired that their initialization done by memsetting their backing
> memory to zero is also invalid because now any write there before
> construction can be considered dead. Plus that having them in an
> array is a little bit old-school and does not get the extra checking
> offered by vector along with automatic construction and destruction
> when necessary.
>
> So this patch converts the array to a vector. That however means that
> ipcp_param_lattices cannot be just a forward declared type but must be
> known to all code that deal with ipa_node_params and thus to all code
> that includes ipa-prop.h. Therefore I have moved ipcp_param_lattices
> and the type it depends on to a new header ipa-cp.h which now
> ipa-prop.h depends on. Because we have the (IMHO not a very wise)
> rule that headers don't include what they need themselves, I had to
> add inclusions of ipa-cp.h and sreal.h (on which it depends) to very
> many files, which made the patch rather ugly.
>
> Bootstrapped and tested on x86_64-linux. I also had it checked by our
> script which builds more than a hundred of cross-compilers, so other
> targets are hopefully also fine.
>
> OK for master?
>
> Martin
>
>
> gcc/lto/ChangeLog:
>
> 2024-02-16 Martin Jambor <mjambor@suse.cz>
>
> * lto-common.cc: Include sreal.h and ipa-cp.h.
> * lto-partition.cc: Include ipa-cp.h, move inclusion of sreal higher.
> * lto.cc: Include sreal.h and ipa-cp.h.
>
> gcc/ChangeLog:
>
> 2024-02-16 Martin Jambor <mjambor@suse.cz>
>
> * ipa-prop.h (ipa_node_params): Convert lattices to a vector, adjust
> initializers in the contructor.
> (ipa_node_params::~ipa_node_params): Release lattices as a vector.
> * ipa-cp.h: New file.
> * ipa-cp.cc: Include sreal.h and ipa-cp.h.
> (ipcp_value_source): Move to ipa-cp.h.
> (ipcp_value_base): Likewise.
> (ipcp_value): Likewise.
> (ipcp_lattice): Likewise.
> (ipcp_agg_lattice): Likewise.
> (ipcp_bits_lattice): Likewise.
> (ipcp_vr_lattice): Likewise.
> (ipcp_param_lattices): Likewise.
> (ipa_get_parm_lattices): Remove assert latticess is non-NULL).
> (ipa_value_from_jfunc): Adjust a check for empty lattices.
> (ipa_context_from_jfunc): Likewise.
> (ipa_agg_value_from_jfunc): Likewise.
> (merge_agg_lats_step): Do not memset new aggregate lattices to zero.
> (ipcp_propagate_stage): Allocate lattices in a vector as opposed to
> just in contiguous memory.
> (ipcp_store_vr_results): Adjust a check for empty lattices.
> * auto-profile.cc: Include sreal.h and ipa-cp.h.
> * cgraph.cc: Likewise.
> * cgraphclones.cc: Likewise.
> * cgraphunit.cc: Likewise.
> * config/aarch64/aarch64.cc: Likewise.
> * config/i386/i386-builtins.cc: Likewise.
> * config/i386/i386-expand.cc: Likewise.
> * config/i386/i386-features.cc: Likewise.
> * config/i386/i386-options.cc: Likewise.
> * config/i386/i386.cc: Likewise.
> * config/rs6000/rs6000.cc: Likewise.
> * config/s390/s390.cc: Likewise.
> * gengtype.cc (open_base_files): Added sreal.h and ipa-cp.h to the
> files to be included in gtype-desc.cc.
> * gimple-range-fold.cc: Include sreal.h and ipa-cp.h.
> * ipa-devirt.cc: Likewise.
> * ipa-fnsummary.cc: Likewise.
> * ipa-icf.cc: Likewise.
> * ipa-inline-analysis.cc: Likewise.
> * ipa-inline-transform.cc: Likewise.
> * ipa-inline.cc: Include ipa-cp.h, move inclusion of sreal.h higher.
> * ipa-modref.cc: Include sreal.h and ipa-cp.h.
> * ipa-param-manipulation.cc: Likewise.
> * ipa-predicate.cc: Likewise.
> * ipa-profile.cc: Likewise.
> * ipa-prop.cc: Likewise.
> (ipa_node_params_t::duplicate): Assert new lattices remain empty
> instead of setting them to NULL.
> * ipa-pure-const.cc: Include sreal.h and ipa-cp.h.
> * ipa-split.cc: Likewise.
> * ipa-sra.cc: Likewise.
> * ipa-strub.cc: Likewise.
> * ipa-utils.cc: Likewise.
> * ipa.cc: Likewise.
> * toplev.cc: Likewise.
> * tree-ssa-ccp.cc: Likewise.
> * tree-ssa-sccvn.cc: Likewise.
> * tree-vrp.cc: Likewise.
It is sad that in order to get one forward-declaration solved we need to
add so many #includes.
I hope eventually we will get headers independently includable again -
especially for new developers it is a noticeable blocker that they have to walk
the dependency chain by trial&error.
OK,
thanks!
> ---
> gcc/auto-profile.cc | 2 +
> gcc/cgraph.cc | 2 +
> gcc/cgraphclones.cc | 2 +
> gcc/cgraphunit.cc | 2 +
> gcc/config/aarch64/aarch64.cc | 2 +
> gcc/config/i386/i386-builtins.cc | 2 +
> gcc/config/i386/i386-expand.cc | 2 +
> gcc/config/i386/i386-features.cc | 2 +
> gcc/config/i386/i386-options.cc | 2 +
> gcc/config/i386/i386.cc | 2 +
> gcc/config/rs6000/rs6000.cc | 2 +
> gcc/config/s390/s390.cc | 2 +
> gcc/gengtype.cc | 6 +-
> gcc/gimple-range-fold.cc | 2 +
> gcc/ipa-cp.cc | 283 +-----------------------------
> gcc/ipa-cp.h | 292 +++++++++++++++++++++++++++++++
> gcc/ipa-devirt.cc | 2 +
> gcc/ipa-fnsummary.cc | 2 +
> gcc/ipa-icf.cc | 2 +
> gcc/ipa-inline-analysis.cc | 2 +
> gcc/ipa-inline-transform.cc | 2 +
> gcc/ipa-inline.cc | 3 +-
> gcc/ipa-modref.cc | 2 +
> gcc/ipa-param-manipulation.cc | 2 +
> gcc/ipa-predicate.cc | 2 +
> gcc/ipa-profile.cc | 2 +
> gcc/ipa-prop.cc | 4 +-
> gcc/ipa-prop.h | 6 +-
> gcc/ipa-pure-const.cc | 2 +
> gcc/ipa-split.cc | 2 +
> gcc/ipa-sra.cc | 2 +
> gcc/ipa-strub.cc | 2 +
> gcc/ipa-utils.cc | 2 +
> gcc/ipa.cc | 2 +
> gcc/lto/lto-common.cc | 2 +
> gcc/lto/lto-partition.cc | 3 +-
> gcc/lto/lto.cc | 2 +
> gcc/toplev.cc | 2 +
> gcc/tree-ssa-ccp.cc | 2 +
> gcc/tree-ssa-sccvn.cc | 2 +
> gcc/tree-vrp.cc | 2 +
> 41 files changed, 380 insertions(+), 285 deletions(-)
> create mode 100644 gcc/ipa-cp.h
>
> diff --git a/gcc/auto-profile.cc b/gcc/auto-profile.cc
> index 63d0c3dc36d..e5407d32fbb 100644
> --- a/gcc/auto-profile.cc
> +++ b/gcc/auto-profile.cc
> @@ -42,6 +42,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-iterator.h"
> #include "value-prof.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/cgraph.cc b/gcc/cgraph.cc
> index 0ac8f73204b..473d8410bc9 100644
> --- a/gcc/cgraph.cc
> +++ b/gcc/cgraph.cc
> @@ -51,6 +51,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "cfgloop.h"
> diff --git a/gcc/cgraphclones.cc b/gcc/cgraphclones.cc
> index 6d7bc402a29..4fff6873a36 100644
> --- a/gcc/cgraphclones.cc
> +++ b/gcc/cgraphclones.cc
> @@ -84,6 +84,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "symtab-thunks.h"
> diff --git a/gcc/cgraphunit.cc b/gcc/cgraphunit.cc
> index 5c405258ec3..d200166f7e9 100644
> --- a/gcc/cgraphunit.cc
> +++ b/gcc/cgraphunit.cc
> @@ -191,6 +191,8 @@ along with GCC; see the file COPYING3. If not see
> #include "debug.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "gimple-pretty-print.h"
> #include "plugin.h"
> diff --git a/gcc/config/aarch64/aarch64.cc b/gcc/config/aarch64/aarch64.cc
> index 32eae49d4e9..29c899157e1 100644
> --- a/gcc/config/aarch64/aarch64.cc
> +++ b/gcc/config/aarch64/aarch64.cc
> @@ -91,6 +91,8 @@
> #include "tree-pass.h"
> #include "cfgbuild.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "hash-map.h"
> diff --git a/gcc/config/i386/i386-builtins.cc b/gcc/config/i386/i386-builtins.cc
> index d5b83e9d90f..8b79d335c88 100644
> --- a/gcc/config/i386/i386-builtins.cc
> +++ b/gcc/config/i386/i386-builtins.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc
> index 50f9fe2c0d7..a4d3369f01b 100644
> --- a/gcc/config/i386/i386-expand.cc
> +++ b/gcc/config/i386/i386-expand.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-features.cc b/gcc/config/i386/i386-features.cc
> index f1b1cf24233..d3b9ae81025 100644
> --- a/gcc/config/i386/i386-features.cc
> +++ b/gcc/config/i386/i386-features.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
> index 8f5ce817630..93a01146db7 100644
> --- a/gcc/config/i386/i386-options.cc
> +++ b/gcc/config/i386/i386-options.cc
> @@ -82,6 +82,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/i386/i386.cc b/gcc/config/i386/i386.cc
> index dbb26e8f76a..53db72e95f9 100644
> --- a/gcc/config/i386/i386.cc
> +++ b/gcc/config/i386/i386.cc
> @@ -86,6 +86,8 @@ along with GCC; see the file COPYING3. If not see
> #include "intl.h"
> #include "ifcvt.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "wide-int-bitmask.h"
> diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc
> index 5d975dab921..a2a679d8eed 100644
> --- a/gcc/config/rs6000/rs6000.cc
> +++ b/gcc/config/rs6000/rs6000.cc
> @@ -72,6 +72,8 @@
> #include "context.h"
> #include "tree-pass.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "except.h"
> diff --git a/gcc/config/s390/s390.cc b/gcc/config/s390/s390.cc
> index f182c26e78b..c857b2028f2 100644
> --- a/gcc/config/s390/s390.cc
> +++ b/gcc/config/s390/s390.cc
> @@ -83,6 +83,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tm-constrs.h"
> #include "tree-vrp.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "sched-int.h"
> diff --git a/gcc/gengtype.cc b/gcc/gengtype.cc
> index b1db727b958..a72249eacf8 100644
> --- a/gcc/gengtype.cc
> +++ b/gcc/gengtype.cc
> @@ -1713,9 +1713,9 @@ open_base_files (void)
> "tree-dfa.h", "tree-ssa.h", "reload.h", "cpplib.h", "tree-chrec.h",
> "except.h", "output.h", "cfgloop.h", "target.h", "lto-streamer.h",
> "target-globals.h", "ipa-ref.h", "cgraph.h", "symbol-summary.h",
> - "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h", "omp-general.h",
> - "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h", "symtab-thunks.h",
> - "symtab-clones.h", "diagnostic-spec.h", "ctfc.h",
> + "sreal.h", "ipa-cp.h", "ipa-prop.h", "ipa-fnsummary.h", "dwarf2out.h",
> + "omp-general.h", "omp-offload.h", "ipa-modref-tree.h", "ipa-modref.h",
> + "symtab-thunks.h", "symtab-clones.h", "diagnostic-spec.h", "ctfc.h",
> NULL
> };
> const char *const *ifp;
> diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc
> index 0cc53199963..9c4ad1ee7b9 100644
> --- a/gcc/gimple-range-fold.cc
> +++ b/gcc/gimple-range-fold.cc
> @@ -48,6 +48,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> // Construct a fur_source, and set the m_query field.
>
> diff --git a/gcc/ipa-cp.cc b/gcc/ipa-cp.cc
> index e85477df32d..2a1da631e9c 100644
> --- a/gcc/ipa-cp.cc
> +++ b/gcc/ipa-cp.cc
> @@ -109,6 +109,7 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-expr.h"
> #include "gimple.h"
> #include "predict.h"
> +#include "sreal.h"
> #include "alloc-pool.h"
> #include "tree-pass.h"
> #include "cgraph.h"
> @@ -118,6 +119,7 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-fold.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-pretty-print.h"
> #include "tree-inline.h"
> @@ -130,274 +132,6 @@ along with GCC; see the file COPYING3. If not see
> #include "symtab-clones.h"
> #include "gimple-range.h"
>
> -template <typename valtype> class ipcp_value;
> -
> -/* Describes a particular source for an IPA-CP value. */
> -
> -template <typename valtype>
> -struct ipcp_value_source
> -{
> -public:
> - /* Aggregate offset of the source, negative if the source is scalar value of
> - the argument itself. */
> - HOST_WIDE_INT offset;
> - /* The incoming edge that brought the value. */
> - cgraph_edge *cs;
> - /* If the jump function that resulted into his value was a pass-through or an
> - ancestor, this is the ipcp_value of the caller from which the described
> - value has been derived. Otherwise it is NULL. */
> - ipcp_value<valtype> *val;
> - /* Next pointer in a linked list of sources of a value. */
> - ipcp_value_source *next;
> - /* If the jump function that resulted into his value was a pass-through or an
> - ancestor, this is the index of the parameter of the caller the jump
> - function references. */
> - int index;
> -};
> -
> -/* Common ancestor for all ipcp_value instantiations. */
> -
> -class ipcp_value_base
> -{
> -public:
> - /* Time benefit and that specializing the function for this value would bring
> - about in this function alone. */
> - sreal local_time_benefit;
> - /* Time benefit that specializing the function for this value can bring about
> - in it's callees. */
> - sreal prop_time_benefit;
> - /* Size cost that specializing the function for this value would bring about
> - in this function alone. */
> - int local_size_cost;
> - /* Size cost that specializing the function for this value can bring about in
> - it's callees. */
> - int prop_size_cost;
> -
> - ipcp_value_base ()
> - : local_time_benefit (0), prop_time_benefit (0),
> - local_size_cost (0), prop_size_cost (0) {}
> -};
> -
> -/* Describes one particular value stored in struct ipcp_lattice. */
> -
> -template <typename valtype>
> -class ipcp_value : public ipcp_value_base
> -{
> -public:
> - /* The actual value for the given parameter. */
> - valtype value;
> - /* The list of sources from which this value originates. */
> - ipcp_value_source <valtype> *sources = nullptr;
> - /* Next pointers in a linked list of all values in a lattice. */
> - ipcp_value *next = nullptr;
> - /* Next pointers in a linked list of values in a strongly connected component
> - of values. */
> - ipcp_value *scc_next = nullptr;
> - /* Next pointers in a linked list of SCCs of values sorted topologically
> - according their sources. */
> - ipcp_value *topo_next = nullptr;
> - /* A specialized node created for this value, NULL if none has been (so far)
> - created. */
> - cgraph_node *spec_node = nullptr;
> - /* Depth first search number and low link for topological sorting of
> - values. */
> - int dfs = 0;
> - int low_link = 0;
> - /* SCC number to identify values which recursively feed into each other.
> - Values in the same SCC have the same SCC number. */
> - int scc_no = 0;
> - /* Non zero if the value is generated from another value in the same lattice
> - for a self-recursive call, the actual number is how many times the
> - operation has been performed. In the unlikely event of the value being
> - present in two chains fo self-recursive value generation chains, it is the
> - maximum. */
> - unsigned self_recursion_generated_level = 0;
> - /* True if this value is currently on the topo-sort stack. */
> - bool on_stack = false;
> -
> - void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
> - HOST_WIDE_INT offset);
> -
> - /* Return true if both THIS value and O feed into each other. */
> -
> - bool same_scc (const ipcp_value<valtype> *o)
> - {
> - return o->scc_no == scc_no;
> - }
> -
> -/* Return true, if a this value has been generated for a self-recursive call as
> - a result of an arithmetic pass-through jump-function acting on a value in
> - the same lattice function. */
> -
> - bool self_recursion_generated_p ()
> - {
> - return self_recursion_generated_level > 0;
> - }
> -};
> -
> -/* Lattice describing potential values of a formal parameter of a function, or
> - a part of an aggregate. TOP is represented by a lattice with zero values
> - and with contains_variable and bottom flags cleared. BOTTOM is represented
> - by a lattice with the bottom flag set. In that case, values and
> - contains_variable flag should be disregarded. */
> -
> -template <typename valtype>
> -struct ipcp_lattice
> -{
> -public:
> - /* The list of known values and types in this lattice. Note that values are
> - not deallocated if a lattice is set to bottom because there may be value
> - sources referencing them. */
> - ipcp_value<valtype> *values;
> - /* Number of known values and types in this lattice. */
> - int values_count;
> - /* The lattice contains a variable component (in addition to values). */
> - bool contains_variable;
> - /* The value of the lattice is bottom (i.e. variable and unusable for any
> - propagation). */
> - bool bottom;
> -
> - inline bool is_single_const ();
> - inline bool set_to_bottom ();
> - inline bool set_contains_variable ();
> - bool add_value (valtype newval, cgraph_edge *cs,
> - ipcp_value<valtype> *src_val = NULL,
> - int src_idx = 0, HOST_WIDE_INT offset = -1,
> - ipcp_value<valtype> **val_p = NULL,
> - unsigned same_lat_gen_level = 0);
> - void print (FILE * f, bool dump_sources, bool dump_benefits);
> -};
> -
> -/* Lattice of tree values with an offset to describe a part of an
> - aggregate. */
> -
> -struct ipcp_agg_lattice : public ipcp_lattice<tree>
> -{
> -public:
> - /* Offset that is being described by this lattice. */
> - HOST_WIDE_INT offset;
> - /* Size so that we don't have to re-compute it every time we traverse the
> - list. Must correspond to TYPE_SIZE of all lat values. */
> - HOST_WIDE_INT size;
> - /* Next element of the linked list. */
> - struct ipcp_agg_lattice *next;
> -};
> -
> -/* Lattice of known bits, only capable of holding one value.
> - Bitwise constant propagation propagates which bits of a
> - value are constant.
> - For eg:
> - int f(int x)
> - {
> - return some_op (x);
> - }
> -
> - int f1(int y)
> - {
> - if (cond)
> - return f (y & 0xff);
> - else
> - return f (y & 0xf);
> - }
> -
> - In the above case, the param 'x' will always have all
> - the bits (except the bits in lsb) set to 0.
> - Hence the mask of 'x' would be 0xff. The mask
> - reflects that the bits in lsb are unknown.
> - The actual propagated value is given by m_value & ~m_mask. */
> -
> -class ipcp_bits_lattice
> -{
> -public:
> - bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
> - bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
> - bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
> - bool set_to_bottom ();
> - bool set_to_constant (widest_int, widest_int);
> - bool known_nonzero_p () const;
> -
> - widest_int get_value () const { return m_value; }
> - widest_int get_mask () const { return m_mask; }
> -
> - bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
> - enum tree_code, tree, bool);
> -
> - bool meet_with (widest_int, widest_int, unsigned);
> -
> - void print (FILE *);
> -
> -private:
> - enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
> -
> - /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
> - If a bit in mask is set to 0, then the corresponding bit in
> - value is known to be constant. */
> - widest_int m_value, m_mask;
> -
> - bool meet_with_1 (widest_int, widest_int, unsigned, bool);
> - void get_value_and_mask (tree, widest_int *, widest_int *);
> -};
> -
> -/* Lattice of value ranges. */
> -
> -class ipcp_vr_lattice
> -{
> -public:
> - Value_Range m_vr;
> -
> - inline bool bottom_p () const;
> - inline bool top_p () const;
> - inline bool set_to_bottom ();
> - bool meet_with (const vrange &p_vr);
> - bool meet_with (const ipcp_vr_lattice &other);
> - void init (tree type);
> - void print (FILE * f);
> -
> -private:
> - bool meet_with_1 (const vrange &other_vr);
> -};
> -
> -inline void
> -ipcp_vr_lattice::init (tree type)
> -{
> - if (type)
> - m_vr.set_type (type);
> -
> - // Otherwise m_vr will default to unsupported_range.
> -}
> -
> -/* Structure containing lattices for a parameter itself and for pieces of
> - aggregates that are passed in the parameter or by a reference in a parameter
> - plus some other useful flags. */
> -
> -class ipcp_param_lattices
> -{
> -public:
> - /* Lattice describing the value of the parameter itself. */
> - ipcp_lattice<tree> itself;
> - /* Lattice describing the polymorphic contexts of a parameter. */
> - ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
> - /* Lattices describing aggregate parts. */
> - ipcp_agg_lattice *aggs;
> - /* Lattice describing known bits. */
> - ipcp_bits_lattice bits_lattice;
> - /* Lattice describing value range. */
> - ipcp_vr_lattice m_value_range;
> - /* Number of aggregate lattices */
> - int aggs_count;
> - /* True if aggregate data were passed by reference (as opposed to by
> - value). */
> - bool aggs_by_ref;
> - /* All aggregate lattices contain a variable component (in addition to
> - values). */
> - bool aggs_contain_variable;
> - /* The value of all aggregate lattices is bottom (i.e. variable and unusable
> - for any propagation). */
> - bool aggs_bottom;
> -
> - /* There is a virtual call based on this parameter. */
> - bool virt_call;
> -};
>
> /* Allocation pools for values and their sources in ipa-cp. */
>
> @@ -431,7 +165,6 @@ ipa_get_parm_lattices (class ipa_node_params *info, int i)
> {
> gcc_assert (i >= 0 && i < ipa_get_param_count (info));
> gcc_checking_assert (!info->ipcp_orig_node);
> - gcc_checking_assert (info->lattices);
> return &(info->lattices[i]);
> }
>
> @@ -1821,7 +1554,7 @@ ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
> {
> ipcp_lattice<tree> *lat;
>
> - if (!info->lattices
> + if (info->lattices.is_empty ()
> || idx >= ipa_get_param_count (info))
> return NULL_TREE;
> lat = ipa_get_scalar_lat (info, idx);
> @@ -1884,7 +1617,7 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
> }
> else
> {
> - if (!info->lattices
> + if (info->lattices.is_empty ()
> || srcidx >= ipa_get_param_count (info))
> return ctx;
> ipcp_lattice<ipa_polymorphic_call_context> *lat;
> @@ -2056,7 +1789,7 @@ ipa_agg_value_from_jfunc (ipa_node_params *info, cgraph_node *node,
> item->value.load_agg.by_ref);
> }
> }
> - else if (info->lattices)
> + else if (!info->lattices.is_empty ())
> {
> class ipcp_param_lattices *src_plats
> = ipa_get_parm_lattices (info, src_idx);
> @@ -2937,7 +2670,6 @@ merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
> return false;
> dest_plats->aggs_count++;
> new_al = ipcp_agg_lattice_pool.allocate ();
> - memset (new_al, 0, sizeof (*new_al));
>
> new_al->offset = offset;
> new_al->size = val_size;
> @@ -4295,8 +4027,7 @@ ipcp_propagate_stage (class ipa_topo_info *topo)
> determine_versionability (node, info);
>
> unsigned nlattices = ipa_get_param_count (info);
> - void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
> - info->lattices = new (chunk) ipcp_param_lattices[nlattices];
> + info->lattices.safe_grow_cleared (nlattices, true);
> initialize_node_lattices (node);
> }
> ipa_size_summary *s = ipa_size_summaries->get (node);
> @@ -6568,7 +6299,7 @@ ipcp_store_vr_results (void)
>
> if (info->ipcp_orig_node)
> info = ipa_node_params_sum->get (info->ipcp_orig_node);
> - if (!info->lattices)
> + if (info->lattices.is_empty ())
> /* Newly expanded artificial thunks do not have lattices. */
> continue;
>
> diff --git a/gcc/ipa-cp.h b/gcc/ipa-cp.h
> new file mode 100644
> index 00000000000..0b3cfe4b526
> --- /dev/null
> +++ b/gcc/ipa-cp.h
> @@ -0,0 +1,292 @@
> +/* Interprocedural constant propagation
> + Copyright (C) 2024 Free Software Foundation, Inc.
> +
> +This file is part of GCC.
> +
> +GCC is free software; you can redistribute it and/or modify it under
> +the terms of the GNU General Public License as published by the Free
> +Software Foundation; either version 3, or (at your option) any later
> +version.
> +
> +GCC is distributed in the hope that it will be useful, but WITHOUT ANY
> +WARRANTY; without even the implied warranty of MERCHANTABILITY or
> +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> +for more details.
> +
> +You should have received a copy of the GNU General Public License
> +along with GCC; see the file COPYING3. If not see
> +<http://www.gnu.org/licenses/>. */
> +
> +#ifndef IPA_CP_H
> +#define IPA_CP_H
> +
> +template <typename valtype> class ipcp_value;
> +
> +/* Describes a particular source for an IPA-CP value. */
> +
> +template <typename valtype>
> +struct ipcp_value_source
> +{
> +public:
> + /* Aggregate offset of the source, negative if the source is scalar value of
> + the argument itself. */
> + HOST_WIDE_INT offset;
> + /* The incoming edge that brought the value. */
> + cgraph_edge *cs;
> + /* If the jump function that resulted into his value was a pass-through or an
> + ancestor, this is the ipcp_value of the caller from which the described
> + value has been derived. Otherwise it is NULL. */
> + ipcp_value<valtype> *val;
> + /* Next pointer in a linked list of sources of a value. */
> + ipcp_value_source *next;
> + /* If the jump function that resulted into his value was a pass-through or an
> + ancestor, this is the index of the parameter of the caller the jump
> + function references. */
> + int index;
> +};
> +
> +/* Common ancestor for all ipcp_value instantiations. */
> +
> +class ipcp_value_base
> +{
> +public:
> + /* Time benefit and that specializing the function for this value would bring
> + about in this function alone. */
> + sreal local_time_benefit = 0;
> + /* Time benefit that specializing the function for this value can bring about
> + in it's callees. */
> + sreal prop_time_benefit = 0;
> + /* Size cost that specializing the function for this value would bring about
> + in this function alone. */
> + int local_size_cost = 0;
> + /* Size cost that specializing the function for this value can bring about in
> + it's callees. */
> + int prop_size_cost = 0;
> +};
> +
> +/* Describes one particular value stored in struct ipcp_lattice. */
> +
> +template <typename valtype>
> +class ipcp_value : public ipcp_value_base
> +{
> +public:
> + /* The actual value for the given parameter. */
> + valtype value;
> + /* The list of sources from which this value originates. */
> + ipcp_value_source <valtype> *sources = nullptr;
> + /* Next pointers in a linked list of all values in a lattice. */
> + ipcp_value *next = nullptr;
> + /* Next pointers in a linked list of values in a strongly connected component
> + of values. */
> + ipcp_value *scc_next = nullptr;
> + /* Next pointers in a linked list of SCCs of values sorted topologically
> + according their sources. */
> + ipcp_value *topo_next = nullptr;
> + /* A specialized node created for this value, NULL if none has been (so far)
> + created. */
> + cgraph_node *spec_node = nullptr;
> + /* Depth first search number and low link for topological sorting of
> + values. */
> + int dfs = 0;
> + int low_link = 0;
> + /* SCC number to identify values which recursively feed into each other.
> + Values in the same SCC have the same SCC number. */
> + int scc_no = 0;
> + /* Non zero if the value is generated from another value in the same lattice
> + for a self-recursive call, the actual number is how many times the
> + operation has been performed. In the unlikely event of the value being
> + present in two chains fo self-recursive value generation chains, it is the
> + maximum. */
> + unsigned self_recursion_generated_level = 0;
> + /* True if this value is currently on the topo-sort stack. */
> + bool on_stack = false;
> +
> + void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
> + HOST_WIDE_INT offset);
> +
> + /* Return true if both THIS value and O feed into each other. */
> +
> + bool same_scc (const ipcp_value<valtype> *o)
> + {
> + return o->scc_no == scc_no;
> + }
> +
> +/* Return true, if a this value has been generated for a self-recursive call as
> + a result of an arithmetic pass-through jump-function acting on a value in
> + the same lattice function. */
> +
> + bool self_recursion_generated_p ()
> + {
> + return self_recursion_generated_level > 0;
> + }
> +};
> +
> +/* Lattice describing potential values of a formal parameter of a function, or
> + a part of an aggregate. TOP is represented by a lattice with zero values
> + and with contains_variable and bottom flags cleared. BOTTOM is represented
> + by a lattice with the bottom flag set. In that case, values and
> + contains_variable flag should be disregarded. */
> +
> +template <typename valtype>
> +struct ipcp_lattice
> +{
> +public:
> + /* The list of known values and types in this lattice. Note that values are
> + not deallocated if a lattice is set to bottom because there may be value
> + sources referencing them. */
> + ipcp_value<valtype> *values = nullptr;
> + /* Number of known values and types in this lattice. */
> + int values_count = 0;
> + /* The lattice contains a variable component (in addition to values). */
> + bool contains_variable = false;
> + /* The value of the lattice is bottom (i.e. variable and unusable for any
> + propagation). */
> + bool bottom = false;
> +
> + inline bool is_single_const ();
> + inline bool set_to_bottom ();
> + inline bool set_contains_variable ();
> + bool add_value (valtype newval, cgraph_edge *cs,
> + ipcp_value<valtype> *src_val = NULL,
> + int src_idx = 0, HOST_WIDE_INT offset = -1,
> + ipcp_value<valtype> **val_p = NULL,
> + unsigned same_lat_gen_level = 0);
> + void print (FILE * f, bool dump_sources, bool dump_benefits);
> +};
> +
> +/* Lattice of tree values with an offset to describe a part of an
> + aggregate. */
> +
> +struct ipcp_agg_lattice : public ipcp_lattice<tree>
> +{
> +public:
> + /* Offset that is being described by this lattice. */
> + HOST_WIDE_INT offset = 0;
> + /* Size so that we don't have to re-compute it every time we traverse the
> + list. Must correspond to TYPE_SIZE of all lat values. */
> + HOST_WIDE_INT size = 0;
> + /* Next element of the linked list. */
> + struct ipcp_agg_lattice *next = nullptr;
> +};
> +
> +/* Lattice of known bits, only capable of holding one value.
> + Bitwise constant propagation propagates which bits of a
> + value are constant.
> + For eg:
> + int f(int x)
> + {
> + return some_op (x);
> + }
> +
> + int f1(int y)
> + {
> + if (cond)
> + return f (y & 0xff);
> + else
> + return f (y & 0xf);
> + }
> +
> + In the above case, the param 'x' will always have all
> + the bits (except the bits in lsb) set to 0.
> + Hence the mask of 'x' would be 0xff. The mask
> + reflects that the bits in lsb are unknown.
> + The actual propagated value is given by m_value & ~m_mask. */
> +
> +class ipcp_bits_lattice
> +{
> +public:
> + bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
> + bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
> + bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
> + bool set_to_bottom ();
> + bool set_to_constant (widest_int, widest_int);
> + bool known_nonzero_p () const;
> +
> + widest_int get_value () const { return m_value; }
> + widest_int get_mask () const { return m_mask; }
> +
> + bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
> + enum tree_code, tree, bool);
> +
> + bool meet_with (widest_int, widest_int, unsigned);
> +
> + void print (FILE *);
> +
> +private:
> + enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING }
> + m_lattice_val = IPA_BITS_UNDEFINED;
> +
> + /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
> + If a bit in mask is set to 0, then the corresponding bit in
> + value is known to be constant. */
> + widest_int m_value, m_mask;
> +
> + bool meet_with_1 (widest_int, widest_int, unsigned, bool);
> + void get_value_and_mask (tree, widest_int *, widest_int *);
> +};
> +
> +/* Lattice of value ranges. */
> +
> +class ipcp_vr_lattice
> +{
> +public:
> + Value_Range m_vr;
> +
> + inline bool bottom_p () const;
> + inline bool top_p () const;
> + inline bool set_to_bottom ();
> + bool meet_with (const vrange &p_vr);
> + bool meet_with (const ipcp_vr_lattice &other);
> + void init (tree type);
> + void print (FILE * f);
> +
> +private:
> + bool meet_with_1 (const vrange &other_vr);
> +};
> +
> +inline void
> +ipcp_vr_lattice::init (tree type)
> +{
> + if (type)
> + m_vr.set_type (type);
> +
> + // Otherwise m_vr will default to unsupported_range.
> +}
> +
> +/* Structure containing lattices for a parameter itself and for pieces of
> + aggregates that are passed in the parameter or by a reference in a parameter
> + plus some other useful flags.
> +
> + Even after construction, m_value_range parts still need to be initialized
> + with the type they represent with the init method. */
> +
> +class ipcp_param_lattices
> +{
> +public:
> + /* Lattice describing the value of the parameter itself. */
> + ipcp_lattice<tree> itself;
> + /* Lattice describing the polymorphic contexts of a parameter. */
> + ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
> + /* Lattices describing aggregate parts. */
> + ipcp_agg_lattice *aggs = nullptr;
> + /* Lattice describing known bits. */
> + ipcp_bits_lattice bits_lattice;
> + /* Lattice describing value range. */
> + ipcp_vr_lattice m_value_range;
> + /* Number of aggregate lattices */
> + int aggs_count = 0;
> + /* True if aggregate data were passed by reference (as opposed to by
> + value). */
> + bool aggs_by_ref = false;
> + /* All aggregate lattices contain a variable component (in addition to
> + values). */
> + bool aggs_contain_variable = false;
> + /* The value of all aggregate lattices is bottom (i.e. variable and unusable
> + for any propagation). */
> + bool aggs_bottom = false;
> +
> + /* There is a virtual call based on this parameter. */
> + bool virt_call = false;
> +};
> +
> +#endif /* IPA_CP_H */
> diff --git a/gcc/ipa-devirt.cc b/gcc/ipa-devirt.cc
> index caf8548fbc9..a7ce434bffb 100644
> --- a/gcc/ipa-devirt.cc
> +++ b/gcc/ipa-devirt.cc
> @@ -124,6 +124,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-fold.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "demangle.h"
> diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
> index 74c9b4e1d1e..dff40cd8aa5 100644
> --- a/gcc/ipa-fnsummary.cc
> +++ b/gcc/ipa-fnsummary.cc
> @@ -75,6 +75,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-loop-niter.h"
> #include "tree-ssa-loop.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "cfgloop.h"
> diff --git a/gcc/ipa-icf.cc b/gcc/ipa-icf.cc
> index f56891325f3..5d5a42f9c6c 100644
> --- a/gcc/ipa-icf.cc
> +++ b/gcc/ipa-icf.cc
> @@ -73,6 +73,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimple-iterator.h"
> #include "tree-cfg.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "except.h"
> diff --git a/gcc/ipa-inline-analysis.cc b/gcc/ipa-inline-analysis.cc
> index 24ac4cbafc0..a190cb6501b 100644
> --- a/gcc/ipa-inline-analysis.cc
> +++ b/gcc/ipa-inline-analysis.cc
> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-loop-niter.h"
> #include "tree-ssa-loop.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/ipa-inline-transform.cc b/gcc/ipa-inline-transform.cc
> index a05631a085d..73ae4e68ef3 100644
> --- a/gcc/ipa-inline-transform.cc
> +++ b/gcc/ipa-inline-transform.cc
> @@ -40,6 +40,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-cfg.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> diff --git a/gcc/ipa-inline.cc b/gcc/ipa-inline.cc
> index be2ca58c7dd..cc509b0c4a4 100644
> --- a/gcc/ipa-inline.cc
> +++ b/gcc/ipa-inline.cc
> @@ -108,11 +108,12 @@ along with GCC; see the file COPYING3. If not see
> #include "profile.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "ipa-inline.h"
> #include "ipa-utils.h"
> -#include "sreal.h"
> #include "auto-profile.h"
> #include "builtins.h"
> #include "fibonacci_heap.h"
> diff --git a/gcc/ipa-modref.cc b/gcc/ipa-modref.cc
> index cec730dfa4b..a5adce8ea39 100644
> --- a/gcc/ipa-modref.cc
> +++ b/gcc/ipa-modref.cc
> @@ -75,6 +75,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-modref-tree.h"
> #include "ipa-modref.h"
> #include "value-range.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "attr-fnspec.h"
> diff --git a/gcc/ipa-param-manipulation.cc b/gcc/ipa-param-manipulation.cc
> index 02f71a42237..3e0df6a6f77 100644
> --- a/gcc/ipa-param-manipulation.cc
> +++ b/gcc/ipa-param-manipulation.cc
> @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-phinodes.h"
> #include "cfgexpand.h"
> #include "attribs.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
>
> /* Actual prefixes of different newly synthetized parameters. Keep in sync
> diff --git a/gcc/ipa-predicate.cc b/gcc/ipa-predicate.cc
> index d3b3227b0fe..164aba4a126 100644
> --- a/gcc/ipa-predicate.cc
> +++ b/gcc/ipa-predicate.cc
> @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-vrp.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "real.h"
> diff --git a/gcc/ipa-profile.cc b/gcc/ipa-profile.cc
> index 5e89f677c3e..27f411ce81a 100644
> --- a/gcc/ipa-profile.cc
> +++ b/gcc/ipa-profile.cc
> @@ -55,6 +55,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-inline.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
>
> diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
> index bec0ebd210c..e22c4f78405 100644
> --- a/gcc/ipa-prop.cc
> +++ b/gcc/ipa-prop.cc
> @@ -41,6 +41,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimplify-me.h"
> #include "gimple-walk.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-cfg.h"
> #include "tree-dfa.h"
> @@ -4561,7 +4563,7 @@ ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
> ipa_node_params *new_info)
> {
> new_info->descriptors = vec_safe_copy (old_info->descriptors);
> - new_info->lattices = NULL;
> + gcc_assert (new_info->lattices.is_empty ());
> new_info->ipcp_orig_node = old_info->ipcp_orig_node;
> new_info->known_csts = old_info->known_csts.copy ();
> new_info->known_contexts = old_info->known_contexts.copy ();
> diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
> index 9c78dc9f486..ee3c0006add 100644
> --- a/gcc/ipa-prop.h
> +++ b/gcc/ipa-prop.h
> @@ -627,7 +627,7 @@ public:
> vec<ipa_param_descriptor, va_gc> *descriptors;
> /* Pointer to an array of structures describing individual formal
> parameters. */
> - class ipcp_param_lattices * GTY((skip)) lattices;
> + vec<ipcp_param_lattices> GTY((skip)) lattices;
> /* Only for versioned nodes this field would not be NULL,
> it points to the node that IPA cp cloned from. */
> struct cgraph_node * GTY((skip)) ipcp_orig_node;
> @@ -662,7 +662,7 @@ public:
>
> inline
> ipa_node_params::ipa_node_params ()
> -: descriptors (NULL), lattices (NULL), ipcp_orig_node (NULL),
> +: descriptors (NULL), lattices (vNULL), ipcp_orig_node (NULL),
> known_csts (vNULL), known_contexts (vNULL), analysis_done (0),
> node_enqueued (0), do_clone_for_all_contexts (0), is_all_contexts_clone (0),
> node_dead (0), node_within_scc (0), node_is_self_scc (0),
> @@ -673,8 +673,8 @@ ipa_node_params::ipa_node_params ()
> inline
> ipa_node_params::~ipa_node_params ()
> {
> - free (lattices);
> vec_free (descriptors);
> + lattices.release ();
> known_csts.release ();
> known_contexts.release ();
> }
> diff --git a/gcc/ipa-pure-const.cc b/gcc/ipa-pure-const.cc
> index 7e9ece21b22..d285462b6cf 100644
> --- a/gcc/ipa-pure-const.cc
> +++ b/gcc/ipa-pure-const.cc
> @@ -59,6 +59,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ssa.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "symtab-thunks.h"
> diff --git a/gcc/ipa-split.cc b/gcc/ipa-split.cc
> index 8e6aa018a7d..39ad822608b 100644
> --- a/gcc/ipa-split.cc
> +++ b/gcc/ipa-split.cc
> @@ -95,6 +95,8 @@ along with GCC; see the file COPYING3. If not see
> #include "gimplify-me.h"
> #include "gimple-walk.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "tree-cfg.h"
> #include "tree-into-ssa.h"
> diff --git a/gcc/ipa-sra.cc b/gcc/ipa-sra.cc
> index 14c2a344e6d..6d6da408925 100644
> --- a/gcc/ipa-sra.cc
> +++ b/gcc/ipa-sra.cc
> @@ -84,6 +84,8 @@ along with GCC; see the file COPYING3. If not see
> #include "internal-fn.h"
> #include "symtab-clones.h"
> #include "attribs.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
>
> static void ipa_sra_summarize_function (cgraph_node *);
> diff --git a/gcc/ipa-strub.cc b/gcc/ipa-strub.cc
> index 0ee063c9edd..09db1e04431 100644
> --- a/gcc/ipa-strub.cc
> +++ b/gcc/ipa-strub.cc
> @@ -43,6 +43,8 @@ along with GCC; see the file COPYING3. If not see
> #include "cgraph.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "gimple-fold.h"
> diff --git a/gcc/ipa-utils.cc b/gcc/ipa-utils.cc
> index 1567874882f..3be0ddb8e96 100644
> --- a/gcc/ipa-utils.cc
> +++ b/gcc/ipa-utils.cc
> @@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "tree-eh.h"
> diff --git a/gcc/ipa.cc b/gcc/ipa.cc
> index 82d8c59d660..c453fca5d9b 100644
> --- a/gcc/ipa.cc
> +++ b/gcc/ipa.cc
> @@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-utils.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "dbgcnt.h"
> diff --git a/gcc/lto/lto-common.cc b/gcc/lto/lto-common.cc
> index e54ddf2ca41..2ce94cc3282 100644
> --- a/gcc/lto/lto-common.cc
> +++ b/gcc/lto/lto-common.cc
> @@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
> #include "stor-layout.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "common.h"
> #include "debug.h"
> diff --git a/gcc/lto/lto-partition.cc b/gcc/lto/lto-partition.cc
> index 7165747d57e..19f91e5d660 100644
> --- a/gcc/lto/lto-partition.cc
> +++ b/gcc/lto/lto-partition.cc
> @@ -31,10 +31,11 @@ along with GCC; see the file COPYING3. If not see
> #include "lto-streamer.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-fnsummary.h"
> #include "lto-partition.h"
> -#include "sreal.h"
>
> vec<ltrans_partition> ltrans_partitions;
>
> diff --git a/gcc/lto/lto.cc b/gcc/lto/lto.cc
> index f7c0623f6b2..91aa2fbddb4 100644
> --- a/gcc/lto/lto.cc
> +++ b/gcc/lto/lto.cc
> @@ -38,6 +38,8 @@ along with GCC; see the file COPYING3. If not see
> #include "stor-layout.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "debug.h"
> #include "lto.h"
> diff --git a/gcc/toplev.cc b/gcc/toplev.cc
> index 175d4cd18fa..2cd4096558e 100644
> --- a/gcc/toplev.cc
> +++ b/gcc/toplev.cc
> @@ -74,6 +74,8 @@ along with GCC; see the file COPYING3. If not see
> #include "ipa-reference.h"
> #include "symbol-summary.h"
> #include "tree-vrp.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "ipa-utils.h"
> #include "gcse.h"
> diff --git a/gcc/tree-ssa-ccp.cc b/gcc/tree-ssa-ccp.cc
> index ad3b9b87c9d..f6a5cd0ee6e 100644
> --- a/gcc/tree-ssa-ccp.cc
> +++ b/gcc/tree-ssa-ccp.cc
> @@ -150,6 +150,8 @@ along with GCC; see the file COPYING3. If not see
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "internal-fn.h"
>
> diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
> index 8792cd07901..97c6d5895f0 100644
> --- a/gcc/tree-ssa-sccvn.cc
> +++ b/gcc/tree-ssa-sccvn.cc
> @@ -76,6 +76,8 @@ along with GCC; see the file COPYING3. If not see
> #include "tree-ssa-sccvn.h"
> #include "alloc-pool.h"
> #include "symbol-summary.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "target.h"
>
> diff --git a/gcc/tree-vrp.cc b/gcc/tree-vrp.cc
> index 978025b51de..b0f21e3aa60 100644
> --- a/gcc/tree-vrp.cc
> +++ b/gcc/tree-vrp.cc
> @@ -56,6 +56,8 @@ along with GCC; see the file COPYING3. If not see
> #include "cgraph.h"
> #include "symbol-summary.h"
> #include "ipa-utils.h"
> +#include "sreal.h"
> +#include "ipa-cp.h"
> #include "ipa-prop.h"
> #include "attribs.h"
>
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 9+ messages in thread