Message ID | ri6frxoxzpk.fsf@virgil.suse.cz |
---|---|
State | New |
Headers | show |
Series | ipa: Convert lattices from pure array to vector (PR 113476) | expand |
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" > >
> 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 >
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"