Home | History | Annotate | Line # | Download | only in gcc
      1  1.1  mrg /* Interprocedural constant propagation
      2  1.1  mrg    Copyright (C) 2005-2022 Free Software Foundation, Inc.
      3  1.1  mrg 
      4  1.1  mrg    Contributed by Razya Ladelsky <RAZYA (at) il.ibm.com> and Martin Jambor
      5  1.1  mrg    <mjambor (at) suse.cz>
      6  1.1  mrg 
      7  1.1  mrg This file is part of GCC.
      8  1.1  mrg 
      9  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
     10  1.1  mrg the terms of the GNU General Public License as published by the Free
     11  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     12  1.1  mrg version.
     13  1.1  mrg 
     14  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     15  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     16  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     17  1.1  mrg for more details.
     18  1.1  mrg 
     19  1.1  mrg You should have received a copy of the GNU General Public License
     20  1.1  mrg along with GCC; see the file COPYING3.  If not see
     21  1.1  mrg <http://www.gnu.org/licenses/>.  */
     22  1.1  mrg 
     23  1.1  mrg /* Interprocedural constant propagation (IPA-CP).
     24  1.1  mrg 
     25  1.1  mrg    The goal of this transformation is to
     26  1.1  mrg 
     27  1.1  mrg    1) discover functions which are always invoked with some arguments with the
     28  1.1  mrg       same known constant values and modify the functions so that the
     29  1.1  mrg       subsequent optimizations can take advantage of the knowledge, and
     30  1.1  mrg 
     31  1.1  mrg    2) partial specialization - create specialized versions of functions
     32  1.1  mrg       transformed in this way if some parameters are known constants only in
     33  1.1  mrg       certain contexts but the estimated tradeoff between speedup and cost size
     34  1.1  mrg       is deemed good.
     35  1.1  mrg 
     36  1.1  mrg    The algorithm also propagates types and attempts to perform type based
     37  1.1  mrg    devirtualization.  Types are propagated much like constants.
     38  1.1  mrg 
     39  1.1  mrg    The algorithm basically consists of three stages.  In the first, functions
     40  1.1  mrg    are analyzed one at a time and jump functions are constructed for all known
     41  1.1  mrg    call-sites.  In the second phase, the pass propagates information from the
     42  1.1  mrg    jump functions across the call to reveal what values are available at what
     43  1.1  mrg    call sites, performs estimations of effects of known values on functions and
     44  1.1  mrg    their callees, and finally decides what specialized extra versions should be
     45  1.1  mrg    created.  In the third, the special versions materialize and appropriate
     46  1.1  mrg    calls are redirected.
     47  1.1  mrg 
     48  1.1  mrg    The algorithm used is to a certain extent based on "Interprocedural Constant
     49  1.1  mrg    Propagation", by David Callahan, Keith D Cooper, Ken Kennedy, Linda Torczon,
     50  1.1  mrg    Comp86, pg 152-161 and "A Methodology for Procedure Cloning" by Keith D
     51  1.1  mrg    Cooper, Mary W. Hall, and Ken Kennedy.
     52  1.1  mrg 
     53  1.1  mrg 
     54  1.1  mrg    First stage - intraprocedural analysis
     55  1.1  mrg    =======================================
     56  1.1  mrg 
     57  1.1  mrg    This phase computes jump_function and modification flags.
     58  1.1  mrg 
     59  1.1  mrg    A jump function for a call-site represents the values passed as an actual
     60  1.1  mrg    arguments of a given call-site. In principle, there are three types of
     61  1.1  mrg    values:
     62  1.1  mrg 
     63  1.1  mrg    Pass through - the caller's formal parameter is passed as an actual
     64  1.1  mrg 		  argument, plus an operation on it can be performed.
     65  1.1  mrg    Constant - a constant is passed as an actual argument.
     66  1.1  mrg    Unknown - neither of the above.
     67  1.1  mrg 
     68  1.1  mrg    All jump function types are described in detail in ipa-prop.h, together with
     69  1.1  mrg    the data structures that represent them and methods of accessing them.
     70  1.1  mrg 
     71  1.1  mrg    ipcp_generate_summary() is the main function of the first stage.
     72  1.1  mrg 
     73  1.1  mrg    Second stage - interprocedural analysis
     74  1.1  mrg    ========================================
     75  1.1  mrg 
     76  1.1  mrg    This stage is itself divided into two phases.  In the first, we propagate
     77  1.1  mrg    known values over the call graph, in the second, we make cloning decisions.
     78  1.1  mrg    It uses a different algorithm than the original Callahan's paper.
     79  1.1  mrg 
     80  1.1  mrg    First, we traverse the functions topologically from callers to callees and,
     81  1.1  mrg    for each strongly connected component (SCC), we propagate constants
     82  1.1  mrg    according to previously computed jump functions.  We also record what known
     83  1.1  mrg    values depend on other known values and estimate local effects.  Finally, we
     84  1.1  mrg    propagate cumulative information about these effects from dependent values
     85  1.1  mrg    to those on which they depend.
     86  1.1  mrg 
     87  1.1  mrg    Second, we again traverse the call graph in the same topological order and
     88  1.1  mrg    make clones for functions which we know are called with the same values in
     89  1.1  mrg    all contexts and decide about extra specialized clones of functions just for
     90  1.1  mrg    some contexts - these decisions are based on both local estimates and
     91  1.1  mrg    cumulative estimates propagated from callees.
     92  1.1  mrg 
     93  1.1  mrg    ipcp_propagate_stage() and ipcp_decision_stage() together constitute the
     94  1.1  mrg    third stage.
     95  1.1  mrg 
     96  1.1  mrg    Third phase - materialization of clones, call statement updates.
     97  1.1  mrg    ============================================
     98  1.1  mrg 
     99  1.1  mrg    This stage is currently performed by call graph code (mainly in cgraphunit.cc
    100  1.1  mrg    and tree-inline.cc) according to instructions inserted to the call graph by
    101  1.1  mrg    the second stage.  */
    102  1.1  mrg 
    103  1.1  mrg #include "config.h"
    104  1.1  mrg #include "system.h"
    105  1.1  mrg #include "coretypes.h"
    106  1.1  mrg #include "backend.h"
    107  1.1  mrg #include "tree.h"
    108  1.1  mrg #include "gimple-expr.h"
    109  1.1  mrg #include "gimple.h"
    110  1.1  mrg #include "predict.h"
    111  1.1  mrg #include "alloc-pool.h"
    112  1.1  mrg #include "tree-pass.h"
    113  1.1  mrg #include "cgraph.h"
    114  1.1  mrg #include "diagnostic.h"
    115  1.1  mrg #include "fold-const.h"
    116  1.1  mrg #include "gimple-fold.h"
    117  1.1  mrg #include "symbol-summary.h"
    118  1.1  mrg #include "tree-vrp.h"
    119  1.1  mrg #include "ipa-prop.h"
    120  1.1  mrg #include "tree-pretty-print.h"
    121  1.1  mrg #include "tree-inline.h"
    122  1.1  mrg #include "ipa-fnsummary.h"
    123  1.1  mrg #include "ipa-utils.h"
    124  1.1  mrg #include "tree-ssa-ccp.h"
    125  1.1  mrg #include "stringpool.h"
    126  1.1  mrg #include "attribs.h"
    127  1.1  mrg #include "dbgcnt.h"
    128  1.1  mrg #include "symtab-clones.h"
    129  1.1  mrg 
    130  1.1  mrg template <typename valtype> class ipcp_value;
    131  1.1  mrg 
    132  1.1  mrg /* Describes a particular source for an IPA-CP value.  */
    133  1.1  mrg 
    134  1.1  mrg template <typename valtype>
    135  1.1  mrg struct ipcp_value_source
    136  1.1  mrg {
    137  1.1  mrg public:
    138  1.1  mrg   /* Aggregate offset of the source, negative if the source is scalar value of
    139  1.1  mrg      the argument itself.  */
    140  1.1  mrg   HOST_WIDE_INT offset;
    141  1.1  mrg   /* The incoming edge that brought the value.  */
    142  1.1  mrg   cgraph_edge *cs;
    143  1.1  mrg   /* If the jump function that resulted into his value was a pass-through or an
    144  1.1  mrg      ancestor, this is the ipcp_value of the caller from which the described
    145  1.1  mrg      value has been derived.  Otherwise it is NULL.  */
    146  1.1  mrg   ipcp_value<valtype> *val;
    147  1.1  mrg   /* Next pointer in a linked list of sources of a value.  */
    148  1.1  mrg   ipcp_value_source *next;
    149  1.1  mrg   /* If the jump function that resulted into his value was a pass-through or an
    150  1.1  mrg      ancestor, this is the index of the parameter of the caller the jump
    151  1.1  mrg      function references.  */
    152  1.1  mrg   int index;
    153  1.1  mrg };
    154  1.1  mrg 
    155  1.1  mrg /* Common ancestor for all ipcp_value instantiations.  */
    156  1.1  mrg 
    157  1.1  mrg class ipcp_value_base
    158  1.1  mrg {
    159  1.1  mrg public:
    160  1.1  mrg   /* Time benefit and that specializing the function for this value would bring
    161  1.1  mrg      about in this function alone.  */
    162  1.1  mrg   sreal local_time_benefit;
    163  1.1  mrg   /* Time benefit that specializing the function for this value can bring about
    164  1.1  mrg      in it's callees.  */
    165  1.1  mrg   sreal prop_time_benefit;
    166  1.1  mrg   /* Size cost that specializing the function for this value would bring about
    167  1.1  mrg      in this function alone.  */
    168  1.1  mrg   int local_size_cost;
    169  1.1  mrg   /* Size cost that specializing the function for this value can bring about in
    170  1.1  mrg      it's callees.  */
    171  1.1  mrg   int prop_size_cost;
    172  1.1  mrg 
    173  1.1  mrg   ipcp_value_base ()
    174  1.1  mrg     : local_time_benefit (0), prop_time_benefit (0),
    175  1.1  mrg       local_size_cost (0), prop_size_cost (0) {}
    176  1.1  mrg };
    177  1.1  mrg 
    178  1.1  mrg /* Describes one particular value stored in struct ipcp_lattice.  */
    179  1.1  mrg 
    180  1.1  mrg template <typename valtype>
    181  1.1  mrg class ipcp_value : public ipcp_value_base
    182  1.1  mrg {
    183  1.1  mrg public:
    184  1.1  mrg   /* The actual value for the given parameter.  */
    185  1.1  mrg   valtype value;
    186  1.1  mrg   /* The list of sources from which this value originates.  */
    187  1.1  mrg   ipcp_value_source <valtype> *sources = nullptr;
    188  1.1  mrg   /* Next pointers in a linked list of all values in a lattice.  */
    189  1.1  mrg   ipcp_value *next = nullptr;
    190  1.1  mrg   /* Next pointers in a linked list of values in a strongly connected component
    191  1.1  mrg      of values. */
    192  1.1  mrg   ipcp_value *scc_next = nullptr;
    193  1.1  mrg   /* Next pointers in a linked list of SCCs of values sorted topologically
    194  1.1  mrg      according their sources.  */
    195  1.1  mrg   ipcp_value  *topo_next = nullptr;
    196  1.1  mrg   /* A specialized node created for this value, NULL if none has been (so far)
    197  1.1  mrg      created.  */
    198  1.1  mrg   cgraph_node *spec_node = nullptr;
    199  1.1  mrg   /* Depth first search number and low link for topological sorting of
    200  1.1  mrg      values.  */
    201  1.1  mrg   int dfs = 0;
    202  1.1  mrg   int low_link = 0;
    203  1.1  mrg   /* SCC number to identify values which recursively feed into each other.
    204  1.1  mrg      Values in the same SCC have the same SCC number.  */
    205  1.1  mrg   int scc_no = 0;
    206  1.1  mrg   /* Non zero if the value is generated from another value in the same lattice
    207  1.1  mrg      for a self-recursive call, the actual number is how many times the
    208  1.1  mrg      operation has been performed.  In the unlikely event of the value being
    209  1.1  mrg      present in two chains fo self-recursive value generation chains, it is the
    210  1.1  mrg      maximum.  */
    211  1.1  mrg   unsigned self_recursion_generated_level = 0;
    212  1.1  mrg   /* True if this value is currently on the topo-sort stack.  */
    213  1.1  mrg   bool on_stack = false;
    214  1.1  mrg 
    215  1.1  mrg   void add_source (cgraph_edge *cs, ipcp_value *src_val, int src_idx,
    216  1.1  mrg 		   HOST_WIDE_INT offset);
    217  1.1  mrg 
    218  1.1  mrg   /* Return true if both THIS value and O feed into each other.  */
    219  1.1  mrg 
    220  1.1  mrg   bool same_scc (const ipcp_value<valtype> *o)
    221  1.1  mrg   {
    222  1.1  mrg     return o->scc_no == scc_no;
    223  1.1  mrg   }
    224  1.1  mrg 
    225  1.1  mrg /* Return true, if a this value has been generated for a self-recursive call as
    226  1.1  mrg    a result of an arithmetic pass-through jump-function acting on a value in
    227  1.1  mrg    the same lattice function.  */
    228  1.1  mrg 
    229  1.1  mrg   bool self_recursion_generated_p ()
    230  1.1  mrg   {
    231  1.1  mrg     return self_recursion_generated_level > 0;
    232  1.1  mrg   }
    233  1.1  mrg };
    234  1.1  mrg 
    235  1.1  mrg /* Lattice describing potential values of a formal parameter of a function, or
    236  1.1  mrg    a part of an aggregate.  TOP is represented by a lattice with zero values
    237  1.1  mrg    and with contains_variable and bottom flags cleared.  BOTTOM is represented
    238  1.1  mrg    by a lattice with the bottom flag set.  In that case, values and
    239  1.1  mrg    contains_variable flag should be disregarded.  */
    240  1.1  mrg 
    241  1.1  mrg template <typename valtype>
    242  1.1  mrg struct ipcp_lattice
    243  1.1  mrg {
    244  1.1  mrg public:
    245  1.1  mrg   /* The list of known values and types in this lattice.  Note that values are
    246  1.1  mrg      not deallocated if a lattice is set to bottom because there may be value
    247  1.1  mrg      sources referencing them.  */
    248  1.1  mrg   ipcp_value<valtype> *values;
    249  1.1  mrg   /* Number of known values and types in this lattice.  */
    250  1.1  mrg   int values_count;
    251  1.1  mrg   /* The lattice contains a variable component (in addition to values).  */
    252  1.1  mrg   bool contains_variable;
    253  1.1  mrg   /* The value of the lattice is bottom (i.e. variable and unusable for any
    254  1.1  mrg      propagation).  */
    255  1.1  mrg   bool bottom;
    256  1.1  mrg 
    257  1.1  mrg   inline bool is_single_const ();
    258  1.1  mrg   inline bool set_to_bottom ();
    259  1.1  mrg   inline bool set_contains_variable ();
    260  1.1  mrg   bool add_value (valtype newval, cgraph_edge *cs,
    261  1.1  mrg 		  ipcp_value<valtype> *src_val = NULL,
    262  1.1  mrg 		  int src_idx = 0, HOST_WIDE_INT offset = -1,
    263  1.1  mrg 		  ipcp_value<valtype> **val_p = NULL,
    264  1.1  mrg 		  unsigned same_lat_gen_level = 0);
    265  1.1  mrg   void print (FILE * f, bool dump_sources, bool dump_benefits);
    266  1.1  mrg };
    267  1.1  mrg 
    268  1.1  mrg /* Lattice of tree values with an offset to describe a part of an
    269  1.1  mrg    aggregate.  */
    270  1.1  mrg 
    271  1.1  mrg struct ipcp_agg_lattice : public ipcp_lattice<tree>
    272  1.1  mrg {
    273  1.1  mrg public:
    274  1.1  mrg   /* Offset that is being described by this lattice. */
    275  1.1  mrg   HOST_WIDE_INT offset;
    276  1.1  mrg   /* Size so that we don't have to re-compute it every time we traverse the
    277  1.1  mrg      list.  Must correspond to TYPE_SIZE of all lat values.  */
    278  1.1  mrg   HOST_WIDE_INT size;
    279  1.1  mrg   /* Next element of the linked list.  */
    280  1.1  mrg   struct ipcp_agg_lattice *next;
    281  1.1  mrg };
    282  1.1  mrg 
    283  1.1  mrg /* Lattice of known bits, only capable of holding one value.
    284  1.1  mrg    Bitwise constant propagation propagates which bits of a
    285  1.1  mrg    value are constant.
    286  1.1  mrg    For eg:
    287  1.1  mrg    int f(int x)
    288  1.1  mrg    {
    289  1.1  mrg      return some_op (x);
    290  1.1  mrg    }
    291  1.1  mrg 
    292  1.1  mrg    int f1(int y)
    293  1.1  mrg    {
    294  1.1  mrg      if (cond)
    295  1.1  mrg       return f (y & 0xff);
    296  1.1  mrg      else
    297  1.1  mrg       return f (y & 0xf);
    298  1.1  mrg    }
    299  1.1  mrg 
    300  1.1  mrg    In the above case, the param 'x' will always have all
    301  1.1  mrg    the bits (except the bits in lsb) set to 0.
    302  1.1  mrg    Hence the mask of 'x' would be 0xff. The mask
    303  1.1  mrg    reflects that the bits in lsb are unknown.
    304  1.1  mrg    The actual propagated value is given by m_value & ~m_mask.  */
    305  1.1  mrg 
    306  1.1  mrg class ipcp_bits_lattice
    307  1.1  mrg {
    308  1.1  mrg public:
    309  1.1  mrg   bool bottom_p () const { return m_lattice_val == IPA_BITS_VARYING; }
    310  1.1  mrg   bool top_p () const { return m_lattice_val == IPA_BITS_UNDEFINED; }
    311  1.1  mrg   bool constant_p () const { return m_lattice_val == IPA_BITS_CONSTANT; }
    312  1.1  mrg   bool set_to_bottom ();
    313  1.1  mrg   bool set_to_constant (widest_int, widest_int);
    314  1.1  mrg   bool known_nonzero_p () const;
    315  1.1  mrg 
    316  1.1  mrg   widest_int get_value () const { return m_value; }
    317  1.1  mrg   widest_int get_mask () const { return m_mask; }
    318  1.1  mrg 
    319  1.1  mrg   bool meet_with (ipcp_bits_lattice& other, unsigned, signop,
    320  1.1  mrg 		  enum tree_code, tree, bool);
    321  1.1  mrg 
    322  1.1  mrg   bool meet_with (widest_int, widest_int, unsigned);
    323  1.1  mrg 
    324  1.1  mrg   void print (FILE *);
    325  1.1  mrg 
    326  1.1  mrg private:
    327  1.1  mrg   enum { IPA_BITS_UNDEFINED, IPA_BITS_CONSTANT, IPA_BITS_VARYING } m_lattice_val;
    328  1.1  mrg 
    329  1.1  mrg   /* Similar to ccp_lattice_t, mask represents which bits of value are constant.
    330  1.1  mrg      If a bit in mask is set to 0, then the corresponding bit in
    331  1.1  mrg      value is known to be constant.  */
    332  1.1  mrg   widest_int m_value, m_mask;
    333  1.1  mrg 
    334  1.1  mrg   bool meet_with_1 (widest_int, widest_int, unsigned, bool);
    335  1.1  mrg   void get_value_and_mask (tree, widest_int *, widest_int *);
    336  1.1  mrg };
    337  1.1  mrg 
    338  1.1  mrg /* Lattice of value ranges.  */
    339  1.1  mrg 
    340  1.1  mrg class ipcp_vr_lattice
    341  1.1  mrg {
    342  1.1  mrg public:
    343  1.1  mrg   value_range m_vr;
    344  1.1  mrg 
    345  1.1  mrg   inline bool bottom_p () const;
    346  1.1  mrg   inline bool top_p () const;
    347  1.1  mrg   inline bool set_to_bottom ();
    348  1.1  mrg   bool meet_with (const value_range *p_vr);
    349  1.1  mrg   bool meet_with (const ipcp_vr_lattice &other);
    350  1.1  mrg   void init () { gcc_assert (m_vr.undefined_p ()); }
    351  1.1  mrg   void print (FILE * f);
    352  1.1  mrg 
    353  1.1  mrg private:
    354  1.1  mrg   bool meet_with_1 (const value_range *other_vr);
    355  1.1  mrg };
    356  1.1  mrg 
    357  1.1  mrg /* Structure containing lattices for a parameter itself and for pieces of
    358  1.1  mrg    aggregates that are passed in the parameter or by a reference in a parameter
    359  1.1  mrg    plus some other useful flags.  */
    360  1.1  mrg 
    361  1.1  mrg class ipcp_param_lattices
    362  1.1  mrg {
    363  1.1  mrg public:
    364  1.1  mrg   /* Lattice describing the value of the parameter itself.  */
    365  1.1  mrg   ipcp_lattice<tree> itself;
    366  1.1  mrg   /* Lattice describing the polymorphic contexts of a parameter.  */
    367  1.1  mrg   ipcp_lattice<ipa_polymorphic_call_context> ctxlat;
    368  1.1  mrg   /* Lattices describing aggregate parts.  */
    369  1.1  mrg   ipcp_agg_lattice *aggs;
    370  1.1  mrg   /* Lattice describing known bits.  */
    371  1.1  mrg   ipcp_bits_lattice bits_lattice;
    372  1.1  mrg   /* Lattice describing value range.  */
    373  1.1  mrg   ipcp_vr_lattice m_value_range;
    374  1.1  mrg   /* Number of aggregate lattices */
    375  1.1  mrg   int aggs_count;
    376  1.1  mrg   /* True if aggregate data were passed by reference (as opposed to by
    377  1.1  mrg      value).  */
    378  1.1  mrg   bool aggs_by_ref;
    379  1.1  mrg   /* All aggregate lattices contain a variable component (in addition to
    380  1.1  mrg      values).  */
    381  1.1  mrg   bool aggs_contain_variable;
    382  1.1  mrg   /* The value of all aggregate lattices is bottom (i.e. variable and unusable
    383  1.1  mrg      for any propagation).  */
    384  1.1  mrg   bool aggs_bottom;
    385  1.1  mrg 
    386  1.1  mrg   /* There is a virtual call based on this parameter.  */
    387  1.1  mrg   bool virt_call;
    388  1.1  mrg };
    389  1.1  mrg 
    390  1.1  mrg /* Allocation pools for values and their sources in ipa-cp.  */
    391  1.1  mrg 
    392  1.1  mrg object_allocator<ipcp_value<tree> > ipcp_cst_values_pool
    393  1.1  mrg   ("IPA-CP constant values");
    394  1.1  mrg 
    395  1.1  mrg object_allocator<ipcp_value<ipa_polymorphic_call_context> >
    396  1.1  mrg   ipcp_poly_ctx_values_pool ("IPA-CP polymorphic contexts");
    397  1.1  mrg 
    398  1.1  mrg object_allocator<ipcp_value_source<tree> > ipcp_sources_pool
    399  1.1  mrg   ("IPA-CP value sources");
    400  1.1  mrg 
    401  1.1  mrg object_allocator<ipcp_agg_lattice> ipcp_agg_lattice_pool
    402  1.1  mrg   ("IPA_CP aggregate lattices");
    403  1.1  mrg 
    404  1.1  mrg /* Base count to use in heuristics when using profile feedback.  */
    405  1.1  mrg 
    406  1.1  mrg static profile_count base_count;
    407  1.1  mrg 
    408  1.1  mrg /* Original overall size of the program.  */
    409  1.1  mrg 
    410  1.1  mrg static long overall_size, orig_overall_size;
    411  1.1  mrg 
    412  1.1  mrg /* Node name to unique clone suffix number map.  */
    413  1.1  mrg static hash_map<const char *, unsigned> *clone_num_suffixes;
    414  1.1  mrg 
    415  1.1  mrg /* Return the param lattices structure corresponding to the Ith formal
    416  1.1  mrg    parameter of the function described by INFO.  */
    417  1.1  mrg static inline class ipcp_param_lattices *
    418  1.1  mrg ipa_get_parm_lattices (class ipa_node_params *info, int i)
    419  1.1  mrg {
    420  1.1  mrg   gcc_assert (i >= 0 && i < ipa_get_param_count (info));
    421  1.1  mrg   gcc_checking_assert (!info->ipcp_orig_node);
    422  1.1  mrg   gcc_checking_assert (info->lattices);
    423  1.1  mrg   return &(info->lattices[i]);
    424  1.1  mrg }
    425  1.1  mrg 
    426  1.1  mrg /* Return the lattice corresponding to the scalar value of the Ith formal
    427  1.1  mrg    parameter of the function described by INFO.  */
    428  1.1  mrg static inline ipcp_lattice<tree> *
    429  1.1  mrg ipa_get_scalar_lat (class ipa_node_params *info, int i)
    430  1.1  mrg {
    431  1.1  mrg   class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
    432  1.1  mrg   return &plats->itself;
    433  1.1  mrg }
    434  1.1  mrg 
    435  1.1  mrg /* Return the lattice corresponding to the scalar value of the Ith formal
    436  1.1  mrg    parameter of the function described by INFO.  */
    437  1.1  mrg static inline ipcp_lattice<ipa_polymorphic_call_context> *
    438  1.1  mrg ipa_get_poly_ctx_lat (class ipa_node_params *info, int i)
    439  1.1  mrg {
    440  1.1  mrg   class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
    441  1.1  mrg   return &plats->ctxlat;
    442  1.1  mrg }
    443  1.1  mrg 
    444  1.1  mrg /* Return whether LAT is a lattice with a single constant and without an
    445  1.1  mrg    undefined value.  */
    446  1.1  mrg 
    447  1.1  mrg template <typename valtype>
    448  1.1  mrg inline bool
    449  1.1  mrg ipcp_lattice<valtype>::is_single_const ()
    450  1.1  mrg {
    451  1.1  mrg   if (bottom || contains_variable || values_count != 1)
    452  1.1  mrg     return false;
    453  1.1  mrg   else
    454  1.1  mrg     return true;
    455  1.1  mrg }
    456  1.1  mrg 
    457  1.1  mrg /* Print V which is extracted from a value in a lattice to F.  */
    458  1.1  mrg 
    459  1.1  mrg static void
    460  1.1  mrg print_ipcp_constant_value (FILE * f, tree v)
    461  1.1  mrg {
    462  1.1  mrg   if (TREE_CODE (v) == ADDR_EXPR
    463  1.1  mrg       && TREE_CODE (TREE_OPERAND (v, 0)) == CONST_DECL)
    464  1.1  mrg     {
    465  1.1  mrg       fprintf (f, "& ");
    466  1.1  mrg       print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (v, 0)));
    467  1.1  mrg     }
    468  1.1  mrg   else
    469  1.1  mrg     print_generic_expr (f, v);
    470  1.1  mrg }
    471  1.1  mrg 
    472  1.1  mrg /* Print V which is extracted from a value in a lattice to F.  */
    473  1.1  mrg 
    474  1.1  mrg static void
    475  1.1  mrg print_ipcp_constant_value (FILE * f, ipa_polymorphic_call_context v)
    476  1.1  mrg {
    477  1.1  mrg   v.dump(f, false);
    478  1.1  mrg }
    479  1.1  mrg 
    480  1.1  mrg /* Print a lattice LAT to F.  */
    481  1.1  mrg 
    482  1.1  mrg template <typename valtype>
    483  1.1  mrg void
    484  1.1  mrg ipcp_lattice<valtype>::print (FILE * f, bool dump_sources, bool dump_benefits)
    485  1.1  mrg {
    486  1.1  mrg   ipcp_value<valtype> *val;
    487  1.1  mrg   bool prev = false;
    488  1.1  mrg 
    489  1.1  mrg   if (bottom)
    490  1.1  mrg     {
    491  1.1  mrg       fprintf (f, "BOTTOM\n");
    492  1.1  mrg       return;
    493  1.1  mrg     }
    494  1.1  mrg 
    495  1.1  mrg   if (!values_count && !contains_variable)
    496  1.1  mrg     {
    497  1.1  mrg       fprintf (f, "TOP\n");
    498  1.1  mrg       return;
    499  1.1  mrg     }
    500  1.1  mrg 
    501  1.1  mrg   if (contains_variable)
    502  1.1  mrg     {
    503  1.1  mrg       fprintf (f, "VARIABLE");
    504  1.1  mrg       prev = true;
    505  1.1  mrg       if (dump_benefits)
    506  1.1  mrg 	fprintf (f, "\n");
    507  1.1  mrg     }
    508  1.1  mrg 
    509  1.1  mrg   for (val = values; val; val = val->next)
    510  1.1  mrg     {
    511  1.1  mrg       if (dump_benefits && prev)
    512  1.1  mrg 	fprintf (f, "               ");
    513  1.1  mrg       else if (!dump_benefits && prev)
    514  1.1  mrg 	fprintf (f, ", ");
    515  1.1  mrg       else
    516  1.1  mrg 	prev = true;
    517  1.1  mrg 
    518  1.1  mrg       print_ipcp_constant_value (f, val->value);
    519  1.1  mrg 
    520  1.1  mrg       if (dump_sources)
    521  1.1  mrg 	{
    522  1.1  mrg 	  ipcp_value_source<valtype> *s;
    523  1.1  mrg 
    524  1.1  mrg 	  if (val->self_recursion_generated_p ())
    525  1.1  mrg 	    fprintf (f, " [self_gen(%i), from:",
    526  1.1  mrg 		     val->self_recursion_generated_level);
    527  1.1  mrg 	  else
    528  1.1  mrg 	    fprintf (f, " [scc: %i, from:", val->scc_no);
    529  1.1  mrg 	  for (s = val->sources; s; s = s->next)
    530  1.1  mrg 	    fprintf (f, " %i(%f)", s->cs->caller->order,
    531  1.1  mrg 		     s->cs->sreal_frequency ().to_double ());
    532  1.1  mrg 	  fprintf (f, "]");
    533  1.1  mrg 	}
    534  1.1  mrg 
    535  1.1  mrg       if (dump_benefits)
    536  1.1  mrg 	fprintf (f, " [loc_time: %g, loc_size: %i, "
    537  1.1  mrg 		 "prop_time: %g, prop_size: %i]\n",
    538  1.1  mrg 		 val->local_time_benefit.to_double (), val->local_size_cost,
    539  1.1  mrg 		 val->prop_time_benefit.to_double (), val->prop_size_cost);
    540  1.1  mrg     }
    541  1.1  mrg   if (!dump_benefits)
    542  1.1  mrg     fprintf (f, "\n");
    543  1.1  mrg }
    544  1.1  mrg 
    545  1.1  mrg void
    546  1.1  mrg ipcp_bits_lattice::print (FILE *f)
    547  1.1  mrg {
    548  1.1  mrg   if (top_p ())
    549  1.1  mrg     fprintf (f, "         Bits unknown (TOP)\n");
    550  1.1  mrg   else if (bottom_p ())
    551  1.1  mrg     fprintf (f, "         Bits unusable (BOTTOM)\n");
    552  1.1  mrg   else
    553  1.1  mrg     {
    554  1.1  mrg       fprintf (f, "         Bits: value = "); print_hex (get_value (), f);
    555  1.1  mrg       fprintf (f, ", mask = "); print_hex (get_mask (), f);
    556  1.1  mrg       fprintf (f, "\n");
    557  1.1  mrg     }
    558  1.1  mrg }
    559  1.1  mrg 
    560  1.1  mrg /* Print value range lattice to F.  */
    561  1.1  mrg 
    562  1.1  mrg void
    563  1.1  mrg ipcp_vr_lattice::print (FILE * f)
    564  1.1  mrg {
    565  1.1  mrg   dump_value_range (f, &m_vr);
    566  1.1  mrg }
    567  1.1  mrg 
    568  1.1  mrg /* Print all ipcp_lattices of all functions to F.  */
    569  1.1  mrg 
    570  1.1  mrg static void
    571  1.1  mrg print_all_lattices (FILE * f, bool dump_sources, bool dump_benefits)
    572  1.1  mrg {
    573  1.1  mrg   struct cgraph_node *node;
    574  1.1  mrg   int i, count;
    575  1.1  mrg 
    576  1.1  mrg   fprintf (f, "\nLattices:\n");
    577  1.1  mrg   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
    578  1.1  mrg     {
    579  1.1  mrg       class ipa_node_params *info;
    580  1.1  mrg 
    581  1.1  mrg       info = ipa_node_params_sum->get (node);
    582  1.1  mrg       /* Skip unoptimized functions and constprop clones since we don't make
    583  1.1  mrg 	 lattices for them.  */
    584  1.1  mrg       if (!info || info->ipcp_orig_node)
    585  1.1  mrg 	continue;
    586  1.1  mrg       fprintf (f, "  Node: %s:\n", node->dump_name ());
    587  1.1  mrg       count = ipa_get_param_count (info);
    588  1.1  mrg       for (i = 0; i < count; i++)
    589  1.1  mrg 	{
    590  1.1  mrg 	  struct ipcp_agg_lattice *aglat;
    591  1.1  mrg 	  class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
    592  1.1  mrg 	  fprintf (f, "    param [%d]: ", i);
    593  1.1  mrg 	  plats->itself.print (f, dump_sources, dump_benefits);
    594  1.1  mrg 	  fprintf (f, "         ctxs: ");
    595  1.1  mrg 	  plats->ctxlat.print (f, dump_sources, dump_benefits);
    596  1.1  mrg 	  plats->bits_lattice.print (f);
    597  1.1  mrg 	  fprintf (f, "         ");
    598  1.1  mrg 	  plats->m_value_range.print (f);
    599  1.1  mrg 	  fprintf (f, "\n");
    600  1.1  mrg 	  if (plats->virt_call)
    601  1.1  mrg 	    fprintf (f, "        virt_call flag set\n");
    602  1.1  mrg 
    603  1.1  mrg 	  if (plats->aggs_bottom)
    604  1.1  mrg 	    {
    605  1.1  mrg 	      fprintf (f, "        AGGS BOTTOM\n");
    606  1.1  mrg 	      continue;
    607  1.1  mrg 	    }
    608  1.1  mrg 	  if (plats->aggs_contain_variable)
    609  1.1  mrg 	    fprintf (f, "        AGGS VARIABLE\n");
    610  1.1  mrg 	  for (aglat = plats->aggs; aglat; aglat = aglat->next)
    611  1.1  mrg 	    {
    612  1.1  mrg 	      fprintf (f, "        %soffset " HOST_WIDE_INT_PRINT_DEC ": ",
    613  1.1  mrg 		       plats->aggs_by_ref ? "ref " : "", aglat->offset);
    614  1.1  mrg 	      aglat->print (f, dump_sources, dump_benefits);
    615  1.1  mrg 	    }
    616  1.1  mrg 	}
    617  1.1  mrg     }
    618  1.1  mrg }
    619  1.1  mrg 
    620  1.1  mrg /* Determine whether it is at all technically possible to create clones of NODE
    621  1.1  mrg    and store this information in the ipa_node_params structure associated
    622  1.1  mrg    with NODE.  */
    623  1.1  mrg 
    624  1.1  mrg static void
    625  1.1  mrg determine_versionability (struct cgraph_node *node,
    626  1.1  mrg 			  class ipa_node_params *info)
    627  1.1  mrg {
    628  1.1  mrg   const char *reason = NULL;
    629  1.1  mrg 
    630  1.1  mrg   /* There are a number of generic reasons functions cannot be versioned.  We
    631  1.1  mrg      also cannot remove parameters if there are type attributes such as fnspec
    632  1.1  mrg      present.  */
    633  1.1  mrg   if (node->alias || node->thunk)
    634  1.1  mrg     reason = "alias or thunk";
    635  1.1  mrg   else if (!node->versionable)
    636  1.1  mrg     reason = "not a tree_versionable_function";
    637  1.1  mrg   else if (node->get_availability () <= AVAIL_INTERPOSABLE)
    638  1.1  mrg     reason = "insufficient body availability";
    639  1.1  mrg   else if (!opt_for_fn (node->decl, optimize)
    640  1.1  mrg 	   || !opt_for_fn (node->decl, flag_ipa_cp))
    641  1.1  mrg     reason = "non-optimized function";
    642  1.1  mrg   else if (lookup_attribute ("omp declare simd", DECL_ATTRIBUTES (node->decl)))
    643  1.1  mrg     {
    644  1.1  mrg       /* Ideally we should clone the SIMD clones themselves and create
    645  1.1  mrg 	 vector copies of them, so IPA-cp and SIMD clones can happily
    646  1.1  mrg 	 coexist, but that may not be worth the effort.  */
    647  1.1  mrg       reason = "function has SIMD clones";
    648  1.1  mrg     }
    649  1.1  mrg   else if (lookup_attribute ("target_clones", DECL_ATTRIBUTES (node->decl)))
    650  1.1  mrg     {
    651  1.1  mrg       /* Ideally we should clone the target clones themselves and create
    652  1.1  mrg 	 copies of them, so IPA-cp and target clones can happily
    653  1.1  mrg 	 coexist, but that may not be worth the effort.  */
    654  1.1  mrg       reason = "function target_clones attribute";
    655  1.1  mrg     }
    656  1.1  mrg   /* Don't clone decls local to a comdat group; it breaks and for C++
    657  1.1  mrg      decloned constructors, inlining is always better anyway.  */
    658  1.1  mrg   else if (node->comdat_local_p ())
    659  1.1  mrg     reason = "comdat-local function";
    660  1.1  mrg   else if (node->calls_comdat_local)
    661  1.1  mrg     {
    662  1.1  mrg       /* TODO: call is versionable if we make sure that all
    663  1.1  mrg 	 callers are inside of a comdat group.  */
    664  1.1  mrg       reason = "calls comdat-local function";
    665  1.1  mrg     }
    666  1.1  mrg 
    667  1.1  mrg   /* Functions calling BUILT_IN_VA_ARG_PACK and BUILT_IN_VA_ARG_PACK_LEN
    668  1.1  mrg      work only when inlined.  Cloning them may still lead to better code
    669  1.1  mrg      because ipa-cp will not give up on cloning further.  If the function is
    670  1.1  mrg      external this however leads to wrong code because we may end up producing
    671  1.1  mrg      offline copy of the function.  */
    672  1.1  mrg   if (DECL_EXTERNAL (node->decl))
    673  1.1  mrg     for (cgraph_edge *edge = node->callees; !reason && edge;
    674  1.1  mrg 	 edge = edge->next_callee)
    675  1.1  mrg       if (fndecl_built_in_p (edge->callee->decl, BUILT_IN_NORMAL))
    676  1.1  mrg         {
    677  1.1  mrg 	  if (DECL_FUNCTION_CODE (edge->callee->decl) == BUILT_IN_VA_ARG_PACK)
    678  1.1  mrg 	    reason = "external function which calls va_arg_pack";
    679  1.1  mrg 	  if (DECL_FUNCTION_CODE (edge->callee->decl)
    680  1.1  mrg 	      == BUILT_IN_VA_ARG_PACK_LEN)
    681  1.1  mrg 	    reason = "external function which calls va_arg_pack_len";
    682  1.1  mrg         }
    683  1.1  mrg 
    684  1.1  mrg   if (reason && dump_file && !node->alias && !node->thunk)
    685  1.1  mrg     fprintf (dump_file, "Function %s is not versionable, reason: %s.\n",
    686  1.1  mrg 	     node->dump_name (), reason);
    687  1.1  mrg 
    688  1.1  mrg   info->versionable = (reason == NULL);
    689  1.1  mrg }
    690  1.1  mrg 
    691  1.1  mrg /* Return true if it is at all technically possible to create clones of a
    692  1.1  mrg    NODE.  */
    693  1.1  mrg 
    694  1.1  mrg static bool
    695  1.1  mrg ipcp_versionable_function_p (struct cgraph_node *node)
    696  1.1  mrg {
    697  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
    698  1.1  mrg   return info && info->versionable;
    699  1.1  mrg }
    700  1.1  mrg 
    701  1.1  mrg /* Structure holding accumulated information about callers of a node.  */
    702  1.1  mrg 
    703  1.1  mrg struct caller_statistics
    704  1.1  mrg {
    705  1.1  mrg   /* If requested (see below), self-recursive call counts are summed into this
    706  1.1  mrg      field.  */
    707  1.1  mrg   profile_count rec_count_sum;
    708  1.1  mrg   /* The sum of all ipa counts of all the other (non-recursive) calls.  */
    709  1.1  mrg   profile_count count_sum;
    710  1.1  mrg   /* Sum of all frequencies for all calls.  */
    711  1.1  mrg   sreal freq_sum;
    712  1.1  mrg   /* Number of calls and hot calls respectively.  */
    713  1.1  mrg   int n_calls, n_hot_calls;
    714  1.1  mrg   /* If itself is set up, also count the number of non-self-recursive
    715  1.1  mrg      calls.  */
    716  1.1  mrg   int n_nonrec_calls;
    717  1.1  mrg   /* If non-NULL, this is the node itself and calls from it should have their
    718  1.1  mrg      counts included in rec_count_sum and not count_sum.  */
    719  1.1  mrg   cgraph_node *itself;
    720  1.1  mrg };
    721  1.1  mrg 
    722  1.1  mrg /* Initialize fields of STAT to zeroes and optionally set it up so that edges
    723  1.1  mrg    from IGNORED_CALLER are not counted.  */
    724  1.1  mrg 
    725  1.1  mrg static inline void
    726  1.1  mrg init_caller_stats (caller_statistics *stats, cgraph_node *itself = NULL)
    727  1.1  mrg {
    728  1.1  mrg   stats->rec_count_sum = profile_count::zero ();
    729  1.1  mrg   stats->count_sum = profile_count::zero ();
    730  1.1  mrg   stats->n_calls = 0;
    731  1.1  mrg   stats->n_hot_calls = 0;
    732  1.1  mrg   stats->n_nonrec_calls = 0;
    733  1.1  mrg   stats->freq_sum = 0;
    734  1.1  mrg   stats->itself = itself;
    735  1.1  mrg }
    736  1.1  mrg 
    737  1.1  mrg /* Worker callback of cgraph_for_node_and_aliases accumulating statistics of
    738  1.1  mrg    non-thunk incoming edges to NODE.  */
    739  1.1  mrg 
    740  1.1  mrg static bool
    741  1.1  mrg gather_caller_stats (struct cgraph_node *node, void *data)
    742  1.1  mrg {
    743  1.1  mrg   struct caller_statistics *stats = (struct caller_statistics *) data;
    744  1.1  mrg   struct cgraph_edge *cs;
    745  1.1  mrg 
    746  1.1  mrg   for (cs = node->callers; cs; cs = cs->next_caller)
    747  1.1  mrg     if (!cs->caller->thunk)
    748  1.1  mrg       {
    749  1.1  mrg 	ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
    750  1.1  mrg 	if (info && info->node_dead)
    751  1.1  mrg 	  continue;
    752  1.1  mrg 
    753  1.1  mrg 	if (cs->count.ipa ().initialized_p ())
    754  1.1  mrg 	  {
    755  1.1  mrg 	    if (stats->itself && stats->itself == cs->caller)
    756  1.1  mrg 	      stats->rec_count_sum += cs->count.ipa ();
    757  1.1  mrg 	    else
    758  1.1  mrg 	      stats->count_sum += cs->count.ipa ();
    759  1.1  mrg 	  }
    760  1.1  mrg 	stats->freq_sum += cs->sreal_frequency ();
    761  1.1  mrg 	stats->n_calls++;
    762  1.1  mrg 	if (stats->itself && stats->itself != cs->caller)
    763  1.1  mrg 	  stats->n_nonrec_calls++;
    764  1.1  mrg 
    765  1.1  mrg 	if (cs->maybe_hot_p ())
    766  1.1  mrg 	  stats->n_hot_calls ++;
    767  1.1  mrg       }
    768  1.1  mrg   return false;
    769  1.1  mrg 
    770  1.1  mrg }
    771  1.1  mrg 
    772  1.1  mrg /* Return true if this NODE is viable candidate for cloning.  */
    773  1.1  mrg 
    774  1.1  mrg static bool
    775  1.1  mrg ipcp_cloning_candidate_p (struct cgraph_node *node)
    776  1.1  mrg {
    777  1.1  mrg   struct caller_statistics stats;
    778  1.1  mrg 
    779  1.1  mrg   gcc_checking_assert (node->has_gimple_body_p ());
    780  1.1  mrg 
    781  1.1  mrg   if (!opt_for_fn (node->decl, flag_ipa_cp_clone))
    782  1.1  mrg     {
    783  1.1  mrg       if (dump_file)
    784  1.1  mrg 	fprintf (dump_file, "Not considering %s for cloning; "
    785  1.1  mrg 		 "-fipa-cp-clone disabled.\n",
    786  1.1  mrg 		 node->dump_name ());
    787  1.1  mrg       return false;
    788  1.1  mrg     }
    789  1.1  mrg 
    790  1.1  mrg   if (node->optimize_for_size_p ())
    791  1.1  mrg     {
    792  1.1  mrg       if (dump_file)
    793  1.1  mrg 	fprintf (dump_file, "Not considering %s for cloning; "
    794  1.1  mrg 		 "optimizing it for size.\n",
    795  1.1  mrg 		 node->dump_name ());
    796  1.1  mrg       return false;
    797  1.1  mrg     }
    798  1.1  mrg 
    799  1.1  mrg   init_caller_stats (&stats);
    800  1.1  mrg   node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats, false);
    801  1.1  mrg 
    802  1.1  mrg   if (ipa_size_summaries->get (node)->self_size < stats.n_calls)
    803  1.1  mrg     {
    804  1.1  mrg       if (dump_file)
    805  1.1  mrg 	fprintf (dump_file, "Considering %s for cloning; code might shrink.\n",
    806  1.1  mrg 		 node->dump_name ());
    807  1.1  mrg       return true;
    808  1.1  mrg     }
    809  1.1  mrg 
    810  1.1  mrg   /* When profile is available and function is hot, propagate into it even if
    811  1.1  mrg      calls seems cold; constant propagation can improve function's speed
    812  1.1  mrg      significantly.  */
    813  1.1  mrg   if (stats.count_sum > profile_count::zero ()
    814  1.1  mrg       && node->count.ipa ().initialized_p ())
    815  1.1  mrg     {
    816  1.1  mrg       if (stats.count_sum > node->count.ipa ().apply_scale (90, 100))
    817  1.1  mrg 	{
    818  1.1  mrg 	  if (dump_file)
    819  1.1  mrg 	    fprintf (dump_file, "Considering %s for cloning; "
    820  1.1  mrg 		     "usually called directly.\n",
    821  1.1  mrg 		     node->dump_name ());
    822  1.1  mrg 	  return true;
    823  1.1  mrg 	}
    824  1.1  mrg     }
    825  1.1  mrg   if (!stats.n_hot_calls)
    826  1.1  mrg     {
    827  1.1  mrg       if (dump_file)
    828  1.1  mrg 	fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
    829  1.1  mrg 		 node->dump_name ());
    830  1.1  mrg       return false;
    831  1.1  mrg     }
    832  1.1  mrg   if (dump_file)
    833  1.1  mrg     fprintf (dump_file, "Considering %s for cloning.\n",
    834  1.1  mrg 	     node->dump_name ());
    835  1.1  mrg   return true;
    836  1.1  mrg }
    837  1.1  mrg 
    838  1.1  mrg template <typename valtype>
    839  1.1  mrg class value_topo_info
    840  1.1  mrg {
    841  1.1  mrg public:
    842  1.1  mrg   /* Head of the linked list of topologically sorted values. */
    843  1.1  mrg   ipcp_value<valtype> *values_topo;
    844  1.1  mrg   /* Stack for creating SCCs, represented by a linked list too.  */
    845  1.1  mrg   ipcp_value<valtype> *stack;
    846  1.1  mrg   /* Counter driving the algorithm in add_val_to_toposort.  */
    847  1.1  mrg   int dfs_counter;
    848  1.1  mrg 
    849  1.1  mrg   value_topo_info () : values_topo (NULL), stack (NULL), dfs_counter (0)
    850  1.1  mrg   {}
    851  1.1  mrg   void add_val (ipcp_value<valtype> *cur_val);
    852  1.1  mrg   void propagate_effects ();
    853  1.1  mrg };
    854  1.1  mrg 
    855  1.1  mrg /* Arrays representing a topological ordering of call graph nodes and a stack
    856  1.1  mrg    of nodes used during constant propagation and also data required to perform
    857  1.1  mrg    topological sort of values and propagation of benefits in the determined
    858  1.1  mrg    order.  */
    859  1.1  mrg 
    860  1.1  mrg class ipa_topo_info
    861  1.1  mrg {
    862  1.1  mrg public:
    863  1.1  mrg   /* Array with obtained topological order of cgraph nodes.  */
    864  1.1  mrg   struct cgraph_node **order;
    865  1.1  mrg   /* Stack of cgraph nodes used during propagation within SCC until all values
    866  1.1  mrg      in the SCC stabilize.  */
    867  1.1  mrg   struct cgraph_node **stack;
    868  1.1  mrg   int nnodes, stack_top;
    869  1.1  mrg 
    870  1.1  mrg   value_topo_info<tree> constants;
    871  1.1  mrg   value_topo_info<ipa_polymorphic_call_context> contexts;
    872  1.1  mrg 
    873  1.1  mrg   ipa_topo_info () : order(NULL), stack(NULL), nnodes(0), stack_top(0),
    874  1.1  mrg     constants ()
    875  1.1  mrg   {}
    876  1.1  mrg };
    877  1.1  mrg 
    878  1.1  mrg /* Skip edges from and to nodes without ipa_cp enabled.
    879  1.1  mrg    Ignore not available symbols.  */
    880  1.1  mrg 
    881  1.1  mrg static bool
    882  1.1  mrg ignore_edge_p (cgraph_edge *e)
    883  1.1  mrg {
    884  1.1  mrg   enum availability avail;
    885  1.1  mrg   cgraph_node *ultimate_target
    886  1.1  mrg     = e->callee->function_or_virtual_thunk_symbol (&avail, e->caller);
    887  1.1  mrg 
    888  1.1  mrg   return (avail <= AVAIL_INTERPOSABLE
    889  1.1  mrg 	  || !opt_for_fn (ultimate_target->decl, optimize)
    890  1.1  mrg 	  || !opt_for_fn (ultimate_target->decl, flag_ipa_cp));
    891  1.1  mrg }
    892  1.1  mrg 
    893  1.1  mrg /* Allocate the arrays in TOPO and topologically sort the nodes into order.  */
    894  1.1  mrg 
    895  1.1  mrg static void
    896  1.1  mrg build_toporder_info (class ipa_topo_info *topo)
    897  1.1  mrg {
    898  1.1  mrg   topo->order = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    899  1.1  mrg   topo->stack = XCNEWVEC (struct cgraph_node *, symtab->cgraph_count);
    900  1.1  mrg 
    901  1.1  mrg   gcc_checking_assert (topo->stack_top == 0);
    902  1.1  mrg   topo->nnodes = ipa_reduced_postorder (topo->order, true,
    903  1.1  mrg 					ignore_edge_p);
    904  1.1  mrg }
    905  1.1  mrg 
    906  1.1  mrg /* Free information about strongly connected components and the arrays in
    907  1.1  mrg    TOPO.  */
    908  1.1  mrg 
    909  1.1  mrg static void
    910  1.1  mrg free_toporder_info (class ipa_topo_info *topo)
    911  1.1  mrg {
    912  1.1  mrg   ipa_free_postorder_info ();
    913  1.1  mrg   free (topo->order);
    914  1.1  mrg   free (topo->stack);
    915  1.1  mrg }
    916  1.1  mrg 
    917  1.1  mrg /* Add NODE to the stack in TOPO, unless it is already there.  */
    918  1.1  mrg 
    919  1.1  mrg static inline void
    920  1.1  mrg push_node_to_stack (class ipa_topo_info *topo, struct cgraph_node *node)
    921  1.1  mrg {
    922  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
    923  1.1  mrg   if (info->node_enqueued)
    924  1.1  mrg     return;
    925  1.1  mrg   info->node_enqueued = 1;
    926  1.1  mrg   topo->stack[topo->stack_top++] = node;
    927  1.1  mrg }
    928  1.1  mrg 
    929  1.1  mrg /* Pop a node from the stack in TOPO and return it or return NULL if the stack
    930  1.1  mrg    is empty.  */
    931  1.1  mrg 
    932  1.1  mrg static struct cgraph_node *
    933  1.1  mrg pop_node_from_stack (class ipa_topo_info *topo)
    934  1.1  mrg {
    935  1.1  mrg   if (topo->stack_top)
    936  1.1  mrg     {
    937  1.1  mrg       struct cgraph_node *node;
    938  1.1  mrg       topo->stack_top--;
    939  1.1  mrg       node = topo->stack[topo->stack_top];
    940  1.1  mrg       ipa_node_params_sum->get (node)->node_enqueued = 0;
    941  1.1  mrg       return node;
    942  1.1  mrg     }
    943  1.1  mrg   else
    944  1.1  mrg     return NULL;
    945  1.1  mrg }
    946  1.1  mrg 
    947  1.1  mrg /* Set lattice LAT to bottom and return true if it previously was not set as
    948  1.1  mrg    such.  */
    949  1.1  mrg 
    950  1.1  mrg template <typename valtype>
    951  1.1  mrg inline bool
    952  1.1  mrg ipcp_lattice<valtype>::set_to_bottom ()
    953  1.1  mrg {
    954  1.1  mrg   bool ret = !bottom;
    955  1.1  mrg   bottom = true;
    956  1.1  mrg   return ret;
    957  1.1  mrg }
    958  1.1  mrg 
    959  1.1  mrg /* Mark lattice as containing an unknown value and return true if it previously
    960  1.1  mrg    was not marked as such.  */
    961  1.1  mrg 
    962  1.1  mrg template <typename valtype>
    963  1.1  mrg inline bool
    964  1.1  mrg ipcp_lattice<valtype>::set_contains_variable ()
    965  1.1  mrg {
    966  1.1  mrg   bool ret = !contains_variable;
    967  1.1  mrg   contains_variable = true;
    968  1.1  mrg   return ret;
    969  1.1  mrg }
    970  1.1  mrg 
    971  1.1  mrg /* Set all aggregate lattices in PLATS to bottom and return true if they were
    972  1.1  mrg    not previously set as such.  */
    973  1.1  mrg 
    974  1.1  mrg static inline bool
    975  1.1  mrg set_agg_lats_to_bottom (class ipcp_param_lattices *plats)
    976  1.1  mrg {
    977  1.1  mrg   bool ret = !plats->aggs_bottom;
    978  1.1  mrg   plats->aggs_bottom = true;
    979  1.1  mrg   return ret;
    980  1.1  mrg }
    981  1.1  mrg 
    982  1.1  mrg /* Mark all aggregate lattices in PLATS as containing an unknown value and
    983  1.1  mrg    return true if they were not previously marked as such.  */
    984  1.1  mrg 
    985  1.1  mrg static inline bool
    986  1.1  mrg set_agg_lats_contain_variable (class ipcp_param_lattices *plats)
    987  1.1  mrg {
    988  1.1  mrg   bool ret = !plats->aggs_contain_variable;
    989  1.1  mrg   plats->aggs_contain_variable = true;
    990  1.1  mrg   return ret;
    991  1.1  mrg }
    992  1.1  mrg 
    993  1.1  mrg bool
    994  1.1  mrg ipcp_vr_lattice::meet_with (const ipcp_vr_lattice &other)
    995  1.1  mrg {
    996  1.1  mrg   return meet_with_1 (&other.m_vr);
    997  1.1  mrg }
    998  1.1  mrg 
    999  1.1  mrg /* Meet the current value of the lattice with value range described by VR
   1000  1.1  mrg    lattice.  */
   1001  1.1  mrg 
   1002  1.1  mrg bool
   1003  1.1  mrg ipcp_vr_lattice::meet_with (const value_range *p_vr)
   1004  1.1  mrg {
   1005  1.1  mrg   return meet_with_1 (p_vr);
   1006  1.1  mrg }
   1007  1.1  mrg 
   1008  1.1  mrg /* Meet the current value of the lattice with value range described by
   1009  1.1  mrg    OTHER_VR lattice.  Return TRUE if anything changed.  */
   1010  1.1  mrg 
   1011  1.1  mrg bool
   1012  1.1  mrg ipcp_vr_lattice::meet_with_1 (const value_range *other_vr)
   1013  1.1  mrg {
   1014  1.1  mrg   if (bottom_p ())
   1015  1.1  mrg     return false;
   1016  1.1  mrg 
   1017  1.1  mrg   if (other_vr->varying_p ())
   1018  1.1  mrg     return set_to_bottom ();
   1019  1.1  mrg 
   1020  1.1  mrg   value_range save (m_vr);
   1021  1.1  mrg   m_vr.union_ (other_vr);
   1022  1.1  mrg   return !m_vr.equal_p (save);
   1023  1.1  mrg }
   1024  1.1  mrg 
   1025  1.1  mrg /* Return true if value range information in the lattice is yet unknown.  */
   1026  1.1  mrg 
   1027  1.1  mrg bool
   1028  1.1  mrg ipcp_vr_lattice::top_p () const
   1029  1.1  mrg {
   1030  1.1  mrg   return m_vr.undefined_p ();
   1031  1.1  mrg }
   1032  1.1  mrg 
   1033  1.1  mrg /* Return true if value range information in the lattice is known to be
   1034  1.1  mrg    unusable.  */
   1035  1.1  mrg 
   1036  1.1  mrg bool
   1037  1.1  mrg ipcp_vr_lattice::bottom_p () const
   1038  1.1  mrg {
   1039  1.1  mrg   return m_vr.varying_p ();
   1040  1.1  mrg }
   1041  1.1  mrg 
   1042  1.1  mrg /* Set value range information in the lattice to bottom.  Return true if it
   1043  1.1  mrg    previously was in a different state.  */
   1044  1.1  mrg 
   1045  1.1  mrg bool
   1046  1.1  mrg ipcp_vr_lattice::set_to_bottom ()
   1047  1.1  mrg {
   1048  1.1  mrg   if (m_vr.varying_p ())
   1049  1.1  mrg     return false;
   1050  1.1  mrg   /* ?? We create all sorts of VARYING ranges for floats, structures,
   1051  1.1  mrg      and other types which we cannot handle as ranges.  We should
   1052  1.1  mrg      probably avoid handling them throughout the pass, but it's easier
   1053  1.1  mrg      to create a sensible VARYING here and let the lattice
   1054  1.1  mrg      propagate.  */
   1055  1.1  mrg   m_vr.set_varying (integer_type_node);
   1056  1.1  mrg   return true;
   1057  1.1  mrg }
   1058  1.1  mrg 
   1059  1.1  mrg /* Set lattice value to bottom, if it already isn't the case.  */
   1060  1.1  mrg 
   1061  1.1  mrg bool
   1062  1.1  mrg ipcp_bits_lattice::set_to_bottom ()
   1063  1.1  mrg {
   1064  1.1  mrg   if (bottom_p ())
   1065  1.1  mrg     return false;
   1066  1.1  mrg   m_lattice_val = IPA_BITS_VARYING;
   1067  1.1  mrg   m_value = 0;
   1068  1.1  mrg   m_mask = -1;
   1069  1.1  mrg   return true;
   1070  1.1  mrg }
   1071  1.1  mrg 
   1072  1.1  mrg /* Set to constant if it isn't already. Only meant to be called
   1073  1.1  mrg    when switching state from TOP.  */
   1074  1.1  mrg 
   1075  1.1  mrg bool
   1076  1.1  mrg ipcp_bits_lattice::set_to_constant (widest_int value, widest_int mask)
   1077  1.1  mrg {
   1078  1.1  mrg   gcc_assert (top_p ());
   1079  1.1  mrg   m_lattice_val = IPA_BITS_CONSTANT;
   1080  1.1  mrg   m_value = wi::bit_and (wi::bit_not (mask), value);
   1081  1.1  mrg   m_mask = mask;
   1082  1.1  mrg   return true;
   1083  1.1  mrg }
   1084  1.1  mrg 
   1085  1.1  mrg /* Return true if any of the known bits are non-zero.  */
   1086  1.1  mrg 
   1087  1.1  mrg bool
   1088  1.1  mrg ipcp_bits_lattice::known_nonzero_p () const
   1089  1.1  mrg {
   1090  1.1  mrg   if (!constant_p ())
   1091  1.1  mrg     return false;
   1092  1.1  mrg   return wi::ne_p (wi::bit_and (wi::bit_not (m_mask), m_value), 0);
   1093  1.1  mrg }
   1094  1.1  mrg 
   1095  1.1  mrg /* Convert operand to value, mask form.  */
   1096  1.1  mrg 
   1097  1.1  mrg void
   1098  1.1  mrg ipcp_bits_lattice::get_value_and_mask (tree operand, widest_int *valuep, widest_int *maskp)
   1099  1.1  mrg {
   1100  1.1  mrg   wide_int get_nonzero_bits (const_tree);
   1101  1.1  mrg 
   1102  1.1  mrg   if (TREE_CODE (operand) == INTEGER_CST)
   1103  1.1  mrg     {
   1104  1.1  mrg       *valuep = wi::to_widest (operand);
   1105  1.1  mrg       *maskp = 0;
   1106  1.1  mrg     }
   1107  1.1  mrg   else
   1108  1.1  mrg     {
   1109  1.1  mrg       *valuep = 0;
   1110  1.1  mrg       *maskp = -1;
   1111  1.1  mrg     }
   1112  1.1  mrg }
   1113  1.1  mrg 
   1114  1.1  mrg /* Meet operation, similar to ccp_lattice_meet, we xor values
   1115  1.1  mrg    if this->value, value have different values at same bit positions, we want
   1116  1.1  mrg    to drop that bit to varying. Return true if mask is changed.
   1117  1.1  mrg    This function assumes that the lattice value is in CONSTANT state.  If
   1118  1.1  mrg    DROP_ALL_ONES, mask out any known bits with value one afterwards.  */
   1119  1.1  mrg 
   1120  1.1  mrg bool
   1121  1.1  mrg ipcp_bits_lattice::meet_with_1 (widest_int value, widest_int mask,
   1122  1.1  mrg 				unsigned precision, bool drop_all_ones)
   1123  1.1  mrg {
   1124  1.1  mrg   gcc_assert (constant_p ());
   1125  1.1  mrg 
   1126  1.1  mrg   widest_int old_mask = m_mask;
   1127  1.1  mrg   m_mask = (m_mask | mask) | (m_value ^ value);
   1128  1.1  mrg   if (drop_all_ones)
   1129  1.1  mrg     m_mask |= m_value;
   1130  1.1  mrg   m_value &= ~m_mask;
   1131  1.1  mrg 
   1132  1.1  mrg   if (wi::sext (m_mask, precision) == -1)
   1133  1.1  mrg     return set_to_bottom ();
   1134  1.1  mrg 
   1135  1.1  mrg   return m_mask != old_mask;
   1136  1.1  mrg }
   1137  1.1  mrg 
   1138  1.1  mrg /* Meet the bits lattice with operand
   1139  1.1  mrg    described by <value, mask, sgn, precision.  */
   1140  1.1  mrg 
   1141  1.1  mrg bool
   1142  1.1  mrg ipcp_bits_lattice::meet_with (widest_int value, widest_int mask,
   1143  1.1  mrg 			      unsigned precision)
   1144  1.1  mrg {
   1145  1.1  mrg   if (bottom_p ())
   1146  1.1  mrg     return false;
   1147  1.1  mrg 
   1148  1.1  mrg   if (top_p ())
   1149  1.1  mrg     {
   1150  1.1  mrg       if (wi::sext (mask, precision) == -1)
   1151  1.1  mrg 	return set_to_bottom ();
   1152  1.1  mrg       return set_to_constant (value, mask);
   1153  1.1  mrg     }
   1154  1.1  mrg 
   1155  1.1  mrg   return meet_with_1 (value, mask, precision, false);
   1156  1.1  mrg }
   1157  1.1  mrg 
   1158  1.1  mrg /* Meet bits lattice with the result of bit_value_binop (other, operand)
   1159  1.1  mrg    if code is binary operation or bit_value_unop (other) if code is unary op.
   1160  1.1  mrg    In the case when code is nop_expr, no adjustment is required.  If
   1161  1.1  mrg    DROP_ALL_ONES, mask out any known bits with value one afterwards.  */
   1162  1.1  mrg 
   1163  1.1  mrg bool
   1164  1.1  mrg ipcp_bits_lattice::meet_with (ipcp_bits_lattice& other, unsigned precision,
   1165  1.1  mrg 			      signop sgn, enum tree_code code, tree operand,
   1166  1.1  mrg 			      bool drop_all_ones)
   1167  1.1  mrg {
   1168  1.1  mrg   if (other.bottom_p ())
   1169  1.1  mrg     return set_to_bottom ();
   1170  1.1  mrg 
   1171  1.1  mrg   if (bottom_p () || other.top_p ())
   1172  1.1  mrg     return false;
   1173  1.1  mrg 
   1174  1.1  mrg   widest_int adjusted_value, adjusted_mask;
   1175  1.1  mrg 
   1176  1.1  mrg   if (TREE_CODE_CLASS (code) == tcc_binary)
   1177  1.1  mrg     {
   1178  1.1  mrg       tree type = TREE_TYPE (operand);
   1179  1.1  mrg       widest_int o_value, o_mask;
   1180  1.1  mrg       get_value_and_mask (operand, &o_value, &o_mask);
   1181  1.1  mrg 
   1182  1.1  mrg       bit_value_binop (code, sgn, precision, &adjusted_value, &adjusted_mask,
   1183  1.1  mrg 		       sgn, precision, other.get_value (), other.get_mask (),
   1184  1.1  mrg 		       TYPE_SIGN (type), TYPE_PRECISION (type), o_value, o_mask);
   1185  1.1  mrg 
   1186  1.1  mrg       if (wi::sext (adjusted_mask, precision) == -1)
   1187  1.1  mrg 	return set_to_bottom ();
   1188  1.1  mrg     }
   1189  1.1  mrg 
   1190  1.1  mrg   else if (TREE_CODE_CLASS (code) == tcc_unary)
   1191  1.1  mrg     {
   1192  1.1  mrg       bit_value_unop (code, sgn, precision, &adjusted_value,
   1193  1.1  mrg 		      &adjusted_mask, sgn, precision, other.get_value (),
   1194  1.1  mrg 		      other.get_mask ());
   1195  1.1  mrg 
   1196  1.1  mrg       if (wi::sext (adjusted_mask, precision) == -1)
   1197  1.1  mrg 	return set_to_bottom ();
   1198  1.1  mrg     }
   1199  1.1  mrg 
   1200  1.1  mrg   else
   1201  1.1  mrg     return set_to_bottom ();
   1202  1.1  mrg 
   1203  1.1  mrg   if (top_p ())
   1204  1.1  mrg     {
   1205  1.1  mrg       if (drop_all_ones)
   1206  1.1  mrg 	{
   1207  1.1  mrg 	  adjusted_mask |= adjusted_value;
   1208  1.1  mrg 	  adjusted_value &= ~adjusted_mask;
   1209  1.1  mrg 	}
   1210  1.1  mrg       if (wi::sext (adjusted_mask, precision) == -1)
   1211  1.1  mrg 	return set_to_bottom ();
   1212  1.1  mrg       return set_to_constant (adjusted_value, adjusted_mask);
   1213  1.1  mrg     }
   1214  1.1  mrg   else
   1215  1.1  mrg     return meet_with_1 (adjusted_value, adjusted_mask, precision,
   1216  1.1  mrg 			drop_all_ones);
   1217  1.1  mrg }
   1218  1.1  mrg 
   1219  1.1  mrg /* Mark bot aggregate and scalar lattices as containing an unknown variable,
   1220  1.1  mrg    return true is any of them has not been marked as such so far.  */
   1221  1.1  mrg 
   1222  1.1  mrg static inline bool
   1223  1.1  mrg set_all_contains_variable (class ipcp_param_lattices *plats)
   1224  1.1  mrg {
   1225  1.1  mrg   bool ret;
   1226  1.1  mrg   ret = plats->itself.set_contains_variable ();
   1227  1.1  mrg   ret |= plats->ctxlat.set_contains_variable ();
   1228  1.1  mrg   ret |= set_agg_lats_contain_variable (plats);
   1229  1.1  mrg   ret |= plats->bits_lattice.set_to_bottom ();
   1230  1.1  mrg   ret |= plats->m_value_range.set_to_bottom ();
   1231  1.1  mrg   return ret;
   1232  1.1  mrg }
   1233  1.1  mrg 
   1234  1.1  mrg /* Worker of call_for_symbol_thunks_and_aliases, increment the integer DATA
   1235  1.1  mrg    points to by the number of callers to NODE.  */
   1236  1.1  mrg 
   1237  1.1  mrg static bool
   1238  1.1  mrg count_callers (cgraph_node *node, void *data)
   1239  1.1  mrg {
   1240  1.1  mrg   int *caller_count = (int *) data;
   1241  1.1  mrg 
   1242  1.1  mrg   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
   1243  1.1  mrg     /* Local thunks can be handled transparently, but if the thunk cannot
   1244  1.1  mrg        be optimized out, count it as a real use.  */
   1245  1.1  mrg     if (!cs->caller->thunk || !cs->caller->local)
   1246  1.1  mrg       ++*caller_count;
   1247  1.1  mrg   return false;
   1248  1.1  mrg }
   1249  1.1  mrg 
   1250  1.1  mrg /* Worker of call_for_symbol_thunks_and_aliases, it is supposed to be called on
   1251  1.1  mrg    the one caller of some other node.  Set the caller's corresponding flag.  */
   1252  1.1  mrg 
   1253  1.1  mrg static bool
   1254  1.1  mrg set_single_call_flag (cgraph_node *node, void *)
   1255  1.1  mrg {
   1256  1.1  mrg   cgraph_edge *cs = node->callers;
   1257  1.1  mrg   /* Local thunks can be handled transparently, skip them.  */
   1258  1.1  mrg   while (cs && cs->caller->thunk && cs->caller->local)
   1259  1.1  mrg     cs = cs->next_caller;
   1260  1.1  mrg   if (cs)
   1261  1.1  mrg     if (ipa_node_params* info = ipa_node_params_sum->get (cs->caller))
   1262  1.1  mrg       {
   1263  1.1  mrg 	info->node_calling_single_call = true;
   1264  1.1  mrg 	return true;
   1265  1.1  mrg       }
   1266  1.1  mrg   return false;
   1267  1.1  mrg }
   1268  1.1  mrg 
   1269  1.1  mrg /* Initialize ipcp_lattices.  */
   1270  1.1  mrg 
   1271  1.1  mrg static void
   1272  1.1  mrg initialize_node_lattices (struct cgraph_node *node)
   1273  1.1  mrg {
   1274  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   1275  1.1  mrg   struct cgraph_edge *ie;
   1276  1.1  mrg   bool disable = false, variable = false;
   1277  1.1  mrg   int i;
   1278  1.1  mrg 
   1279  1.1  mrg   gcc_checking_assert (node->has_gimple_body_p ());
   1280  1.1  mrg 
   1281  1.1  mrg   if (!ipa_get_param_count (info))
   1282  1.1  mrg     disable = true;
   1283  1.1  mrg   else if (node->local)
   1284  1.1  mrg     {
   1285  1.1  mrg       int caller_count = 0;
   1286  1.1  mrg       node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
   1287  1.1  mrg 						true);
   1288  1.1  mrg       gcc_checking_assert (caller_count > 0);
   1289  1.1  mrg       if (caller_count == 1)
   1290  1.1  mrg 	node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
   1291  1.1  mrg 						  NULL, true);
   1292  1.1  mrg     }
   1293  1.1  mrg   else
   1294  1.1  mrg     {
   1295  1.1  mrg       /* When cloning is allowed, we can assume that externally visible
   1296  1.1  mrg 	 functions are not called.  We will compensate this by cloning
   1297  1.1  mrg 	 later.  */
   1298  1.1  mrg       if (ipcp_versionable_function_p (node)
   1299  1.1  mrg 	  && ipcp_cloning_candidate_p (node))
   1300  1.1  mrg 	variable = true;
   1301  1.1  mrg       else
   1302  1.1  mrg 	disable = true;
   1303  1.1  mrg     }
   1304  1.1  mrg 
   1305  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS)
   1306  1.1  mrg       && !node->alias && !node->thunk)
   1307  1.1  mrg     {
   1308  1.1  mrg       fprintf (dump_file, "Initializing lattices of %s\n",
   1309  1.1  mrg 	       node->dump_name ());
   1310  1.1  mrg       if (disable || variable)
   1311  1.1  mrg 	fprintf (dump_file, "  Marking all lattices as %s\n",
   1312  1.1  mrg 		 disable ? "BOTTOM" : "VARIABLE");
   1313  1.1  mrg     }
   1314  1.1  mrg 
   1315  1.1  mrg   auto_vec<bool, 16> surviving_params;
   1316  1.1  mrg   bool pre_modified = false;
   1317  1.1  mrg 
   1318  1.1  mrg   clone_info *cinfo = clone_info::get (node);
   1319  1.1  mrg 
   1320  1.1  mrg   if (!disable && cinfo && cinfo->param_adjustments)
   1321  1.1  mrg     {
   1322  1.1  mrg       /* At the moment all IPA optimizations should use the number of
   1323  1.1  mrg 	 parameters of the prevailing decl as the m_always_copy_start.
   1324  1.1  mrg 	 Handling any other value would complicate the code below, so for the
   1325  1.1  mrg 	 time bing let's only assert it is so.  */
   1326  1.1  mrg       gcc_assert ((cinfo->param_adjustments->m_always_copy_start
   1327  1.1  mrg 		   == ipa_get_param_count (info))
   1328  1.1  mrg 		  || cinfo->param_adjustments->m_always_copy_start < 0);
   1329  1.1  mrg 
   1330  1.1  mrg       pre_modified = true;
   1331  1.1  mrg       cinfo->param_adjustments->get_surviving_params (&surviving_params);
   1332  1.1  mrg 
   1333  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS)
   1334  1.1  mrg 	  && !node->alias && !node->thunk)
   1335  1.1  mrg 	{
   1336  1.1  mrg 	  bool first = true;
   1337  1.1  mrg 	  for (int j = 0; j < ipa_get_param_count (info); j++)
   1338  1.1  mrg 	    {
   1339  1.1  mrg 	      if (j < (int) surviving_params.length ()
   1340  1.1  mrg 		  && surviving_params[j])
   1341  1.1  mrg 		continue;
   1342  1.1  mrg 	      if (first)
   1343  1.1  mrg 		{
   1344  1.1  mrg 		  fprintf (dump_file,
   1345  1.1  mrg 			   "  The following parameters are dead on arrival:");
   1346  1.1  mrg 		  first = false;
   1347  1.1  mrg 		}
   1348  1.1  mrg 	      fprintf (dump_file, " %u", j);
   1349  1.1  mrg 	    }
   1350  1.1  mrg 	  if (!first)
   1351  1.1  mrg 	      fprintf (dump_file, "\n");
   1352  1.1  mrg 	}
   1353  1.1  mrg     }
   1354  1.1  mrg 
   1355  1.1  mrg   for (i = 0; i < ipa_get_param_count (info); i++)
   1356  1.1  mrg     {
   1357  1.1  mrg       ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   1358  1.1  mrg       if (disable
   1359  1.1  mrg 	  || !ipa_get_type (info, i)
   1360  1.1  mrg 	  || (pre_modified && (surviving_params.length () <= (unsigned) i
   1361  1.1  mrg 			       || !surviving_params[i])))
   1362  1.1  mrg 	{
   1363  1.1  mrg 	  plats->itself.set_to_bottom ();
   1364  1.1  mrg 	  plats->ctxlat.set_to_bottom ();
   1365  1.1  mrg 	  set_agg_lats_to_bottom (plats);
   1366  1.1  mrg 	  plats->bits_lattice.set_to_bottom ();
   1367  1.1  mrg 	  plats->m_value_range.m_vr = value_range ();
   1368  1.1  mrg 	  plats->m_value_range.set_to_bottom ();
   1369  1.1  mrg 	}
   1370  1.1  mrg       else
   1371  1.1  mrg 	{
   1372  1.1  mrg 	  plats->m_value_range.init ();
   1373  1.1  mrg 	  if (variable)
   1374  1.1  mrg 	    set_all_contains_variable (plats);
   1375  1.1  mrg 	}
   1376  1.1  mrg     }
   1377  1.1  mrg 
   1378  1.1  mrg   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
   1379  1.1  mrg     if (ie->indirect_info->polymorphic
   1380  1.1  mrg 	&& ie->indirect_info->param_index >= 0)
   1381  1.1  mrg       {
   1382  1.1  mrg 	gcc_checking_assert (ie->indirect_info->param_index >= 0);
   1383  1.1  mrg 	ipa_get_parm_lattices (info,
   1384  1.1  mrg 			       ie->indirect_info->param_index)->virt_call = 1;
   1385  1.1  mrg       }
   1386  1.1  mrg }
   1387  1.1  mrg 
   1388  1.1  mrg /* Return true if VALUE can be safely IPA-CP propagated to a parameter of type
   1389  1.1  mrg    PARAM_TYPE.  */
   1390  1.1  mrg 
   1391  1.1  mrg static bool
   1392  1.1  mrg ipacp_value_safe_for_type (tree param_type, tree value)
   1393  1.1  mrg {
   1394  1.1  mrg   tree val_type = TREE_TYPE (value);
   1395  1.1  mrg   if (param_type == val_type
   1396  1.1  mrg       || useless_type_conversion_p (param_type, val_type)
   1397  1.1  mrg       || fold_convertible_p (param_type, value))
   1398  1.1  mrg     return true;
   1399  1.1  mrg   else
   1400  1.1  mrg     return false;
   1401  1.1  mrg }
   1402  1.1  mrg 
   1403  1.1  mrg /* Return true iff X and Y should be considered equal values by IPA-CP.  */
   1404  1.1  mrg 
   1405  1.1  mrg bool
   1406  1.1  mrg values_equal_for_ipcp_p (tree x, tree y)
   1407  1.1  mrg {
   1408  1.1  mrg   gcc_checking_assert (x != NULL_TREE && y != NULL_TREE);
   1409  1.1  mrg 
   1410  1.1  mrg   if (x == y)
   1411  1.1  mrg     return true;
   1412  1.1  mrg 
   1413  1.1  mrg   if (TREE_CODE (x) == ADDR_EXPR
   1414  1.1  mrg       && TREE_CODE (y) == ADDR_EXPR
   1415  1.1  mrg       && TREE_CODE (TREE_OPERAND (x, 0)) == CONST_DECL
   1416  1.1  mrg       && TREE_CODE (TREE_OPERAND (y, 0)) == CONST_DECL)
   1417  1.1  mrg     return operand_equal_p (DECL_INITIAL (TREE_OPERAND (x, 0)),
   1418  1.1  mrg 			    DECL_INITIAL (TREE_OPERAND (y, 0)), 0);
   1419  1.1  mrg   else
   1420  1.1  mrg     return operand_equal_p (x, y, 0);
   1421  1.1  mrg }
   1422  1.1  mrg 
   1423  1.1  mrg /* Return the result of a (possibly arithmetic) operation on the constant
   1424  1.1  mrg    value INPUT.  OPERAND is 2nd operand for binary operation.  RES_TYPE is
   1425  1.1  mrg    the type of the parameter to which the result is passed.  Return
   1426  1.1  mrg    NULL_TREE if that cannot be determined or be considered an
   1427  1.1  mrg    interprocedural invariant.  */
   1428  1.1  mrg 
   1429  1.1  mrg static tree
   1430  1.1  mrg ipa_get_jf_arith_result (enum tree_code opcode, tree input, tree operand,
   1431  1.1  mrg 			 tree res_type)
   1432  1.1  mrg {
   1433  1.1  mrg   tree res;
   1434  1.1  mrg 
   1435  1.1  mrg   if (opcode == NOP_EXPR)
   1436  1.1  mrg     return input;
   1437  1.1  mrg   if (!is_gimple_ip_invariant (input))
   1438  1.1  mrg     return NULL_TREE;
   1439  1.1  mrg 
   1440  1.1  mrg   if (opcode == ASSERT_EXPR)
   1441  1.1  mrg     {
   1442  1.1  mrg       if (values_equal_for_ipcp_p (input, operand))
   1443  1.1  mrg 	return input;
   1444  1.1  mrg       else
   1445  1.1  mrg 	return NULL_TREE;
   1446  1.1  mrg     }
   1447  1.1  mrg 
   1448  1.1  mrg   if (!res_type)
   1449  1.1  mrg     {
   1450  1.1  mrg       if (TREE_CODE_CLASS (opcode) == tcc_comparison)
   1451  1.1  mrg 	res_type = boolean_type_node;
   1452  1.1  mrg       else if (expr_type_first_operand_type_p (opcode))
   1453  1.1  mrg 	res_type = TREE_TYPE (input);
   1454  1.1  mrg       else
   1455  1.1  mrg 	return NULL_TREE;
   1456  1.1  mrg     }
   1457  1.1  mrg 
   1458  1.1  mrg   if (TREE_CODE_CLASS (opcode) == tcc_unary)
   1459  1.1  mrg     res = fold_unary (opcode, res_type, input);
   1460  1.1  mrg   else
   1461  1.1  mrg     res = fold_binary (opcode, res_type, input, operand);
   1462  1.1  mrg 
   1463  1.1  mrg   if (res && !is_gimple_ip_invariant (res))
   1464  1.1  mrg     return NULL_TREE;
   1465  1.1  mrg 
   1466  1.1  mrg   return res;
   1467  1.1  mrg }
   1468  1.1  mrg 
   1469  1.1  mrg /* Return the result of a (possibly arithmetic) pass through jump function
   1470  1.1  mrg    JFUNC on the constant value INPUT.  RES_TYPE is the type of the parameter
   1471  1.1  mrg    to which the result is passed.  Return NULL_TREE if that cannot be
   1472  1.1  mrg    determined or be considered an interprocedural invariant.  */
   1473  1.1  mrg 
   1474  1.1  mrg static tree
   1475  1.1  mrg ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input,
   1476  1.1  mrg 				tree res_type)
   1477  1.1  mrg {
   1478  1.1  mrg   return ipa_get_jf_arith_result (ipa_get_jf_pass_through_operation (jfunc),
   1479  1.1  mrg 				  input,
   1480  1.1  mrg 				  ipa_get_jf_pass_through_operand (jfunc),
   1481  1.1  mrg 				  res_type);
   1482  1.1  mrg }
   1483  1.1  mrg 
   1484  1.1  mrg /* Return the result of an ancestor jump function JFUNC on the constant value
   1485  1.1  mrg    INPUT.  Return NULL_TREE if that cannot be determined.  */
   1486  1.1  mrg 
   1487  1.1  mrg static tree
   1488  1.1  mrg ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
   1489  1.1  mrg {
   1490  1.1  mrg   gcc_checking_assert (TREE_CODE (input) != TREE_BINFO);
   1491  1.1  mrg   if (TREE_CODE (input) == ADDR_EXPR)
   1492  1.1  mrg     {
   1493  1.1  mrg       gcc_checking_assert (is_gimple_ip_invariant_address (input));
   1494  1.1  mrg       poly_int64 off = ipa_get_jf_ancestor_offset (jfunc);
   1495  1.1  mrg       if (known_eq (off, 0))
   1496  1.1  mrg 	return input;
   1497  1.1  mrg       poly_int64 byte_offset = exact_div (off, BITS_PER_UNIT);
   1498  1.1  mrg       return build1 (ADDR_EXPR, TREE_TYPE (input),
   1499  1.1  mrg 		     fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (input)), input,
   1500  1.1  mrg 				  build_int_cst (ptr_type_node, byte_offset)));
   1501  1.1  mrg     }
   1502  1.1  mrg   else if (ipa_get_jf_ancestor_keep_null (jfunc)
   1503  1.1  mrg 	   && zerop (input))
   1504  1.1  mrg     return input;
   1505  1.1  mrg   else
   1506  1.1  mrg     return NULL_TREE;
   1507  1.1  mrg }
   1508  1.1  mrg 
   1509  1.1  mrg /* Determine whether JFUNC evaluates to a single known constant value and if
   1510  1.1  mrg    so, return it.  Otherwise return NULL.  INFO describes the caller node or
   1511  1.1  mrg    the one it is inlined to, so that pass-through jump functions can be
   1512  1.1  mrg    evaluated.  PARM_TYPE is the type of the parameter to which the result is
   1513  1.1  mrg    passed.  */
   1514  1.1  mrg 
   1515  1.1  mrg tree
   1516  1.1  mrg ipa_value_from_jfunc (class ipa_node_params *info, struct ipa_jump_func *jfunc,
   1517  1.1  mrg 		      tree parm_type)
   1518  1.1  mrg {
   1519  1.1  mrg   if (jfunc->type == IPA_JF_CONST)
   1520  1.1  mrg     return ipa_get_jf_constant (jfunc);
   1521  1.1  mrg   else if (jfunc->type == IPA_JF_PASS_THROUGH
   1522  1.1  mrg 	   || jfunc->type == IPA_JF_ANCESTOR)
   1523  1.1  mrg     {
   1524  1.1  mrg       tree input;
   1525  1.1  mrg       int idx;
   1526  1.1  mrg 
   1527  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   1528  1.1  mrg 	idx = ipa_get_jf_pass_through_formal_id (jfunc);
   1529  1.1  mrg       else
   1530  1.1  mrg 	idx = ipa_get_jf_ancestor_formal_id (jfunc);
   1531  1.1  mrg 
   1532  1.1  mrg       if (info->ipcp_orig_node)
   1533  1.1  mrg 	input = info->known_csts[idx];
   1534  1.1  mrg       else
   1535  1.1  mrg 	{
   1536  1.1  mrg 	  ipcp_lattice<tree> *lat;
   1537  1.1  mrg 
   1538  1.1  mrg 	  if (!info->lattices
   1539  1.1  mrg 	      || idx >= ipa_get_param_count (info))
   1540  1.1  mrg 	    return NULL_TREE;
   1541  1.1  mrg 	  lat = ipa_get_scalar_lat (info, idx);
   1542  1.1  mrg 	  if (!lat->is_single_const ())
   1543  1.1  mrg 	    return NULL_TREE;
   1544  1.1  mrg 	  input = lat->values->value;
   1545  1.1  mrg 	}
   1546  1.1  mrg 
   1547  1.1  mrg       if (!input)
   1548  1.1  mrg 	return NULL_TREE;
   1549  1.1  mrg 
   1550  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   1551  1.1  mrg 	return ipa_get_jf_pass_through_result (jfunc, input, parm_type);
   1552  1.1  mrg       else
   1553  1.1  mrg 	return ipa_get_jf_ancestor_result (jfunc, input);
   1554  1.1  mrg     }
   1555  1.1  mrg   else
   1556  1.1  mrg     return NULL_TREE;
   1557  1.1  mrg }
   1558  1.1  mrg 
   1559  1.1  mrg /* Determine whether JFUNC evaluates to single known polymorphic context, given
   1560  1.1  mrg    that INFO describes the caller node or the one it is inlined to, CS is the
   1561  1.1  mrg    call graph edge corresponding to JFUNC and CSIDX index of the described
   1562  1.1  mrg    parameter.  */
   1563  1.1  mrg 
   1564  1.1  mrg ipa_polymorphic_call_context
   1565  1.1  mrg ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx,
   1566  1.1  mrg 			ipa_jump_func *jfunc)
   1567  1.1  mrg {
   1568  1.1  mrg   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   1569  1.1  mrg   ipa_polymorphic_call_context ctx;
   1570  1.1  mrg   ipa_polymorphic_call_context *edge_ctx
   1571  1.1  mrg     = cs ? ipa_get_ith_polymorhic_call_context (args, csidx) : NULL;
   1572  1.1  mrg 
   1573  1.1  mrg   if (edge_ctx && !edge_ctx->useless_p ())
   1574  1.1  mrg     ctx = *edge_ctx;
   1575  1.1  mrg 
   1576  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH
   1577  1.1  mrg       || jfunc->type == IPA_JF_ANCESTOR)
   1578  1.1  mrg     {
   1579  1.1  mrg       ipa_polymorphic_call_context srcctx;
   1580  1.1  mrg       int srcidx;
   1581  1.1  mrg       bool type_preserved = true;
   1582  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   1583  1.1  mrg 	{
   1584  1.1  mrg 	  if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
   1585  1.1  mrg 	    return ctx;
   1586  1.1  mrg 	  type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
   1587  1.1  mrg 	  srcidx = ipa_get_jf_pass_through_formal_id (jfunc);
   1588  1.1  mrg 	}
   1589  1.1  mrg       else
   1590  1.1  mrg 	{
   1591  1.1  mrg 	  type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
   1592  1.1  mrg 	  srcidx = ipa_get_jf_ancestor_formal_id (jfunc);
   1593  1.1  mrg 	}
   1594  1.1  mrg       if (info->ipcp_orig_node)
   1595  1.1  mrg 	{
   1596  1.1  mrg 	  if (info->known_contexts.exists ())
   1597  1.1  mrg 	    srcctx = info->known_contexts[srcidx];
   1598  1.1  mrg 	}
   1599  1.1  mrg       else
   1600  1.1  mrg 	{
   1601  1.1  mrg 	  if (!info->lattices
   1602  1.1  mrg 	      || srcidx >= ipa_get_param_count (info))
   1603  1.1  mrg 	    return ctx;
   1604  1.1  mrg 	  ipcp_lattice<ipa_polymorphic_call_context> *lat;
   1605  1.1  mrg 	  lat = ipa_get_poly_ctx_lat (info, srcidx);
   1606  1.1  mrg 	  if (!lat->is_single_const ())
   1607  1.1  mrg 	    return ctx;
   1608  1.1  mrg 	  srcctx = lat->values->value;
   1609  1.1  mrg 	}
   1610  1.1  mrg       if (srcctx.useless_p ())
   1611  1.1  mrg 	return ctx;
   1612  1.1  mrg       if (jfunc->type == IPA_JF_ANCESTOR)
   1613  1.1  mrg 	srcctx.offset_by (ipa_get_jf_ancestor_offset (jfunc));
   1614  1.1  mrg       if (!type_preserved)
   1615  1.1  mrg 	srcctx.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
   1616  1.1  mrg       srcctx.combine_with (ctx);
   1617  1.1  mrg       return srcctx;
   1618  1.1  mrg     }
   1619  1.1  mrg 
   1620  1.1  mrg   return ctx;
   1621  1.1  mrg }
   1622  1.1  mrg 
   1623  1.1  mrg /* Emulate effects of unary OPERATION and/or conversion from SRC_TYPE to
   1624  1.1  mrg    DST_TYPE on value range in SRC_VR and store it to DST_VR.  Return true if
   1625  1.1  mrg    the result is a range or an anti-range.  */
   1626  1.1  mrg 
   1627  1.1  mrg static bool
   1628  1.1  mrg ipa_vr_operation_and_type_effects (value_range *dst_vr,
   1629  1.1  mrg 				   value_range *src_vr,
   1630  1.1  mrg 				   enum tree_code operation,
   1631  1.1  mrg 				   tree dst_type, tree src_type)
   1632  1.1  mrg {
   1633  1.1  mrg   range_fold_unary_expr (dst_vr, operation, dst_type, src_vr, src_type);
   1634  1.1  mrg   if (dst_vr->varying_p () || dst_vr->undefined_p ())
   1635  1.1  mrg     return false;
   1636  1.1  mrg   return true;
   1637  1.1  mrg }
   1638  1.1  mrg 
   1639  1.1  mrg /* Determine value_range of JFUNC given that INFO describes the caller node or
   1640  1.1  mrg    the one it is inlined to, CS is the call graph edge corresponding to JFUNC
   1641  1.1  mrg    and PARM_TYPE of the parameter.  */
   1642  1.1  mrg 
   1643  1.1  mrg value_range
   1644  1.1  mrg ipa_value_range_from_jfunc (ipa_node_params *info, cgraph_edge *cs,
   1645  1.1  mrg 			    ipa_jump_func *jfunc, tree parm_type)
   1646  1.1  mrg {
   1647  1.1  mrg   value_range vr;
   1648  1.1  mrg   if (jfunc->m_vr)
   1649  1.1  mrg     ipa_vr_operation_and_type_effects (&vr,
   1650  1.1  mrg 				       jfunc->m_vr,
   1651  1.1  mrg 				       NOP_EXPR, parm_type,
   1652  1.1  mrg 				       jfunc->m_vr->type ());
   1653  1.1  mrg   if (vr.singleton_p ())
   1654  1.1  mrg     return vr;
   1655  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH)
   1656  1.1  mrg     {
   1657  1.1  mrg       int idx;
   1658  1.1  mrg       ipcp_transformation *sum
   1659  1.1  mrg 	= ipcp_get_transformation_summary (cs->caller->inlined_to
   1660  1.1  mrg 					   ? cs->caller->inlined_to
   1661  1.1  mrg 					   : cs->caller);
   1662  1.1  mrg       if (!sum || !sum->m_vr)
   1663  1.1  mrg 	return vr;
   1664  1.1  mrg 
   1665  1.1  mrg       idx = ipa_get_jf_pass_through_formal_id (jfunc);
   1666  1.1  mrg 
   1667  1.1  mrg       if (!(*sum->m_vr)[idx].known)
   1668  1.1  mrg 	return vr;
   1669  1.1  mrg       tree vr_type = ipa_get_type (info, idx);
   1670  1.1  mrg       value_range srcvr (wide_int_to_tree (vr_type, (*sum->m_vr)[idx].min),
   1671  1.1  mrg 			 wide_int_to_tree (vr_type, (*sum->m_vr)[idx].max),
   1672  1.1  mrg 			 (*sum->m_vr)[idx].type);
   1673  1.1  mrg 
   1674  1.1  mrg       enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
   1675  1.1  mrg 
   1676  1.1  mrg       if (TREE_CODE_CLASS (operation) == tcc_unary)
   1677  1.1  mrg 	{
   1678  1.1  mrg 	  value_range res;
   1679  1.1  mrg 
   1680  1.1  mrg 	  if (ipa_vr_operation_and_type_effects (&res,
   1681  1.1  mrg 						 &srcvr,
   1682  1.1  mrg 						 operation, parm_type,
   1683  1.1  mrg 						 vr_type))
   1684  1.1  mrg 	    vr.intersect (res);
   1685  1.1  mrg 	}
   1686  1.1  mrg       else
   1687  1.1  mrg 	{
   1688  1.1  mrg 	  value_range op_res, res;
   1689  1.1  mrg 	  tree op = ipa_get_jf_pass_through_operand (jfunc);
   1690  1.1  mrg 	  value_range op_vr (op, op);
   1691  1.1  mrg 
   1692  1.1  mrg 	  range_fold_binary_expr (&op_res, operation, vr_type, &srcvr, &op_vr);
   1693  1.1  mrg 	  if (ipa_vr_operation_and_type_effects (&res,
   1694  1.1  mrg 						 &op_res,
   1695  1.1  mrg 						 NOP_EXPR, parm_type,
   1696  1.1  mrg 						 vr_type))
   1697  1.1  mrg 	    vr.intersect (res);
   1698  1.1  mrg 	}
   1699  1.1  mrg     }
   1700  1.1  mrg   return vr;
   1701  1.1  mrg }
   1702  1.1  mrg 
   1703  1.1  mrg /* See if NODE is a clone with a known aggregate value at a given OFFSET of a
   1704  1.1  mrg    parameter with the given INDEX.  */
   1705  1.1  mrg 
   1706  1.1  mrg static tree
   1707  1.1  mrg get_clone_agg_value (struct cgraph_node *node, HOST_WIDE_INT offset,
   1708  1.1  mrg 		     int index)
   1709  1.1  mrg {
   1710  1.1  mrg   struct ipa_agg_replacement_value *aggval;
   1711  1.1  mrg 
   1712  1.1  mrg   aggval = ipa_get_agg_replacements_for_node (node);
   1713  1.1  mrg   while (aggval)
   1714  1.1  mrg     {
   1715  1.1  mrg       if (aggval->offset == offset
   1716  1.1  mrg 	  && aggval->index == index)
   1717  1.1  mrg 	return aggval->value;
   1718  1.1  mrg       aggval = aggval->next;
   1719  1.1  mrg     }
   1720  1.1  mrg   return NULL_TREE;
   1721  1.1  mrg }
   1722  1.1  mrg 
   1723  1.1  mrg /* Determine whether ITEM, jump function for an aggregate part, evaluates to a
   1724  1.1  mrg    single known constant value and if so, return it.  Otherwise return NULL.
   1725  1.1  mrg    NODE and INFO describes the caller node or the one it is inlined to, and
   1726  1.1  mrg    its related info.  */
   1727  1.1  mrg 
   1728  1.1  mrg static tree
   1729  1.1  mrg ipa_agg_value_from_node (class ipa_node_params *info,
   1730  1.1  mrg 			 struct cgraph_node *node,
   1731  1.1  mrg 			 struct ipa_agg_jf_item *item)
   1732  1.1  mrg {
   1733  1.1  mrg   tree value = NULL_TREE;
   1734  1.1  mrg   int src_idx;
   1735  1.1  mrg 
   1736  1.1  mrg   if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
   1737  1.1  mrg     return NULL_TREE;
   1738  1.1  mrg 
   1739  1.1  mrg   if (item->jftype == IPA_JF_CONST)
   1740  1.1  mrg     return item->value.constant;
   1741  1.1  mrg 
   1742  1.1  mrg   gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
   1743  1.1  mrg 		       || item->jftype == IPA_JF_LOAD_AGG);
   1744  1.1  mrg 
   1745  1.1  mrg   src_idx = item->value.pass_through.formal_id;
   1746  1.1  mrg 
   1747  1.1  mrg   if (info->ipcp_orig_node)
   1748  1.1  mrg     {
   1749  1.1  mrg       if (item->jftype == IPA_JF_PASS_THROUGH)
   1750  1.1  mrg 	value = info->known_csts[src_idx];
   1751  1.1  mrg       else
   1752  1.1  mrg 	value = get_clone_agg_value (node, item->value.load_agg.offset,
   1753  1.1  mrg 				     src_idx);
   1754  1.1  mrg     }
   1755  1.1  mrg   else if (info->lattices)
   1756  1.1  mrg     {
   1757  1.1  mrg       class ipcp_param_lattices *src_plats
   1758  1.1  mrg 	= ipa_get_parm_lattices (info, src_idx);
   1759  1.1  mrg 
   1760  1.1  mrg       if (item->jftype == IPA_JF_PASS_THROUGH)
   1761  1.1  mrg 	{
   1762  1.1  mrg 	  struct ipcp_lattice<tree> *lat = &src_plats->itself;
   1763  1.1  mrg 
   1764  1.1  mrg 	  if (!lat->is_single_const ())
   1765  1.1  mrg 	    return NULL_TREE;
   1766  1.1  mrg 
   1767  1.1  mrg 	  value = lat->values->value;
   1768  1.1  mrg 	}
   1769  1.1  mrg       else if (src_plats->aggs
   1770  1.1  mrg 	       && !src_plats->aggs_bottom
   1771  1.1  mrg 	       && !src_plats->aggs_contain_variable
   1772  1.1  mrg 	       && src_plats->aggs_by_ref == item->value.load_agg.by_ref)
   1773  1.1  mrg 	{
   1774  1.1  mrg 	  struct ipcp_agg_lattice *aglat;
   1775  1.1  mrg 
   1776  1.1  mrg 	  for (aglat = src_plats->aggs; aglat; aglat = aglat->next)
   1777  1.1  mrg 	    {
   1778  1.1  mrg 	      if (aglat->offset > item->value.load_agg.offset)
   1779  1.1  mrg 		break;
   1780  1.1  mrg 
   1781  1.1  mrg 	      if (aglat->offset == item->value.load_agg.offset)
   1782  1.1  mrg 		{
   1783  1.1  mrg 		  if (aglat->is_single_const ())
   1784  1.1  mrg 		    value = aglat->values->value;
   1785  1.1  mrg 		  break;
   1786  1.1  mrg 		}
   1787  1.1  mrg 	    }
   1788  1.1  mrg 	}
   1789  1.1  mrg     }
   1790  1.1  mrg 
   1791  1.1  mrg   if (!value)
   1792  1.1  mrg     return NULL_TREE;
   1793  1.1  mrg 
   1794  1.1  mrg   if (item->jftype == IPA_JF_LOAD_AGG)
   1795  1.1  mrg     {
   1796  1.1  mrg       tree load_type = item->value.load_agg.type;
   1797  1.1  mrg       tree value_type = TREE_TYPE (value);
   1798  1.1  mrg 
   1799  1.1  mrg       /* Ensure value type is compatible with load type.  */
   1800  1.1  mrg       if (!useless_type_conversion_p (load_type, value_type))
   1801  1.1  mrg 	return NULL_TREE;
   1802  1.1  mrg     }
   1803  1.1  mrg 
   1804  1.1  mrg   return ipa_get_jf_arith_result (item->value.pass_through.operation,
   1805  1.1  mrg 				  value,
   1806  1.1  mrg 				  item->value.pass_through.operand,
   1807  1.1  mrg 				  item->type);
   1808  1.1  mrg }
   1809  1.1  mrg 
   1810  1.1  mrg /* Determine whether AGG_JFUNC evaluates to a set of known constant value for
   1811  1.1  mrg    an aggregate and if so, return it.  Otherwise return an empty set.  NODE
   1812  1.1  mrg    and INFO describes the caller node or the one it is inlined to, and its
   1813  1.1  mrg    related info.  */
   1814  1.1  mrg 
   1815  1.1  mrg struct ipa_agg_value_set
   1816  1.1  mrg ipa_agg_value_set_from_jfunc (class ipa_node_params *info, cgraph_node *node,
   1817  1.1  mrg 			      struct ipa_agg_jump_function *agg_jfunc)
   1818  1.1  mrg {
   1819  1.1  mrg   struct ipa_agg_value_set agg;
   1820  1.1  mrg   struct ipa_agg_jf_item *item;
   1821  1.1  mrg   int i;
   1822  1.1  mrg 
   1823  1.1  mrg   agg.items = vNULL;
   1824  1.1  mrg   agg.by_ref = agg_jfunc->by_ref;
   1825  1.1  mrg 
   1826  1.1  mrg   FOR_EACH_VEC_SAFE_ELT (agg_jfunc->items, i, item)
   1827  1.1  mrg     {
   1828  1.1  mrg       tree value = ipa_agg_value_from_node (info, node, item);
   1829  1.1  mrg 
   1830  1.1  mrg       if (value)
   1831  1.1  mrg 	{
   1832  1.1  mrg 	  struct ipa_agg_value value_item;
   1833  1.1  mrg 
   1834  1.1  mrg 	  value_item.offset = item->offset;
   1835  1.1  mrg 	  value_item.value = value;
   1836  1.1  mrg 
   1837  1.1  mrg 	  agg.items.safe_push (value_item);
   1838  1.1  mrg 	}
   1839  1.1  mrg     }
   1840  1.1  mrg   return agg;
   1841  1.1  mrg }
   1842  1.1  mrg 
   1843  1.1  mrg /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
   1844  1.1  mrg    bottom, not containing a variable component and without any known value at
   1845  1.1  mrg    the same time.  */
   1846  1.1  mrg 
   1847  1.1  mrg DEBUG_FUNCTION void
   1848  1.1  mrg ipcp_verify_propagated_values (void)
   1849  1.1  mrg {
   1850  1.1  mrg   struct cgraph_node *node;
   1851  1.1  mrg 
   1852  1.1  mrg   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
   1853  1.1  mrg     {
   1854  1.1  mrg       ipa_node_params *info = ipa_node_params_sum->get (node);
   1855  1.1  mrg       if (!opt_for_fn (node->decl, flag_ipa_cp)
   1856  1.1  mrg 	  || !opt_for_fn (node->decl, optimize))
   1857  1.1  mrg 	continue;
   1858  1.1  mrg       int i, count = ipa_get_param_count (info);
   1859  1.1  mrg 
   1860  1.1  mrg       for (i = 0; i < count; i++)
   1861  1.1  mrg 	{
   1862  1.1  mrg 	  ipcp_lattice<tree> *lat = ipa_get_scalar_lat (info, i);
   1863  1.1  mrg 
   1864  1.1  mrg 	  if (!lat->bottom
   1865  1.1  mrg 	      && !lat->contains_variable
   1866  1.1  mrg 	      && lat->values_count == 0)
   1867  1.1  mrg 	    {
   1868  1.1  mrg 	      if (dump_file)
   1869  1.1  mrg 		{
   1870  1.1  mrg 		  symtab->dump (dump_file);
   1871  1.1  mrg 		  fprintf (dump_file, "\nIPA lattices after constant "
   1872  1.1  mrg 			   "propagation, before gcc_unreachable:\n");
   1873  1.1  mrg 		  print_all_lattices (dump_file, true, false);
   1874  1.1  mrg 		}
   1875  1.1  mrg 
   1876  1.1  mrg 	      gcc_unreachable ();
   1877  1.1  mrg 	    }
   1878  1.1  mrg 	}
   1879  1.1  mrg     }
   1880  1.1  mrg }
   1881  1.1  mrg 
   1882  1.1  mrg /* Return true iff X and Y should be considered equal contexts by IPA-CP.  */
   1883  1.1  mrg 
   1884  1.1  mrg static bool
   1885  1.1  mrg values_equal_for_ipcp_p (ipa_polymorphic_call_context x,
   1886  1.1  mrg 			 ipa_polymorphic_call_context y)
   1887  1.1  mrg {
   1888  1.1  mrg   return x.equal_to (y);
   1889  1.1  mrg }
   1890  1.1  mrg 
   1891  1.1  mrg 
   1892  1.1  mrg /* Add a new value source to the value represented by THIS, marking that a
   1893  1.1  mrg    value comes from edge CS and (if the underlying jump function is a
   1894  1.1  mrg    pass-through or an ancestor one) from a caller value SRC_VAL of a caller
   1895  1.1  mrg    parameter described by SRC_INDEX.  OFFSET is negative if the source was the
   1896  1.1  mrg    scalar value of the parameter itself or the offset within an aggregate.  */
   1897  1.1  mrg 
   1898  1.1  mrg template <typename valtype>
   1899  1.1  mrg void
   1900  1.1  mrg ipcp_value<valtype>::add_source (cgraph_edge *cs, ipcp_value *src_val,
   1901  1.1  mrg 				 int src_idx, HOST_WIDE_INT offset)
   1902  1.1  mrg {
   1903  1.1  mrg   ipcp_value_source<valtype> *src;
   1904  1.1  mrg 
   1905  1.1  mrg   src = new (ipcp_sources_pool.allocate ()) ipcp_value_source<valtype>;
   1906  1.1  mrg   src->offset = offset;
   1907  1.1  mrg   src->cs = cs;
   1908  1.1  mrg   src->val = src_val;
   1909  1.1  mrg   src->index = src_idx;
   1910  1.1  mrg 
   1911  1.1  mrg   src->next = sources;
   1912  1.1  mrg   sources = src;
   1913  1.1  mrg }
   1914  1.1  mrg 
   1915  1.1  mrg /* Allocate a new ipcp_value holding a tree constant, initialize its value to
   1916  1.1  mrg    SOURCE and clear all other fields.  */
   1917  1.1  mrg 
   1918  1.1  mrg static ipcp_value<tree> *
   1919  1.1  mrg allocate_and_init_ipcp_value (tree cst, unsigned same_lat_gen_level)
   1920  1.1  mrg {
   1921  1.1  mrg   ipcp_value<tree> *val;
   1922  1.1  mrg 
   1923  1.1  mrg   val = new (ipcp_cst_values_pool.allocate ()) ipcp_value<tree>();
   1924  1.1  mrg   val->value = cst;
   1925  1.1  mrg   val->self_recursion_generated_level = same_lat_gen_level;
   1926  1.1  mrg   return val;
   1927  1.1  mrg }
   1928  1.1  mrg 
   1929  1.1  mrg /* Allocate a new ipcp_value holding a polymorphic context, initialize its
   1930  1.1  mrg    value to SOURCE and clear all other fields.  */
   1931  1.1  mrg 
   1932  1.1  mrg static ipcp_value<ipa_polymorphic_call_context> *
   1933  1.1  mrg allocate_and_init_ipcp_value (ipa_polymorphic_call_context ctx,
   1934  1.1  mrg 			      unsigned same_lat_gen_level)
   1935  1.1  mrg {
   1936  1.1  mrg   ipcp_value<ipa_polymorphic_call_context> *val;
   1937  1.1  mrg 
   1938  1.1  mrg   val = new (ipcp_poly_ctx_values_pool.allocate ())
   1939  1.1  mrg     ipcp_value<ipa_polymorphic_call_context>();
   1940  1.1  mrg   val->value = ctx;
   1941  1.1  mrg   val->self_recursion_generated_level = same_lat_gen_level;
   1942  1.1  mrg   return val;
   1943  1.1  mrg }
   1944  1.1  mrg 
   1945  1.1  mrg /* Try to add NEWVAL to LAT, potentially creating a new ipcp_value for it.  CS,
   1946  1.1  mrg    SRC_VAL SRC_INDEX and OFFSET are meant for add_source and have the same
   1947  1.1  mrg    meaning.  OFFSET -1 means the source is scalar and not a part of an
   1948  1.1  mrg    aggregate.  If non-NULL, VAL_P records address of existing or newly added
   1949  1.1  mrg    ipcp_value.
   1950  1.1  mrg 
   1951  1.1  mrg    If the value is generated for a self-recursive call as a result of an
   1952  1.1  mrg    arithmetic pass-through jump-function acting on a value in the same lattice,
   1953  1.1  mrg    SAME_LAT_GEN_LEVEL must be the length of such chain, otherwise it must be
   1954  1.1  mrg    zero.  If it is non-zero, PARAM_IPA_CP_VALUE_LIST_SIZE limit is ignored.  */
   1955  1.1  mrg 
   1956  1.1  mrg template <typename valtype>
   1957  1.1  mrg bool
   1958  1.1  mrg ipcp_lattice<valtype>::add_value (valtype newval, cgraph_edge *cs,
   1959  1.1  mrg 				  ipcp_value<valtype> *src_val,
   1960  1.1  mrg 				  int src_idx, HOST_WIDE_INT offset,
   1961  1.1  mrg 				  ipcp_value<valtype> **val_p,
   1962  1.1  mrg 				  unsigned same_lat_gen_level)
   1963  1.1  mrg {
   1964  1.1  mrg   ipcp_value<valtype> *val, *last_val = NULL;
   1965  1.1  mrg 
   1966  1.1  mrg   if (val_p)
   1967  1.1  mrg     *val_p = NULL;
   1968  1.1  mrg 
   1969  1.1  mrg   if (bottom)
   1970  1.1  mrg     return false;
   1971  1.1  mrg 
   1972  1.1  mrg   for (val = values; val; last_val = val, val = val->next)
   1973  1.1  mrg     if (values_equal_for_ipcp_p (val->value, newval))
   1974  1.1  mrg       {
   1975  1.1  mrg 	if (val_p)
   1976  1.1  mrg 	  *val_p = val;
   1977  1.1  mrg 
   1978  1.1  mrg 	if (val->self_recursion_generated_level < same_lat_gen_level)
   1979  1.1  mrg 	  val->self_recursion_generated_level = same_lat_gen_level;
   1980  1.1  mrg 
   1981  1.1  mrg 	if (ipa_edge_within_scc (cs))
   1982  1.1  mrg 	  {
   1983  1.1  mrg 	    ipcp_value_source<valtype> *s;
   1984  1.1  mrg 	    for (s = val->sources; s; s = s->next)
   1985  1.1  mrg 	      if (s->cs == cs && s->val == src_val)
   1986  1.1  mrg 		break;
   1987  1.1  mrg 	    if (s)
   1988  1.1  mrg 	      return false;
   1989  1.1  mrg 	  }
   1990  1.1  mrg 
   1991  1.1  mrg 	val->add_source (cs, src_val, src_idx, offset);
   1992  1.1  mrg 	return false;
   1993  1.1  mrg       }
   1994  1.1  mrg 
   1995  1.1  mrg   if (!same_lat_gen_level && values_count == opt_for_fn (cs->caller->decl,
   1996  1.1  mrg 						param_ipa_cp_value_list_size))
   1997  1.1  mrg     {
   1998  1.1  mrg       /* We can only free sources, not the values themselves, because sources
   1999  1.1  mrg 	 of other values in this SCC might point to them.   */
   2000  1.1  mrg       for (val = values; val; val = val->next)
   2001  1.1  mrg 	{
   2002  1.1  mrg 	  while (val->sources)
   2003  1.1  mrg 	    {
   2004  1.1  mrg 	      ipcp_value_source<valtype> *src = val->sources;
   2005  1.1  mrg 	      val->sources = src->next;
   2006  1.1  mrg 	      ipcp_sources_pool.remove ((ipcp_value_source<tree>*)src);
   2007  1.1  mrg 	    }
   2008  1.1  mrg 	}
   2009  1.1  mrg       values = NULL;
   2010  1.1  mrg       return set_to_bottom ();
   2011  1.1  mrg     }
   2012  1.1  mrg 
   2013  1.1  mrg   values_count++;
   2014  1.1  mrg   val = allocate_and_init_ipcp_value (newval, same_lat_gen_level);
   2015  1.1  mrg   val->add_source (cs, src_val, src_idx, offset);
   2016  1.1  mrg   val->next = NULL;
   2017  1.1  mrg 
   2018  1.1  mrg   /* Add the new value to end of value list, which can reduce iterations
   2019  1.1  mrg      of propagation stage for recursive function.  */
   2020  1.1  mrg   if (last_val)
   2021  1.1  mrg     last_val->next = val;
   2022  1.1  mrg   else
   2023  1.1  mrg     values = val;
   2024  1.1  mrg 
   2025  1.1  mrg   if (val_p)
   2026  1.1  mrg     *val_p = val;
   2027  1.1  mrg 
   2028  1.1  mrg   return true;
   2029  1.1  mrg }
   2030  1.1  mrg 
   2031  1.1  mrg /* A helper function that returns result of operation specified by OPCODE on
   2032  1.1  mrg    the value of SRC_VAL.  If non-NULL, OPND1_TYPE is expected type for the
   2033  1.1  mrg    value of SRC_VAL.  If the operation is binary, OPND2 is a constant value
   2034  1.1  mrg    acting as its second operand.  If non-NULL, RES_TYPE is expected type of
   2035  1.1  mrg    the result.  */
   2036  1.1  mrg 
   2037  1.1  mrg static tree
   2038  1.1  mrg get_val_across_arith_op (enum tree_code opcode,
   2039  1.1  mrg 			 tree opnd1_type,
   2040  1.1  mrg 			 tree opnd2,
   2041  1.1  mrg 			 ipcp_value<tree> *src_val,
   2042  1.1  mrg 			 tree res_type)
   2043  1.1  mrg {
   2044  1.1  mrg   tree opnd1 = src_val->value;
   2045  1.1  mrg 
   2046  1.1  mrg   /* Skip source values that is incompatible with specified type.  */
   2047  1.1  mrg   if (opnd1_type
   2048  1.1  mrg       && !useless_type_conversion_p (opnd1_type, TREE_TYPE (opnd1)))
   2049  1.1  mrg     return NULL_TREE;
   2050  1.1  mrg 
   2051  1.1  mrg   return ipa_get_jf_arith_result (opcode, opnd1, opnd2, res_type);
   2052  1.1  mrg }
   2053  1.1  mrg 
   2054  1.1  mrg /* Propagate values through an arithmetic transformation described by a jump
   2055  1.1  mrg    function associated with edge CS, taking values from SRC_LAT and putting
   2056  1.1  mrg    them into DEST_LAT.  OPND1_TYPE is expected type for the values in SRC_LAT.
   2057  1.1  mrg    OPND2 is a constant value if transformation is a binary operation.
   2058  1.1  mrg    SRC_OFFSET specifies offset in an aggregate if SRC_LAT describes lattice of
   2059  1.1  mrg    a part of the aggregate.  SRC_IDX is the index of the source parameter.
   2060  1.1  mrg    RES_TYPE is the value type of result being propagated into.  Return true if
   2061  1.1  mrg    DEST_LAT changed.  */
   2062  1.1  mrg 
   2063  1.1  mrg static bool
   2064  1.1  mrg propagate_vals_across_arith_jfunc (cgraph_edge *cs,
   2065  1.1  mrg 				   enum tree_code opcode,
   2066  1.1  mrg 				   tree opnd1_type,
   2067  1.1  mrg 				   tree opnd2,
   2068  1.1  mrg 				   ipcp_lattice<tree> *src_lat,
   2069  1.1  mrg 				   ipcp_lattice<tree> *dest_lat,
   2070  1.1  mrg 				   HOST_WIDE_INT src_offset,
   2071  1.1  mrg 				   int src_idx,
   2072  1.1  mrg 				   tree res_type)
   2073  1.1  mrg {
   2074  1.1  mrg   ipcp_value<tree> *src_val;
   2075  1.1  mrg   bool ret = false;
   2076  1.1  mrg 
   2077  1.1  mrg   /* Due to circular dependencies, propagating within an SCC through arithmetic
   2078  1.1  mrg      transformation would create infinite number of values.  But for
   2079  1.1  mrg      self-feeding recursive function, we could allow propagation in a limited
   2080  1.1  mrg      count, and this can enable a simple kind of recursive function versioning.
   2081  1.1  mrg      For other scenario, we would just make lattices bottom.  */
   2082  1.1  mrg   if (opcode != NOP_EXPR && ipa_edge_within_scc (cs))
   2083  1.1  mrg     {
   2084  1.1  mrg       int i;
   2085  1.1  mrg 
   2086  1.1  mrg       int max_recursive_depth = opt_for_fn(cs->caller->decl,
   2087  1.1  mrg 					   param_ipa_cp_max_recursive_depth);
   2088  1.1  mrg       if (src_lat != dest_lat || max_recursive_depth < 1)
   2089  1.1  mrg 	return dest_lat->set_contains_variable ();
   2090  1.1  mrg 
   2091  1.1  mrg       /* No benefit if recursive execution is in low probability.  */
   2092  1.1  mrg       if (cs->sreal_frequency () * 100
   2093  1.1  mrg 	  <= ((sreal) 1) * opt_for_fn (cs->caller->decl,
   2094  1.1  mrg 				       param_ipa_cp_min_recursive_probability))
   2095  1.1  mrg 	return dest_lat->set_contains_variable ();
   2096  1.1  mrg 
   2097  1.1  mrg       auto_vec<ipcp_value<tree> *, 8> val_seeds;
   2098  1.1  mrg 
   2099  1.1  mrg       for (src_val = src_lat->values; src_val; src_val = src_val->next)
   2100  1.1  mrg 	{
   2101  1.1  mrg 	  /* Now we do not use self-recursively generated value as propagation
   2102  1.1  mrg 	     source, this is absolutely conservative, but could avoid explosion
   2103  1.1  mrg 	     of lattice's value space, especially when one recursive function
   2104  1.1  mrg 	     calls another recursive.  */
   2105  1.1  mrg 	  if (src_val->self_recursion_generated_p ())
   2106  1.1  mrg 	    {
   2107  1.1  mrg 	      ipcp_value_source<tree> *s;
   2108  1.1  mrg 
   2109  1.1  mrg 	      /* If the lattice has already been propagated for the call site,
   2110  1.1  mrg 		 no need to do that again.  */
   2111  1.1  mrg 	      for (s = src_val->sources; s; s = s->next)
   2112  1.1  mrg 		if (s->cs == cs)
   2113  1.1  mrg 		  return dest_lat->set_contains_variable ();
   2114  1.1  mrg 	    }
   2115  1.1  mrg 	  else
   2116  1.1  mrg 	    val_seeds.safe_push (src_val);
   2117  1.1  mrg 	}
   2118  1.1  mrg 
   2119  1.1  mrg       gcc_assert ((int) val_seeds.length () <= param_ipa_cp_value_list_size);
   2120  1.1  mrg 
   2121  1.1  mrg       /* Recursively generate lattice values with a limited count.  */
   2122  1.1  mrg       FOR_EACH_VEC_ELT (val_seeds, i, src_val)
   2123  1.1  mrg 	{
   2124  1.1  mrg 	  for (int j = 1; j < max_recursive_depth; j++)
   2125  1.1  mrg 	    {
   2126  1.1  mrg 	      tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
   2127  1.1  mrg 						     src_val, res_type);
   2128  1.1  mrg 	      if (!cstval
   2129  1.1  mrg 		  || !ipacp_value_safe_for_type (res_type, cstval))
   2130  1.1  mrg 		break;
   2131  1.1  mrg 
   2132  1.1  mrg 	      ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
   2133  1.1  mrg 					  src_offset, &src_val, j);
   2134  1.1  mrg 	      gcc_checking_assert (src_val);
   2135  1.1  mrg 	    }
   2136  1.1  mrg 	}
   2137  1.1  mrg       ret |= dest_lat->set_contains_variable ();
   2138  1.1  mrg     }
   2139  1.1  mrg   else
   2140  1.1  mrg     for (src_val = src_lat->values; src_val; src_val = src_val->next)
   2141  1.1  mrg       {
   2142  1.1  mrg 	/* Now we do not use self-recursively generated value as propagation
   2143  1.1  mrg 	   source, otherwise it is easy to make value space of normal lattice
   2144  1.1  mrg 	   overflow.  */
   2145  1.1  mrg 	if (src_val->self_recursion_generated_p ())
   2146  1.1  mrg 	  {
   2147  1.1  mrg 	    ret |= dest_lat->set_contains_variable ();
   2148  1.1  mrg 	    continue;
   2149  1.1  mrg 	  }
   2150  1.1  mrg 
   2151  1.1  mrg 	tree cstval = get_val_across_arith_op (opcode, opnd1_type, opnd2,
   2152  1.1  mrg 					       src_val, res_type);
   2153  1.1  mrg 	if (cstval
   2154  1.1  mrg 	    && ipacp_value_safe_for_type (res_type, cstval))
   2155  1.1  mrg 	  ret |= dest_lat->add_value (cstval, cs, src_val, src_idx,
   2156  1.1  mrg 				      src_offset);
   2157  1.1  mrg 	else
   2158  1.1  mrg 	  ret |= dest_lat->set_contains_variable ();
   2159  1.1  mrg       }
   2160  1.1  mrg 
   2161  1.1  mrg   return ret;
   2162  1.1  mrg }
   2163  1.1  mrg 
   2164  1.1  mrg /* Propagate values through a pass-through jump function JFUNC associated with
   2165  1.1  mrg    edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
   2166  1.1  mrg    is the index of the source parameter.  PARM_TYPE is the type of the
   2167  1.1  mrg    parameter to which the result is passed.  */
   2168  1.1  mrg 
   2169  1.1  mrg static bool
   2170  1.1  mrg propagate_vals_across_pass_through (cgraph_edge *cs, ipa_jump_func *jfunc,
   2171  1.1  mrg 				    ipcp_lattice<tree> *src_lat,
   2172  1.1  mrg 				    ipcp_lattice<tree> *dest_lat, int src_idx,
   2173  1.1  mrg 				    tree parm_type)
   2174  1.1  mrg {
   2175  1.1  mrg   return propagate_vals_across_arith_jfunc (cs,
   2176  1.1  mrg 				ipa_get_jf_pass_through_operation (jfunc),
   2177  1.1  mrg 				NULL_TREE,
   2178  1.1  mrg 				ipa_get_jf_pass_through_operand (jfunc),
   2179  1.1  mrg 				src_lat, dest_lat, -1, src_idx, parm_type);
   2180  1.1  mrg }
   2181  1.1  mrg 
   2182  1.1  mrg /* Propagate values through an ancestor jump function JFUNC associated with
   2183  1.1  mrg    edge CS, taking values from SRC_LAT and putting them into DEST_LAT.  SRC_IDX
   2184  1.1  mrg    is the index of the source parameter.  */
   2185  1.1  mrg 
   2186  1.1  mrg static bool
   2187  1.1  mrg propagate_vals_across_ancestor (struct cgraph_edge *cs,
   2188  1.1  mrg 				struct ipa_jump_func *jfunc,
   2189  1.1  mrg 				ipcp_lattice<tree> *src_lat,
   2190  1.1  mrg 				ipcp_lattice<tree> *dest_lat, int src_idx,
   2191  1.1  mrg 				tree param_type)
   2192  1.1  mrg {
   2193  1.1  mrg   ipcp_value<tree> *src_val;
   2194  1.1  mrg   bool ret = false;
   2195  1.1  mrg 
   2196  1.1  mrg   if (ipa_edge_within_scc (cs))
   2197  1.1  mrg     return dest_lat->set_contains_variable ();
   2198  1.1  mrg 
   2199  1.1  mrg   for (src_val = src_lat->values; src_val; src_val = src_val->next)
   2200  1.1  mrg     {
   2201  1.1  mrg       tree t = ipa_get_jf_ancestor_result (jfunc, src_val->value);
   2202  1.1  mrg 
   2203  1.1  mrg       if (t && ipacp_value_safe_for_type (param_type, t))
   2204  1.1  mrg 	ret |= dest_lat->add_value (t, cs, src_val, src_idx);
   2205  1.1  mrg       else
   2206  1.1  mrg 	ret |= dest_lat->set_contains_variable ();
   2207  1.1  mrg     }
   2208  1.1  mrg 
   2209  1.1  mrg   return ret;
   2210  1.1  mrg }
   2211  1.1  mrg 
   2212  1.1  mrg /* Propagate scalar values across jump function JFUNC that is associated with
   2213  1.1  mrg    edge CS and put the values into DEST_LAT.  PARM_TYPE is the type of the
   2214  1.1  mrg    parameter to which the result is passed.  */
   2215  1.1  mrg 
   2216  1.1  mrg static bool
   2217  1.1  mrg propagate_scalar_across_jump_function (struct cgraph_edge *cs,
   2218  1.1  mrg 				       struct ipa_jump_func *jfunc,
   2219  1.1  mrg 				       ipcp_lattice<tree> *dest_lat,
   2220  1.1  mrg 				       tree param_type)
   2221  1.1  mrg {
   2222  1.1  mrg   if (dest_lat->bottom)
   2223  1.1  mrg     return false;
   2224  1.1  mrg 
   2225  1.1  mrg   if (jfunc->type == IPA_JF_CONST)
   2226  1.1  mrg     {
   2227  1.1  mrg       tree val = ipa_get_jf_constant (jfunc);
   2228  1.1  mrg       if (ipacp_value_safe_for_type (param_type, val))
   2229  1.1  mrg 	return dest_lat->add_value (val, cs, NULL, 0);
   2230  1.1  mrg       else
   2231  1.1  mrg 	return dest_lat->set_contains_variable ();
   2232  1.1  mrg     }
   2233  1.1  mrg   else if (jfunc->type == IPA_JF_PASS_THROUGH
   2234  1.1  mrg 	   || jfunc->type == IPA_JF_ANCESTOR)
   2235  1.1  mrg     {
   2236  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2237  1.1  mrg       ipcp_lattice<tree> *src_lat;
   2238  1.1  mrg       int src_idx;
   2239  1.1  mrg       bool ret;
   2240  1.1  mrg 
   2241  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   2242  1.1  mrg 	src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   2243  1.1  mrg       else
   2244  1.1  mrg 	src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
   2245  1.1  mrg 
   2246  1.1  mrg       src_lat = ipa_get_scalar_lat (caller_info, src_idx);
   2247  1.1  mrg       if (src_lat->bottom)
   2248  1.1  mrg 	return dest_lat->set_contains_variable ();
   2249  1.1  mrg 
   2250  1.1  mrg       /* If we would need to clone the caller and cannot, do not propagate.  */
   2251  1.1  mrg       if (!ipcp_versionable_function_p (cs->caller)
   2252  1.1  mrg 	  && (src_lat->contains_variable
   2253  1.1  mrg 	      || (src_lat->values_count > 1)))
   2254  1.1  mrg 	return dest_lat->set_contains_variable ();
   2255  1.1  mrg 
   2256  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   2257  1.1  mrg 	ret = propagate_vals_across_pass_through (cs, jfunc, src_lat,
   2258  1.1  mrg 						  dest_lat, src_idx,
   2259  1.1  mrg 						  param_type);
   2260  1.1  mrg       else
   2261  1.1  mrg 	ret = propagate_vals_across_ancestor (cs, jfunc, src_lat, dest_lat,
   2262  1.1  mrg 					      src_idx, param_type);
   2263  1.1  mrg 
   2264  1.1  mrg       if (src_lat->contains_variable)
   2265  1.1  mrg 	ret |= dest_lat->set_contains_variable ();
   2266  1.1  mrg 
   2267  1.1  mrg       return ret;
   2268  1.1  mrg     }
   2269  1.1  mrg 
   2270  1.1  mrg   /* TODO: We currently do not handle member method pointers in IPA-CP (we only
   2271  1.1  mrg      use it for indirect inlining), we should propagate them too.  */
   2272  1.1  mrg   return dest_lat->set_contains_variable ();
   2273  1.1  mrg }
   2274  1.1  mrg 
   2275  1.1  mrg /* Propagate scalar values across jump function JFUNC that is associated with
   2276  1.1  mrg    edge CS and describes argument IDX and put the values into DEST_LAT.  */
   2277  1.1  mrg 
   2278  1.1  mrg static bool
   2279  1.1  mrg propagate_context_across_jump_function (cgraph_edge *cs,
   2280  1.1  mrg 			  ipa_jump_func *jfunc, int idx,
   2281  1.1  mrg 			  ipcp_lattice<ipa_polymorphic_call_context> *dest_lat)
   2282  1.1  mrg {
   2283  1.1  mrg   if (dest_lat->bottom)
   2284  1.1  mrg     return false;
   2285  1.1  mrg   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   2286  1.1  mrg   bool ret = false;
   2287  1.1  mrg   bool added_sth = false;
   2288  1.1  mrg   bool type_preserved = true;
   2289  1.1  mrg 
   2290  1.1  mrg   ipa_polymorphic_call_context edge_ctx, *edge_ctx_ptr
   2291  1.1  mrg     = ipa_get_ith_polymorhic_call_context (args, idx);
   2292  1.1  mrg 
   2293  1.1  mrg   if (edge_ctx_ptr)
   2294  1.1  mrg     edge_ctx = *edge_ctx_ptr;
   2295  1.1  mrg 
   2296  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH
   2297  1.1  mrg       || jfunc->type == IPA_JF_ANCESTOR)
   2298  1.1  mrg     {
   2299  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2300  1.1  mrg       int src_idx;
   2301  1.1  mrg       ipcp_lattice<ipa_polymorphic_call_context> *src_lat;
   2302  1.1  mrg 
   2303  1.1  mrg       /* TODO: Once we figure out how to propagate speculations, it will
   2304  1.1  mrg 	 probably be a good idea to switch to speculation if type_preserved is
   2305  1.1  mrg 	 not set instead of punting.  */
   2306  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   2307  1.1  mrg 	{
   2308  1.1  mrg 	  if (ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
   2309  1.1  mrg 	    goto prop_fail;
   2310  1.1  mrg 	  type_preserved = ipa_get_jf_pass_through_type_preserved (jfunc);
   2311  1.1  mrg 	  src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   2312  1.1  mrg 	}
   2313  1.1  mrg       else
   2314  1.1  mrg 	{
   2315  1.1  mrg 	  type_preserved = ipa_get_jf_ancestor_type_preserved (jfunc);
   2316  1.1  mrg 	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
   2317  1.1  mrg 	}
   2318  1.1  mrg 
   2319  1.1  mrg       src_lat = ipa_get_poly_ctx_lat (caller_info, src_idx);
   2320  1.1  mrg       /* If we would need to clone the caller and cannot, do not propagate.  */
   2321  1.1  mrg       if (!ipcp_versionable_function_p (cs->caller)
   2322  1.1  mrg 	  && (src_lat->contains_variable
   2323  1.1  mrg 	      || (src_lat->values_count > 1)))
   2324  1.1  mrg 	goto prop_fail;
   2325  1.1  mrg 
   2326  1.1  mrg       ipcp_value<ipa_polymorphic_call_context> *src_val;
   2327  1.1  mrg       for (src_val = src_lat->values; src_val; src_val = src_val->next)
   2328  1.1  mrg 	{
   2329  1.1  mrg 	  ipa_polymorphic_call_context cur = src_val->value;
   2330  1.1  mrg 
   2331  1.1  mrg 	  if (!type_preserved)
   2332  1.1  mrg 	    cur.possible_dynamic_type_change (cs->in_polymorphic_cdtor);
   2333  1.1  mrg 	  if (jfunc->type == IPA_JF_ANCESTOR)
   2334  1.1  mrg 	    cur.offset_by (ipa_get_jf_ancestor_offset (jfunc));
   2335  1.1  mrg 	  /* TODO: In cases we know how the context is going to be used,
   2336  1.1  mrg 	     we can improve the result by passing proper OTR_TYPE.  */
   2337  1.1  mrg 	  cur.combine_with (edge_ctx);
   2338  1.1  mrg 	  if (!cur.useless_p ())
   2339  1.1  mrg 	    {
   2340  1.1  mrg 	      if (src_lat->contains_variable
   2341  1.1  mrg 		  && !edge_ctx.equal_to (cur))
   2342  1.1  mrg 		ret |= dest_lat->set_contains_variable ();
   2343  1.1  mrg 	      ret |= dest_lat->add_value (cur, cs, src_val, src_idx);
   2344  1.1  mrg 	      added_sth = true;
   2345  1.1  mrg 	    }
   2346  1.1  mrg 	}
   2347  1.1  mrg     }
   2348  1.1  mrg 
   2349  1.1  mrg  prop_fail:
   2350  1.1  mrg   if (!added_sth)
   2351  1.1  mrg     {
   2352  1.1  mrg       if (!edge_ctx.useless_p ())
   2353  1.1  mrg 	ret |= dest_lat->add_value (edge_ctx, cs);
   2354  1.1  mrg       else
   2355  1.1  mrg 	ret |= dest_lat->set_contains_variable ();
   2356  1.1  mrg     }
   2357  1.1  mrg 
   2358  1.1  mrg   return ret;
   2359  1.1  mrg }
   2360  1.1  mrg 
   2361  1.1  mrg /* Propagate bits across jfunc that is associated with
   2362  1.1  mrg    edge cs and update dest_lattice accordingly.  */
   2363  1.1  mrg 
   2364  1.1  mrg bool
   2365  1.1  mrg propagate_bits_across_jump_function (cgraph_edge *cs, int idx,
   2366  1.1  mrg 				     ipa_jump_func *jfunc,
   2367  1.1  mrg 				     ipcp_bits_lattice *dest_lattice)
   2368  1.1  mrg {
   2369  1.1  mrg   if (dest_lattice->bottom_p ())
   2370  1.1  mrg     return false;
   2371  1.1  mrg 
   2372  1.1  mrg   enum availability availability;
   2373  1.1  mrg   cgraph_node *callee = cs->callee->function_symbol (&availability);
   2374  1.1  mrg   ipa_node_params *callee_info = ipa_node_params_sum->get (callee);
   2375  1.1  mrg   tree parm_type = ipa_get_type (callee_info, idx);
   2376  1.1  mrg 
   2377  1.1  mrg   /* For K&R C programs, ipa_get_type() could return NULL_TREE.  Avoid the
   2378  1.1  mrg      transform for these cases.  Similarly, we can have bad type mismatches
   2379  1.1  mrg      with LTO, avoid doing anything with those too.  */
   2380  1.1  mrg   if (!parm_type
   2381  1.1  mrg       || (!INTEGRAL_TYPE_P (parm_type) && !POINTER_TYPE_P (parm_type)))
   2382  1.1  mrg     {
   2383  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   2384  1.1  mrg 	fprintf (dump_file, "Setting dest_lattice to bottom, because type of "
   2385  1.1  mrg 		 "param %i of %s is NULL or unsuitable for bits propagation\n",
   2386  1.1  mrg 		 idx, cs->callee->dump_name ());
   2387  1.1  mrg 
   2388  1.1  mrg       return dest_lattice->set_to_bottom ();
   2389  1.1  mrg     }
   2390  1.1  mrg 
   2391  1.1  mrg   unsigned precision = TYPE_PRECISION (parm_type);
   2392  1.1  mrg   signop sgn = TYPE_SIGN (parm_type);
   2393  1.1  mrg 
   2394  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH
   2395  1.1  mrg       || jfunc->type == IPA_JF_ANCESTOR)
   2396  1.1  mrg     {
   2397  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2398  1.1  mrg       tree operand = NULL_TREE;
   2399  1.1  mrg       enum tree_code code;
   2400  1.1  mrg       unsigned src_idx;
   2401  1.1  mrg       bool keep_null = false;
   2402  1.1  mrg 
   2403  1.1  mrg       if (jfunc->type == IPA_JF_PASS_THROUGH)
   2404  1.1  mrg 	{
   2405  1.1  mrg 	  code = ipa_get_jf_pass_through_operation (jfunc);
   2406  1.1  mrg 	  src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   2407  1.1  mrg 	  if (code != NOP_EXPR)
   2408  1.1  mrg 	    operand = ipa_get_jf_pass_through_operand (jfunc);
   2409  1.1  mrg 	}
   2410  1.1  mrg       else
   2411  1.1  mrg 	{
   2412  1.1  mrg 	  code = POINTER_PLUS_EXPR;
   2413  1.1  mrg 	  src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
   2414  1.1  mrg 	  unsigned HOST_WIDE_INT offset
   2415  1.1  mrg 	    = ipa_get_jf_ancestor_offset (jfunc) / BITS_PER_UNIT;
   2416  1.1  mrg 	  keep_null = (ipa_get_jf_ancestor_keep_null (jfunc) || !offset);
   2417  1.1  mrg 	  operand = build_int_cstu (size_type_node, offset);
   2418  1.1  mrg 	}
   2419  1.1  mrg 
   2420  1.1  mrg       class ipcp_param_lattices *src_lats
   2421  1.1  mrg 	= ipa_get_parm_lattices (caller_info, src_idx);
   2422  1.1  mrg 
   2423  1.1  mrg       /* Try to propagate bits if src_lattice is bottom, but jfunc is known.
   2424  1.1  mrg 	 for eg consider:
   2425  1.1  mrg 	 int f(int x)
   2426  1.1  mrg 	 {
   2427  1.1  mrg 	   g (x & 0xff);
   2428  1.1  mrg 	 }
   2429  1.1  mrg 	 Assume lattice for x is bottom, however we can still propagate
   2430  1.1  mrg 	 result of x & 0xff == 0xff, which gets computed during ccp1 pass
   2431  1.1  mrg 	 and we store it in jump function during analysis stage.  */
   2432  1.1  mrg 
   2433  1.1  mrg       if (!src_lats->bits_lattice.bottom_p ())
   2434  1.1  mrg 	{
   2435  1.1  mrg 	  bool drop_all_ones
   2436  1.1  mrg 	    = keep_null && !src_lats->bits_lattice.known_nonzero_p ();
   2437  1.1  mrg 
   2438  1.1  mrg 	  return dest_lattice->meet_with (src_lats->bits_lattice, precision,
   2439  1.1  mrg 					  sgn, code, operand, drop_all_ones);
   2440  1.1  mrg 	}
   2441  1.1  mrg     }
   2442  1.1  mrg 
   2443  1.1  mrg   if (jfunc->bits)
   2444  1.1  mrg     return dest_lattice->meet_with (jfunc->bits->value, jfunc->bits->mask,
   2445  1.1  mrg 				    precision);
   2446  1.1  mrg   else
   2447  1.1  mrg     return dest_lattice->set_to_bottom ();
   2448  1.1  mrg }
   2449  1.1  mrg 
   2450  1.1  mrg /* Propagate value range across jump function JFUNC that is associated with
   2451  1.1  mrg    edge CS with param of callee of PARAM_TYPE and update DEST_PLATS
   2452  1.1  mrg    accordingly.  */
   2453  1.1  mrg 
   2454  1.1  mrg static bool
   2455  1.1  mrg propagate_vr_across_jump_function (cgraph_edge *cs, ipa_jump_func *jfunc,
   2456  1.1  mrg 				   class ipcp_param_lattices *dest_plats,
   2457  1.1  mrg 				   tree param_type)
   2458  1.1  mrg {
   2459  1.1  mrg   ipcp_vr_lattice *dest_lat = &dest_plats->m_value_range;
   2460  1.1  mrg 
   2461  1.1  mrg   if (dest_lat->bottom_p ())
   2462  1.1  mrg     return false;
   2463  1.1  mrg 
   2464  1.1  mrg   if (!param_type
   2465  1.1  mrg       || (!INTEGRAL_TYPE_P (param_type)
   2466  1.1  mrg 	  && !POINTER_TYPE_P (param_type)))
   2467  1.1  mrg     return dest_lat->set_to_bottom ();
   2468  1.1  mrg 
   2469  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH)
   2470  1.1  mrg     {
   2471  1.1  mrg       enum tree_code operation = ipa_get_jf_pass_through_operation (jfunc);
   2472  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2473  1.1  mrg       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   2474  1.1  mrg       class ipcp_param_lattices *src_lats
   2475  1.1  mrg 	= ipa_get_parm_lattices (caller_info, src_idx);
   2476  1.1  mrg       tree operand_type = ipa_get_type (caller_info, src_idx);
   2477  1.1  mrg 
   2478  1.1  mrg       if (src_lats->m_value_range.bottom_p ())
   2479  1.1  mrg 	return dest_lat->set_to_bottom ();
   2480  1.1  mrg 
   2481  1.1  mrg       value_range vr;
   2482  1.1  mrg       if (TREE_CODE_CLASS (operation) == tcc_unary)
   2483  1.1  mrg 	ipa_vr_operation_and_type_effects (&vr,
   2484  1.1  mrg 					   &src_lats->m_value_range.m_vr,
   2485  1.1  mrg 					   operation, param_type,
   2486  1.1  mrg 					   operand_type);
   2487  1.1  mrg       /* A crude way to prevent unbounded number of value range updates
   2488  1.1  mrg 	 in SCC components.  We should allow limited number of updates within
   2489  1.1  mrg 	 SCC, too.  */
   2490  1.1  mrg       else if (!ipa_edge_within_scc (cs))
   2491  1.1  mrg 	{
   2492  1.1  mrg 	  tree op = ipa_get_jf_pass_through_operand (jfunc);
   2493  1.1  mrg 	  value_range op_vr (op, op);
   2494  1.1  mrg 	  value_range op_res,res;
   2495  1.1  mrg 
   2496  1.1  mrg 	  range_fold_binary_expr (&op_res, operation, operand_type,
   2497  1.1  mrg 				  &src_lats->m_value_range.m_vr, &op_vr);
   2498  1.1  mrg 	  ipa_vr_operation_and_type_effects (&vr,
   2499  1.1  mrg 					     &op_res,
   2500  1.1  mrg 					     NOP_EXPR, param_type,
   2501  1.1  mrg 					     operand_type);
   2502  1.1  mrg 	}
   2503  1.1  mrg       if (!vr.undefined_p () && !vr.varying_p ())
   2504  1.1  mrg 	{
   2505  1.1  mrg 	  if (jfunc->m_vr)
   2506  1.1  mrg 	    {
   2507  1.1  mrg 	      value_range jvr;
   2508  1.1  mrg 	      if (ipa_vr_operation_and_type_effects (&jvr, jfunc->m_vr,
   2509  1.1  mrg 						     NOP_EXPR,
   2510  1.1  mrg 						     param_type,
   2511  1.1  mrg 						     jfunc->m_vr->type ()))
   2512  1.1  mrg 		vr.intersect (jvr);
   2513  1.1  mrg 	    }
   2514  1.1  mrg 	  return dest_lat->meet_with (&vr);
   2515  1.1  mrg 	}
   2516  1.1  mrg     }
   2517  1.1  mrg   else if (jfunc->type == IPA_JF_CONST)
   2518  1.1  mrg     {
   2519  1.1  mrg       tree val = ipa_get_jf_constant (jfunc);
   2520  1.1  mrg       if (TREE_CODE (val) == INTEGER_CST)
   2521  1.1  mrg 	{
   2522  1.1  mrg 	  val = fold_convert (param_type, val);
   2523  1.1  mrg 	  if (TREE_OVERFLOW_P (val))
   2524  1.1  mrg 	    val = drop_tree_overflow (val);
   2525  1.1  mrg 
   2526  1.1  mrg 	  value_range tmpvr (val, val);
   2527  1.1  mrg 	  return dest_lat->meet_with (&tmpvr);
   2528  1.1  mrg 	}
   2529  1.1  mrg     }
   2530  1.1  mrg 
   2531  1.1  mrg   value_range vr;
   2532  1.1  mrg   if (jfunc->m_vr
   2533  1.1  mrg       && ipa_vr_operation_and_type_effects (&vr, jfunc->m_vr, NOP_EXPR,
   2534  1.1  mrg 					    param_type,
   2535  1.1  mrg 					    jfunc->m_vr->type ()))
   2536  1.1  mrg     return dest_lat->meet_with (&vr);
   2537  1.1  mrg   else
   2538  1.1  mrg     return dest_lat->set_to_bottom ();
   2539  1.1  mrg }
   2540  1.1  mrg 
   2541  1.1  mrg /* If DEST_PLATS already has aggregate items, check that aggs_by_ref matches
   2542  1.1  mrg    NEW_AGGS_BY_REF and if not, mark all aggs as bottoms and return true (in all
   2543  1.1  mrg    other cases, return false).  If there are no aggregate items, set
   2544  1.1  mrg    aggs_by_ref to NEW_AGGS_BY_REF.  */
   2545  1.1  mrg 
   2546  1.1  mrg static bool
   2547  1.1  mrg set_check_aggs_by_ref (class ipcp_param_lattices *dest_plats,
   2548  1.1  mrg 		       bool new_aggs_by_ref)
   2549  1.1  mrg {
   2550  1.1  mrg   if (dest_plats->aggs)
   2551  1.1  mrg     {
   2552  1.1  mrg       if (dest_plats->aggs_by_ref != new_aggs_by_ref)
   2553  1.1  mrg 	{
   2554  1.1  mrg 	  set_agg_lats_to_bottom (dest_plats);
   2555  1.1  mrg 	  return true;
   2556  1.1  mrg 	}
   2557  1.1  mrg     }
   2558  1.1  mrg   else
   2559  1.1  mrg     dest_plats->aggs_by_ref = new_aggs_by_ref;
   2560  1.1  mrg   return false;
   2561  1.1  mrg }
   2562  1.1  mrg 
   2563  1.1  mrg /* Walk aggregate lattices in DEST_PLATS from ***AGLAT on, until ***aglat is an
   2564  1.1  mrg    already existing lattice for the given OFFSET and SIZE, marking all skipped
   2565  1.1  mrg    lattices as containing variable and checking for overlaps.  If there is no
   2566  1.1  mrg    already existing lattice for the OFFSET and VAL_SIZE, create one, initialize
   2567  1.1  mrg    it with offset, size and contains_variable to PRE_EXISTING, and return true,
   2568  1.1  mrg    unless there are too many already.  If there are two many, return false.  If
   2569  1.1  mrg    there are overlaps turn whole DEST_PLATS to bottom and return false.  If any
   2570  1.1  mrg    skipped lattices were newly marked as containing variable, set *CHANGE to
   2571  1.1  mrg    true.  MAX_AGG_ITEMS is the maximum number of lattices.  */
   2572  1.1  mrg 
   2573  1.1  mrg static bool
   2574  1.1  mrg merge_agg_lats_step (class ipcp_param_lattices *dest_plats,
   2575  1.1  mrg 		     HOST_WIDE_INT offset, HOST_WIDE_INT val_size,
   2576  1.1  mrg 		     struct ipcp_agg_lattice ***aglat,
   2577  1.1  mrg 		     bool pre_existing, bool *change, int max_agg_items)
   2578  1.1  mrg {
   2579  1.1  mrg   gcc_checking_assert (offset >= 0);
   2580  1.1  mrg 
   2581  1.1  mrg   while (**aglat && (**aglat)->offset < offset)
   2582  1.1  mrg     {
   2583  1.1  mrg       if ((**aglat)->offset + (**aglat)->size > offset)
   2584  1.1  mrg 	{
   2585  1.1  mrg 	  set_agg_lats_to_bottom (dest_plats);
   2586  1.1  mrg 	  return false;
   2587  1.1  mrg 	}
   2588  1.1  mrg       *change |= (**aglat)->set_contains_variable ();
   2589  1.1  mrg       *aglat = &(**aglat)->next;
   2590  1.1  mrg     }
   2591  1.1  mrg 
   2592  1.1  mrg   if (**aglat && (**aglat)->offset == offset)
   2593  1.1  mrg     {
   2594  1.1  mrg       if ((**aglat)->size != val_size)
   2595  1.1  mrg 	{
   2596  1.1  mrg 	  set_agg_lats_to_bottom (dest_plats);
   2597  1.1  mrg 	  return false;
   2598  1.1  mrg 	}
   2599  1.1  mrg       gcc_assert (!(**aglat)->next
   2600  1.1  mrg 		  || (**aglat)->next->offset >= offset + val_size);
   2601  1.1  mrg       return true;
   2602  1.1  mrg     }
   2603  1.1  mrg   else
   2604  1.1  mrg     {
   2605  1.1  mrg       struct ipcp_agg_lattice *new_al;
   2606  1.1  mrg 
   2607  1.1  mrg       if (**aglat && (**aglat)->offset < offset + val_size)
   2608  1.1  mrg 	{
   2609  1.1  mrg 	  set_agg_lats_to_bottom (dest_plats);
   2610  1.1  mrg 	  return false;
   2611  1.1  mrg 	}
   2612  1.1  mrg       if (dest_plats->aggs_count == max_agg_items)
   2613  1.1  mrg 	return false;
   2614  1.1  mrg       dest_plats->aggs_count++;
   2615  1.1  mrg       new_al = ipcp_agg_lattice_pool.allocate ();
   2616  1.1  mrg       memset (new_al, 0, sizeof (*new_al));
   2617  1.1  mrg 
   2618  1.1  mrg       new_al->offset = offset;
   2619  1.1  mrg       new_al->size = val_size;
   2620  1.1  mrg       new_al->contains_variable = pre_existing;
   2621  1.1  mrg 
   2622  1.1  mrg       new_al->next = **aglat;
   2623  1.1  mrg       **aglat = new_al;
   2624  1.1  mrg       return true;
   2625  1.1  mrg     }
   2626  1.1  mrg }
   2627  1.1  mrg 
   2628  1.1  mrg /* Set all AGLAT and all other aggregate lattices reachable by next pointers as
   2629  1.1  mrg    containing an unknown value.  */
   2630  1.1  mrg 
   2631  1.1  mrg static bool
   2632  1.1  mrg set_chain_of_aglats_contains_variable (struct ipcp_agg_lattice *aglat)
   2633  1.1  mrg {
   2634  1.1  mrg   bool ret = false;
   2635  1.1  mrg   while (aglat)
   2636  1.1  mrg     {
   2637  1.1  mrg       ret |= aglat->set_contains_variable ();
   2638  1.1  mrg       aglat = aglat->next;
   2639  1.1  mrg     }
   2640  1.1  mrg   return ret;
   2641  1.1  mrg }
   2642  1.1  mrg 
   2643  1.1  mrg /* Merge existing aggregate lattices in SRC_PLATS to DEST_PLATS, subtracting
   2644  1.1  mrg    DELTA_OFFSET.  CS is the call graph edge and SRC_IDX the index of the source
   2645  1.1  mrg    parameter used for lattice value sources.  Return true if DEST_PLATS changed
   2646  1.1  mrg    in any way.  */
   2647  1.1  mrg 
   2648  1.1  mrg static bool
   2649  1.1  mrg merge_aggregate_lattices (struct cgraph_edge *cs,
   2650  1.1  mrg 			  class ipcp_param_lattices *dest_plats,
   2651  1.1  mrg 			  class ipcp_param_lattices *src_plats,
   2652  1.1  mrg 			  int src_idx, HOST_WIDE_INT offset_delta)
   2653  1.1  mrg {
   2654  1.1  mrg   bool pre_existing = dest_plats->aggs != NULL;
   2655  1.1  mrg   struct ipcp_agg_lattice **dst_aglat;
   2656  1.1  mrg   bool ret = false;
   2657  1.1  mrg 
   2658  1.1  mrg   if (set_check_aggs_by_ref (dest_plats, src_plats->aggs_by_ref))
   2659  1.1  mrg     return true;
   2660  1.1  mrg   if (src_plats->aggs_bottom)
   2661  1.1  mrg     return set_agg_lats_contain_variable (dest_plats);
   2662  1.1  mrg   if (src_plats->aggs_contain_variable)
   2663  1.1  mrg     ret |= set_agg_lats_contain_variable (dest_plats);
   2664  1.1  mrg   dst_aglat = &dest_plats->aggs;
   2665  1.1  mrg 
   2666  1.1  mrg   int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
   2667  1.1  mrg 				  param_ipa_max_agg_items);
   2668  1.1  mrg   for (struct ipcp_agg_lattice *src_aglat = src_plats->aggs;
   2669  1.1  mrg        src_aglat;
   2670  1.1  mrg        src_aglat = src_aglat->next)
   2671  1.1  mrg     {
   2672  1.1  mrg       HOST_WIDE_INT new_offset = src_aglat->offset - offset_delta;
   2673  1.1  mrg 
   2674  1.1  mrg       if (new_offset < 0)
   2675  1.1  mrg 	continue;
   2676  1.1  mrg       if (merge_agg_lats_step (dest_plats, new_offset, src_aglat->size,
   2677  1.1  mrg 			       &dst_aglat, pre_existing, &ret, max_agg_items))
   2678  1.1  mrg 	{
   2679  1.1  mrg 	  struct ipcp_agg_lattice *new_al = *dst_aglat;
   2680  1.1  mrg 
   2681  1.1  mrg 	  dst_aglat = &(*dst_aglat)->next;
   2682  1.1  mrg 	  if (src_aglat->bottom)
   2683  1.1  mrg 	    {
   2684  1.1  mrg 	      ret |= new_al->set_contains_variable ();
   2685  1.1  mrg 	      continue;
   2686  1.1  mrg 	    }
   2687  1.1  mrg 	  if (src_aglat->contains_variable)
   2688  1.1  mrg 	    ret |= new_al->set_contains_variable ();
   2689  1.1  mrg 	  for (ipcp_value<tree> *val = src_aglat->values;
   2690  1.1  mrg 	       val;
   2691  1.1  mrg 	       val = val->next)
   2692  1.1  mrg 	    ret |= new_al->add_value (val->value, cs, val, src_idx,
   2693  1.1  mrg 				      src_aglat->offset);
   2694  1.1  mrg 	}
   2695  1.1  mrg       else if (dest_plats->aggs_bottom)
   2696  1.1  mrg 	return true;
   2697  1.1  mrg     }
   2698  1.1  mrg   ret |= set_chain_of_aglats_contains_variable (*dst_aglat);
   2699  1.1  mrg   return ret;
   2700  1.1  mrg }
   2701  1.1  mrg 
   2702  1.1  mrg /* Determine whether there is anything to propagate FROM SRC_PLATS through a
   2703  1.1  mrg    pass-through JFUNC and if so, whether it has conform and conforms to the
   2704  1.1  mrg    rules about propagating values passed by reference.  */
   2705  1.1  mrg 
   2706  1.1  mrg static bool
   2707  1.1  mrg agg_pass_through_permissible_p (class ipcp_param_lattices *src_plats,
   2708  1.1  mrg 				struct ipa_jump_func *jfunc)
   2709  1.1  mrg {
   2710  1.1  mrg   return src_plats->aggs
   2711  1.1  mrg     && (!src_plats->aggs_by_ref
   2712  1.1  mrg 	|| ipa_get_jf_pass_through_agg_preserved (jfunc));
   2713  1.1  mrg }
   2714  1.1  mrg 
   2715  1.1  mrg /* Propagate values through ITEM, jump function for a part of an aggregate,
   2716  1.1  mrg    into corresponding aggregate lattice AGLAT.  CS is the call graph edge
   2717  1.1  mrg    associated with the jump function.  Return true if AGLAT changed in any
   2718  1.1  mrg    way.  */
   2719  1.1  mrg 
   2720  1.1  mrg static bool
   2721  1.1  mrg propagate_aggregate_lattice (struct cgraph_edge *cs,
   2722  1.1  mrg 			     struct ipa_agg_jf_item *item,
   2723  1.1  mrg 			     struct ipcp_agg_lattice *aglat)
   2724  1.1  mrg {
   2725  1.1  mrg   class ipa_node_params *caller_info;
   2726  1.1  mrg   class ipcp_param_lattices *src_plats;
   2727  1.1  mrg   struct ipcp_lattice<tree> *src_lat;
   2728  1.1  mrg   HOST_WIDE_INT src_offset;
   2729  1.1  mrg   int src_idx;
   2730  1.1  mrg   tree load_type;
   2731  1.1  mrg   bool ret;
   2732  1.1  mrg 
   2733  1.1  mrg   if (item->jftype == IPA_JF_CONST)
   2734  1.1  mrg     {
   2735  1.1  mrg       tree value = item->value.constant;
   2736  1.1  mrg 
   2737  1.1  mrg       gcc_checking_assert (is_gimple_ip_invariant (value));
   2738  1.1  mrg       return aglat->add_value (value, cs, NULL, 0);
   2739  1.1  mrg     }
   2740  1.1  mrg 
   2741  1.1  mrg   gcc_checking_assert (item->jftype == IPA_JF_PASS_THROUGH
   2742  1.1  mrg 		       || item->jftype == IPA_JF_LOAD_AGG);
   2743  1.1  mrg 
   2744  1.1  mrg   caller_info = ipa_node_params_sum->get (cs->caller);
   2745  1.1  mrg   src_idx = item->value.pass_through.formal_id;
   2746  1.1  mrg   src_plats = ipa_get_parm_lattices (caller_info, src_idx);
   2747  1.1  mrg 
   2748  1.1  mrg   if (item->jftype == IPA_JF_PASS_THROUGH)
   2749  1.1  mrg     {
   2750  1.1  mrg       load_type = NULL_TREE;
   2751  1.1  mrg       src_lat = &src_plats->itself;
   2752  1.1  mrg       src_offset = -1;
   2753  1.1  mrg     }
   2754  1.1  mrg   else
   2755  1.1  mrg     {
   2756  1.1  mrg       HOST_WIDE_INT load_offset = item->value.load_agg.offset;
   2757  1.1  mrg       struct ipcp_agg_lattice *src_aglat;
   2758  1.1  mrg 
   2759  1.1  mrg       for (src_aglat = src_plats->aggs; src_aglat; src_aglat = src_aglat->next)
   2760  1.1  mrg 	if (src_aglat->offset >= load_offset)
   2761  1.1  mrg 	  break;
   2762  1.1  mrg 
   2763  1.1  mrg       load_type = item->value.load_agg.type;
   2764  1.1  mrg       if (!src_aglat
   2765  1.1  mrg 	  || src_aglat->offset > load_offset
   2766  1.1  mrg 	  || src_aglat->size != tree_to_shwi (TYPE_SIZE (load_type))
   2767  1.1  mrg 	  || src_plats->aggs_by_ref != item->value.load_agg.by_ref)
   2768  1.1  mrg 	return aglat->set_contains_variable ();
   2769  1.1  mrg 
   2770  1.1  mrg       src_lat = src_aglat;
   2771  1.1  mrg       src_offset = load_offset;
   2772  1.1  mrg     }
   2773  1.1  mrg 
   2774  1.1  mrg   if (src_lat->bottom
   2775  1.1  mrg       || (!ipcp_versionable_function_p (cs->caller)
   2776  1.1  mrg 	  && !src_lat->is_single_const ()))
   2777  1.1  mrg     return aglat->set_contains_variable ();
   2778  1.1  mrg 
   2779  1.1  mrg   ret = propagate_vals_across_arith_jfunc (cs,
   2780  1.1  mrg 					   item->value.pass_through.operation,
   2781  1.1  mrg 					   load_type,
   2782  1.1  mrg 					   item->value.pass_through.operand,
   2783  1.1  mrg 					   src_lat, aglat,
   2784  1.1  mrg 					   src_offset,
   2785  1.1  mrg 					   src_idx,
   2786  1.1  mrg 					   item->type);
   2787  1.1  mrg 
   2788  1.1  mrg   if (src_lat->contains_variable)
   2789  1.1  mrg     ret |= aglat->set_contains_variable ();
   2790  1.1  mrg 
   2791  1.1  mrg   return ret;
   2792  1.1  mrg }
   2793  1.1  mrg 
   2794  1.1  mrg /* Propagate scalar values across jump function JFUNC that is associated with
   2795  1.1  mrg    edge CS and put the values into DEST_LAT.  */
   2796  1.1  mrg 
   2797  1.1  mrg static bool
   2798  1.1  mrg propagate_aggs_across_jump_function (struct cgraph_edge *cs,
   2799  1.1  mrg 				     struct ipa_jump_func *jfunc,
   2800  1.1  mrg 				     class ipcp_param_lattices *dest_plats)
   2801  1.1  mrg {
   2802  1.1  mrg   bool ret = false;
   2803  1.1  mrg 
   2804  1.1  mrg   if (dest_plats->aggs_bottom)
   2805  1.1  mrg     return false;
   2806  1.1  mrg 
   2807  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH
   2808  1.1  mrg       && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
   2809  1.1  mrg     {
   2810  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2811  1.1  mrg       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   2812  1.1  mrg       class ipcp_param_lattices *src_plats;
   2813  1.1  mrg 
   2814  1.1  mrg       src_plats = ipa_get_parm_lattices (caller_info, src_idx);
   2815  1.1  mrg       if (agg_pass_through_permissible_p (src_plats, jfunc))
   2816  1.1  mrg 	{
   2817  1.1  mrg 	  /* Currently we do not produce clobber aggregate jump
   2818  1.1  mrg 	     functions, replace with merging when we do.  */
   2819  1.1  mrg 	  gcc_assert (!jfunc->agg.items);
   2820  1.1  mrg 	  ret |= merge_aggregate_lattices (cs, dest_plats, src_plats,
   2821  1.1  mrg 					   src_idx, 0);
   2822  1.1  mrg 	  return ret;
   2823  1.1  mrg 	}
   2824  1.1  mrg     }
   2825  1.1  mrg   else if (jfunc->type == IPA_JF_ANCESTOR
   2826  1.1  mrg 	   && ipa_get_jf_ancestor_agg_preserved (jfunc))
   2827  1.1  mrg     {
   2828  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   2829  1.1  mrg       int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
   2830  1.1  mrg       class ipcp_param_lattices *src_plats;
   2831  1.1  mrg 
   2832  1.1  mrg       src_plats = ipa_get_parm_lattices (caller_info, src_idx);
   2833  1.1  mrg       if (src_plats->aggs && src_plats->aggs_by_ref)
   2834  1.1  mrg 	{
   2835  1.1  mrg 	  /* Currently we do not produce clobber aggregate jump
   2836  1.1  mrg 	     functions, replace with merging when we do.  */
   2837  1.1  mrg 	  gcc_assert (!jfunc->agg.items);
   2838  1.1  mrg 	  ret |= merge_aggregate_lattices (cs, dest_plats, src_plats, src_idx,
   2839  1.1  mrg 					   ipa_get_jf_ancestor_offset (jfunc));
   2840  1.1  mrg 	}
   2841  1.1  mrg       else if (!src_plats->aggs_by_ref)
   2842  1.1  mrg 	ret |= set_agg_lats_to_bottom (dest_plats);
   2843  1.1  mrg       else
   2844  1.1  mrg 	ret |= set_agg_lats_contain_variable (dest_plats);
   2845  1.1  mrg       return ret;
   2846  1.1  mrg     }
   2847  1.1  mrg 
   2848  1.1  mrg   if (jfunc->agg.items)
   2849  1.1  mrg     {
   2850  1.1  mrg       bool pre_existing = dest_plats->aggs != NULL;
   2851  1.1  mrg       struct ipcp_agg_lattice **aglat = &dest_plats->aggs;
   2852  1.1  mrg       struct ipa_agg_jf_item *item;
   2853  1.1  mrg       int i;
   2854  1.1  mrg 
   2855  1.1  mrg       if (set_check_aggs_by_ref (dest_plats, jfunc->agg.by_ref))
   2856  1.1  mrg 	return true;
   2857  1.1  mrg 
   2858  1.1  mrg       int max_agg_items = opt_for_fn (cs->callee->function_symbol ()->decl,
   2859  1.1  mrg 				      param_ipa_max_agg_items);
   2860  1.1  mrg       FOR_EACH_VEC_ELT (*jfunc->agg.items, i, item)
   2861  1.1  mrg 	{
   2862  1.1  mrg 	  HOST_WIDE_INT val_size;
   2863  1.1  mrg 
   2864  1.1  mrg 	  if (item->offset < 0 || item->jftype == IPA_JF_UNKNOWN)
   2865  1.1  mrg 	    continue;
   2866  1.1  mrg 	  val_size = tree_to_shwi (TYPE_SIZE (item->type));
   2867  1.1  mrg 
   2868  1.1  mrg 	  if (merge_agg_lats_step (dest_plats, item->offset, val_size,
   2869  1.1  mrg 				   &aglat, pre_existing, &ret, max_agg_items))
   2870  1.1  mrg 	    {
   2871  1.1  mrg 	      ret |= propagate_aggregate_lattice (cs, item, *aglat);
   2872  1.1  mrg 	      aglat = &(*aglat)->next;
   2873  1.1  mrg 	    }
   2874  1.1  mrg 	  else if (dest_plats->aggs_bottom)
   2875  1.1  mrg 	    return true;
   2876  1.1  mrg 	}
   2877  1.1  mrg 
   2878  1.1  mrg       ret |= set_chain_of_aglats_contains_variable (*aglat);
   2879  1.1  mrg     }
   2880  1.1  mrg   else
   2881  1.1  mrg     ret |= set_agg_lats_contain_variable (dest_plats);
   2882  1.1  mrg 
   2883  1.1  mrg   return ret;
   2884  1.1  mrg }
   2885  1.1  mrg 
   2886  1.1  mrg /* Return true if on the way cfrom CS->caller to the final (non-alias and
   2887  1.1  mrg    non-thunk) destination, the call passes through a thunk.  */
   2888  1.1  mrg 
   2889  1.1  mrg static bool
   2890  1.1  mrg call_passes_through_thunk (cgraph_edge *cs)
   2891  1.1  mrg {
   2892  1.1  mrg   cgraph_node *alias_or_thunk = cs->callee;
   2893  1.1  mrg   while (alias_or_thunk->alias)
   2894  1.1  mrg     alias_or_thunk = alias_or_thunk->get_alias_target ();
   2895  1.1  mrg   return alias_or_thunk->thunk;
   2896  1.1  mrg }
   2897  1.1  mrg 
   2898  1.1  mrg /* Propagate constants from the caller to the callee of CS.  INFO describes the
   2899  1.1  mrg    caller.  */
   2900  1.1  mrg 
   2901  1.1  mrg static bool
   2902  1.1  mrg propagate_constants_across_call (struct cgraph_edge *cs)
   2903  1.1  mrg {
   2904  1.1  mrg   class ipa_node_params *callee_info;
   2905  1.1  mrg   enum availability availability;
   2906  1.1  mrg   cgraph_node *callee;
   2907  1.1  mrg   class ipa_edge_args *args;
   2908  1.1  mrg   bool ret = false;
   2909  1.1  mrg   int i, args_count, parms_count;
   2910  1.1  mrg 
   2911  1.1  mrg   callee = cs->callee->function_symbol (&availability);
   2912  1.1  mrg   if (!callee->definition)
   2913  1.1  mrg     return false;
   2914  1.1  mrg   gcc_checking_assert (callee->has_gimple_body_p ());
   2915  1.1  mrg   callee_info = ipa_node_params_sum->get (callee);
   2916  1.1  mrg   if (!callee_info)
   2917  1.1  mrg     return false;
   2918  1.1  mrg 
   2919  1.1  mrg   args = ipa_edge_args_sum->get (cs);
   2920  1.1  mrg   parms_count = ipa_get_param_count (callee_info);
   2921  1.1  mrg   if (parms_count == 0)
   2922  1.1  mrg     return false;
   2923  1.1  mrg   if (!args
   2924  1.1  mrg       || !opt_for_fn (cs->caller->decl, flag_ipa_cp)
   2925  1.1  mrg       || !opt_for_fn (cs->caller->decl, optimize))
   2926  1.1  mrg     {
   2927  1.1  mrg       for (i = 0; i < parms_count; i++)
   2928  1.1  mrg 	ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
   2929  1.1  mrg 								 i));
   2930  1.1  mrg       return ret;
   2931  1.1  mrg     }
   2932  1.1  mrg   args_count = ipa_get_cs_argument_count (args);
   2933  1.1  mrg 
   2934  1.1  mrg   /* If this call goes through a thunk we must not propagate to the first (0th)
   2935  1.1  mrg      parameter.  However, we might need to uncover a thunk from below a series
   2936  1.1  mrg      of aliases first.  */
   2937  1.1  mrg   if (call_passes_through_thunk (cs))
   2938  1.1  mrg     {
   2939  1.1  mrg       ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
   2940  1.1  mrg 							       0));
   2941  1.1  mrg       i = 1;
   2942  1.1  mrg     }
   2943  1.1  mrg   else
   2944  1.1  mrg     i = 0;
   2945  1.1  mrg 
   2946  1.1  mrg   for (; (i < args_count) && (i < parms_count); i++)
   2947  1.1  mrg     {
   2948  1.1  mrg       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
   2949  1.1  mrg       class ipcp_param_lattices *dest_plats;
   2950  1.1  mrg       tree param_type = ipa_get_type (callee_info, i);
   2951  1.1  mrg 
   2952  1.1  mrg       dest_plats = ipa_get_parm_lattices (callee_info, i);
   2953  1.1  mrg       if (availability == AVAIL_INTERPOSABLE)
   2954  1.1  mrg 	ret |= set_all_contains_variable (dest_plats);
   2955  1.1  mrg       else
   2956  1.1  mrg 	{
   2957  1.1  mrg 	  ret |= propagate_scalar_across_jump_function (cs, jump_func,
   2958  1.1  mrg 							&dest_plats->itself,
   2959  1.1  mrg 							param_type);
   2960  1.1  mrg 	  ret |= propagate_context_across_jump_function (cs, jump_func, i,
   2961  1.1  mrg 							 &dest_plats->ctxlat);
   2962  1.1  mrg 	  ret
   2963  1.1  mrg 	    |= propagate_bits_across_jump_function (cs, i, jump_func,
   2964  1.1  mrg 						    &dest_plats->bits_lattice);
   2965  1.1  mrg 	  ret |= propagate_aggs_across_jump_function (cs, jump_func,
   2966  1.1  mrg 						      dest_plats);
   2967  1.1  mrg 	  if (opt_for_fn (callee->decl, flag_ipa_vrp))
   2968  1.1  mrg 	    ret |= propagate_vr_across_jump_function (cs, jump_func,
   2969  1.1  mrg 						      dest_plats, param_type);
   2970  1.1  mrg 	  else
   2971  1.1  mrg 	    ret |= dest_plats->m_value_range.set_to_bottom ();
   2972  1.1  mrg 	}
   2973  1.1  mrg     }
   2974  1.1  mrg   for (; i < parms_count; i++)
   2975  1.1  mrg     ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info, i));
   2976  1.1  mrg 
   2977  1.1  mrg   return ret;
   2978  1.1  mrg }
   2979  1.1  mrg 
   2980  1.1  mrg /* If an indirect edge IE can be turned into a direct one based on KNOWN_VALS
   2981  1.1  mrg    KNOWN_CONTEXTS, KNOWN_AGGS or AGG_REPS return the destination.  The latter
   2982  1.1  mrg    three can be NULL.  If AGG_REPS is not NULL, KNOWN_AGGS is ignored.  */
   2983  1.1  mrg 
   2984  1.1  mrg static tree
   2985  1.1  mrg ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
   2986  1.1  mrg 				const vec<tree> &known_csts,
   2987  1.1  mrg 				const vec<ipa_polymorphic_call_context> &known_contexts,
   2988  1.1  mrg 				const vec<ipa_agg_value_set> &known_aggs,
   2989  1.1  mrg 				struct ipa_agg_replacement_value *agg_reps,
   2990  1.1  mrg 				bool *speculative)
   2991  1.1  mrg {
   2992  1.1  mrg   int param_index = ie->indirect_info->param_index;
   2993  1.1  mrg   HOST_WIDE_INT anc_offset;
   2994  1.1  mrg   tree t = NULL;
   2995  1.1  mrg   tree target = NULL;
   2996  1.1  mrg 
   2997  1.1  mrg   *speculative = false;
   2998  1.1  mrg 
   2999  1.1  mrg   if (param_index == -1)
   3000  1.1  mrg     return NULL_TREE;
   3001  1.1  mrg 
   3002  1.1  mrg   if (!ie->indirect_info->polymorphic)
   3003  1.1  mrg     {
   3004  1.1  mrg       tree t = NULL;
   3005  1.1  mrg 
   3006  1.1  mrg       if (ie->indirect_info->agg_contents)
   3007  1.1  mrg 	{
   3008  1.1  mrg 	  t = NULL;
   3009  1.1  mrg 	  if (agg_reps && ie->indirect_info->guaranteed_unmodified)
   3010  1.1  mrg 	    {
   3011  1.1  mrg 	      while (agg_reps)
   3012  1.1  mrg 		{
   3013  1.1  mrg 		  if (agg_reps->index == param_index
   3014  1.1  mrg 		      && agg_reps->offset == ie->indirect_info->offset
   3015  1.1  mrg 		      && agg_reps->by_ref == ie->indirect_info->by_ref)
   3016  1.1  mrg 		    {
   3017  1.1  mrg 		      t = agg_reps->value;
   3018  1.1  mrg 		      break;
   3019  1.1  mrg 		    }
   3020  1.1  mrg 		  agg_reps = agg_reps->next;
   3021  1.1  mrg 		}
   3022  1.1  mrg 	    }
   3023  1.1  mrg 	  if (!t)
   3024  1.1  mrg 	    {
   3025  1.1  mrg 	      const ipa_agg_value_set *agg;
   3026  1.1  mrg 	      if (known_aggs.length () > (unsigned int) param_index)
   3027  1.1  mrg 		agg = &known_aggs[param_index];
   3028  1.1  mrg 	      else
   3029  1.1  mrg 		agg = NULL;
   3030  1.1  mrg 	      bool from_global_constant;
   3031  1.1  mrg 	      t = ipa_find_agg_cst_for_param (agg,
   3032  1.1  mrg 					      (unsigned) param_index
   3033  1.1  mrg 						 < known_csts.length ()
   3034  1.1  mrg 					      ? known_csts[param_index]
   3035  1.1  mrg 					      : NULL,
   3036  1.1  mrg 					      ie->indirect_info->offset,
   3037  1.1  mrg 					      ie->indirect_info->by_ref,
   3038  1.1  mrg 					      &from_global_constant);
   3039  1.1  mrg 	      if (t
   3040  1.1  mrg 		  && !from_global_constant
   3041  1.1  mrg 		  && !ie->indirect_info->guaranteed_unmodified)
   3042  1.1  mrg 		t = NULL_TREE;
   3043  1.1  mrg 	    }
   3044  1.1  mrg 	}
   3045  1.1  mrg       else if ((unsigned) param_index < known_csts.length ())
   3046  1.1  mrg 	t = known_csts[param_index];
   3047  1.1  mrg 
   3048  1.1  mrg       if (t
   3049  1.1  mrg 	  && TREE_CODE (t) == ADDR_EXPR
   3050  1.1  mrg 	  && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
   3051  1.1  mrg 	return TREE_OPERAND (t, 0);
   3052  1.1  mrg       else
   3053  1.1  mrg 	return NULL_TREE;
   3054  1.1  mrg     }
   3055  1.1  mrg 
   3056  1.1  mrg   if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
   3057  1.1  mrg     return NULL_TREE;
   3058  1.1  mrg 
   3059  1.1  mrg   gcc_assert (!ie->indirect_info->agg_contents);
   3060  1.1  mrg   anc_offset = ie->indirect_info->offset;
   3061  1.1  mrg 
   3062  1.1  mrg   t = NULL;
   3063  1.1  mrg 
   3064  1.1  mrg   /* Try to work out value of virtual table pointer value in replacements.  */
   3065  1.1  mrg   if (!t && agg_reps && !ie->indirect_info->by_ref)
   3066  1.1  mrg     {
   3067  1.1  mrg       while (agg_reps)
   3068  1.1  mrg 	{
   3069  1.1  mrg 	  if (agg_reps->index == param_index
   3070  1.1  mrg 	      && agg_reps->offset == ie->indirect_info->offset
   3071  1.1  mrg 	      && agg_reps->by_ref)
   3072  1.1  mrg 	    {
   3073  1.1  mrg 	      t = agg_reps->value;
   3074  1.1  mrg 	      break;
   3075  1.1  mrg 	    }
   3076  1.1  mrg 	  agg_reps = agg_reps->next;
   3077  1.1  mrg 	}
   3078  1.1  mrg     }
   3079  1.1  mrg 
   3080  1.1  mrg   /* Try to work out value of virtual table pointer value in known
   3081  1.1  mrg      aggregate values.  */
   3082  1.1  mrg   if (!t && known_aggs.length () > (unsigned int) param_index
   3083  1.1  mrg       && !ie->indirect_info->by_ref)
   3084  1.1  mrg     {
   3085  1.1  mrg       const ipa_agg_value_set *agg = &known_aggs[param_index];
   3086  1.1  mrg       t = ipa_find_agg_cst_for_param (agg,
   3087  1.1  mrg 				      (unsigned) param_index
   3088  1.1  mrg 					 < known_csts.length ()
   3089  1.1  mrg 				      ? known_csts[param_index] : NULL,
   3090  1.1  mrg 				      ie->indirect_info->offset, true);
   3091  1.1  mrg     }
   3092  1.1  mrg 
   3093  1.1  mrg   /* If we found the virtual table pointer, lookup the target.  */
   3094  1.1  mrg   if (t)
   3095  1.1  mrg     {
   3096  1.1  mrg       tree vtable;
   3097  1.1  mrg       unsigned HOST_WIDE_INT offset;
   3098  1.1  mrg       if (vtable_pointer_value_to_vtable (t, &vtable, &offset))
   3099  1.1  mrg 	{
   3100  1.1  mrg 	  bool can_refer;
   3101  1.1  mrg 	  target = gimple_get_virt_method_for_vtable (ie->indirect_info->otr_token,
   3102  1.1  mrg 						      vtable, offset, &can_refer);
   3103  1.1  mrg 	  if (can_refer)
   3104  1.1  mrg 	    {
   3105  1.1  mrg 	      if (!target
   3106  1.1  mrg 		  || fndecl_built_in_p (target, BUILT_IN_UNREACHABLE)
   3107  1.1  mrg 		  || !possible_polymorphic_call_target_p
   3108  1.1  mrg 		       (ie, cgraph_node::get (target)))
   3109  1.1  mrg 		{
   3110  1.1  mrg 		  /* Do not speculate builtin_unreachable, it is stupid!  */
   3111  1.1  mrg 		  if (ie->indirect_info->vptr_changed)
   3112  1.1  mrg 		    return NULL;
   3113  1.1  mrg 		  target = ipa_impossible_devirt_target (ie, target);
   3114  1.1  mrg 		}
   3115  1.1  mrg 	      *speculative = ie->indirect_info->vptr_changed;
   3116  1.1  mrg 	      if (!*speculative)
   3117  1.1  mrg 		return target;
   3118  1.1  mrg 	    }
   3119  1.1  mrg 	}
   3120  1.1  mrg     }
   3121  1.1  mrg 
   3122  1.1  mrg   /* Do we know the constant value of pointer?  */
   3123  1.1  mrg   if (!t && (unsigned) param_index < known_csts.length ())
   3124  1.1  mrg     t = known_csts[param_index];
   3125  1.1  mrg 
   3126  1.1  mrg   gcc_checking_assert (!t || TREE_CODE (t) != TREE_BINFO);
   3127  1.1  mrg 
   3128  1.1  mrg   ipa_polymorphic_call_context context;
   3129  1.1  mrg   if (known_contexts.length () > (unsigned int) param_index)
   3130  1.1  mrg     {
   3131  1.1  mrg       context = known_contexts[param_index];
   3132  1.1  mrg       context.offset_by (anc_offset);
   3133  1.1  mrg       if (ie->indirect_info->vptr_changed)
   3134  1.1  mrg 	context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
   3135  1.1  mrg 					      ie->indirect_info->otr_type);
   3136  1.1  mrg       if (t)
   3137  1.1  mrg 	{
   3138  1.1  mrg 	  ipa_polymorphic_call_context ctx2 = ipa_polymorphic_call_context
   3139  1.1  mrg 	    (t, ie->indirect_info->otr_type, anc_offset);
   3140  1.1  mrg 	  if (!ctx2.useless_p ())
   3141  1.1  mrg 	    context.combine_with (ctx2, ie->indirect_info->otr_type);
   3142  1.1  mrg 	}
   3143  1.1  mrg     }
   3144  1.1  mrg   else if (t)
   3145  1.1  mrg     {
   3146  1.1  mrg       context = ipa_polymorphic_call_context (t, ie->indirect_info->otr_type,
   3147  1.1  mrg 					      anc_offset);
   3148  1.1  mrg       if (ie->indirect_info->vptr_changed)
   3149  1.1  mrg 	context.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
   3150  1.1  mrg 					      ie->indirect_info->otr_type);
   3151  1.1  mrg     }
   3152  1.1  mrg   else
   3153  1.1  mrg     return NULL_TREE;
   3154  1.1  mrg 
   3155  1.1  mrg   vec <cgraph_node *>targets;
   3156  1.1  mrg   bool final;
   3157  1.1  mrg 
   3158  1.1  mrg   targets = possible_polymorphic_call_targets
   3159  1.1  mrg     (ie->indirect_info->otr_type,
   3160  1.1  mrg      ie->indirect_info->otr_token,
   3161  1.1  mrg      context, &final);
   3162  1.1  mrg   if (!final || targets.length () > 1)
   3163  1.1  mrg     {
   3164  1.1  mrg       struct cgraph_node *node;
   3165  1.1  mrg       if (*speculative)
   3166  1.1  mrg 	return target;
   3167  1.1  mrg       if (!opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively)
   3168  1.1  mrg 	  || ie->speculative || !ie->maybe_hot_p ())
   3169  1.1  mrg 	return NULL;
   3170  1.1  mrg       node = try_speculative_devirtualization (ie->indirect_info->otr_type,
   3171  1.1  mrg 					       ie->indirect_info->otr_token,
   3172  1.1  mrg 					       context);
   3173  1.1  mrg       if (node)
   3174  1.1  mrg 	{
   3175  1.1  mrg 	  *speculative = true;
   3176  1.1  mrg 	  target = node->decl;
   3177  1.1  mrg 	}
   3178  1.1  mrg       else
   3179  1.1  mrg 	return NULL;
   3180  1.1  mrg     }
   3181  1.1  mrg   else
   3182  1.1  mrg     {
   3183  1.1  mrg       *speculative = false;
   3184  1.1  mrg       if (targets.length () == 1)
   3185  1.1  mrg 	target = targets[0]->decl;
   3186  1.1  mrg       else
   3187  1.1  mrg 	target = ipa_impossible_devirt_target (ie, NULL_TREE);
   3188  1.1  mrg     }
   3189  1.1  mrg 
   3190  1.1  mrg   if (target && !possible_polymorphic_call_target_p (ie,
   3191  1.1  mrg 						     cgraph_node::get (target)))
   3192  1.1  mrg     {
   3193  1.1  mrg       if (*speculative)
   3194  1.1  mrg 	return NULL;
   3195  1.1  mrg       target = ipa_impossible_devirt_target (ie, target);
   3196  1.1  mrg     }
   3197  1.1  mrg 
   3198  1.1  mrg   return target;
   3199  1.1  mrg }
   3200  1.1  mrg 
   3201  1.1  mrg /* If an indirect edge IE can be turned into a direct one based on data in
   3202  1.1  mrg    AVALS, return the destination.  Store into *SPECULATIVE a boolean determinig
   3203  1.1  mrg    whether the discovered target is only speculative guess.  */
   3204  1.1  mrg 
   3205  1.1  mrg tree
   3206  1.1  mrg ipa_get_indirect_edge_target (struct cgraph_edge *ie,
   3207  1.1  mrg 			      ipa_call_arg_values *avals,
   3208  1.1  mrg 			      bool *speculative)
   3209  1.1  mrg {
   3210  1.1  mrg   return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
   3211  1.1  mrg 					 avals->m_known_contexts,
   3212  1.1  mrg 					 avals->m_known_aggs,
   3213  1.1  mrg 					 NULL, speculative);
   3214  1.1  mrg }
   3215  1.1  mrg 
   3216  1.1  mrg /* The same functionality as above overloaded for ipa_auto_call_arg_values.  */
   3217  1.1  mrg 
   3218  1.1  mrg tree
   3219  1.1  mrg ipa_get_indirect_edge_target (struct cgraph_edge *ie,
   3220  1.1  mrg 			      ipa_auto_call_arg_values *avals,
   3221  1.1  mrg 			      bool *speculative)
   3222  1.1  mrg {
   3223  1.1  mrg   return ipa_get_indirect_edge_target_1 (ie, avals->m_known_vals,
   3224  1.1  mrg 					 avals->m_known_contexts,
   3225  1.1  mrg 					 avals->m_known_aggs,
   3226  1.1  mrg 					 NULL, speculative);
   3227  1.1  mrg }
   3228  1.1  mrg 
   3229  1.1  mrg /* Calculate devirtualization time bonus for NODE, assuming we know information
   3230  1.1  mrg    about arguments stored in AVALS.  */
   3231  1.1  mrg 
   3232  1.1  mrg static int
   3233  1.1  mrg devirtualization_time_bonus (struct cgraph_node *node,
   3234  1.1  mrg 			     ipa_auto_call_arg_values *avals)
   3235  1.1  mrg {
   3236  1.1  mrg   struct cgraph_edge *ie;
   3237  1.1  mrg   int res = 0;
   3238  1.1  mrg 
   3239  1.1  mrg   for (ie = node->indirect_calls; ie; ie = ie->next_callee)
   3240  1.1  mrg     {
   3241  1.1  mrg       struct cgraph_node *callee;
   3242  1.1  mrg       class ipa_fn_summary *isummary;
   3243  1.1  mrg       enum availability avail;
   3244  1.1  mrg       tree target;
   3245  1.1  mrg       bool speculative;
   3246  1.1  mrg 
   3247  1.1  mrg       target = ipa_get_indirect_edge_target (ie, avals, &speculative);
   3248  1.1  mrg       if (!target)
   3249  1.1  mrg 	continue;
   3250  1.1  mrg 
   3251  1.1  mrg       /* Only bare minimum benefit for clearly un-inlineable targets.  */
   3252  1.1  mrg       res += 1;
   3253  1.1  mrg       callee = cgraph_node::get (target);
   3254  1.1  mrg       if (!callee || !callee->definition)
   3255  1.1  mrg 	continue;
   3256  1.1  mrg       callee = callee->function_symbol (&avail);
   3257  1.1  mrg       if (avail < AVAIL_AVAILABLE)
   3258  1.1  mrg 	continue;
   3259  1.1  mrg       isummary = ipa_fn_summaries->get (callee);
   3260  1.1  mrg       if (!isummary || !isummary->inlinable)
   3261  1.1  mrg 	continue;
   3262  1.1  mrg 
   3263  1.1  mrg       int size = ipa_size_summaries->get (callee)->size;
   3264  1.1  mrg       /* FIXME: The values below need re-considering and perhaps also
   3265  1.1  mrg 	 integrating into the cost metrics, at lest in some very basic way.  */
   3266  1.1  mrg       int max_inline_insns_auto
   3267  1.1  mrg 	= opt_for_fn (callee->decl, param_max_inline_insns_auto);
   3268  1.1  mrg       if (size <= max_inline_insns_auto / 4)
   3269  1.1  mrg 	res += 31 / ((int)speculative + 1);
   3270  1.1  mrg       else if (size <= max_inline_insns_auto / 2)
   3271  1.1  mrg 	res += 15 / ((int)speculative + 1);
   3272  1.1  mrg       else if (size <= max_inline_insns_auto
   3273  1.1  mrg 	       || DECL_DECLARED_INLINE_P (callee->decl))
   3274  1.1  mrg 	res += 7 / ((int)speculative + 1);
   3275  1.1  mrg     }
   3276  1.1  mrg 
   3277  1.1  mrg   return res;
   3278  1.1  mrg }
   3279  1.1  mrg 
   3280  1.1  mrg /* Return time bonus incurred because of hints stored in ESTIMATES.  */
   3281  1.1  mrg 
   3282  1.1  mrg static int
   3283  1.1  mrg hint_time_bonus (cgraph_node *node, const ipa_call_estimates &estimates)
   3284  1.1  mrg {
   3285  1.1  mrg   int result = 0;
   3286  1.1  mrg   ipa_hints hints = estimates.hints;
   3287  1.1  mrg   if (hints & (INLINE_HINT_loop_iterations | INLINE_HINT_loop_stride))
   3288  1.1  mrg     result += opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
   3289  1.1  mrg 
   3290  1.1  mrg   sreal bonus_for_one = opt_for_fn (node->decl, param_ipa_cp_loop_hint_bonus);
   3291  1.1  mrg 
   3292  1.1  mrg   if (hints & INLINE_HINT_loop_iterations)
   3293  1.1  mrg     result += (estimates.loops_with_known_iterations * bonus_for_one).to_int ();
   3294  1.1  mrg 
   3295  1.1  mrg   if (hints & INLINE_HINT_loop_stride)
   3296  1.1  mrg     result += (estimates.loops_with_known_strides * bonus_for_one).to_int ();
   3297  1.1  mrg 
   3298  1.1  mrg   return result;
   3299  1.1  mrg }
   3300  1.1  mrg 
   3301  1.1  mrg /* If there is a reason to penalize the function described by INFO in the
   3302  1.1  mrg    cloning goodness evaluation, do so.  */
   3303  1.1  mrg 
   3304  1.1  mrg static inline sreal
   3305  1.1  mrg incorporate_penalties (cgraph_node *node, ipa_node_params *info,
   3306  1.1  mrg 		       sreal evaluation)
   3307  1.1  mrg {
   3308  1.1  mrg   if (info->node_within_scc && !info->node_is_self_scc)
   3309  1.1  mrg     evaluation = (evaluation
   3310  1.1  mrg 		  * (100 - opt_for_fn (node->decl,
   3311  1.1  mrg 				       param_ipa_cp_recursion_penalty))) / 100;
   3312  1.1  mrg 
   3313  1.1  mrg   if (info->node_calling_single_call)
   3314  1.1  mrg     evaluation = (evaluation
   3315  1.1  mrg 		  * (100 - opt_for_fn (node->decl,
   3316  1.1  mrg 				       param_ipa_cp_single_call_penalty)))
   3317  1.1  mrg       / 100;
   3318  1.1  mrg 
   3319  1.1  mrg   return evaluation;
   3320  1.1  mrg }
   3321  1.1  mrg 
   3322  1.1  mrg /* Return true if cloning NODE is a good idea, given the estimated TIME_BENEFIT
   3323  1.1  mrg    and SIZE_COST and with the sum of frequencies of incoming edges to the
   3324  1.1  mrg    potential new clone in FREQUENCIES.  */
   3325  1.1  mrg 
   3326  1.1  mrg static bool
   3327  1.1  mrg good_cloning_opportunity_p (struct cgraph_node *node, sreal time_benefit,
   3328  1.1  mrg 			    sreal freq_sum, profile_count count_sum,
   3329  1.1  mrg 			    int size_cost)
   3330  1.1  mrg {
   3331  1.1  mrg   if (time_benefit == 0
   3332  1.1  mrg       || !opt_for_fn (node->decl, flag_ipa_cp_clone)
   3333  1.1  mrg       || node->optimize_for_size_p ())
   3334  1.1  mrg     return false;
   3335  1.1  mrg 
   3336  1.1  mrg   gcc_assert (size_cost > 0);
   3337  1.1  mrg 
   3338  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   3339  1.1  mrg   int eval_threshold = opt_for_fn (node->decl, param_ipa_cp_eval_threshold);
   3340  1.1  mrg   if (count_sum > profile_count::zero ())
   3341  1.1  mrg     {
   3342  1.1  mrg       gcc_assert (base_count > profile_count::zero ());
   3343  1.1  mrg       sreal factor = count_sum.probability_in (base_count).to_sreal ();
   3344  1.1  mrg       sreal evaluation = (time_benefit * factor) / size_cost;
   3345  1.1  mrg       evaluation = incorporate_penalties (node, info, evaluation);
   3346  1.1  mrg       evaluation *= 1000;
   3347  1.1  mrg 
   3348  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   3349  1.1  mrg 	{
   3350  1.1  mrg 	  fprintf (dump_file, "     good_cloning_opportunity_p (time: %g, "
   3351  1.1  mrg 		   "size: %i, count_sum: ", time_benefit.to_double (),
   3352  1.1  mrg 		   size_cost);
   3353  1.1  mrg 	  count_sum.dump (dump_file);
   3354  1.1  mrg 	  fprintf (dump_file, "%s%s) -> evaluation: %.2f, threshold: %i\n",
   3355  1.1  mrg 		 info->node_within_scc
   3356  1.1  mrg 		   ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
   3357  1.1  mrg 		 info->node_calling_single_call ? ", single_call" : "",
   3358  1.1  mrg 		   evaluation.to_double (), eval_threshold);
   3359  1.1  mrg 	}
   3360  1.1  mrg 
   3361  1.1  mrg       return evaluation.to_int () >= eval_threshold;
   3362  1.1  mrg     }
   3363  1.1  mrg   else
   3364  1.1  mrg     {
   3365  1.1  mrg       sreal evaluation = (time_benefit * freq_sum) / size_cost;
   3366  1.1  mrg       evaluation = incorporate_penalties (node, info, evaluation);
   3367  1.1  mrg       evaluation *= 1000;
   3368  1.1  mrg 
   3369  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   3370  1.1  mrg 	fprintf (dump_file, "     good_cloning_opportunity_p (time: %g, "
   3371  1.1  mrg 		 "size: %i, freq_sum: %g%s%s) -> evaluation: %.2f, "
   3372  1.1  mrg 		 "threshold: %i\n",
   3373  1.1  mrg 		 time_benefit.to_double (), size_cost, freq_sum.to_double (),
   3374  1.1  mrg 		 info->node_within_scc
   3375  1.1  mrg 		   ? (info->node_is_self_scc ? ", self_scc" : ", scc") : "",
   3376  1.1  mrg 		 info->node_calling_single_call ? ", single_call" : "",
   3377  1.1  mrg 		 evaluation.to_double (), eval_threshold);
   3378  1.1  mrg 
   3379  1.1  mrg       return evaluation.to_int () >= eval_threshold;
   3380  1.1  mrg     }
   3381  1.1  mrg }
   3382  1.1  mrg 
   3383  1.1  mrg /* Return all context independent values from aggregate lattices in PLATS in a
   3384  1.1  mrg    vector.  Return NULL if there are none.  */
   3385  1.1  mrg 
   3386  1.1  mrg static vec<ipa_agg_value>
   3387  1.1  mrg context_independent_aggregate_values (class ipcp_param_lattices *plats)
   3388  1.1  mrg {
   3389  1.1  mrg   vec<ipa_agg_value> res = vNULL;
   3390  1.1  mrg 
   3391  1.1  mrg   if (plats->aggs_bottom
   3392  1.1  mrg       || plats->aggs_contain_variable
   3393  1.1  mrg       || plats->aggs_count == 0)
   3394  1.1  mrg     return vNULL;
   3395  1.1  mrg 
   3396  1.1  mrg   for (struct ipcp_agg_lattice *aglat = plats->aggs;
   3397  1.1  mrg        aglat;
   3398  1.1  mrg        aglat = aglat->next)
   3399  1.1  mrg     if (aglat->is_single_const ())
   3400  1.1  mrg       {
   3401  1.1  mrg 	struct ipa_agg_value item;
   3402  1.1  mrg 	item.offset = aglat->offset;
   3403  1.1  mrg 	item.value = aglat->values->value;
   3404  1.1  mrg 	res.safe_push (item);
   3405  1.1  mrg       }
   3406  1.1  mrg   return res;
   3407  1.1  mrg }
   3408  1.1  mrg 
   3409  1.1  mrg /* Grow vectors in AVALS and fill them with information about values of
   3410  1.1  mrg    parameters that are known to be independent of the context.  Only calculate
   3411  1.1  mrg    m_known_aggs if CALCULATE_AGGS is true.  INFO describes the function.  If
   3412  1.1  mrg    REMOVABLE_PARAMS_COST is non-NULL, the movement cost of all removable
   3413  1.1  mrg    parameters will be stored in it.
   3414  1.1  mrg 
   3415  1.1  mrg    TODO: Also grow context independent value range vectors.  */
   3416  1.1  mrg 
   3417  1.1  mrg static bool
   3418  1.1  mrg gather_context_independent_values (class ipa_node_params *info,
   3419  1.1  mrg 				   ipa_auto_call_arg_values *avals,
   3420  1.1  mrg 				   bool calculate_aggs,
   3421  1.1  mrg 				   int *removable_params_cost)
   3422  1.1  mrg {
   3423  1.1  mrg   int i, count = ipa_get_param_count (info);
   3424  1.1  mrg   bool ret = false;
   3425  1.1  mrg 
   3426  1.1  mrg   avals->m_known_vals.safe_grow_cleared (count, true);
   3427  1.1  mrg   avals->m_known_contexts.safe_grow_cleared (count, true);
   3428  1.1  mrg   if (calculate_aggs)
   3429  1.1  mrg     avals->m_known_aggs.safe_grow_cleared (count, true);
   3430  1.1  mrg 
   3431  1.1  mrg   if (removable_params_cost)
   3432  1.1  mrg     *removable_params_cost = 0;
   3433  1.1  mrg 
   3434  1.1  mrg   for (i = 0; i < count; i++)
   3435  1.1  mrg     {
   3436  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   3437  1.1  mrg       ipcp_lattice<tree> *lat = &plats->itself;
   3438  1.1  mrg 
   3439  1.1  mrg       if (lat->is_single_const ())
   3440  1.1  mrg 	{
   3441  1.1  mrg 	  ipcp_value<tree> *val = lat->values;
   3442  1.1  mrg 	  gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
   3443  1.1  mrg 	  avals->m_known_vals[i] = val->value;
   3444  1.1  mrg 	  if (removable_params_cost)
   3445  1.1  mrg 	    *removable_params_cost
   3446  1.1  mrg 	      += estimate_move_cost (TREE_TYPE (val->value), false);
   3447  1.1  mrg 	  ret = true;
   3448  1.1  mrg 	}
   3449  1.1  mrg       else if (removable_params_cost
   3450  1.1  mrg 	       && !ipa_is_param_used (info, i))
   3451  1.1  mrg 	*removable_params_cost
   3452  1.1  mrg 	  += ipa_get_param_move_cost (info, i);
   3453  1.1  mrg 
   3454  1.1  mrg       if (!ipa_is_param_used (info, i))
   3455  1.1  mrg 	continue;
   3456  1.1  mrg 
   3457  1.1  mrg       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
   3458  1.1  mrg       /* Do not account known context as reason for cloning.  We can see
   3459  1.1  mrg 	 if it permits devirtualization.  */
   3460  1.1  mrg       if (ctxlat->is_single_const ())
   3461  1.1  mrg 	avals->m_known_contexts[i] = ctxlat->values->value;
   3462  1.1  mrg 
   3463  1.1  mrg       if (calculate_aggs)
   3464  1.1  mrg 	{
   3465  1.1  mrg 	  vec<ipa_agg_value> agg_items;
   3466  1.1  mrg 	  struct ipa_agg_value_set *agg;
   3467  1.1  mrg 
   3468  1.1  mrg 	  agg_items = context_independent_aggregate_values (plats);
   3469  1.1  mrg 	  agg = &avals->m_known_aggs[i];
   3470  1.1  mrg 	  agg->items = agg_items;
   3471  1.1  mrg 	  agg->by_ref = plats->aggs_by_ref;
   3472  1.1  mrg 	  ret |= !agg_items.is_empty ();
   3473  1.1  mrg 	}
   3474  1.1  mrg     }
   3475  1.1  mrg 
   3476  1.1  mrg   return ret;
   3477  1.1  mrg }
   3478  1.1  mrg 
   3479  1.1  mrg /* Perform time and size measurement of NODE with the context given in AVALS,
   3480  1.1  mrg    calculate the benefit compared to the node without specialization and store
   3481  1.1  mrg    it into VAL.  Take into account REMOVABLE_PARAMS_COST of all
   3482  1.1  mrg    context-independent or unused removable parameters and EST_MOVE_COST, the
   3483  1.1  mrg    estimated movement of the considered parameter.  */
   3484  1.1  mrg 
   3485  1.1  mrg static void
   3486  1.1  mrg perform_estimation_of_a_value (cgraph_node *node,
   3487  1.1  mrg 			       ipa_auto_call_arg_values *avals,
   3488  1.1  mrg 			       int removable_params_cost, int est_move_cost,
   3489  1.1  mrg 			       ipcp_value_base *val)
   3490  1.1  mrg {
   3491  1.1  mrg   sreal time_benefit;
   3492  1.1  mrg   ipa_call_estimates estimates;
   3493  1.1  mrg 
   3494  1.1  mrg   estimate_ipcp_clone_size_and_time (node, avals, &estimates);
   3495  1.1  mrg 
   3496  1.1  mrg   /* Extern inline functions have no cloning local time benefits because they
   3497  1.1  mrg      will be inlined anyway.  The only reason to clone them is if it enables
   3498  1.1  mrg      optimization in any of the functions they call.  */
   3499  1.1  mrg   if (DECL_EXTERNAL (node->decl) && DECL_DECLARED_INLINE_P (node->decl))
   3500  1.1  mrg     time_benefit = 0;
   3501  1.1  mrg   else
   3502  1.1  mrg     time_benefit = (estimates.nonspecialized_time - estimates.time)
   3503  1.1  mrg       + (devirtualization_time_bonus (node, avals)
   3504  1.1  mrg 	 + hint_time_bonus (node, estimates)
   3505  1.1  mrg 	 + removable_params_cost + est_move_cost);
   3506  1.1  mrg 
   3507  1.1  mrg   int size = estimates.size;
   3508  1.1  mrg   gcc_checking_assert (size >=0);
   3509  1.1  mrg   /* The inliner-heuristics based estimates may think that in certain
   3510  1.1  mrg      contexts some functions do not have any size at all but we want
   3511  1.1  mrg      all specializations to have at least a tiny cost, not least not to
   3512  1.1  mrg      divide by zero.  */
   3513  1.1  mrg   if (size == 0)
   3514  1.1  mrg     size = 1;
   3515  1.1  mrg 
   3516  1.1  mrg   val->local_time_benefit = time_benefit;
   3517  1.1  mrg   val->local_size_cost = size;
   3518  1.1  mrg }
   3519  1.1  mrg 
   3520  1.1  mrg /* Get the overall limit oof growth based on parameters extracted from growth.
   3521  1.1  mrg    it does not really make sense to mix functions with different overall growth
   3522  1.1  mrg    limits but it is possible and if it happens, we do not want to select one
   3523  1.1  mrg    limit at random.  */
   3524  1.1  mrg 
   3525  1.1  mrg static long
   3526  1.1  mrg get_max_overall_size (cgraph_node *node)
   3527  1.1  mrg {
   3528  1.1  mrg   long max_new_size = orig_overall_size;
   3529  1.1  mrg   long large_unit = opt_for_fn (node->decl, param_ipa_cp_large_unit_insns);
   3530  1.1  mrg   if (max_new_size < large_unit)
   3531  1.1  mrg     max_new_size = large_unit;
   3532  1.1  mrg   int unit_growth = opt_for_fn (node->decl, param_ipa_cp_unit_growth);
   3533  1.1  mrg   max_new_size += max_new_size * unit_growth / 100 + 1;
   3534  1.1  mrg   return max_new_size;
   3535  1.1  mrg }
   3536  1.1  mrg 
   3537  1.1  mrg /* Iterate over known values of parameters of NODE and estimate the local
   3538  1.1  mrg    effects in terms of time and size they have.  */
   3539  1.1  mrg 
   3540  1.1  mrg static void
   3541  1.1  mrg estimate_local_effects (struct cgraph_node *node)
   3542  1.1  mrg {
   3543  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   3544  1.1  mrg   int i, count = ipa_get_param_count (info);
   3545  1.1  mrg   bool always_const;
   3546  1.1  mrg   int removable_params_cost;
   3547  1.1  mrg 
   3548  1.1  mrg   if (!count || !ipcp_versionable_function_p (node))
   3549  1.1  mrg     return;
   3550  1.1  mrg 
   3551  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   3552  1.1  mrg     fprintf (dump_file, "\nEstimating effects for %s.\n", node->dump_name ());
   3553  1.1  mrg 
   3554  1.1  mrg   ipa_auto_call_arg_values avals;
   3555  1.1  mrg   always_const = gather_context_independent_values (info, &avals, true,
   3556  1.1  mrg 						    &removable_params_cost);
   3557  1.1  mrg   int devirt_bonus = devirtualization_time_bonus (node, &avals);
   3558  1.1  mrg   if (always_const || devirt_bonus
   3559  1.1  mrg       || (removable_params_cost && node->can_change_signature))
   3560  1.1  mrg     {
   3561  1.1  mrg       struct caller_statistics stats;
   3562  1.1  mrg       ipa_call_estimates estimates;
   3563  1.1  mrg 
   3564  1.1  mrg       init_caller_stats (&stats);
   3565  1.1  mrg       node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
   3566  1.1  mrg 					      false);
   3567  1.1  mrg       estimate_ipcp_clone_size_and_time (node, &avals, &estimates);
   3568  1.1  mrg       sreal time = estimates.nonspecialized_time - estimates.time;
   3569  1.1  mrg       time += devirt_bonus;
   3570  1.1  mrg       time += hint_time_bonus (node, estimates);
   3571  1.1  mrg       time += removable_params_cost;
   3572  1.1  mrg       int size = estimates.size - stats.n_calls * removable_params_cost;
   3573  1.1  mrg 
   3574  1.1  mrg       if (dump_file)
   3575  1.1  mrg 	fprintf (dump_file, " - context independent values, size: %i, "
   3576  1.1  mrg 		 "time_benefit: %f\n", size, (time).to_double ());
   3577  1.1  mrg 
   3578  1.1  mrg       if (size <= 0 || node->local)
   3579  1.1  mrg 	{
   3580  1.1  mrg 	  info->do_clone_for_all_contexts = true;
   3581  1.1  mrg 
   3582  1.1  mrg 	  if (dump_file)
   3583  1.1  mrg 	    fprintf (dump_file, "     Decided to specialize for all "
   3584  1.1  mrg 		     "known contexts, code not going to grow.\n");
   3585  1.1  mrg 	}
   3586  1.1  mrg       else if (good_cloning_opportunity_p (node, time, stats.freq_sum,
   3587  1.1  mrg 					   stats.count_sum, size))
   3588  1.1  mrg 	{
   3589  1.1  mrg 	  if (size + overall_size <= get_max_overall_size (node))
   3590  1.1  mrg 	    {
   3591  1.1  mrg 	      info->do_clone_for_all_contexts = true;
   3592  1.1  mrg 	      overall_size += size;
   3593  1.1  mrg 
   3594  1.1  mrg 	      if (dump_file)
   3595  1.1  mrg 		fprintf (dump_file, "     Decided to specialize for all "
   3596  1.1  mrg 			 "known contexts, growth (to %li) deemed "
   3597  1.1  mrg 			 "beneficial.\n", overall_size);
   3598  1.1  mrg 	    }
   3599  1.1  mrg 	  else if (dump_file && (dump_flags & TDF_DETAILS))
   3600  1.1  mrg 	    fprintf (dump_file, "  Not cloning for all contexts because "
   3601  1.1  mrg 		     "maximum unit size would be reached with %li.\n",
   3602  1.1  mrg 		     size + overall_size);
   3603  1.1  mrg 	}
   3604  1.1  mrg       else if (dump_file && (dump_flags & TDF_DETAILS))
   3605  1.1  mrg 	fprintf (dump_file, "   Not cloning for all contexts because "
   3606  1.1  mrg 		 "!good_cloning_opportunity_p.\n");
   3607  1.1  mrg 
   3608  1.1  mrg     }
   3609  1.1  mrg 
   3610  1.1  mrg   for (i = 0; i < count; i++)
   3611  1.1  mrg     {
   3612  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   3613  1.1  mrg       ipcp_lattice<tree> *lat = &plats->itself;
   3614  1.1  mrg       ipcp_value<tree> *val;
   3615  1.1  mrg 
   3616  1.1  mrg       if (lat->bottom
   3617  1.1  mrg 	  || !lat->values
   3618  1.1  mrg 	  || avals.m_known_vals[i])
   3619  1.1  mrg 	continue;
   3620  1.1  mrg 
   3621  1.1  mrg       for (val = lat->values; val; val = val->next)
   3622  1.1  mrg 	{
   3623  1.1  mrg 	  gcc_checking_assert (TREE_CODE (val->value) != TREE_BINFO);
   3624  1.1  mrg 	  avals.m_known_vals[i] = val->value;
   3625  1.1  mrg 
   3626  1.1  mrg 	  int emc = estimate_move_cost (TREE_TYPE (val->value), true);
   3627  1.1  mrg 	  perform_estimation_of_a_value (node, &avals, removable_params_cost,
   3628  1.1  mrg 					 emc, val);
   3629  1.1  mrg 
   3630  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   3631  1.1  mrg 	    {
   3632  1.1  mrg 	      fprintf (dump_file, " - estimates for value ");
   3633  1.1  mrg 	      print_ipcp_constant_value (dump_file, val->value);
   3634  1.1  mrg 	      fprintf (dump_file, " for ");
   3635  1.1  mrg 	      ipa_dump_param (dump_file, info, i);
   3636  1.1  mrg 	      fprintf (dump_file, ": time_benefit: %g, size: %i\n",
   3637  1.1  mrg 		       val->local_time_benefit.to_double (),
   3638  1.1  mrg 		       val->local_size_cost);
   3639  1.1  mrg 	    }
   3640  1.1  mrg 	}
   3641  1.1  mrg       avals.m_known_vals[i] = NULL_TREE;
   3642  1.1  mrg     }
   3643  1.1  mrg 
   3644  1.1  mrg   for (i = 0; i < count; i++)
   3645  1.1  mrg     {
   3646  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   3647  1.1  mrg 
   3648  1.1  mrg       if (!plats->virt_call)
   3649  1.1  mrg 	continue;
   3650  1.1  mrg 
   3651  1.1  mrg       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
   3652  1.1  mrg       ipcp_value<ipa_polymorphic_call_context> *val;
   3653  1.1  mrg 
   3654  1.1  mrg       if (ctxlat->bottom
   3655  1.1  mrg 	  || !ctxlat->values
   3656  1.1  mrg 	  || !avals.m_known_contexts[i].useless_p ())
   3657  1.1  mrg 	continue;
   3658  1.1  mrg 
   3659  1.1  mrg       for (val = ctxlat->values; val; val = val->next)
   3660  1.1  mrg 	{
   3661  1.1  mrg 	  avals.m_known_contexts[i] = val->value;
   3662  1.1  mrg 	  perform_estimation_of_a_value (node, &avals, removable_params_cost,
   3663  1.1  mrg 					 0, val);
   3664  1.1  mrg 
   3665  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   3666  1.1  mrg 	    {
   3667  1.1  mrg 	      fprintf (dump_file, " - estimates for polymorphic context ");
   3668  1.1  mrg 	      print_ipcp_constant_value (dump_file, val->value);
   3669  1.1  mrg 	      fprintf (dump_file, " for ");
   3670  1.1  mrg 	      ipa_dump_param (dump_file, info, i);
   3671  1.1  mrg 	      fprintf (dump_file, ": time_benefit: %g, size: %i\n",
   3672  1.1  mrg 		       val->local_time_benefit.to_double (),
   3673  1.1  mrg 		       val->local_size_cost);
   3674  1.1  mrg 	    }
   3675  1.1  mrg 	}
   3676  1.1  mrg       avals.m_known_contexts[i] = ipa_polymorphic_call_context ();
   3677  1.1  mrg     }
   3678  1.1  mrg 
   3679  1.1  mrg   for (i = 0; i < count; i++)
   3680  1.1  mrg     {
   3681  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   3682  1.1  mrg 
   3683  1.1  mrg       if (plats->aggs_bottom || !plats->aggs)
   3684  1.1  mrg 	continue;
   3685  1.1  mrg 
   3686  1.1  mrg       ipa_agg_value_set *agg = &avals.m_known_aggs[i];
   3687  1.1  mrg       for (ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
   3688  1.1  mrg 	{
   3689  1.1  mrg 	  ipcp_value<tree> *val;
   3690  1.1  mrg 	  if (aglat->bottom || !aglat->values
   3691  1.1  mrg 	      /* If the following is true, the one value is in known_aggs.  */
   3692  1.1  mrg 	      || (!plats->aggs_contain_variable
   3693  1.1  mrg 		  && aglat->is_single_const ()))
   3694  1.1  mrg 	    continue;
   3695  1.1  mrg 
   3696  1.1  mrg 	  for (val = aglat->values; val; val = val->next)
   3697  1.1  mrg 	    {
   3698  1.1  mrg 	      struct ipa_agg_value item;
   3699  1.1  mrg 
   3700  1.1  mrg 	      item.offset = aglat->offset;
   3701  1.1  mrg 	      item.value = val->value;
   3702  1.1  mrg 	      agg->items.safe_push (item);
   3703  1.1  mrg 
   3704  1.1  mrg 	      perform_estimation_of_a_value (node, &avals,
   3705  1.1  mrg 					     removable_params_cost, 0, val);
   3706  1.1  mrg 
   3707  1.1  mrg 	      if (dump_file && (dump_flags & TDF_DETAILS))
   3708  1.1  mrg 		{
   3709  1.1  mrg 		  fprintf (dump_file, " - estimates for value ");
   3710  1.1  mrg 		  print_ipcp_constant_value (dump_file, val->value);
   3711  1.1  mrg 		  fprintf (dump_file, " for ");
   3712  1.1  mrg 		  ipa_dump_param (dump_file, info, i);
   3713  1.1  mrg 		  fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
   3714  1.1  mrg 			   "]: time_benefit: %g, size: %i\n",
   3715  1.1  mrg 			   plats->aggs_by_ref ? "ref " : "",
   3716  1.1  mrg 			   aglat->offset,
   3717  1.1  mrg 			   val->local_time_benefit.to_double (),
   3718  1.1  mrg 			   val->local_size_cost);
   3719  1.1  mrg 		}
   3720  1.1  mrg 
   3721  1.1  mrg 	      agg->items.pop ();
   3722  1.1  mrg 	    }
   3723  1.1  mrg 	}
   3724  1.1  mrg     }
   3725  1.1  mrg }
   3726  1.1  mrg 
   3727  1.1  mrg 
   3728  1.1  mrg /* Add value CUR_VAL and all yet-unsorted values it is dependent on to the
   3729  1.1  mrg    topological sort of values.  */
   3730  1.1  mrg 
   3731  1.1  mrg template <typename valtype>
   3732  1.1  mrg void
   3733  1.1  mrg value_topo_info<valtype>::add_val (ipcp_value<valtype> *cur_val)
   3734  1.1  mrg {
   3735  1.1  mrg   ipcp_value_source<valtype> *src;
   3736  1.1  mrg 
   3737  1.1  mrg   if (cur_val->dfs)
   3738  1.1  mrg     return;
   3739  1.1  mrg 
   3740  1.1  mrg   dfs_counter++;
   3741  1.1  mrg   cur_val->dfs = dfs_counter;
   3742  1.1  mrg   cur_val->low_link = dfs_counter;
   3743  1.1  mrg 
   3744  1.1  mrg   cur_val->topo_next = stack;
   3745  1.1  mrg   stack = cur_val;
   3746  1.1  mrg   cur_val->on_stack = true;
   3747  1.1  mrg 
   3748  1.1  mrg   for (src = cur_val->sources; src; src = src->next)
   3749  1.1  mrg     if (src->val)
   3750  1.1  mrg       {
   3751  1.1  mrg 	if (src->val->dfs == 0)
   3752  1.1  mrg 	  {
   3753  1.1  mrg 	    add_val (src->val);
   3754  1.1  mrg 	    if (src->val->low_link < cur_val->low_link)
   3755  1.1  mrg 	      cur_val->low_link = src->val->low_link;
   3756  1.1  mrg 	  }
   3757  1.1  mrg 	else if (src->val->on_stack
   3758  1.1  mrg 		 && src->val->dfs < cur_val->low_link)
   3759  1.1  mrg 	  cur_val->low_link = src->val->dfs;
   3760  1.1  mrg       }
   3761  1.1  mrg 
   3762  1.1  mrg   if (cur_val->dfs == cur_val->low_link)
   3763  1.1  mrg     {
   3764  1.1  mrg       ipcp_value<valtype> *v, *scc_list = NULL;
   3765  1.1  mrg 
   3766  1.1  mrg       do
   3767  1.1  mrg 	{
   3768  1.1  mrg 	  v = stack;
   3769  1.1  mrg 	  stack = v->topo_next;
   3770  1.1  mrg 	  v->on_stack = false;
   3771  1.1  mrg 	  v->scc_no = cur_val->dfs;
   3772  1.1  mrg 
   3773  1.1  mrg 	  v->scc_next = scc_list;
   3774  1.1  mrg 	  scc_list = v;
   3775  1.1  mrg 	}
   3776  1.1  mrg       while (v != cur_val);
   3777  1.1  mrg 
   3778  1.1  mrg       cur_val->topo_next = values_topo;
   3779  1.1  mrg       values_topo = cur_val;
   3780  1.1  mrg     }
   3781  1.1  mrg }
   3782  1.1  mrg 
   3783  1.1  mrg /* Add all values in lattices associated with NODE to the topological sort if
   3784  1.1  mrg    they are not there yet.  */
   3785  1.1  mrg 
   3786  1.1  mrg static void
   3787  1.1  mrg add_all_node_vals_to_toposort (cgraph_node *node, ipa_topo_info *topo)
   3788  1.1  mrg {
   3789  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   3790  1.1  mrg   int i, count = ipa_get_param_count (info);
   3791  1.1  mrg 
   3792  1.1  mrg   for (i = 0; i < count; i++)
   3793  1.1  mrg     {
   3794  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   3795  1.1  mrg       ipcp_lattice<tree> *lat = &plats->itself;
   3796  1.1  mrg       struct ipcp_agg_lattice *aglat;
   3797  1.1  mrg 
   3798  1.1  mrg       if (!lat->bottom)
   3799  1.1  mrg 	{
   3800  1.1  mrg 	  ipcp_value<tree> *val;
   3801  1.1  mrg 	  for (val = lat->values; val; val = val->next)
   3802  1.1  mrg 	    topo->constants.add_val (val);
   3803  1.1  mrg 	}
   3804  1.1  mrg 
   3805  1.1  mrg       if (!plats->aggs_bottom)
   3806  1.1  mrg 	for (aglat = plats->aggs; aglat; aglat = aglat->next)
   3807  1.1  mrg 	  if (!aglat->bottom)
   3808  1.1  mrg 	    {
   3809  1.1  mrg 	      ipcp_value<tree> *val;
   3810  1.1  mrg 	      for (val = aglat->values; val; val = val->next)
   3811  1.1  mrg 		topo->constants.add_val (val);
   3812  1.1  mrg 	    }
   3813  1.1  mrg 
   3814  1.1  mrg       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
   3815  1.1  mrg       if (!ctxlat->bottom)
   3816  1.1  mrg 	{
   3817  1.1  mrg 	  ipcp_value<ipa_polymorphic_call_context> *ctxval;
   3818  1.1  mrg 	  for (ctxval = ctxlat->values; ctxval; ctxval = ctxval->next)
   3819  1.1  mrg 	    topo->contexts.add_val (ctxval);
   3820  1.1  mrg 	}
   3821  1.1  mrg     }
   3822  1.1  mrg }
   3823  1.1  mrg 
   3824  1.1  mrg /* One pass of constants propagation along the call graph edges, from callers
   3825  1.1  mrg    to callees (requires topological ordering in TOPO), iterate over strongly
   3826  1.1  mrg    connected components.  */
   3827  1.1  mrg 
   3828  1.1  mrg static void
   3829  1.1  mrg propagate_constants_topo (class ipa_topo_info *topo)
   3830  1.1  mrg {
   3831  1.1  mrg   int i;
   3832  1.1  mrg 
   3833  1.1  mrg   for (i = topo->nnodes - 1; i >= 0; i--)
   3834  1.1  mrg     {
   3835  1.1  mrg       unsigned j;
   3836  1.1  mrg       struct cgraph_node *v, *node = topo->order[i];
   3837  1.1  mrg       vec<cgraph_node *> cycle_nodes = ipa_get_nodes_in_cycle (node);
   3838  1.1  mrg 
   3839  1.1  mrg       /* First, iteratively propagate within the strongly connected component
   3840  1.1  mrg 	 until all lattices stabilize.  */
   3841  1.1  mrg       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
   3842  1.1  mrg 	if (v->has_gimple_body_p ())
   3843  1.1  mrg 	  {
   3844  1.1  mrg 	    if (opt_for_fn (v->decl, flag_ipa_cp)
   3845  1.1  mrg 		&& opt_for_fn (v->decl, optimize))
   3846  1.1  mrg 	      push_node_to_stack (topo, v);
   3847  1.1  mrg 	    /* When V is not optimized, we can not push it to stack, but
   3848  1.1  mrg 	       still we need to set all its callees lattices to bottom.  */
   3849  1.1  mrg 	    else
   3850  1.1  mrg 	      {
   3851  1.1  mrg 		for (cgraph_edge *cs = v->callees; cs; cs = cs->next_callee)
   3852  1.1  mrg 	           propagate_constants_across_call (cs);
   3853  1.1  mrg 	      }
   3854  1.1  mrg 	  }
   3855  1.1  mrg 
   3856  1.1  mrg       v = pop_node_from_stack (topo);
   3857  1.1  mrg       while (v)
   3858  1.1  mrg 	{
   3859  1.1  mrg 	  struct cgraph_edge *cs;
   3860  1.1  mrg 	  class ipa_node_params *info = NULL;
   3861  1.1  mrg 	  bool self_scc = true;
   3862  1.1  mrg 
   3863  1.1  mrg 	  for (cs = v->callees; cs; cs = cs->next_callee)
   3864  1.1  mrg 	    if (ipa_edge_within_scc (cs))
   3865  1.1  mrg 	      {
   3866  1.1  mrg 		cgraph_node *callee = cs->callee->function_symbol ();
   3867  1.1  mrg 
   3868  1.1  mrg 		if (v != callee)
   3869  1.1  mrg 		  self_scc = false;
   3870  1.1  mrg 
   3871  1.1  mrg 		if (!info)
   3872  1.1  mrg 		  {
   3873  1.1  mrg 		    info = ipa_node_params_sum->get (v);
   3874  1.1  mrg 		    info->node_within_scc = true;
   3875  1.1  mrg 		  }
   3876  1.1  mrg 
   3877  1.1  mrg 		if (propagate_constants_across_call (cs))
   3878  1.1  mrg 		  push_node_to_stack (topo, callee);
   3879  1.1  mrg 	      }
   3880  1.1  mrg 
   3881  1.1  mrg 	  if (info)
   3882  1.1  mrg 	    info->node_is_self_scc = self_scc;
   3883  1.1  mrg 
   3884  1.1  mrg 	  v = pop_node_from_stack (topo);
   3885  1.1  mrg 	}
   3886  1.1  mrg 
   3887  1.1  mrg       /* Afterwards, propagate along edges leading out of the SCC, calculates
   3888  1.1  mrg 	 the local effects of the discovered constants and all valid values to
   3889  1.1  mrg 	 their topological sort.  */
   3890  1.1  mrg       FOR_EACH_VEC_ELT (cycle_nodes, j, v)
   3891  1.1  mrg 	if (v->has_gimple_body_p ()
   3892  1.1  mrg 	    && opt_for_fn (v->decl, flag_ipa_cp)
   3893  1.1  mrg 	    && opt_for_fn (v->decl, optimize))
   3894  1.1  mrg 	  {
   3895  1.1  mrg 	    struct cgraph_edge *cs;
   3896  1.1  mrg 
   3897  1.1  mrg 	    estimate_local_effects (v);
   3898  1.1  mrg 	    add_all_node_vals_to_toposort (v, topo);
   3899  1.1  mrg 	    for (cs = v->callees; cs; cs = cs->next_callee)
   3900  1.1  mrg 	      if (!ipa_edge_within_scc (cs))
   3901  1.1  mrg 		propagate_constants_across_call (cs);
   3902  1.1  mrg 	  }
   3903  1.1  mrg       cycle_nodes.release ();
   3904  1.1  mrg     }
   3905  1.1  mrg }
   3906  1.1  mrg 
   3907  1.1  mrg /* Propagate the estimated effects of individual values along the topological
   3908  1.1  mrg    from the dependent values to those they depend on.  */
   3909  1.1  mrg 
   3910  1.1  mrg template <typename valtype>
   3911  1.1  mrg void
   3912  1.1  mrg value_topo_info<valtype>::propagate_effects ()
   3913  1.1  mrg {
   3914  1.1  mrg   ipcp_value<valtype> *base;
   3915  1.1  mrg   hash_set<ipcp_value<valtype> *> processed_srcvals;
   3916  1.1  mrg 
   3917  1.1  mrg   for (base = values_topo; base; base = base->topo_next)
   3918  1.1  mrg     {
   3919  1.1  mrg       ipcp_value_source<valtype> *src;
   3920  1.1  mrg       ipcp_value<valtype> *val;
   3921  1.1  mrg       sreal time = 0;
   3922  1.1  mrg       HOST_WIDE_INT size = 0;
   3923  1.1  mrg 
   3924  1.1  mrg       for (val = base; val; val = val->scc_next)
   3925  1.1  mrg 	{
   3926  1.1  mrg 	  time = time + val->local_time_benefit + val->prop_time_benefit;
   3927  1.1  mrg 	  size = size + val->local_size_cost + val->prop_size_cost;
   3928  1.1  mrg 	}
   3929  1.1  mrg 
   3930  1.1  mrg       for (val = base; val; val = val->scc_next)
   3931  1.1  mrg 	{
   3932  1.1  mrg 	  processed_srcvals.empty ();
   3933  1.1  mrg 	  for (src = val->sources; src; src = src->next)
   3934  1.1  mrg 	    if (src->val
   3935  1.1  mrg 		&& src->cs->maybe_hot_p ())
   3936  1.1  mrg 	      {
   3937  1.1  mrg 		if (!processed_srcvals.add (src->val))
   3938  1.1  mrg 		  {
   3939  1.1  mrg 		    HOST_WIDE_INT prop_size = size + src->val->prop_size_cost;
   3940  1.1  mrg 		    if (prop_size < INT_MAX)
   3941  1.1  mrg 		      src->val->prop_size_cost = prop_size;
   3942  1.1  mrg 		    else
   3943  1.1  mrg 		      continue;
   3944  1.1  mrg 		  }
   3945  1.1  mrg 
   3946  1.1  mrg 		int special_factor = 1;
   3947  1.1  mrg 		if (val->same_scc (src->val))
   3948  1.1  mrg 		  special_factor
   3949  1.1  mrg 		    = opt_for_fn(src->cs->caller->decl,
   3950  1.1  mrg 				 param_ipa_cp_recursive_freq_factor);
   3951  1.1  mrg 		else if (val->self_recursion_generated_p ()
   3952  1.1  mrg 			 && (src->cs->callee->function_symbol ()
   3953  1.1  mrg 			     == src->cs->caller))
   3954  1.1  mrg 		  {
   3955  1.1  mrg 		    int max_recur_gen_depth
   3956  1.1  mrg 		      = opt_for_fn(src->cs->caller->decl,
   3957  1.1  mrg 				   param_ipa_cp_max_recursive_depth);
   3958  1.1  mrg 		    special_factor = max_recur_gen_depth
   3959  1.1  mrg 		      - val->self_recursion_generated_level + 1;
   3960  1.1  mrg 		  }
   3961  1.1  mrg 
   3962  1.1  mrg 		src->val->prop_time_benefit
   3963  1.1  mrg 		  += time * special_factor * src->cs->sreal_frequency ();
   3964  1.1  mrg 	      }
   3965  1.1  mrg 
   3966  1.1  mrg 	  if (size < INT_MAX)
   3967  1.1  mrg 	    {
   3968  1.1  mrg 	      val->prop_time_benefit = time;
   3969  1.1  mrg 	      val->prop_size_cost = size;
   3970  1.1  mrg 	    }
   3971  1.1  mrg 	  else
   3972  1.1  mrg 	    {
   3973  1.1  mrg 	      val->prop_time_benefit = 0;
   3974  1.1  mrg 	      val->prop_size_cost = 0;
   3975  1.1  mrg 	    }
   3976  1.1  mrg 	}
   3977  1.1  mrg     }
   3978  1.1  mrg }
   3979  1.1  mrg 
   3980  1.1  mrg /* Callback for qsort to sort counts of all edges.  */
   3981  1.1  mrg 
   3982  1.1  mrg static int
   3983  1.1  mrg compare_edge_profile_counts (const void *a, const void *b)
   3984  1.1  mrg {
   3985  1.1  mrg   const profile_count *cnt1 = (const profile_count *) a;
   3986  1.1  mrg   const profile_count *cnt2 = (const profile_count *) b;
   3987  1.1  mrg 
   3988  1.1  mrg   if (*cnt1 < *cnt2)
   3989  1.1  mrg     return 1;
   3990  1.1  mrg   if (*cnt1 > *cnt2)
   3991  1.1  mrg     return -1;
   3992  1.1  mrg   return 0;
   3993  1.1  mrg }
   3994  1.1  mrg 
   3995  1.1  mrg 
   3996  1.1  mrg /* Propagate constants, polymorphic contexts and their effects from the
   3997  1.1  mrg    summaries interprocedurally.  */
   3998  1.1  mrg 
   3999  1.1  mrg static void
   4000  1.1  mrg ipcp_propagate_stage (class ipa_topo_info *topo)
   4001  1.1  mrg {
   4002  1.1  mrg   struct cgraph_node *node;
   4003  1.1  mrg 
   4004  1.1  mrg   if (dump_file)
   4005  1.1  mrg     fprintf (dump_file, "\n Propagating constants:\n\n");
   4006  1.1  mrg 
   4007  1.1  mrg   base_count = profile_count::uninitialized ();
   4008  1.1  mrg 
   4009  1.1  mrg   bool compute_count_base = false;
   4010  1.1  mrg   unsigned base_count_pos_percent = 0;
   4011  1.1  mrg   FOR_EACH_DEFINED_FUNCTION (node)
   4012  1.1  mrg   {
   4013  1.1  mrg     if (node->has_gimple_body_p ()
   4014  1.1  mrg 	&& opt_for_fn (node->decl, flag_ipa_cp)
   4015  1.1  mrg 	&& opt_for_fn (node->decl, optimize))
   4016  1.1  mrg       {
   4017  1.1  mrg         ipa_node_params *info = ipa_node_params_sum->get (node);
   4018  1.1  mrg         determine_versionability (node, info);
   4019  1.1  mrg 
   4020  1.1  mrg 	unsigned nlattices = ipa_get_param_count (info);
   4021  1.1  mrg 	void *chunk = XCNEWVEC (class ipcp_param_lattices, nlattices);
   4022  1.1  mrg 	info->lattices = new (chunk) ipcp_param_lattices[nlattices];
   4023  1.1  mrg 	initialize_node_lattices (node);
   4024  1.1  mrg       }
   4025  1.1  mrg     ipa_size_summary *s = ipa_size_summaries->get (node);
   4026  1.1  mrg     if (node->definition && !node->alias && s != NULL)
   4027  1.1  mrg       overall_size += s->self_size;
   4028  1.1  mrg     if (node->count.ipa ().initialized_p ())
   4029  1.1  mrg       {
   4030  1.1  mrg 	compute_count_base = true;
   4031  1.1  mrg 	unsigned pos_percent = opt_for_fn (node->decl,
   4032  1.1  mrg 					   param_ipa_cp_profile_count_base);
   4033  1.1  mrg 	base_count_pos_percent = MAX (base_count_pos_percent, pos_percent);
   4034  1.1  mrg       }
   4035  1.1  mrg   }
   4036  1.1  mrg 
   4037  1.1  mrg   if (compute_count_base)
   4038  1.1  mrg     {
   4039  1.1  mrg       auto_vec<profile_count> all_edge_counts;
   4040  1.1  mrg       all_edge_counts.reserve_exact (symtab->edges_count);
   4041  1.1  mrg       FOR_EACH_DEFINED_FUNCTION (node)
   4042  1.1  mrg 	for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
   4043  1.1  mrg 	  {
   4044  1.1  mrg 	    profile_count count = cs->count.ipa ();
   4045  1.1  mrg 	    if (!(count > profile_count::zero ()))
   4046  1.1  mrg 	      continue;
   4047  1.1  mrg 
   4048  1.1  mrg 	    enum availability avail;
   4049  1.1  mrg 	    cgraph_node *tgt
   4050  1.1  mrg 	      = cs->callee->function_or_virtual_thunk_symbol (&avail);
   4051  1.1  mrg 	    ipa_node_params *info = ipa_node_params_sum->get (tgt);
   4052  1.1  mrg 	    if (info && info->versionable)
   4053  1.1  mrg 	      all_edge_counts.quick_push (count);
   4054  1.1  mrg 	  }
   4055  1.1  mrg 
   4056  1.1  mrg       if (!all_edge_counts.is_empty ())
   4057  1.1  mrg 	{
   4058  1.1  mrg 	  gcc_assert (base_count_pos_percent <= 100);
   4059  1.1  mrg 	  all_edge_counts.qsort (compare_edge_profile_counts);
   4060  1.1  mrg 
   4061  1.1  mrg 	  unsigned base_count_pos
   4062  1.1  mrg 	    = ((all_edge_counts.length () * (base_count_pos_percent)) / 100);
   4063  1.1  mrg 	  base_count = all_edge_counts[base_count_pos];
   4064  1.1  mrg 
   4065  1.1  mrg 	  if (dump_file)
   4066  1.1  mrg 	    {
   4067  1.1  mrg 	      fprintf (dump_file, "\nSelected base_count from %u edges at "
   4068  1.1  mrg 		       "position %u, arriving at: ", all_edge_counts.length (),
   4069  1.1  mrg 		       base_count_pos);
   4070  1.1  mrg 	      base_count.dump (dump_file);
   4071  1.1  mrg 	      fprintf (dump_file, "\n");
   4072  1.1  mrg 	    }
   4073  1.1  mrg 	}
   4074  1.1  mrg       else if (dump_file)
   4075  1.1  mrg 	fprintf (dump_file, "\nNo candidates with non-zero call count found, "
   4076  1.1  mrg 		 "continuing as if without profile feedback.\n");
   4077  1.1  mrg     }
   4078  1.1  mrg 
   4079  1.1  mrg   orig_overall_size = overall_size;
   4080  1.1  mrg 
   4081  1.1  mrg   if (dump_file)
   4082  1.1  mrg     fprintf (dump_file, "\noverall_size: %li\n", overall_size);
   4083  1.1  mrg 
   4084  1.1  mrg   propagate_constants_topo (topo);
   4085  1.1  mrg   if (flag_checking)
   4086  1.1  mrg     ipcp_verify_propagated_values ();
   4087  1.1  mrg   topo->constants.propagate_effects ();
   4088  1.1  mrg   topo->contexts.propagate_effects ();
   4089  1.1  mrg 
   4090  1.1  mrg   if (dump_file)
   4091  1.1  mrg     {
   4092  1.1  mrg       fprintf (dump_file, "\nIPA lattices after all propagation:\n");
   4093  1.1  mrg       print_all_lattices (dump_file, (dump_flags & TDF_DETAILS), true);
   4094  1.1  mrg     }
   4095  1.1  mrg }
   4096  1.1  mrg 
   4097  1.1  mrg /* Discover newly direct outgoing edges from NODE which is a new clone with
   4098  1.1  mrg    known KNOWN_CSTS and make them direct.  */
   4099  1.1  mrg 
   4100  1.1  mrg static void
   4101  1.1  mrg ipcp_discover_new_direct_edges (struct cgraph_node *node,
   4102  1.1  mrg 				vec<tree> known_csts,
   4103  1.1  mrg 				vec<ipa_polymorphic_call_context>
   4104  1.1  mrg 				known_contexts,
   4105  1.1  mrg 				struct ipa_agg_replacement_value *aggvals)
   4106  1.1  mrg {
   4107  1.1  mrg   struct cgraph_edge *ie, *next_ie;
   4108  1.1  mrg   bool found = false;
   4109  1.1  mrg 
   4110  1.1  mrg   for (ie = node->indirect_calls; ie; ie = next_ie)
   4111  1.1  mrg     {
   4112  1.1  mrg       tree target;
   4113  1.1  mrg       bool speculative;
   4114  1.1  mrg 
   4115  1.1  mrg       next_ie = ie->next_callee;
   4116  1.1  mrg       target = ipa_get_indirect_edge_target_1 (ie, known_csts, known_contexts,
   4117  1.1  mrg 					       vNULL, aggvals, &speculative);
   4118  1.1  mrg       if (target)
   4119  1.1  mrg 	{
   4120  1.1  mrg 	  bool agg_contents = ie->indirect_info->agg_contents;
   4121  1.1  mrg 	  bool polymorphic = ie->indirect_info->polymorphic;
   4122  1.1  mrg 	  int param_index = ie->indirect_info->param_index;
   4123  1.1  mrg 	  struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target,
   4124  1.1  mrg 								   speculative);
   4125  1.1  mrg 	  found = true;
   4126  1.1  mrg 
   4127  1.1  mrg 	  if (cs && !agg_contents && !polymorphic)
   4128  1.1  mrg 	    {
   4129  1.1  mrg 	      ipa_node_params *info = ipa_node_params_sum->get (node);
   4130  1.1  mrg 	      int c = ipa_get_controlled_uses (info, param_index);
   4131  1.1  mrg 	      if (c != IPA_UNDESCRIBED_USE
   4132  1.1  mrg 		  && !ipa_get_param_load_dereferenced (info, param_index))
   4133  1.1  mrg 		{
   4134  1.1  mrg 		  struct ipa_ref *to_del;
   4135  1.1  mrg 
   4136  1.1  mrg 		  c--;
   4137  1.1  mrg 		  ipa_set_controlled_uses (info, param_index, c);
   4138  1.1  mrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
   4139  1.1  mrg 		    fprintf (dump_file, "     controlled uses count of param "
   4140  1.1  mrg 			     "%i bumped down to %i\n", param_index, c);
   4141  1.1  mrg 		  if (c == 0
   4142  1.1  mrg 		      && (to_del = node->find_reference (cs->callee, NULL, 0,
   4143  1.1  mrg 							 IPA_REF_ADDR)))
   4144  1.1  mrg 		    {
   4145  1.1  mrg 		      if (dump_file && (dump_flags & TDF_DETAILS))
   4146  1.1  mrg 			fprintf (dump_file, "       and even removing its "
   4147  1.1  mrg 				 "cloning-created reference\n");
   4148  1.1  mrg 		      to_del->remove_reference ();
   4149  1.1  mrg 		    }
   4150  1.1  mrg 		}
   4151  1.1  mrg 	    }
   4152  1.1  mrg 	}
   4153  1.1  mrg     }
   4154  1.1  mrg   /* Turning calls to direct calls will improve overall summary.  */
   4155  1.1  mrg   if (found)
   4156  1.1  mrg     ipa_update_overall_fn_summary (node);
   4157  1.1  mrg }
   4158  1.1  mrg 
   4159  1.1  mrg class edge_clone_summary;
   4160  1.1  mrg static call_summary <edge_clone_summary *> *edge_clone_summaries = NULL;
   4161  1.1  mrg 
   4162  1.1  mrg /* Edge clone summary.  */
   4163  1.1  mrg 
   4164  1.1  mrg class edge_clone_summary
   4165  1.1  mrg {
   4166  1.1  mrg public:
   4167  1.1  mrg   /* Default constructor.  */
   4168  1.1  mrg   edge_clone_summary (): prev_clone (NULL), next_clone (NULL) {}
   4169  1.1  mrg 
   4170  1.1  mrg   /* Default destructor.  */
   4171  1.1  mrg   ~edge_clone_summary ()
   4172  1.1  mrg   {
   4173  1.1  mrg     if (prev_clone)
   4174  1.1  mrg       edge_clone_summaries->get (prev_clone)->next_clone = next_clone;
   4175  1.1  mrg     if (next_clone)
   4176  1.1  mrg       edge_clone_summaries->get (next_clone)->prev_clone = prev_clone;
   4177  1.1  mrg   }
   4178  1.1  mrg 
   4179  1.1  mrg   cgraph_edge *prev_clone;
   4180  1.1  mrg   cgraph_edge *next_clone;
   4181  1.1  mrg };
   4182  1.1  mrg 
   4183  1.1  mrg class edge_clone_summary_t:
   4184  1.1  mrg   public call_summary <edge_clone_summary *>
   4185  1.1  mrg {
   4186  1.1  mrg public:
   4187  1.1  mrg   edge_clone_summary_t (symbol_table *symtab):
   4188  1.1  mrg     call_summary <edge_clone_summary *> (symtab)
   4189  1.1  mrg     {
   4190  1.1  mrg       m_initialize_when_cloning = true;
   4191  1.1  mrg     }
   4192  1.1  mrg 
   4193  1.1  mrg   virtual void duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
   4194  1.1  mrg 			  edge_clone_summary *src_data,
   4195  1.1  mrg 			  edge_clone_summary *dst_data);
   4196  1.1  mrg };
   4197  1.1  mrg 
   4198  1.1  mrg /* Edge duplication hook.  */
   4199  1.1  mrg 
   4200  1.1  mrg void
   4201  1.1  mrg edge_clone_summary_t::duplicate (cgraph_edge *src_edge, cgraph_edge *dst_edge,
   4202  1.1  mrg 				 edge_clone_summary *src_data,
   4203  1.1  mrg 				 edge_clone_summary *dst_data)
   4204  1.1  mrg {
   4205  1.1  mrg   if (src_data->next_clone)
   4206  1.1  mrg     edge_clone_summaries->get (src_data->next_clone)->prev_clone = dst_edge;
   4207  1.1  mrg   dst_data->prev_clone = src_edge;
   4208  1.1  mrg   dst_data->next_clone = src_data->next_clone;
   4209  1.1  mrg   src_data->next_clone = dst_edge;
   4210  1.1  mrg }
   4211  1.1  mrg 
   4212  1.1  mrg /* Return true is CS calls DEST or its clone for all contexts.  When
   4213  1.1  mrg    ALLOW_RECURSION_TO_CLONE is false, also return false for self-recursive
   4214  1.1  mrg    edges from/to an all-context clone.  */
   4215  1.1  mrg 
   4216  1.1  mrg static bool
   4217  1.1  mrg calls_same_node_or_its_all_contexts_clone_p (cgraph_edge *cs, cgraph_node *dest,
   4218  1.1  mrg 					     bool allow_recursion_to_clone)
   4219  1.1  mrg {
   4220  1.1  mrg   enum availability availability;
   4221  1.1  mrg   cgraph_node *callee = cs->callee->function_symbol (&availability);
   4222  1.1  mrg 
   4223  1.1  mrg   if (availability <= AVAIL_INTERPOSABLE)
   4224  1.1  mrg     return false;
   4225  1.1  mrg   if (callee == dest)
   4226  1.1  mrg     return true;
   4227  1.1  mrg   if (!allow_recursion_to_clone && cs->caller == callee)
   4228  1.1  mrg     return false;
   4229  1.1  mrg 
   4230  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (callee);
   4231  1.1  mrg   return info->is_all_contexts_clone && info->ipcp_orig_node == dest;
   4232  1.1  mrg }
   4233  1.1  mrg 
   4234  1.1  mrg /* Return true if edge CS does bring about the value described by SRC to
   4235  1.1  mrg    DEST_VAL of node DEST or its clone for all contexts.  */
   4236  1.1  mrg 
   4237  1.1  mrg static bool
   4238  1.1  mrg cgraph_edge_brings_value_p (cgraph_edge *cs, ipcp_value_source<tree> *src,
   4239  1.1  mrg 			    cgraph_node *dest, ipcp_value<tree> *dest_val)
   4240  1.1  mrg {
   4241  1.1  mrg   ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   4242  1.1  mrg 
   4243  1.1  mrg   if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, !src->val)
   4244  1.1  mrg       || caller_info->node_dead)
   4245  1.1  mrg     return false;
   4246  1.1  mrg 
   4247  1.1  mrg   if (!src->val)
   4248  1.1  mrg     return true;
   4249  1.1  mrg 
   4250  1.1  mrg   if (caller_info->ipcp_orig_node)
   4251  1.1  mrg     {
   4252  1.1  mrg       tree t;
   4253  1.1  mrg       if (src->offset == -1)
   4254  1.1  mrg 	t = caller_info->known_csts[src->index];
   4255  1.1  mrg       else
   4256  1.1  mrg 	t = get_clone_agg_value (cs->caller, src->offset, src->index);
   4257  1.1  mrg       return (t != NULL_TREE
   4258  1.1  mrg 	      && values_equal_for_ipcp_p (src->val->value, t));
   4259  1.1  mrg     }
   4260  1.1  mrg   else
   4261  1.1  mrg     {
   4262  1.1  mrg       if (src->val == dest_val)
   4263  1.1  mrg 	return true;
   4264  1.1  mrg 
   4265  1.1  mrg       struct ipcp_agg_lattice *aglat;
   4266  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
   4267  1.1  mrg 								 src->index);
   4268  1.1  mrg       if (src->offset == -1)
   4269  1.1  mrg 	return (plats->itself.is_single_const ()
   4270  1.1  mrg 		&& values_equal_for_ipcp_p (src->val->value,
   4271  1.1  mrg 					    plats->itself.values->value));
   4272  1.1  mrg       else
   4273  1.1  mrg 	{
   4274  1.1  mrg 	  if (plats->aggs_bottom || plats->aggs_contain_variable)
   4275  1.1  mrg 	    return false;
   4276  1.1  mrg 	  for (aglat = plats->aggs; aglat; aglat = aglat->next)
   4277  1.1  mrg 	    if (aglat->offset == src->offset)
   4278  1.1  mrg 	      return  (aglat->is_single_const ()
   4279  1.1  mrg 		       && values_equal_for_ipcp_p (src->val->value,
   4280  1.1  mrg 						   aglat->values->value));
   4281  1.1  mrg 	}
   4282  1.1  mrg       return false;
   4283  1.1  mrg     }
   4284  1.1  mrg }
   4285  1.1  mrg 
   4286  1.1  mrg /* Return true if edge CS does bring about the value described by SRC to
   4287  1.1  mrg    DST_VAL of node DEST or its clone for all contexts.  */
   4288  1.1  mrg 
   4289  1.1  mrg static bool
   4290  1.1  mrg cgraph_edge_brings_value_p (cgraph_edge *cs,
   4291  1.1  mrg 			    ipcp_value_source<ipa_polymorphic_call_context> *src,
   4292  1.1  mrg 			    cgraph_node *dest,
   4293  1.1  mrg 			    ipcp_value<ipa_polymorphic_call_context> *)
   4294  1.1  mrg {
   4295  1.1  mrg   ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   4296  1.1  mrg 
   4297  1.1  mrg   if (!calls_same_node_or_its_all_contexts_clone_p (cs, dest, true)
   4298  1.1  mrg       || caller_info->node_dead)
   4299  1.1  mrg     return false;
   4300  1.1  mrg   if (!src->val)
   4301  1.1  mrg     return true;
   4302  1.1  mrg 
   4303  1.1  mrg   if (caller_info->ipcp_orig_node)
   4304  1.1  mrg     return (caller_info->known_contexts.length () > (unsigned) src->index)
   4305  1.1  mrg       && values_equal_for_ipcp_p (src->val->value,
   4306  1.1  mrg 				  caller_info->known_contexts[src->index]);
   4307  1.1  mrg 
   4308  1.1  mrg   class ipcp_param_lattices *plats = ipa_get_parm_lattices (caller_info,
   4309  1.1  mrg 							     src->index);
   4310  1.1  mrg   return plats->ctxlat.is_single_const ()
   4311  1.1  mrg     && values_equal_for_ipcp_p (src->val->value,
   4312  1.1  mrg 				plats->ctxlat.values->value);
   4313  1.1  mrg }
   4314  1.1  mrg 
   4315  1.1  mrg /* Get the next clone in the linked list of clones of an edge.  */
   4316  1.1  mrg 
   4317  1.1  mrg static inline struct cgraph_edge *
   4318  1.1  mrg get_next_cgraph_edge_clone (struct cgraph_edge *cs)
   4319  1.1  mrg {
   4320  1.1  mrg   edge_clone_summary *s = edge_clone_summaries->get (cs);
   4321  1.1  mrg   return s != NULL ? s->next_clone : NULL;
   4322  1.1  mrg }
   4323  1.1  mrg 
   4324  1.1  mrg /* Given VAL that is intended for DEST, iterate over all its sources and if any
   4325  1.1  mrg    of them is viable and hot, return true.  In that case, for those that still
   4326  1.1  mrg    hold, add their edge frequency and their number and cumulative profile
   4327  1.1  mrg    counts of self-ecursive and other edges into *FREQUENCY, *CALLER_COUNT,
   4328  1.1  mrg    REC_COUNT_SUM and NONREC_COUNT_SUM respectively.  */
   4329  1.1  mrg 
   4330  1.1  mrg template <typename valtype>
   4331  1.1  mrg static bool
   4332  1.1  mrg get_info_about_necessary_edges (ipcp_value<valtype> *val, cgraph_node *dest,
   4333  1.1  mrg 				sreal *freq_sum, int *caller_count,
   4334  1.1  mrg 				profile_count *rec_count_sum,
   4335  1.1  mrg 				profile_count *nonrec_count_sum)
   4336  1.1  mrg {
   4337  1.1  mrg   ipcp_value_source<valtype> *src;
   4338  1.1  mrg   sreal freq = 0;
   4339  1.1  mrg   int count = 0;
   4340  1.1  mrg   profile_count rec_cnt = profile_count::zero ();
   4341  1.1  mrg   profile_count nonrec_cnt = profile_count::zero ();
   4342  1.1  mrg   bool hot = false;
   4343  1.1  mrg   bool non_self_recursive = false;
   4344  1.1  mrg 
   4345  1.1  mrg   for (src = val->sources; src; src = src->next)
   4346  1.1  mrg     {
   4347  1.1  mrg       struct cgraph_edge *cs = src->cs;
   4348  1.1  mrg       while (cs)
   4349  1.1  mrg 	{
   4350  1.1  mrg 	  if (cgraph_edge_brings_value_p (cs, src, dest, val))
   4351  1.1  mrg 	    {
   4352  1.1  mrg 	      count++;
   4353  1.1  mrg 	      freq += cs->sreal_frequency ();
   4354  1.1  mrg 	      hot |= cs->maybe_hot_p ();
   4355  1.1  mrg 	      if (cs->caller != dest)
   4356  1.1  mrg 		{
   4357  1.1  mrg 		  non_self_recursive = true;
   4358  1.1  mrg 		  if (cs->count.ipa ().initialized_p ())
   4359  1.1  mrg 		    rec_cnt += cs->count.ipa ();
   4360  1.1  mrg 		}
   4361  1.1  mrg 	      else if (cs->count.ipa ().initialized_p ())
   4362  1.1  mrg 	        nonrec_cnt += cs->count.ipa ();
   4363  1.1  mrg 	    }
   4364  1.1  mrg 	  cs = get_next_cgraph_edge_clone (cs);
   4365  1.1  mrg 	}
   4366  1.1  mrg     }
   4367  1.1  mrg 
   4368  1.1  mrg   /* If the only edges bringing a value are self-recursive ones, do not bother
   4369  1.1  mrg      evaluating it.  */
   4370  1.1  mrg   if (!non_self_recursive)
   4371  1.1  mrg     return false;
   4372  1.1  mrg 
   4373  1.1  mrg   *freq_sum = freq;
   4374  1.1  mrg   *caller_count = count;
   4375  1.1  mrg   *rec_count_sum = rec_cnt;
   4376  1.1  mrg   *nonrec_count_sum = nonrec_cnt;
   4377  1.1  mrg 
   4378  1.1  mrg   if (!hot && ipa_node_params_sum->get (dest)->node_within_scc)
   4379  1.1  mrg     {
   4380  1.1  mrg       struct cgraph_edge *cs;
   4381  1.1  mrg 
   4382  1.1  mrg       /* Cold non-SCC source edge could trigger hot recursive execution of
   4383  1.1  mrg 	 function. Consider the case as hot and rely on following cost model
   4384  1.1  mrg 	 computation to further select right one.  */
   4385  1.1  mrg       for (cs = dest->callers; cs; cs = cs->next_caller)
   4386  1.1  mrg 	if (cs->caller == dest && cs->maybe_hot_p ())
   4387  1.1  mrg 	  return true;
   4388  1.1  mrg     }
   4389  1.1  mrg 
   4390  1.1  mrg   return hot;
   4391  1.1  mrg }
   4392  1.1  mrg 
   4393  1.1  mrg /* Given a NODE, and a set of its CALLERS, try to adjust order of the callers
   4394  1.1  mrg    to let a non-self-recursive caller be the first element.  Thus, we can
   4395  1.1  mrg    simplify intersecting operations on values that arrive from all of these
   4396  1.1  mrg    callers, especially when there exists self-recursive call.  Return true if
   4397  1.1  mrg    this kind of adjustment is possible.  */
   4398  1.1  mrg 
   4399  1.1  mrg static bool
   4400  1.1  mrg adjust_callers_for_value_intersection (vec<cgraph_edge *> &callers,
   4401  1.1  mrg 				       cgraph_node *node)
   4402  1.1  mrg {
   4403  1.1  mrg   for (unsigned i = 0; i < callers.length (); i++)
   4404  1.1  mrg     {
   4405  1.1  mrg       cgraph_edge *cs = callers[i];
   4406  1.1  mrg 
   4407  1.1  mrg       if (cs->caller != node)
   4408  1.1  mrg 	{
   4409  1.1  mrg 	  if (i > 0)
   4410  1.1  mrg 	    {
   4411  1.1  mrg 	      callers[i] = callers[0];
   4412  1.1  mrg 	      callers[0] = cs;
   4413  1.1  mrg 	    }
   4414  1.1  mrg 	  return true;
   4415  1.1  mrg 	}
   4416  1.1  mrg     }
   4417  1.1  mrg   return false;
   4418  1.1  mrg }
   4419  1.1  mrg 
   4420  1.1  mrg /* Return a vector of incoming edges that do bring value VAL to node DEST.  It
   4421  1.1  mrg    is assumed their number is known and equal to CALLER_COUNT.  */
   4422  1.1  mrg 
   4423  1.1  mrg template <typename valtype>
   4424  1.1  mrg static vec<cgraph_edge *>
   4425  1.1  mrg gather_edges_for_value (ipcp_value<valtype> *val, cgraph_node *dest,
   4426  1.1  mrg 			int caller_count)
   4427  1.1  mrg {
   4428  1.1  mrg   ipcp_value_source<valtype> *src;
   4429  1.1  mrg   vec<cgraph_edge *> ret;
   4430  1.1  mrg 
   4431  1.1  mrg   ret.create (caller_count);
   4432  1.1  mrg   for (src = val->sources; src; src = src->next)
   4433  1.1  mrg     {
   4434  1.1  mrg       struct cgraph_edge *cs = src->cs;
   4435  1.1  mrg       while (cs)
   4436  1.1  mrg 	{
   4437  1.1  mrg 	  if (cgraph_edge_brings_value_p (cs, src, dest, val))
   4438  1.1  mrg 	    ret.quick_push (cs);
   4439  1.1  mrg 	  cs = get_next_cgraph_edge_clone (cs);
   4440  1.1  mrg 	}
   4441  1.1  mrg     }
   4442  1.1  mrg 
   4443  1.1  mrg   if (caller_count > 1)
   4444  1.1  mrg     adjust_callers_for_value_intersection (ret, dest);
   4445  1.1  mrg 
   4446  1.1  mrg   return ret;
   4447  1.1  mrg }
   4448  1.1  mrg 
   4449  1.1  mrg /* Construct a replacement map for a know VALUE for a formal parameter PARAM.
   4450  1.1  mrg    Return it or NULL if for some reason it cannot be created.  FORCE_LOAD_REF
   4451  1.1  mrg    should be set to true when the reference created for the constant should be
   4452  1.1  mrg    a load one and not an address one because the corresponding parameter p is
   4453  1.1  mrg    only used as *p.  */
   4454  1.1  mrg 
   4455  1.1  mrg static struct ipa_replace_map *
   4456  1.1  mrg get_replacement_map (class ipa_node_params *info, tree value, int parm_num,
   4457  1.1  mrg 		     bool force_load_ref)
   4458  1.1  mrg {
   4459  1.1  mrg   struct ipa_replace_map *replace_map;
   4460  1.1  mrg 
   4461  1.1  mrg   replace_map = ggc_alloc<ipa_replace_map> ();
   4462  1.1  mrg   if (dump_file)
   4463  1.1  mrg     {
   4464  1.1  mrg       fprintf (dump_file, "    replacing ");
   4465  1.1  mrg       ipa_dump_param (dump_file, info, parm_num);
   4466  1.1  mrg 
   4467  1.1  mrg       fprintf (dump_file, " with const ");
   4468  1.1  mrg       print_generic_expr (dump_file, value);
   4469  1.1  mrg 
   4470  1.1  mrg       if (force_load_ref)
   4471  1.1  mrg 	fprintf (dump_file, " - forcing load reference\n");
   4472  1.1  mrg       else
   4473  1.1  mrg 	fprintf (dump_file, "\n");
   4474  1.1  mrg     }
   4475  1.1  mrg   replace_map->parm_num = parm_num;
   4476  1.1  mrg   replace_map->new_tree = value;
   4477  1.1  mrg   replace_map->force_load_ref = force_load_ref;
   4478  1.1  mrg   return replace_map;
   4479  1.1  mrg }
   4480  1.1  mrg 
   4481  1.1  mrg /* Dump new profiling counts of NODE.  SPEC is true when NODE is a specialzied
   4482  1.1  mrg    one, otherwise it will be referred to as the original node.  */
   4483  1.1  mrg 
   4484  1.1  mrg static void
   4485  1.1  mrg dump_profile_updates (cgraph_node *node, bool spec)
   4486  1.1  mrg {
   4487  1.1  mrg   if (spec)
   4488  1.1  mrg     fprintf (dump_file, "     setting count of the specialized node %s to ",
   4489  1.1  mrg 	     node->dump_name ());
   4490  1.1  mrg   else
   4491  1.1  mrg     fprintf (dump_file, "     setting count of the original node %s to ",
   4492  1.1  mrg 	     node->dump_name ());
   4493  1.1  mrg 
   4494  1.1  mrg   node->count.dump (dump_file);
   4495  1.1  mrg   fprintf (dump_file, "\n");
   4496  1.1  mrg   for (cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
   4497  1.1  mrg     {
   4498  1.1  mrg       fprintf (dump_file, "       edge to %s has count ",
   4499  1.1  mrg 	       cs->callee->dump_name ());
   4500  1.1  mrg       cs->count.dump (dump_file);
   4501  1.1  mrg       fprintf (dump_file, "\n");
   4502  1.1  mrg     }
   4503  1.1  mrg }
   4504  1.1  mrg 
   4505  1.1  mrg /* With partial train run we do not want to assume that original's count is
   4506  1.1  mrg    zero whenever we redurect all executed edges to clone.  Simply drop profile
   4507  1.1  mrg    to local one in this case.  In eany case, return the new value.  ORIG_NODE
   4508  1.1  mrg    is the original node and its count has not been updaed yet.  */
   4509  1.1  mrg 
   4510  1.1  mrg profile_count
   4511  1.1  mrg lenient_count_portion_handling (profile_count remainder, cgraph_node *orig_node)
   4512  1.1  mrg {
   4513  1.1  mrg   if (remainder.ipa_p () && !remainder.ipa ().nonzero_p ()
   4514  1.1  mrg       && orig_node->count.ipa_p () && orig_node->count.ipa ().nonzero_p ()
   4515  1.1  mrg       && opt_for_fn (orig_node->decl, flag_profile_partial_training))
   4516  1.1  mrg     remainder = remainder.guessed_local ();
   4517  1.1  mrg 
   4518  1.1  mrg   return remainder;
   4519  1.1  mrg }
   4520  1.1  mrg 
   4521  1.1  mrg /* Structure to sum counts coming from nodes other than the original node and
   4522  1.1  mrg    its clones.  */
   4523  1.1  mrg 
   4524  1.1  mrg struct gather_other_count_struct
   4525  1.1  mrg {
   4526  1.1  mrg   cgraph_node *orig;
   4527  1.1  mrg   profile_count other_count;
   4528  1.1  mrg };
   4529  1.1  mrg 
   4530  1.1  mrg /* Worker callback of call_for_symbol_thunks_and_aliases summing the number of
   4531  1.1  mrg    counts that come from non-self-recursive calls..  */
   4532  1.1  mrg 
   4533  1.1  mrg static bool
   4534  1.1  mrg gather_count_of_non_rec_edges (cgraph_node *node, void *data)
   4535  1.1  mrg {
   4536  1.1  mrg   gather_other_count_struct *desc = (gather_other_count_struct *) data;
   4537  1.1  mrg   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
   4538  1.1  mrg     if (cs->caller != desc->orig && cs->caller->clone_of != desc->orig)
   4539  1.1  mrg       desc->other_count += cs->count.ipa ();
   4540  1.1  mrg   return false;
   4541  1.1  mrg }
   4542  1.1  mrg 
   4543  1.1  mrg /* Structure to help analyze if we need to boost counts of some clones of some
   4544  1.1  mrg    non-recursive edges to match the new callee count.  */
   4545  1.1  mrg 
   4546  1.1  mrg struct desc_incoming_count_struct
   4547  1.1  mrg {
   4548  1.1  mrg   cgraph_node *orig;
   4549  1.1  mrg   hash_set <cgraph_edge *> *processed_edges;
   4550  1.1  mrg   profile_count count;
   4551  1.1  mrg   unsigned unproc_orig_rec_edges;
   4552  1.1  mrg };
   4553  1.1  mrg 
   4554  1.1  mrg /* Go over edges calling NODE and its thunks and gather information about
   4555  1.1  mrg    incoming counts so that we know if we need to make any adjustments.  */
   4556  1.1  mrg 
   4557  1.1  mrg static void
   4558  1.1  mrg analyze_clone_icoming_counts (cgraph_node *node,
   4559  1.1  mrg 			      desc_incoming_count_struct *desc)
   4560  1.1  mrg {
   4561  1.1  mrg   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
   4562  1.1  mrg     if (cs->caller->thunk)
   4563  1.1  mrg       {
   4564  1.1  mrg 	analyze_clone_icoming_counts (cs->caller, desc);
   4565  1.1  mrg 	continue;
   4566  1.1  mrg       }
   4567  1.1  mrg     else
   4568  1.1  mrg       {
   4569  1.1  mrg 	if (cs->count.initialized_p ())
   4570  1.1  mrg 	  desc->count += cs->count.ipa ();
   4571  1.1  mrg 	if (!desc->processed_edges->contains (cs)
   4572  1.1  mrg 	    && cs->caller->clone_of == desc->orig)
   4573  1.1  mrg 	  desc->unproc_orig_rec_edges++;
   4574  1.1  mrg       }
   4575  1.1  mrg }
   4576  1.1  mrg 
   4577  1.1  mrg /* If caller edge counts of a clone created for a self-recursive arithmetic
   4578  1.1  mrg    jump function must be adjusted because it is coming from a the "seed" clone
   4579  1.1  mrg    for the first value and so has been excessively scaled back as if it was not
   4580  1.1  mrg    a recursive call, adjust it so that the incoming counts of NODE match its
   4581  1.1  mrg    count. NODE is the node or its thunk.  */
   4582  1.1  mrg 
   4583  1.1  mrg static void
   4584  1.1  mrg adjust_clone_incoming_counts (cgraph_node *node,
   4585  1.1  mrg 			      desc_incoming_count_struct *desc)
   4586  1.1  mrg {
   4587  1.1  mrg   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
   4588  1.1  mrg     if (cs->caller->thunk)
   4589  1.1  mrg       {
   4590  1.1  mrg 	adjust_clone_incoming_counts (cs->caller, desc);
   4591  1.1  mrg 	profile_count sum = profile_count::zero ();
   4592  1.1  mrg 	for (cgraph_edge *e = cs->caller->callers; e; e = e->next_caller)
   4593  1.1  mrg 	  if (e->count.initialized_p ())
   4594  1.1  mrg 	    sum += e->count.ipa ();
   4595  1.1  mrg 	cs->count = cs->count.combine_with_ipa_count (sum);
   4596  1.1  mrg       }
   4597  1.1  mrg     else if (!desc->processed_edges->contains (cs)
   4598  1.1  mrg 	     && cs->caller->clone_of == desc->orig)
   4599  1.1  mrg       {
   4600  1.1  mrg 	cs->count += desc->count;
   4601  1.1  mrg 	if (dump_file)
   4602  1.1  mrg 	  {
   4603  1.1  mrg 	    fprintf (dump_file, "       Adjusted count of an incoming edge of "
   4604  1.1  mrg 		     "a clone %s -> %s to ", cs->caller->dump_name (),
   4605  1.1  mrg 		     cs->callee->dump_name ());
   4606  1.1  mrg 	    cs->count.dump (dump_file);
   4607  1.1  mrg 	    fprintf (dump_file, "\n");
   4608  1.1  mrg 	  }
   4609  1.1  mrg       }
   4610  1.1  mrg }
   4611  1.1  mrg 
   4612  1.1  mrg /* When ORIG_NODE has been cloned for values which have been generated fora
   4613  1.1  mrg    self-recursive call as a result of an arithmetic pass-through
   4614  1.1  mrg    jump-functions, adjust its count together with counts of all such clones in
   4615  1.1  mrg    SELF_GEN_CLONES which also at this point contains ORIG_NODE itself.
   4616  1.1  mrg 
   4617  1.1  mrg    The function sums the counts of the original node and all its clones that
   4618  1.1  mrg    cannot be attributed to a specific clone because it comes from a
   4619  1.1  mrg    non-recursive edge.  This sum is then evenly divided between the clones and
   4620  1.1  mrg    on top of that each one gets all the counts which can be attributed directly
   4621  1.1  mrg    to it.  */
   4622  1.1  mrg 
   4623  1.1  mrg static void
   4624  1.1  mrg update_counts_for_self_gen_clones (cgraph_node *orig_node,
   4625  1.1  mrg 				   const vec<cgraph_node *> &self_gen_clones)
   4626  1.1  mrg {
   4627  1.1  mrg   profile_count redist_sum = orig_node->count.ipa ();
   4628  1.1  mrg   if (!(redist_sum > profile_count::zero ()))
   4629  1.1  mrg     return;
   4630  1.1  mrg 
   4631  1.1  mrg   if (dump_file)
   4632  1.1  mrg     fprintf (dump_file, "     Updating profile of self recursive clone "
   4633  1.1  mrg 	     "series\n");
   4634  1.1  mrg 
   4635  1.1  mrg   gather_other_count_struct gocs;
   4636  1.1  mrg   gocs.orig = orig_node;
   4637  1.1  mrg   gocs.other_count = profile_count::zero ();
   4638  1.1  mrg 
   4639  1.1  mrg   auto_vec <profile_count, 8> other_edges_count;
   4640  1.1  mrg   for (cgraph_node *n : self_gen_clones)
   4641  1.1  mrg     {
   4642  1.1  mrg       gocs.other_count = profile_count::zero ();
   4643  1.1  mrg       n->call_for_symbol_thunks_and_aliases (gather_count_of_non_rec_edges,
   4644  1.1  mrg 					     &gocs, false);
   4645  1.1  mrg       other_edges_count.safe_push (gocs.other_count);
   4646  1.1  mrg       redist_sum -= gocs.other_count;
   4647  1.1  mrg     }
   4648  1.1  mrg 
   4649  1.1  mrg   hash_set<cgraph_edge *> processed_edges;
   4650  1.1  mrg   unsigned i = 0;
   4651  1.1  mrg   for (cgraph_node *n : self_gen_clones)
   4652  1.1  mrg     {
   4653  1.1  mrg       profile_count orig_count = n->count;
   4654  1.1  mrg       profile_count new_count
   4655  1.1  mrg 	= (redist_sum.apply_scale (1, self_gen_clones.length ())
   4656  1.1  mrg 	   + other_edges_count[i]);
   4657  1.1  mrg       new_count = lenient_count_portion_handling (new_count, orig_node);
   4658  1.1  mrg       n->count = new_count;
   4659  1.1  mrg       profile_count::adjust_for_ipa_scaling (&new_count, &orig_count);
   4660  1.1  mrg       for (cgraph_edge *cs = n->callees; cs; cs = cs->next_callee)
   4661  1.1  mrg 	{
   4662  1.1  mrg 	  cs->count = cs->count.apply_scale (new_count, orig_count);
   4663  1.1  mrg 	  processed_edges.add (cs);
   4664  1.1  mrg 	}
   4665  1.1  mrg       for (cgraph_edge *cs = n->indirect_calls; cs; cs = cs->next_callee)
   4666  1.1  mrg 	cs->count = cs->count.apply_scale (new_count, orig_count);
   4667  1.1  mrg 
   4668  1.1  mrg       i++;
   4669  1.1  mrg     }
   4670  1.1  mrg 
   4671  1.1  mrg   /* There are still going to be edges to ORIG_NODE that have one or more
   4672  1.1  mrg      clones coming from another node clone in SELF_GEN_CLONES and which we
   4673  1.1  mrg      scaled by the same amount, which means that the total incoming sum of
   4674  1.1  mrg      counts to ORIG_NODE will be too high, scale such edges back.  */
   4675  1.1  mrg   for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee)
   4676  1.1  mrg     {
   4677  1.1  mrg       if (cs->callee->ultimate_alias_target () == orig_node)
   4678  1.1  mrg 	{
   4679  1.1  mrg 	  unsigned den = 0;
   4680  1.1  mrg 	  for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e))
   4681  1.1  mrg 	    if (e->callee->ultimate_alias_target () == orig_node
   4682  1.1  mrg 		&& processed_edges.contains (e))
   4683  1.1  mrg 	      den++;
   4684  1.1  mrg 	  if (den > 0)
   4685  1.1  mrg 	    for (cgraph_edge *e = cs; e; e = get_next_cgraph_edge_clone (e))
   4686  1.1  mrg 	      if (e->callee->ultimate_alias_target () == orig_node
   4687  1.1  mrg 		  && processed_edges.contains (e))
   4688  1.1  mrg 		e->count = e->count.apply_scale (1, den);
   4689  1.1  mrg 	}
   4690  1.1  mrg     }
   4691  1.1  mrg 
   4692  1.1  mrg   /* Edges from the seeds of the valus generated for arithmetic jump-functions
   4693  1.1  mrg      along self-recursive edges are likely to have fairly low count and so
   4694  1.1  mrg      edges from them to nodes in the self_gen_clones do not correspond to the
   4695  1.1  mrg      artificially distributed count of the nodes, the total sum of incoming
   4696  1.1  mrg      edges to some clones might be too low.  Detect this situation and correct
   4697  1.1  mrg      it.  */
   4698  1.1  mrg   for (cgraph_node *n : self_gen_clones)
   4699  1.1  mrg     {
   4700  1.1  mrg       if (!(n->count.ipa () > profile_count::zero ()))
   4701  1.1  mrg 	continue;
   4702  1.1  mrg 
   4703  1.1  mrg       desc_incoming_count_struct desc;
   4704  1.1  mrg       desc.orig = orig_node;
   4705  1.1  mrg       desc.processed_edges = &processed_edges;
   4706  1.1  mrg       desc.count = profile_count::zero ();
   4707  1.1  mrg       desc.unproc_orig_rec_edges = 0;
   4708  1.1  mrg       analyze_clone_icoming_counts (n, &desc);
   4709  1.1  mrg 
   4710  1.1  mrg       if (n->count.differs_from_p (desc.count))
   4711  1.1  mrg 	{
   4712  1.1  mrg 	  if (n->count > desc.count
   4713  1.1  mrg 	      && desc.unproc_orig_rec_edges > 0)
   4714  1.1  mrg 	    {
   4715  1.1  mrg 	      desc.count = n->count - desc.count;
   4716  1.1  mrg 	      desc.count
   4717  1.1  mrg 		= desc.count.apply_scale (1, desc.unproc_orig_rec_edges);
   4718  1.1  mrg 	      adjust_clone_incoming_counts (n, &desc);
   4719  1.1  mrg 	    }
   4720  1.1  mrg 	  else if (dump_file)
   4721  1.1  mrg 	    fprintf (dump_file,
   4722  1.1  mrg 		     "       Unable to fix up incoming counts for %s.\n",
   4723  1.1  mrg 		     n->dump_name ());
   4724  1.1  mrg 	}
   4725  1.1  mrg     }
   4726  1.1  mrg 
   4727  1.1  mrg   if (dump_file)
   4728  1.1  mrg     for (cgraph_node *n : self_gen_clones)
   4729  1.1  mrg       dump_profile_updates (n, n != orig_node);
   4730  1.1  mrg   return;
   4731  1.1  mrg }
   4732  1.1  mrg 
   4733  1.1  mrg /* After a specialized NEW_NODE version of ORIG_NODE has been created, update
   4734  1.1  mrg    their profile information to reflect this.  This function should not be used
   4735  1.1  mrg    for clones generated for arithmetic pass-through jump functions on a
   4736  1.1  mrg    self-recursive call graph edge, that situation is handled by
   4737  1.1  mrg    update_counts_for_self_gen_clones.  */
   4738  1.1  mrg 
   4739  1.1  mrg static void
   4740  1.1  mrg update_profiling_info (struct cgraph_node *orig_node,
   4741  1.1  mrg 		       struct cgraph_node *new_node)
   4742  1.1  mrg {
   4743  1.1  mrg   struct caller_statistics stats;
   4744  1.1  mrg   profile_count new_sum;
   4745  1.1  mrg   profile_count remainder, orig_node_count = orig_node->count.ipa ();
   4746  1.1  mrg 
   4747  1.1  mrg   if (!(orig_node_count > profile_count::zero ()))
   4748  1.1  mrg     return;
   4749  1.1  mrg 
   4750  1.1  mrg   if (dump_file)
   4751  1.1  mrg     {
   4752  1.1  mrg       fprintf (dump_file, "     Updating profile from original count: ");
   4753  1.1  mrg       orig_node_count.dump (dump_file);
   4754  1.1  mrg       fprintf (dump_file, "\n");
   4755  1.1  mrg     }
   4756  1.1  mrg 
   4757  1.1  mrg   init_caller_stats (&stats, new_node);
   4758  1.1  mrg   new_node->call_for_symbol_thunks_and_aliases (gather_caller_stats, &stats,
   4759  1.1  mrg 					      false);
   4760  1.1  mrg   new_sum = stats.count_sum;
   4761  1.1  mrg 
   4762  1.1  mrg   if (new_sum > orig_node_count)
   4763  1.1  mrg     {
   4764  1.1  mrg       /* TODO: Perhaps this should be gcc_unreachable ()?  */
   4765  1.1  mrg       remainder = profile_count::zero ().guessed_local ();
   4766  1.1  mrg     }
   4767  1.1  mrg   else if (stats.rec_count_sum.nonzero_p ())
   4768  1.1  mrg     {
   4769  1.1  mrg       int new_nonrec_calls = stats.n_nonrec_calls;
   4770  1.1  mrg       /* There are self-recursive edges which are likely to bring in the
   4771  1.1  mrg 	 majority of calls but which we must divide in between the original and
   4772  1.1  mrg 	 new node.  */
   4773  1.1  mrg       init_caller_stats (&stats, orig_node);
   4774  1.1  mrg       orig_node->call_for_symbol_thunks_and_aliases (gather_caller_stats,
   4775  1.1  mrg 						     &stats, false);
   4776  1.1  mrg       int orig_nonrec_calls = stats.n_nonrec_calls;
   4777  1.1  mrg       profile_count orig_nonrec_call_count = stats.count_sum;
   4778  1.1  mrg 
   4779  1.1  mrg       if (orig_node->local)
   4780  1.1  mrg 	{
   4781  1.1  mrg 	  if (!orig_nonrec_call_count.nonzero_p ())
   4782  1.1  mrg 	    {
   4783  1.1  mrg 	      if (dump_file)
   4784  1.1  mrg 		fprintf (dump_file, "       The original is local and the only "
   4785  1.1  mrg 			 "incoming edges from non-dead callers with nonzero "
   4786  1.1  mrg 			 "counts are self-recursive, assuming it is cold.\n");
   4787  1.1  mrg 	      /* The NEW_NODE count and counts of all its outgoing edges
   4788  1.1  mrg 		 are still unmodified copies of ORIG_NODE's.  Just clear
   4789  1.1  mrg 		 the latter and bail out.  */
   4790  1.1  mrg 	      profile_count zero;
   4791  1.1  mrg               if (opt_for_fn (orig_node->decl, flag_profile_partial_training))
   4792  1.1  mrg                 zero = profile_count::zero ().guessed_local ();
   4793  1.1  mrg 	      else
   4794  1.1  mrg 		zero = profile_count::adjusted_zero ();
   4795  1.1  mrg 	      orig_node->count = zero;
   4796  1.1  mrg 	      for (cgraph_edge *cs = orig_node->callees;
   4797  1.1  mrg 		   cs;
   4798  1.1  mrg 		   cs = cs->next_callee)
   4799  1.1  mrg 		cs->count = zero;
   4800  1.1  mrg 	      for (cgraph_edge *cs = orig_node->indirect_calls;
   4801  1.1  mrg 		   cs;
   4802  1.1  mrg 		   cs = cs->next_callee)
   4803  1.1  mrg 		cs->count = zero;
   4804  1.1  mrg 	      return;
   4805  1.1  mrg 	    }
   4806  1.1  mrg 	}
   4807  1.1  mrg       else
   4808  1.1  mrg 	{
   4809  1.1  mrg 	  /* Let's behave as if there was another caller that accounts for all
   4810  1.1  mrg 	     the calls that were either indirect or from other compilation
   4811  1.1  mrg 	     units. */
   4812  1.1  mrg 	  orig_nonrec_calls++;
   4813  1.1  mrg 	  profile_count pretend_caller_count
   4814  1.1  mrg 	    = (orig_node_count - new_sum - orig_nonrec_call_count
   4815  1.1  mrg 	       - stats.rec_count_sum);
   4816  1.1  mrg 	  orig_nonrec_call_count += pretend_caller_count;
   4817  1.1  mrg 	}
   4818  1.1  mrg 
   4819  1.1  mrg       /* Divide all "unexplained" counts roughly proportionally to sums of
   4820  1.1  mrg 	 counts of non-recursive calls.
   4821  1.1  mrg 
   4822  1.1  mrg 	 We put rather arbitrary limits on how many counts we claim because the
   4823  1.1  mrg 	 number of non-self-recursive incoming count is only a rough guideline
   4824  1.1  mrg 	 and there are cases (such as mcf) where using it blindly just takes
   4825  1.1  mrg 	 too many.  And if lattices are considered in the opposite order we
   4826  1.1  mrg 	 could also take too few.  */
   4827  1.1  mrg       profile_count unexp = orig_node_count - new_sum - orig_nonrec_call_count;
   4828  1.1  mrg 
   4829  1.1  mrg       int limit_den = 2 * (orig_nonrec_calls + new_nonrec_calls);
   4830  1.1  mrg       profile_count new_part
   4831  1.1  mrg 	= MAX(MIN (unexp.apply_scale (new_sum,
   4832  1.1  mrg 				      new_sum + orig_nonrec_call_count),
   4833  1.1  mrg 		   unexp.apply_scale (limit_den - 1, limit_den)),
   4834  1.1  mrg 	      unexp.apply_scale (new_nonrec_calls, limit_den));
   4835  1.1  mrg       if (dump_file)
   4836  1.1  mrg 	{
   4837  1.1  mrg 	  fprintf (dump_file, "       Claiming ");
   4838  1.1  mrg 	  new_part.dump (dump_file);
   4839  1.1  mrg 	  fprintf (dump_file, " of unexplained ");
   4840  1.1  mrg 	  unexp.dump (dump_file);
   4841  1.1  mrg 	  fprintf (dump_file, " counts because of self-recursive "
   4842  1.1  mrg 		   "calls\n");
   4843  1.1  mrg 	}
   4844  1.1  mrg       new_sum += new_part;
   4845  1.1  mrg       remainder = lenient_count_portion_handling (orig_node_count - new_sum,
   4846  1.1  mrg 						  orig_node);
   4847  1.1  mrg     }
   4848  1.1  mrg   else
   4849  1.1  mrg     remainder = lenient_count_portion_handling (orig_node_count - new_sum,
   4850  1.1  mrg 						orig_node);
   4851  1.1  mrg 
   4852  1.1  mrg   new_sum = orig_node_count.combine_with_ipa_count (new_sum);
   4853  1.1  mrg   new_node->count = new_sum;
   4854  1.1  mrg   orig_node->count = remainder;
   4855  1.1  mrg 
   4856  1.1  mrg   profile_count orig_new_node_count = orig_node_count;
   4857  1.1  mrg   profile_count::adjust_for_ipa_scaling (&new_sum, &orig_new_node_count);
   4858  1.1  mrg   for (cgraph_edge *cs = new_node->callees; cs; cs = cs->next_callee)
   4859  1.1  mrg     cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
   4860  1.1  mrg   for (cgraph_edge *cs = new_node->indirect_calls; cs; cs = cs->next_callee)
   4861  1.1  mrg     cs->count = cs->count.apply_scale (new_sum, orig_new_node_count);
   4862  1.1  mrg 
   4863  1.1  mrg   profile_count::adjust_for_ipa_scaling (&remainder, &orig_node_count);
   4864  1.1  mrg   for (cgraph_edge *cs = orig_node->callees; cs; cs = cs->next_callee)
   4865  1.1  mrg     cs->count = cs->count.apply_scale (remainder, orig_node_count);
   4866  1.1  mrg   for (cgraph_edge *cs = orig_node->indirect_calls; cs; cs = cs->next_callee)
   4867  1.1  mrg     cs->count = cs->count.apply_scale (remainder, orig_node_count);
   4868  1.1  mrg 
   4869  1.1  mrg   if (dump_file)
   4870  1.1  mrg     {
   4871  1.1  mrg       dump_profile_updates (new_node, true);
   4872  1.1  mrg       dump_profile_updates (orig_node, false);
   4873  1.1  mrg     }
   4874  1.1  mrg }
   4875  1.1  mrg 
   4876  1.1  mrg /* Update the respective profile of specialized NEW_NODE and the original
   4877  1.1  mrg    ORIG_NODE after additional edges with cumulative count sum REDIRECTED_SUM
   4878  1.1  mrg    have been redirected to the specialized version.  */
   4879  1.1  mrg 
   4880  1.1  mrg static void
   4881  1.1  mrg update_specialized_profile (struct cgraph_node *new_node,
   4882  1.1  mrg 			    struct cgraph_node *orig_node,
   4883  1.1  mrg 			    profile_count redirected_sum)
   4884  1.1  mrg {
   4885  1.1  mrg   struct cgraph_edge *cs;
   4886  1.1  mrg   profile_count new_node_count, orig_node_count = orig_node->count.ipa ();
   4887  1.1  mrg 
   4888  1.1  mrg   if (dump_file)
   4889  1.1  mrg     {
   4890  1.1  mrg       fprintf (dump_file, "    the sum of counts of redirected  edges is ");
   4891  1.1  mrg       redirected_sum.dump (dump_file);
   4892  1.1  mrg       fprintf (dump_file, "\n    old ipa count of the original node is ");
   4893  1.1  mrg       orig_node_count.dump (dump_file);
   4894  1.1  mrg       fprintf (dump_file, "\n");
   4895  1.1  mrg     }
   4896  1.1  mrg   if (!(orig_node_count > profile_count::zero ()))
   4897  1.1  mrg     return;
   4898  1.1  mrg 
   4899  1.1  mrg   new_node_count = new_node->count;
   4900  1.1  mrg   new_node->count += redirected_sum;
   4901  1.1  mrg   orig_node->count
   4902  1.1  mrg     = lenient_count_portion_handling (orig_node->count - redirected_sum,
   4903  1.1  mrg 				      orig_node);
   4904  1.1  mrg 
   4905  1.1  mrg   for (cs = new_node->callees; cs; cs = cs->next_callee)
   4906  1.1  mrg     cs->count += cs->count.apply_scale (redirected_sum, new_node_count);
   4907  1.1  mrg 
   4908  1.1  mrg   for (cs = orig_node->callees; cs; cs = cs->next_callee)
   4909  1.1  mrg     {
   4910  1.1  mrg       profile_count dec = cs->count.apply_scale (redirected_sum,
   4911  1.1  mrg 						 orig_node_count);
   4912  1.1  mrg       cs->count -= dec;
   4913  1.1  mrg     }
   4914  1.1  mrg 
   4915  1.1  mrg   if (dump_file)
   4916  1.1  mrg     {
   4917  1.1  mrg       dump_profile_updates (new_node, true);
   4918  1.1  mrg       dump_profile_updates (orig_node, false);
   4919  1.1  mrg     }
   4920  1.1  mrg }
   4921  1.1  mrg 
   4922  1.1  mrg static void adjust_references_in_caller (cgraph_edge *cs,
   4923  1.1  mrg 					 symtab_node *symbol, int index);
   4924  1.1  mrg 
   4925  1.1  mrg /* Simple structure to pass a symbol and index (with same meaning as parameters
   4926  1.1  mrg    of adjust_references_in_caller) through a void* parameter of a
   4927  1.1  mrg    call_for_symbol_thunks_and_aliases callback. */
   4928  1.1  mrg struct symbol_and_index_together
   4929  1.1  mrg {
   4930  1.1  mrg   symtab_node *symbol;
   4931  1.1  mrg   int index;
   4932  1.1  mrg };
   4933  1.1  mrg 
   4934  1.1  mrg /* Worker callback of call_for_symbol_thunks_and_aliases to recursively call
   4935  1.1  mrg    adjust_references_in_caller on edges up in the call-graph, if necessary. */
   4936  1.1  mrg static bool
   4937  1.1  mrg adjust_refs_in_act_callers (struct cgraph_node *node, void *data)
   4938  1.1  mrg {
   4939  1.1  mrg   symbol_and_index_together *pack = (symbol_and_index_together *) data;
   4940  1.1  mrg   for (cgraph_edge *cs = node->callers; cs; cs = cs->next_caller)
   4941  1.1  mrg     if (!cs->caller->thunk)
   4942  1.1  mrg       adjust_references_in_caller (cs, pack->symbol, pack->index);
   4943  1.1  mrg   return false;
   4944  1.1  mrg }
   4945  1.1  mrg 
   4946  1.1  mrg /* At INDEX of a function being called by CS there is an ADDR_EXPR of a
   4947  1.1  mrg    variable which is only dereferenced and which is represented by SYMBOL.  See
   4948  1.1  mrg    if we can remove ADDR reference in callers assosiated witht the call. */
   4949  1.1  mrg 
   4950  1.1  mrg static void
   4951  1.1  mrg adjust_references_in_caller (cgraph_edge *cs, symtab_node *symbol, int index)
   4952  1.1  mrg {
   4953  1.1  mrg   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   4954  1.1  mrg   ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, index);
   4955  1.1  mrg   if (jfunc->type == IPA_JF_CONST)
   4956  1.1  mrg     {
   4957  1.1  mrg       ipa_ref *to_del = cs->caller->find_reference (symbol, cs->call_stmt,
   4958  1.1  mrg 						    cs->lto_stmt_uid,
   4959  1.1  mrg 						    IPA_REF_ADDR);
   4960  1.1  mrg       if (!to_del)
   4961  1.1  mrg 	return;
   4962  1.1  mrg       to_del->remove_reference ();
   4963  1.1  mrg       ipa_zap_jf_refdesc (jfunc);
   4964  1.1  mrg       if (dump_file)
   4965  1.1  mrg 	fprintf (dump_file, "    Removed a reference from %s to %s.\n",
   4966  1.1  mrg 		 cs->caller->dump_name (), symbol->dump_name ());
   4967  1.1  mrg       return;
   4968  1.1  mrg     }
   4969  1.1  mrg 
   4970  1.1  mrg   if (jfunc->type != IPA_JF_PASS_THROUGH
   4971  1.1  mrg       || ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR
   4972  1.1  mrg       || ipa_get_jf_pass_through_refdesc_decremented (jfunc))
   4973  1.1  mrg     return;
   4974  1.1  mrg 
   4975  1.1  mrg   int fidx = ipa_get_jf_pass_through_formal_id (jfunc);
   4976  1.1  mrg   cgraph_node *caller = cs->caller;
   4977  1.1  mrg   ipa_node_params *caller_info = ipa_node_params_sum->get (caller);
   4978  1.1  mrg   /* TODO: This consistency check may be too big and not really
   4979  1.1  mrg      that useful.  Consider removing it.  */
   4980  1.1  mrg   tree cst;
   4981  1.1  mrg   if (caller_info->ipcp_orig_node)
   4982  1.1  mrg     cst = caller_info->known_csts[fidx];
   4983  1.1  mrg   else
   4984  1.1  mrg     {
   4985  1.1  mrg       ipcp_lattice<tree> *lat = ipa_get_scalar_lat (caller_info, fidx);
   4986  1.1  mrg       gcc_assert (lat->is_single_const ());
   4987  1.1  mrg       cst = lat->values->value;
   4988  1.1  mrg     }
   4989  1.1  mrg   gcc_assert (TREE_CODE (cst) == ADDR_EXPR
   4990  1.1  mrg 	      && (symtab_node::get (get_base_address (TREE_OPERAND (cst, 0)))
   4991  1.1  mrg 		  == symbol));
   4992  1.1  mrg 
   4993  1.1  mrg   int cuses = ipa_get_controlled_uses (caller_info, fidx);
   4994  1.1  mrg   if (cuses == IPA_UNDESCRIBED_USE)
   4995  1.1  mrg     return;
   4996  1.1  mrg   gcc_assert (cuses > 0);
   4997  1.1  mrg   cuses--;
   4998  1.1  mrg   ipa_set_controlled_uses (caller_info, fidx, cuses);
   4999  1.1  mrg   ipa_set_jf_pass_through_refdesc_decremented (jfunc, true);
   5000  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   5001  1.1  mrg     fprintf (dump_file, "    Controlled uses of parameter %i of %s dropped "
   5002  1.1  mrg 	     "to %i.\n", fidx, caller->dump_name (), cuses);
   5003  1.1  mrg   if (cuses)
   5004  1.1  mrg     return;
   5005  1.1  mrg 
   5006  1.1  mrg   if (caller_info->ipcp_orig_node)
   5007  1.1  mrg     {
   5008  1.1  mrg       /* Cloning machinery has created a reference here, we need to either
   5009  1.1  mrg 	 remove it or change it to a read one.  */
   5010  1.1  mrg       ipa_ref *to_del = caller->find_reference (symbol, NULL, 0, IPA_REF_ADDR);
   5011  1.1  mrg       if (to_del)
   5012  1.1  mrg 	{
   5013  1.1  mrg 	  to_del->remove_reference ();
   5014  1.1  mrg 	  if (dump_file)
   5015  1.1  mrg 	    fprintf (dump_file, "    Removed a reference from %s to %s.\n",
   5016  1.1  mrg 		     cs->caller->dump_name (), symbol->dump_name ());
   5017  1.1  mrg 	  if (ipa_get_param_load_dereferenced (caller_info, fidx))
   5018  1.1  mrg 	    {
   5019  1.1  mrg 	      caller->create_reference (symbol, IPA_REF_LOAD, NULL);
   5020  1.1  mrg 	      if (dump_file)
   5021  1.1  mrg 		fprintf (dump_file,
   5022  1.1  mrg 			 "      ...and replaced it with LOAD one.\n");
   5023  1.1  mrg 	    }
   5024  1.1  mrg 	}
   5025  1.1  mrg     }
   5026  1.1  mrg 
   5027  1.1  mrg   symbol_and_index_together pack;
   5028  1.1  mrg   pack.symbol = symbol;
   5029  1.1  mrg   pack.index = fidx;
   5030  1.1  mrg   if (caller->can_change_signature)
   5031  1.1  mrg     caller->call_for_symbol_thunks_and_aliases (adjust_refs_in_act_callers,
   5032  1.1  mrg 						&pack, true);
   5033  1.1  mrg }
   5034  1.1  mrg 
   5035  1.1  mrg 
   5036  1.1  mrg /* Return true if we would like to remove a parameter from NODE when cloning it
   5037  1.1  mrg    with KNOWN_CSTS scalar constants.  */
   5038  1.1  mrg 
   5039  1.1  mrg static bool
   5040  1.1  mrg want_remove_some_param_p (cgraph_node *node, vec<tree> known_csts)
   5041  1.1  mrg {
   5042  1.1  mrg   auto_vec<bool, 16> surviving;
   5043  1.1  mrg   bool filled_vec = false;
   5044  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   5045  1.1  mrg   int i, count = ipa_get_param_count (info);
   5046  1.1  mrg 
   5047  1.1  mrg   for (i = 0; i < count; i++)
   5048  1.1  mrg     {
   5049  1.1  mrg       if (!known_csts[i] && ipa_is_param_used (info, i))
   5050  1.1  mrg        continue;
   5051  1.1  mrg 
   5052  1.1  mrg       if (!filled_vec)
   5053  1.1  mrg        {
   5054  1.1  mrg 	 clone_info *info = clone_info::get (node);
   5055  1.1  mrg 	 if (!info || !info->param_adjustments)
   5056  1.1  mrg            return true;
   5057  1.1  mrg 	 info->param_adjustments->get_surviving_params (&surviving);
   5058  1.1  mrg          filled_vec = true;
   5059  1.1  mrg        }
   5060  1.1  mrg       if (surviving.length() < (unsigned) i &&  surviving[i])
   5061  1.1  mrg        return true;
   5062  1.1  mrg     }
   5063  1.1  mrg   return false;
   5064  1.1  mrg }
   5065  1.1  mrg 
   5066  1.1  mrg /* Create a specialized version of NODE with known constants in KNOWN_CSTS,
   5067  1.1  mrg    known contexts in KNOWN_CONTEXTS and known aggregate values in AGGVALS and
   5068  1.1  mrg    redirect all edges in CALLERS to it.  */
   5069  1.1  mrg 
   5070  1.1  mrg static struct cgraph_node *
   5071  1.1  mrg create_specialized_node (struct cgraph_node *node,
   5072  1.1  mrg 			 vec<tree> known_csts,
   5073  1.1  mrg 			 vec<ipa_polymorphic_call_context> known_contexts,
   5074  1.1  mrg 			 struct ipa_agg_replacement_value *aggvals,
   5075  1.1  mrg 			 vec<cgraph_edge *> &callers)
   5076  1.1  mrg {
   5077  1.1  mrg   ipa_node_params *new_info, *info = ipa_node_params_sum->get (node);
   5078  1.1  mrg   vec<ipa_replace_map *, va_gc> *replace_trees = NULL;
   5079  1.1  mrg   vec<ipa_adjusted_param, va_gc> *new_params = NULL;
   5080  1.1  mrg   struct ipa_agg_replacement_value *av;
   5081  1.1  mrg   struct cgraph_node *new_node;
   5082  1.1  mrg   int i, count = ipa_get_param_count (info);
   5083  1.1  mrg   clone_info *cinfo = clone_info::get (node);
   5084  1.1  mrg   ipa_param_adjustments *old_adjustments = cinfo
   5085  1.1  mrg 					   ? cinfo->param_adjustments : NULL;
   5086  1.1  mrg   ipa_param_adjustments *new_adjustments;
   5087  1.1  mrg   gcc_assert (!info->ipcp_orig_node);
   5088  1.1  mrg   gcc_assert (node->can_change_signature
   5089  1.1  mrg 	      || !old_adjustments);
   5090  1.1  mrg 
   5091  1.1  mrg   if (old_adjustments)
   5092  1.1  mrg     {
   5093  1.1  mrg       /* At the moment all IPA optimizations should use the number of
   5094  1.1  mrg 	 parameters of the prevailing decl as the m_always_copy_start.
   5095  1.1  mrg 	 Handling any other value would complicate the code below, so for the
   5096  1.1  mrg 	 time bing let's only assert it is so.  */
   5097  1.1  mrg       gcc_assert (old_adjustments->m_always_copy_start == count
   5098  1.1  mrg 		  || old_adjustments->m_always_copy_start < 0);
   5099  1.1  mrg       int old_adj_count = vec_safe_length (old_adjustments->m_adj_params);
   5100  1.1  mrg       for (i = 0; i < old_adj_count; i++)
   5101  1.1  mrg 	{
   5102  1.1  mrg 	  ipa_adjusted_param *old_adj = &(*old_adjustments->m_adj_params)[i];
   5103  1.1  mrg 	  if (!node->can_change_signature
   5104  1.1  mrg 	      || old_adj->op != IPA_PARAM_OP_COPY
   5105  1.1  mrg 	      || (!known_csts[old_adj->base_index]
   5106  1.1  mrg 		  && ipa_is_param_used (info, old_adj->base_index)))
   5107  1.1  mrg 	    {
   5108  1.1  mrg 	      ipa_adjusted_param new_adj = *old_adj;
   5109  1.1  mrg 
   5110  1.1  mrg 	      new_adj.prev_clone_adjustment = true;
   5111  1.1  mrg 	      new_adj.prev_clone_index = i;
   5112  1.1  mrg 	      vec_safe_push (new_params, new_adj);
   5113  1.1  mrg 	    }
   5114  1.1  mrg 	}
   5115  1.1  mrg       bool skip_return = old_adjustments->m_skip_return;
   5116  1.1  mrg       new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
   5117  1.1  mrg 			 ipa_param_adjustments (new_params, count,
   5118  1.1  mrg 						skip_return));
   5119  1.1  mrg     }
   5120  1.1  mrg   else if (node->can_change_signature
   5121  1.1  mrg 	   && want_remove_some_param_p (node, known_csts))
   5122  1.1  mrg     {
   5123  1.1  mrg       ipa_adjusted_param adj;
   5124  1.1  mrg       memset (&adj, 0, sizeof (adj));
   5125  1.1  mrg       adj.op = IPA_PARAM_OP_COPY;
   5126  1.1  mrg       for (i = 0; i < count; i++)
   5127  1.1  mrg 	if (!known_csts[i] && ipa_is_param_used (info, i))
   5128  1.1  mrg 	  {
   5129  1.1  mrg 	    adj.base_index = i;
   5130  1.1  mrg 	    adj.prev_clone_index = i;
   5131  1.1  mrg 	    vec_safe_push (new_params, adj);
   5132  1.1  mrg 	  }
   5133  1.1  mrg       new_adjustments = (new (ggc_alloc <ipa_param_adjustments> ())
   5134  1.1  mrg 			 ipa_param_adjustments (new_params, count, false));
   5135  1.1  mrg     }
   5136  1.1  mrg   else
   5137  1.1  mrg     new_adjustments = NULL;
   5138  1.1  mrg 
   5139  1.1  mrg   auto_vec<cgraph_edge *, 2> self_recursive_calls;
   5140  1.1  mrg   for (i = callers.length () - 1; i >= 0; i--)
   5141  1.1  mrg     {
   5142  1.1  mrg       cgraph_edge *cs = callers[i];
   5143  1.1  mrg       if (cs->caller == node)
   5144  1.1  mrg 	{
   5145  1.1  mrg 	  self_recursive_calls.safe_push (cs);
   5146  1.1  mrg 	  callers.unordered_remove (i);
   5147  1.1  mrg 	}
   5148  1.1  mrg     }
   5149  1.1  mrg   replace_trees = cinfo ? vec_safe_copy (cinfo->tree_map) : NULL;
   5150  1.1  mrg   for (i = 0; i < count; i++)
   5151  1.1  mrg     {
   5152  1.1  mrg       tree t = known_csts[i];
   5153  1.1  mrg       if (!t)
   5154  1.1  mrg 	continue;
   5155  1.1  mrg 
   5156  1.1  mrg       gcc_checking_assert (TREE_CODE (t) != TREE_BINFO);
   5157  1.1  mrg 
   5158  1.1  mrg       bool load_ref = false;
   5159  1.1  mrg       symtab_node *ref_symbol;
   5160  1.1  mrg       if (TREE_CODE (t) == ADDR_EXPR)
   5161  1.1  mrg 	{
   5162  1.1  mrg 	  tree base = get_base_address (TREE_OPERAND (t, 0));
   5163  1.1  mrg 	  if (TREE_CODE (base) == VAR_DECL
   5164  1.1  mrg 	      && ipa_get_controlled_uses (info, i) == 0
   5165  1.1  mrg 	      && ipa_get_param_load_dereferenced (info, i)
   5166  1.1  mrg 	      && (ref_symbol = symtab_node::get (base)))
   5167  1.1  mrg 	    {
   5168  1.1  mrg 	      load_ref = true;
   5169  1.1  mrg 	      if (node->can_change_signature)
   5170  1.1  mrg 		for (cgraph_edge *caller : callers)
   5171  1.1  mrg 		  adjust_references_in_caller (caller, ref_symbol, i);
   5172  1.1  mrg 	    }
   5173  1.1  mrg 	}
   5174  1.1  mrg 
   5175  1.1  mrg       ipa_replace_map *replace_map = get_replacement_map (info, t, i, load_ref);
   5176  1.1  mrg       if (replace_map)
   5177  1.1  mrg 	vec_safe_push (replace_trees, replace_map);
   5178  1.1  mrg     }
   5179  1.1  mrg 
   5180  1.1  mrg   unsigned &suffix_counter = clone_num_suffixes->get_or_insert (
   5181  1.1  mrg 			       IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (
   5182  1.1  mrg 				 node->decl)));
   5183  1.1  mrg   new_node = node->create_virtual_clone (callers, replace_trees,
   5184  1.1  mrg 					 new_adjustments, "constprop",
   5185  1.1  mrg 					 suffix_counter);
   5186  1.1  mrg   suffix_counter++;
   5187  1.1  mrg 
   5188  1.1  mrg   bool have_self_recursive_calls = !self_recursive_calls.is_empty ();
   5189  1.1  mrg   for (unsigned j = 0; j < self_recursive_calls.length (); j++)
   5190  1.1  mrg     {
   5191  1.1  mrg       cgraph_edge *cs = get_next_cgraph_edge_clone (self_recursive_calls[j]);
   5192  1.1  mrg       /* Cloned edges can disappear during cloning as speculation can be
   5193  1.1  mrg 	 resolved, check that we have one and that it comes from the last
   5194  1.1  mrg 	 cloning.  */
   5195  1.1  mrg       if (cs && cs->caller == new_node)
   5196  1.1  mrg 	cs->redirect_callee_duplicating_thunks (new_node);
   5197  1.1  mrg       /* Any future code that would make more than one clone of an outgoing
   5198  1.1  mrg 	 edge would confuse this mechanism, so let's check that does not
   5199  1.1  mrg 	 happen.  */
   5200  1.1  mrg       gcc_checking_assert (!cs
   5201  1.1  mrg 			   || !get_next_cgraph_edge_clone (cs)
   5202  1.1  mrg 			   || get_next_cgraph_edge_clone (cs)->caller != new_node);
   5203  1.1  mrg     }
   5204  1.1  mrg   if (have_self_recursive_calls)
   5205  1.1  mrg     new_node->expand_all_artificial_thunks ();
   5206  1.1  mrg 
   5207  1.1  mrg   ipa_set_node_agg_value_chain (new_node, aggvals);
   5208  1.1  mrg   for (av = aggvals; av; av = av->next)
   5209  1.1  mrg     new_node->maybe_create_reference (av->value, NULL);
   5210  1.1  mrg 
   5211  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   5212  1.1  mrg     {
   5213  1.1  mrg       fprintf (dump_file, "     the new node is %s.\n", new_node->dump_name ());
   5214  1.1  mrg       if (known_contexts.exists ())
   5215  1.1  mrg 	{
   5216  1.1  mrg 	  for (i = 0; i < count; i++)
   5217  1.1  mrg 	    if (!known_contexts[i].useless_p ())
   5218  1.1  mrg 	      {
   5219  1.1  mrg 		fprintf (dump_file, "     known ctx %i is ", i);
   5220  1.1  mrg 		known_contexts[i].dump (dump_file);
   5221  1.1  mrg 	      }
   5222  1.1  mrg 	}
   5223  1.1  mrg       if (aggvals)
   5224  1.1  mrg 	ipa_dump_agg_replacement_values (dump_file, aggvals);
   5225  1.1  mrg     }
   5226  1.1  mrg 
   5227  1.1  mrg   new_info = ipa_node_params_sum->get (new_node);
   5228  1.1  mrg   new_info->ipcp_orig_node = node;
   5229  1.1  mrg   new_node->ipcp_clone = true;
   5230  1.1  mrg   new_info->known_csts = known_csts;
   5231  1.1  mrg   new_info->known_contexts = known_contexts;
   5232  1.1  mrg 
   5233  1.1  mrg   ipcp_discover_new_direct_edges (new_node, known_csts, known_contexts, aggvals);
   5234  1.1  mrg 
   5235  1.1  mrg   return new_node;
   5236  1.1  mrg }
   5237  1.1  mrg 
   5238  1.1  mrg /* Return true if JFUNC, which describes a i-th parameter of call CS, is a
   5239  1.1  mrg    pass-through function to itself when the cgraph_node involved is not an
   5240  1.1  mrg    IPA-CP clone.  When SIMPLE is true, further check if JFUNC is a simple
   5241  1.1  mrg    no-operation pass-through.  */
   5242  1.1  mrg 
   5243  1.1  mrg static bool
   5244  1.1  mrg self_recursive_pass_through_p (cgraph_edge *cs, ipa_jump_func *jfunc, int i,
   5245  1.1  mrg 			       bool simple = true)
   5246  1.1  mrg {
   5247  1.1  mrg   enum availability availability;
   5248  1.1  mrg   if (cs->caller == cs->callee->function_symbol (&availability)
   5249  1.1  mrg       && availability > AVAIL_INTERPOSABLE
   5250  1.1  mrg       && jfunc->type == IPA_JF_PASS_THROUGH
   5251  1.1  mrg       && (!simple || ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
   5252  1.1  mrg       && ipa_get_jf_pass_through_formal_id (jfunc) == i
   5253  1.1  mrg       && ipa_node_params_sum->get (cs->caller)
   5254  1.1  mrg       && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node)
   5255  1.1  mrg     return true;
   5256  1.1  mrg   return false;
   5257  1.1  mrg }
   5258  1.1  mrg 
   5259  1.1  mrg /* Return true if JFUNC, which describes a part of an aggregate represented or
   5260  1.1  mrg    pointed to by the i-th parameter of call CS, is a pass-through function to
   5261  1.1  mrg    itself when the cgraph_node involved is not an IPA-CP clone..  When
   5262  1.1  mrg    SIMPLE is true, further check if JFUNC is a simple no-operation
   5263  1.1  mrg    pass-through.  */
   5264  1.1  mrg 
   5265  1.1  mrg static bool
   5266  1.1  mrg self_recursive_agg_pass_through_p (cgraph_edge *cs, ipa_agg_jf_item *jfunc,
   5267  1.1  mrg 				   int i, bool simple = true)
   5268  1.1  mrg {
   5269  1.1  mrg   enum availability availability;
   5270  1.1  mrg   if (cs->caller == cs->callee->function_symbol (&availability)
   5271  1.1  mrg       && availability > AVAIL_INTERPOSABLE
   5272  1.1  mrg       && jfunc->jftype == IPA_JF_LOAD_AGG
   5273  1.1  mrg       && jfunc->offset == jfunc->value.load_agg.offset
   5274  1.1  mrg       && (!simple || jfunc->value.pass_through.operation == NOP_EXPR)
   5275  1.1  mrg       && jfunc->value.pass_through.formal_id == i
   5276  1.1  mrg       && useless_type_conversion_p (jfunc->value.load_agg.type, jfunc->type)
   5277  1.1  mrg       && ipa_node_params_sum->get (cs->caller)
   5278  1.1  mrg       && !ipa_node_params_sum->get (cs->caller)->ipcp_orig_node)
   5279  1.1  mrg     return true;
   5280  1.1  mrg   return false;
   5281  1.1  mrg }
   5282  1.1  mrg 
   5283  1.1  mrg /* Given a NODE, and a subset of its CALLERS, try to populate blanks slots in
   5284  1.1  mrg    KNOWN_CSTS with constants that are also known for all of the CALLERS.  */
   5285  1.1  mrg 
   5286  1.1  mrg static void
   5287  1.1  mrg find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
   5288  1.1  mrg 					    vec<tree> &known_csts,
   5289  1.1  mrg 					    const vec<cgraph_edge *> &callers)
   5290  1.1  mrg {
   5291  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   5292  1.1  mrg   int i, count = ipa_get_param_count (info);
   5293  1.1  mrg 
   5294  1.1  mrg   for (i = 0; i < count; i++)
   5295  1.1  mrg     {
   5296  1.1  mrg       struct cgraph_edge *cs;
   5297  1.1  mrg       tree newval = NULL_TREE;
   5298  1.1  mrg       int j;
   5299  1.1  mrg       bool first = true;
   5300  1.1  mrg       tree type = ipa_get_type (info, i);
   5301  1.1  mrg 
   5302  1.1  mrg       if (ipa_get_scalar_lat (info, i)->bottom || known_csts[i])
   5303  1.1  mrg 	continue;
   5304  1.1  mrg 
   5305  1.1  mrg       FOR_EACH_VEC_ELT (callers, j, cs)
   5306  1.1  mrg 	{
   5307  1.1  mrg 	  struct ipa_jump_func *jump_func;
   5308  1.1  mrg 	  tree t;
   5309  1.1  mrg 
   5310  1.1  mrg 	  ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   5311  1.1  mrg 	  if (!args
   5312  1.1  mrg 	      || i >= ipa_get_cs_argument_count (args)
   5313  1.1  mrg 	      || (i == 0
   5314  1.1  mrg 		  && call_passes_through_thunk (cs)))
   5315  1.1  mrg 	    {
   5316  1.1  mrg 	      newval = NULL_TREE;
   5317  1.1  mrg 	      break;
   5318  1.1  mrg 	    }
   5319  1.1  mrg 	  jump_func = ipa_get_ith_jump_func (args, i);
   5320  1.1  mrg 
   5321  1.1  mrg 	  /* Besides simple pass-through jump function, arithmetic jump
   5322  1.1  mrg 	     function could also introduce argument-direct-pass-through for
   5323  1.1  mrg 	     self-feeding recursive call.  For example,
   5324  1.1  mrg 
   5325  1.1  mrg 	        fn (int i)
   5326  1.1  mrg 	        {
   5327  1.1  mrg 	          fn (i & 1);
   5328  1.1  mrg 	        }
   5329  1.1  mrg 
   5330  1.1  mrg 	     Given that i is 0, recursive propagation via (i & 1) also gets
   5331  1.1  mrg 	     0.  */
   5332  1.1  mrg 	  if (self_recursive_pass_through_p (cs, jump_func, i, false))
   5333  1.1  mrg 	    {
   5334  1.1  mrg 	      gcc_assert (newval);
   5335  1.1  mrg 	      t = ipa_get_jf_arith_result (
   5336  1.1  mrg 				ipa_get_jf_pass_through_operation (jump_func),
   5337  1.1  mrg 				newval,
   5338  1.1  mrg 				ipa_get_jf_pass_through_operand (jump_func),
   5339  1.1  mrg 				type);
   5340  1.1  mrg 	    }
   5341  1.1  mrg 	  else
   5342  1.1  mrg 	    t = ipa_value_from_jfunc (ipa_node_params_sum->get (cs->caller),
   5343  1.1  mrg 				      jump_func, type);
   5344  1.1  mrg 	  if (!t
   5345  1.1  mrg 	      || (newval
   5346  1.1  mrg 		  && !values_equal_for_ipcp_p (t, newval))
   5347  1.1  mrg 	      || (!first && !newval))
   5348  1.1  mrg 	    {
   5349  1.1  mrg 	      newval = NULL_TREE;
   5350  1.1  mrg 	      break;
   5351  1.1  mrg 	    }
   5352  1.1  mrg 	  else
   5353  1.1  mrg 	    newval = t;
   5354  1.1  mrg 	  first = false;
   5355  1.1  mrg 	}
   5356  1.1  mrg 
   5357  1.1  mrg       if (newval)
   5358  1.1  mrg 	{
   5359  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   5360  1.1  mrg 	    {
   5361  1.1  mrg 	      fprintf (dump_file, "    adding an extra known scalar value ");
   5362  1.1  mrg 	      print_ipcp_constant_value (dump_file, newval);
   5363  1.1  mrg 	      fprintf (dump_file, " for ");
   5364  1.1  mrg 	      ipa_dump_param (dump_file, info, i);
   5365  1.1  mrg 	      fprintf (dump_file, "\n");
   5366  1.1  mrg 	    }
   5367  1.1  mrg 
   5368  1.1  mrg 	  known_csts[i] = newval;
   5369  1.1  mrg 	}
   5370  1.1  mrg     }
   5371  1.1  mrg }
   5372  1.1  mrg 
   5373  1.1  mrg /* Given a NODE and a subset of its CALLERS, try to populate plank slots in
   5374  1.1  mrg    KNOWN_CONTEXTS with polymorphic contexts that are also known for all of the
   5375  1.1  mrg    CALLERS.  */
   5376  1.1  mrg 
   5377  1.1  mrg static void
   5378  1.1  mrg find_more_contexts_for_caller_subset (cgraph_node *node,
   5379  1.1  mrg 				      vec<ipa_polymorphic_call_context>
   5380  1.1  mrg 				      *known_contexts,
   5381  1.1  mrg 				      const vec<cgraph_edge *> &callers)
   5382  1.1  mrg {
   5383  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   5384  1.1  mrg   int i, count = ipa_get_param_count (info);
   5385  1.1  mrg 
   5386  1.1  mrg   for (i = 0; i < count; i++)
   5387  1.1  mrg     {
   5388  1.1  mrg       cgraph_edge *cs;
   5389  1.1  mrg 
   5390  1.1  mrg       if (ipa_get_poly_ctx_lat (info, i)->bottom
   5391  1.1  mrg 	  || (known_contexts->exists ()
   5392  1.1  mrg 	      && !(*known_contexts)[i].useless_p ()))
   5393  1.1  mrg 	continue;
   5394  1.1  mrg 
   5395  1.1  mrg       ipa_polymorphic_call_context newval;
   5396  1.1  mrg       bool first = true;
   5397  1.1  mrg       int j;
   5398  1.1  mrg 
   5399  1.1  mrg       FOR_EACH_VEC_ELT (callers, j, cs)
   5400  1.1  mrg 	{
   5401  1.1  mrg 	  ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   5402  1.1  mrg 	  if (!args
   5403  1.1  mrg 	      || i >= ipa_get_cs_argument_count (args))
   5404  1.1  mrg 	    return;
   5405  1.1  mrg 	  ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, i);
   5406  1.1  mrg 	  ipa_polymorphic_call_context ctx;
   5407  1.1  mrg 	  ctx = ipa_context_from_jfunc (ipa_node_params_sum->get (cs->caller),
   5408  1.1  mrg 					cs, i, jfunc);
   5409  1.1  mrg 	  if (first)
   5410  1.1  mrg 	    {
   5411  1.1  mrg 	      newval = ctx;
   5412  1.1  mrg 	      first = false;
   5413  1.1  mrg 	    }
   5414  1.1  mrg 	  else
   5415  1.1  mrg 	    newval.meet_with (ctx);
   5416  1.1  mrg 	  if (newval.useless_p ())
   5417  1.1  mrg 	    break;
   5418  1.1  mrg 	}
   5419  1.1  mrg 
   5420  1.1  mrg       if (!newval.useless_p ())
   5421  1.1  mrg 	{
   5422  1.1  mrg 	  if (dump_file && (dump_flags & TDF_DETAILS))
   5423  1.1  mrg 	    {
   5424  1.1  mrg 	      fprintf (dump_file, "    adding an extra known polymorphic "
   5425  1.1  mrg 		       "context ");
   5426  1.1  mrg 	      print_ipcp_constant_value (dump_file, newval);
   5427  1.1  mrg 	      fprintf (dump_file, " for ");
   5428  1.1  mrg 	      ipa_dump_param (dump_file, info, i);
   5429  1.1  mrg 	      fprintf (dump_file, "\n");
   5430  1.1  mrg 	    }
   5431  1.1  mrg 
   5432  1.1  mrg 	  if (!known_contexts->exists ())
   5433  1.1  mrg 	    known_contexts->safe_grow_cleared (ipa_get_param_count (info),
   5434  1.1  mrg 					       true);
   5435  1.1  mrg 	  (*known_contexts)[i] = newval;
   5436  1.1  mrg 	}
   5437  1.1  mrg 
   5438  1.1  mrg     }
   5439  1.1  mrg }
   5440  1.1  mrg 
   5441  1.1  mrg /* Go through PLATS and create a vector of values consisting of values and
   5442  1.1  mrg    offsets (minus OFFSET) of lattices that contain only a single value.  */
   5443  1.1  mrg 
   5444  1.1  mrg static vec<ipa_agg_value>
   5445  1.1  mrg copy_plats_to_inter (class ipcp_param_lattices *plats, HOST_WIDE_INT offset)
   5446  1.1  mrg {
   5447  1.1  mrg   vec<ipa_agg_value> res = vNULL;
   5448  1.1  mrg 
   5449  1.1  mrg   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
   5450  1.1  mrg     return vNULL;
   5451  1.1  mrg 
   5452  1.1  mrg   for (struct ipcp_agg_lattice *aglat = plats->aggs; aglat; aglat = aglat->next)
   5453  1.1  mrg     if (aglat->is_single_const ())
   5454  1.1  mrg       {
   5455  1.1  mrg 	struct ipa_agg_value ti;
   5456  1.1  mrg 	ti.offset = aglat->offset - offset;
   5457  1.1  mrg 	ti.value = aglat->values->value;
   5458  1.1  mrg 	res.safe_push (ti);
   5459  1.1  mrg       }
   5460  1.1  mrg   return res;
   5461  1.1  mrg }
   5462  1.1  mrg 
   5463  1.1  mrg /* Intersect all values in INTER with single value lattices in PLATS (while
   5464  1.1  mrg    subtracting OFFSET).  */
   5465  1.1  mrg 
   5466  1.1  mrg static void
   5467  1.1  mrg intersect_with_plats (class ipcp_param_lattices *plats,
   5468  1.1  mrg 		      vec<ipa_agg_value> *inter,
   5469  1.1  mrg 		      HOST_WIDE_INT offset)
   5470  1.1  mrg {
   5471  1.1  mrg   struct ipcp_agg_lattice *aglat;
   5472  1.1  mrg   struct ipa_agg_value *item;
   5473  1.1  mrg   int k;
   5474  1.1  mrg 
   5475  1.1  mrg   if (!plats->aggs || plats->aggs_contain_variable || plats->aggs_bottom)
   5476  1.1  mrg     {
   5477  1.1  mrg       inter->release ();
   5478  1.1  mrg       return;
   5479  1.1  mrg     }
   5480  1.1  mrg 
   5481  1.1  mrg   aglat = plats->aggs;
   5482  1.1  mrg   FOR_EACH_VEC_ELT (*inter, k, item)
   5483  1.1  mrg     {
   5484  1.1  mrg       bool found = false;
   5485  1.1  mrg       if (!item->value)
   5486  1.1  mrg 	continue;
   5487  1.1  mrg       while (aglat)
   5488  1.1  mrg 	{
   5489  1.1  mrg 	  if (aglat->offset - offset > item->offset)
   5490  1.1  mrg 	    break;
   5491  1.1  mrg 	  if (aglat->offset - offset == item->offset)
   5492  1.1  mrg 	    {
   5493  1.1  mrg 	      if (aglat->is_single_const ())
   5494  1.1  mrg 		{
   5495  1.1  mrg 		  tree value = aglat->values->value;
   5496  1.1  mrg 
   5497  1.1  mrg 		  if (values_equal_for_ipcp_p (item->value, value))
   5498  1.1  mrg 		    found = true;
   5499  1.1  mrg 		}
   5500  1.1  mrg 	      break;
   5501  1.1  mrg 	    }
   5502  1.1  mrg 	  aglat = aglat->next;
   5503  1.1  mrg 	}
   5504  1.1  mrg       if (!found)
   5505  1.1  mrg 	item->value = NULL_TREE;
   5506  1.1  mrg     }
   5507  1.1  mrg }
   5508  1.1  mrg 
   5509  1.1  mrg /* Copy aggregate replacement values of NODE (which is an IPA-CP clone) to the
   5510  1.1  mrg    vector result while subtracting OFFSET from the individual value offsets.  */
   5511  1.1  mrg 
   5512  1.1  mrg static vec<ipa_agg_value>
   5513  1.1  mrg agg_replacements_to_vector (struct cgraph_node *node, int index,
   5514  1.1  mrg 			    HOST_WIDE_INT offset)
   5515  1.1  mrg {
   5516  1.1  mrg   struct ipa_agg_replacement_value *av;
   5517  1.1  mrg   vec<ipa_agg_value> res = vNULL;
   5518  1.1  mrg 
   5519  1.1  mrg   for (av = ipa_get_agg_replacements_for_node (node); av; av = av->next)
   5520  1.1  mrg     if (av->index == index
   5521  1.1  mrg 	&& (av->offset - offset) >= 0)
   5522  1.1  mrg     {
   5523  1.1  mrg       struct ipa_agg_value item;
   5524  1.1  mrg       gcc_checking_assert (av->value);
   5525  1.1  mrg       item.offset = av->offset - offset;
   5526  1.1  mrg       item.value = av->value;
   5527  1.1  mrg       res.safe_push (item);
   5528  1.1  mrg     }
   5529  1.1  mrg 
   5530  1.1  mrg   return res;
   5531  1.1  mrg }
   5532  1.1  mrg 
   5533  1.1  mrg /* Intersect all values in INTER with those that we have already scheduled to
   5534  1.1  mrg    be replaced in parameter number INDEX of NODE, which is an IPA-CP clone
   5535  1.1  mrg    (while subtracting OFFSET).  */
   5536  1.1  mrg 
   5537  1.1  mrg static void
   5538  1.1  mrg intersect_with_agg_replacements (struct cgraph_node *node, int index,
   5539  1.1  mrg 				 vec<ipa_agg_value> *inter,
   5540  1.1  mrg 				 HOST_WIDE_INT offset)
   5541  1.1  mrg {
   5542  1.1  mrg   struct ipa_agg_replacement_value *srcvals;
   5543  1.1  mrg   struct ipa_agg_value *item;
   5544  1.1  mrg   int i;
   5545  1.1  mrg 
   5546  1.1  mrg   srcvals = ipa_get_agg_replacements_for_node (node);
   5547  1.1  mrg   if (!srcvals)
   5548  1.1  mrg     {
   5549  1.1  mrg       inter->release ();
   5550  1.1  mrg       return;
   5551  1.1  mrg     }
   5552  1.1  mrg 
   5553  1.1  mrg   FOR_EACH_VEC_ELT (*inter, i, item)
   5554  1.1  mrg     {
   5555  1.1  mrg       struct ipa_agg_replacement_value *av;
   5556  1.1  mrg       bool found = false;
   5557  1.1  mrg       if (!item->value)
   5558  1.1  mrg 	continue;
   5559  1.1  mrg       for (av = srcvals; av; av = av->next)
   5560  1.1  mrg 	{
   5561  1.1  mrg 	  gcc_checking_assert (av->value);
   5562  1.1  mrg 	  if (av->index == index
   5563  1.1  mrg 	      && av->offset - offset == item->offset)
   5564  1.1  mrg 	    {
   5565  1.1  mrg 	      if (values_equal_for_ipcp_p (item->value, av->value))
   5566  1.1  mrg 		found = true;
   5567  1.1  mrg 	      break;
   5568  1.1  mrg 	    }
   5569  1.1  mrg 	}
   5570  1.1  mrg       if (!found)
   5571  1.1  mrg 	item->value = NULL_TREE;
   5572  1.1  mrg     }
   5573  1.1  mrg }
   5574  1.1  mrg 
   5575  1.1  mrg /* Intersect values in INTER with aggregate values that come along edge CS to
   5576  1.1  mrg    parameter number INDEX and return it.  If INTER does not actually exist yet,
   5577  1.1  mrg    copy all incoming values to it.  If we determine we ended up with no values
   5578  1.1  mrg    whatsoever, return a released vector.  */
   5579  1.1  mrg 
   5580  1.1  mrg static vec<ipa_agg_value>
   5581  1.1  mrg intersect_aggregates_with_edge (struct cgraph_edge *cs, int index,
   5582  1.1  mrg 				vec<ipa_agg_value> inter)
   5583  1.1  mrg {
   5584  1.1  mrg   struct ipa_jump_func *jfunc;
   5585  1.1  mrg   jfunc = ipa_get_ith_jump_func (ipa_edge_args_sum->get (cs), index);
   5586  1.1  mrg   if (jfunc->type == IPA_JF_PASS_THROUGH
   5587  1.1  mrg       && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
   5588  1.1  mrg     {
   5589  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   5590  1.1  mrg       int src_idx = ipa_get_jf_pass_through_formal_id (jfunc);
   5591  1.1  mrg 
   5592  1.1  mrg       if (caller_info->ipcp_orig_node)
   5593  1.1  mrg 	{
   5594  1.1  mrg 	  struct cgraph_node *orig_node = caller_info->ipcp_orig_node;
   5595  1.1  mrg 	  class ipcp_param_lattices *orig_plats;
   5596  1.1  mrg 	  ipa_node_params *orig_info = ipa_node_params_sum->get (orig_node);
   5597  1.1  mrg 	  orig_plats = ipa_get_parm_lattices (orig_info, src_idx);
   5598  1.1  mrg 	  if (agg_pass_through_permissible_p (orig_plats, jfunc))
   5599  1.1  mrg 	    {
   5600  1.1  mrg 	      if (!inter.exists ())
   5601  1.1  mrg 		inter = agg_replacements_to_vector (cs->caller, src_idx, 0);
   5602  1.1  mrg 	      else
   5603  1.1  mrg 		intersect_with_agg_replacements (cs->caller, src_idx,
   5604  1.1  mrg 						 &inter, 0);
   5605  1.1  mrg 	      return inter;
   5606  1.1  mrg 	    }
   5607  1.1  mrg 	}
   5608  1.1  mrg       else
   5609  1.1  mrg 	{
   5610  1.1  mrg 	  class ipcp_param_lattices *src_plats;
   5611  1.1  mrg 	  src_plats = ipa_get_parm_lattices (caller_info, src_idx);
   5612  1.1  mrg 	  if (agg_pass_through_permissible_p (src_plats, jfunc))
   5613  1.1  mrg 	    {
   5614  1.1  mrg 	      /* Currently we do not produce clobber aggregate jump
   5615  1.1  mrg 		 functions, adjust when we do.  */
   5616  1.1  mrg 	      gcc_checking_assert (!jfunc->agg.items);
   5617  1.1  mrg 	      if (!inter.exists ())
   5618  1.1  mrg 		inter = copy_plats_to_inter (src_plats, 0);
   5619  1.1  mrg 	      else
   5620  1.1  mrg 		intersect_with_plats (src_plats, &inter, 0);
   5621  1.1  mrg 	      return inter;
   5622  1.1  mrg 	    }
   5623  1.1  mrg 	}
   5624  1.1  mrg     }
   5625  1.1  mrg   else if (jfunc->type == IPA_JF_ANCESTOR
   5626  1.1  mrg 	   && ipa_get_jf_ancestor_agg_preserved (jfunc))
   5627  1.1  mrg     {
   5628  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   5629  1.1  mrg       int src_idx = ipa_get_jf_ancestor_formal_id (jfunc);
   5630  1.1  mrg       class ipcp_param_lattices *src_plats;
   5631  1.1  mrg       HOST_WIDE_INT delta = ipa_get_jf_ancestor_offset (jfunc);
   5632  1.1  mrg 
   5633  1.1  mrg       if (caller_info->ipcp_orig_node)
   5634  1.1  mrg 	{
   5635  1.1  mrg 	  if (!inter.exists ())
   5636  1.1  mrg 	    inter = agg_replacements_to_vector (cs->caller, src_idx, delta);
   5637  1.1  mrg 	  else
   5638  1.1  mrg 	    intersect_with_agg_replacements (cs->caller, src_idx, &inter,
   5639  1.1  mrg 					     delta);
   5640  1.1  mrg 	}
   5641  1.1  mrg       else
   5642  1.1  mrg 	{
   5643  1.1  mrg 	  src_plats = ipa_get_parm_lattices (caller_info, src_idx);
   5644  1.1  mrg 	  /* Currently we do not produce clobber aggregate jump
   5645  1.1  mrg 	     functions, adjust when we do.  */
   5646  1.1  mrg 	  gcc_checking_assert (!src_plats->aggs || !jfunc->agg.items);
   5647  1.1  mrg 	  if (!inter.exists ())
   5648  1.1  mrg 	    inter = copy_plats_to_inter (src_plats, delta);
   5649  1.1  mrg 	  else
   5650  1.1  mrg 	    intersect_with_plats (src_plats, &inter, delta);
   5651  1.1  mrg 	}
   5652  1.1  mrg       return inter;
   5653  1.1  mrg     }
   5654  1.1  mrg 
   5655  1.1  mrg   if (jfunc->agg.items)
   5656  1.1  mrg     {
   5657  1.1  mrg       ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   5658  1.1  mrg       struct ipa_agg_value *item;
   5659  1.1  mrg       int k;
   5660  1.1  mrg 
   5661  1.1  mrg       if (!inter.exists ())
   5662  1.1  mrg 	for (unsigned i = 0; i < jfunc->agg.items->length (); i++)
   5663  1.1  mrg 	  {
   5664  1.1  mrg 	    struct ipa_agg_jf_item *agg_item = &(*jfunc->agg.items)[i];
   5665  1.1  mrg 	    tree value = ipa_agg_value_from_node (caller_info, cs->caller,
   5666  1.1  mrg 						  agg_item);
   5667  1.1  mrg 	    if (value)
   5668  1.1  mrg 	      {
   5669  1.1  mrg 		struct ipa_agg_value agg_value;
   5670  1.1  mrg 
   5671  1.1  mrg 		agg_value.value = value;
   5672  1.1  mrg 		agg_value.offset = agg_item->offset;
   5673  1.1  mrg 		inter.safe_push (agg_value);
   5674  1.1  mrg 	      }
   5675  1.1  mrg 	  }
   5676  1.1  mrg       else
   5677  1.1  mrg 	FOR_EACH_VEC_ELT (inter, k, item)
   5678  1.1  mrg 	  {
   5679  1.1  mrg 	    int l = 0;
   5680  1.1  mrg 	    bool found = false;
   5681  1.1  mrg 
   5682  1.1  mrg 	    if (!item->value)
   5683  1.1  mrg 	      continue;
   5684  1.1  mrg 
   5685  1.1  mrg 	    while ((unsigned) l < jfunc->agg.items->length ())
   5686  1.1  mrg 	      {
   5687  1.1  mrg 		struct ipa_agg_jf_item *ti;
   5688  1.1  mrg 		ti = &(*jfunc->agg.items)[l];
   5689  1.1  mrg 		if (ti->offset > item->offset)
   5690  1.1  mrg 		  break;
   5691  1.1  mrg 		if (ti->offset == item->offset)
   5692  1.1  mrg 		  {
   5693  1.1  mrg 		    tree value;
   5694  1.1  mrg 
   5695  1.1  mrg 		    /* Besides simple pass-through aggregate jump function,
   5696  1.1  mrg 		       arithmetic aggregate jump function could also bring
   5697  1.1  mrg 		       same aggregate value as parameter passed-in for
   5698  1.1  mrg 		       self-feeding recursive call.  For example,
   5699  1.1  mrg 
   5700  1.1  mrg 		         fn (int *i)
   5701  1.1  mrg 		           {
   5702  1.1  mrg 		             int j = *i & 1;
   5703  1.1  mrg 		             fn (&j);
   5704  1.1  mrg 		           }
   5705  1.1  mrg 
   5706  1.1  mrg 		       Given that *i is 0, recursive propagation via (*i & 1)
   5707  1.1  mrg 		       also gets 0.  */
   5708  1.1  mrg 		    if (self_recursive_agg_pass_through_p (cs, ti, index,
   5709  1.1  mrg 							   false))
   5710  1.1  mrg 		      value = ipa_get_jf_arith_result (
   5711  1.1  mrg 					ti->value.pass_through.operation,
   5712  1.1  mrg 					item->value,
   5713  1.1  mrg 					ti->value.pass_through.operand,
   5714  1.1  mrg 					ti->type);
   5715  1.1  mrg 		    else
   5716  1.1  mrg 		      value = ipa_agg_value_from_node (caller_info,
   5717  1.1  mrg 						       cs->caller, ti);
   5718  1.1  mrg 
   5719  1.1  mrg 		    if (value && values_equal_for_ipcp_p (item->value, value))
   5720  1.1  mrg 		      found = true;
   5721  1.1  mrg 		    break;
   5722  1.1  mrg 		  }
   5723  1.1  mrg 		l++;
   5724  1.1  mrg 	      }
   5725  1.1  mrg 	    if (!found)
   5726  1.1  mrg 	      item->value = NULL;
   5727  1.1  mrg 	  }
   5728  1.1  mrg     }
   5729  1.1  mrg   else
   5730  1.1  mrg     {
   5731  1.1  mrg       inter.release ();
   5732  1.1  mrg       return vNULL;
   5733  1.1  mrg     }
   5734  1.1  mrg   return inter;
   5735  1.1  mrg }
   5736  1.1  mrg 
   5737  1.1  mrg /* Look at edges in CALLERS and collect all known aggregate values that arrive
   5738  1.1  mrg    from all of them.  */
   5739  1.1  mrg 
   5740  1.1  mrg static struct ipa_agg_replacement_value *
   5741  1.1  mrg find_aggregate_values_for_callers_subset (struct cgraph_node *node,
   5742  1.1  mrg 					  const vec<cgraph_edge *> &callers)
   5743  1.1  mrg {
   5744  1.1  mrg   ipa_node_params *dest_info = ipa_node_params_sum->get (node);
   5745  1.1  mrg   struct ipa_agg_replacement_value *res;
   5746  1.1  mrg   struct ipa_agg_replacement_value **tail = &res;
   5747  1.1  mrg   struct cgraph_edge *cs;
   5748  1.1  mrg   int i, j, count = ipa_get_param_count (dest_info);
   5749  1.1  mrg 
   5750  1.1  mrg   FOR_EACH_VEC_ELT (callers, j, cs)
   5751  1.1  mrg     {
   5752  1.1  mrg       ipa_edge_args *args = ipa_edge_args_sum->get (cs);
   5753  1.1  mrg       if (!args)
   5754  1.1  mrg 	{
   5755  1.1  mrg 	  count = 0;
   5756  1.1  mrg 	  break;
   5757  1.1  mrg 	}
   5758  1.1  mrg       int c = ipa_get_cs_argument_count (args);
   5759  1.1  mrg       if (c < count)
   5760  1.1  mrg 	count = c;
   5761  1.1  mrg     }
   5762  1.1  mrg 
   5763  1.1  mrg   for (i = 0; i < count; i++)
   5764  1.1  mrg     {
   5765  1.1  mrg       struct cgraph_edge *cs;
   5766  1.1  mrg       vec<ipa_agg_value> inter = vNULL;
   5767  1.1  mrg       struct ipa_agg_value *item;
   5768  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (dest_info, i);
   5769  1.1  mrg       int j;
   5770  1.1  mrg 
   5771  1.1  mrg       /* Among other things, the following check should deal with all by_ref
   5772  1.1  mrg 	 mismatches.  */
   5773  1.1  mrg       if (plats->aggs_bottom)
   5774  1.1  mrg 	continue;
   5775  1.1  mrg 
   5776  1.1  mrg       FOR_EACH_VEC_ELT (callers, j, cs)
   5777  1.1  mrg 	{
   5778  1.1  mrg 	  struct ipa_jump_func *jfunc
   5779  1.1  mrg 	    = ipa_get_ith_jump_func (ipa_edge_args_sum->get (cs), i);
   5780  1.1  mrg 	  if (self_recursive_pass_through_p (cs, jfunc, i)
   5781  1.1  mrg 	      && (!plats->aggs_by_ref
   5782  1.1  mrg 		  || ipa_get_jf_pass_through_agg_preserved (jfunc)))
   5783  1.1  mrg 	    continue;
   5784  1.1  mrg 	  inter = intersect_aggregates_with_edge (cs, i, inter);
   5785  1.1  mrg 
   5786  1.1  mrg 	  if (!inter.exists ())
   5787  1.1  mrg 	    goto next_param;
   5788  1.1  mrg 	}
   5789  1.1  mrg 
   5790  1.1  mrg       FOR_EACH_VEC_ELT (inter, j, item)
   5791  1.1  mrg 	{
   5792  1.1  mrg 	  struct ipa_agg_replacement_value *v;
   5793  1.1  mrg 
   5794  1.1  mrg 	  if (!item->value)
   5795  1.1  mrg 	    continue;
   5796  1.1  mrg 
   5797  1.1  mrg 	  v = ggc_alloc<ipa_agg_replacement_value> ();
   5798  1.1  mrg 	  v->index = i;
   5799  1.1  mrg 	  v->offset = item->offset;
   5800  1.1  mrg 	  v->value = item->value;
   5801  1.1  mrg 	  v->by_ref = plats->aggs_by_ref;
   5802  1.1  mrg 	  *tail = v;
   5803  1.1  mrg 	  tail = &v->next;
   5804  1.1  mrg 	}
   5805  1.1  mrg 
   5806  1.1  mrg     next_param:
   5807  1.1  mrg       if (inter.exists ())
   5808  1.1  mrg 	inter.release ();
   5809  1.1  mrg     }
   5810  1.1  mrg   *tail = NULL;
   5811  1.1  mrg   return res;
   5812  1.1  mrg }
   5813  1.1  mrg 
   5814  1.1  mrg /* Determine whether CS also brings all scalar values that the NODE is
   5815  1.1  mrg    specialized for.  */
   5816  1.1  mrg 
   5817  1.1  mrg static bool
   5818  1.1  mrg cgraph_edge_brings_all_scalars_for_node (struct cgraph_edge *cs,
   5819  1.1  mrg 					 struct cgraph_node *node)
   5820  1.1  mrg {
   5821  1.1  mrg   ipa_node_params *dest_info = ipa_node_params_sum->get (node);
   5822  1.1  mrg   int count = ipa_get_param_count (dest_info);
   5823  1.1  mrg   class ipa_node_params *caller_info;
   5824  1.1  mrg   class ipa_edge_args *args;
   5825  1.1  mrg   int i;
   5826  1.1  mrg 
   5827  1.1  mrg   caller_info = ipa_node_params_sum->get (cs->caller);
   5828  1.1  mrg   args = ipa_edge_args_sum->get (cs);
   5829  1.1  mrg   for (i = 0; i < count; i++)
   5830  1.1  mrg     {
   5831  1.1  mrg       struct ipa_jump_func *jump_func;
   5832  1.1  mrg       tree val, t;
   5833  1.1  mrg 
   5834  1.1  mrg       val = dest_info->known_csts[i];
   5835  1.1  mrg       if (!val)
   5836  1.1  mrg 	continue;
   5837  1.1  mrg 
   5838  1.1  mrg       if (i >= ipa_get_cs_argument_count (args))
   5839  1.1  mrg 	return false;
   5840  1.1  mrg       jump_func = ipa_get_ith_jump_func (args, i);
   5841  1.1  mrg       t = ipa_value_from_jfunc (caller_info, jump_func,
   5842  1.1  mrg 				ipa_get_type (dest_info, i));
   5843  1.1  mrg       if (!t || !values_equal_for_ipcp_p (val, t))
   5844  1.1  mrg 	return false;
   5845  1.1  mrg     }
   5846  1.1  mrg   return true;
   5847  1.1  mrg }
   5848  1.1  mrg 
   5849  1.1  mrg /* Determine whether CS also brings all aggregate values that NODE is
   5850  1.1  mrg    specialized for.  */
   5851  1.1  mrg static bool
   5852  1.1  mrg cgraph_edge_brings_all_agg_vals_for_node (struct cgraph_edge *cs,
   5853  1.1  mrg 					  struct cgraph_node *node)
   5854  1.1  mrg {
   5855  1.1  mrg   struct ipa_agg_replacement_value *aggval;
   5856  1.1  mrg   int i, ec, count;
   5857  1.1  mrg 
   5858  1.1  mrg   aggval = ipa_get_agg_replacements_for_node (node);
   5859  1.1  mrg   if (!aggval)
   5860  1.1  mrg     return true;
   5861  1.1  mrg 
   5862  1.1  mrg   ipa_node_params *clone_node_info = ipa_node_params_sum->get (node);
   5863  1.1  mrg   count = ipa_get_param_count (clone_node_info);
   5864  1.1  mrg   ec = ipa_get_cs_argument_count (ipa_edge_args_sum->get (cs));
   5865  1.1  mrg   if (ec < count)
   5866  1.1  mrg     for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
   5867  1.1  mrg       if (aggval->index >= ec)
   5868  1.1  mrg 	return false;
   5869  1.1  mrg 
   5870  1.1  mrg   ipa_node_params *orig_node_info
   5871  1.1  mrg     = ipa_node_params_sum->get (clone_node_info->ipcp_orig_node);
   5872  1.1  mrg 
   5873  1.1  mrg   for (i = 0; i < count; i++)
   5874  1.1  mrg     {
   5875  1.1  mrg       class ipcp_param_lattices *plats;
   5876  1.1  mrg       bool interesting = false;
   5877  1.1  mrg       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
   5878  1.1  mrg 	if (aggval->index == i)
   5879  1.1  mrg 	  {
   5880  1.1  mrg 	    interesting = true;
   5881  1.1  mrg 	    break;
   5882  1.1  mrg 	  }
   5883  1.1  mrg       if (!interesting)
   5884  1.1  mrg 	continue;
   5885  1.1  mrg 
   5886  1.1  mrg       plats = ipa_get_parm_lattices (orig_node_info, aggval->index);
   5887  1.1  mrg       if (plats->aggs_bottom)
   5888  1.1  mrg 	return false;
   5889  1.1  mrg 
   5890  1.1  mrg       vec<ipa_agg_value> values = intersect_aggregates_with_edge (cs, i, vNULL);
   5891  1.1  mrg       if (!values.exists ())
   5892  1.1  mrg 	return false;
   5893  1.1  mrg 
   5894  1.1  mrg       for (struct ipa_agg_replacement_value *av = aggval; av; av = av->next)
   5895  1.1  mrg 	if (aggval->index == i)
   5896  1.1  mrg 	  {
   5897  1.1  mrg 	    struct ipa_agg_value *item;
   5898  1.1  mrg 	    int j;
   5899  1.1  mrg 	    bool found = false;
   5900  1.1  mrg 	    FOR_EACH_VEC_ELT (values, j, item)
   5901  1.1  mrg 	      if (item->value
   5902  1.1  mrg 		  && item->offset == av->offset
   5903  1.1  mrg 		  && values_equal_for_ipcp_p (item->value, av->value))
   5904  1.1  mrg 		{
   5905  1.1  mrg 		  found = true;
   5906  1.1  mrg 		  break;
   5907  1.1  mrg 		}
   5908  1.1  mrg 	    if (!found)
   5909  1.1  mrg 	      {
   5910  1.1  mrg 		values.release ();
   5911  1.1  mrg 		return false;
   5912  1.1  mrg 	      }
   5913  1.1  mrg 	  }
   5914  1.1  mrg       values.release ();
   5915  1.1  mrg     }
   5916  1.1  mrg   return true;
   5917  1.1  mrg }
   5918  1.1  mrg 
   5919  1.1  mrg /* Given an original NODE and a VAL for which we have already created a
   5920  1.1  mrg    specialized clone, look whether there are incoming edges that still lead
   5921  1.1  mrg    into the old node but now also bring the requested value and also conform to
   5922  1.1  mrg    all other criteria such that they can be redirected the special node.
   5923  1.1  mrg    This function can therefore redirect the final edge in a SCC.  */
   5924  1.1  mrg 
   5925  1.1  mrg template <typename valtype>
   5926  1.1  mrg static void
   5927  1.1  mrg perhaps_add_new_callers (cgraph_node *node, ipcp_value<valtype> *val)
   5928  1.1  mrg {
   5929  1.1  mrg   ipcp_value_source<valtype> *src;
   5930  1.1  mrg   profile_count redirected_sum = profile_count::zero ();
   5931  1.1  mrg 
   5932  1.1  mrg   for (src = val->sources; src; src = src->next)
   5933  1.1  mrg     {
   5934  1.1  mrg       struct cgraph_edge *cs = src->cs;
   5935  1.1  mrg       while (cs)
   5936  1.1  mrg 	{
   5937  1.1  mrg 	  if (cgraph_edge_brings_value_p (cs, src, node, val)
   5938  1.1  mrg 	      && cgraph_edge_brings_all_scalars_for_node (cs, val->spec_node)
   5939  1.1  mrg 	      && cgraph_edge_brings_all_agg_vals_for_node (cs, val->spec_node))
   5940  1.1  mrg 	    {
   5941  1.1  mrg 	      if (dump_file)
   5942  1.1  mrg 		fprintf (dump_file, " - adding an extra caller %s of %s\n",
   5943  1.1  mrg 			 cs->caller->dump_name (),
   5944  1.1  mrg 			 val->spec_node->dump_name ());
   5945  1.1  mrg 
   5946  1.1  mrg 	      cs->redirect_callee_duplicating_thunks (val->spec_node);
   5947  1.1  mrg 	      val->spec_node->expand_all_artificial_thunks ();
   5948  1.1  mrg 	      if (cs->count.ipa ().initialized_p ())
   5949  1.1  mrg 	        redirected_sum = redirected_sum + cs->count.ipa ();
   5950  1.1  mrg 	    }
   5951  1.1  mrg 	  cs = get_next_cgraph_edge_clone (cs);
   5952  1.1  mrg 	}
   5953  1.1  mrg     }
   5954  1.1  mrg 
   5955  1.1  mrg   if (redirected_sum.nonzero_p ())
   5956  1.1  mrg     update_specialized_profile (val->spec_node, node, redirected_sum);
   5957  1.1  mrg }
   5958  1.1  mrg 
   5959  1.1  mrg /* Return true if KNOWN_CONTEXTS contain at least one useful context.  */
   5960  1.1  mrg 
   5961  1.1  mrg static bool
   5962  1.1  mrg known_contexts_useful_p (vec<ipa_polymorphic_call_context> known_contexts)
   5963  1.1  mrg {
   5964  1.1  mrg   ipa_polymorphic_call_context *ctx;
   5965  1.1  mrg   int i;
   5966  1.1  mrg 
   5967  1.1  mrg   FOR_EACH_VEC_ELT (known_contexts, i, ctx)
   5968  1.1  mrg     if (!ctx->useless_p ())
   5969  1.1  mrg       return true;
   5970  1.1  mrg   return false;
   5971  1.1  mrg }
   5972  1.1  mrg 
   5973  1.1  mrg /* Return a copy of KNOWN_CSTS if it is not empty, otherwise return vNULL.  */
   5974  1.1  mrg 
   5975  1.1  mrg static vec<ipa_polymorphic_call_context>
   5976  1.1  mrg copy_useful_known_contexts (const vec<ipa_polymorphic_call_context> &known_contexts)
   5977  1.1  mrg {
   5978  1.1  mrg   if (known_contexts_useful_p (known_contexts))
   5979  1.1  mrg     return known_contexts.copy ();
   5980  1.1  mrg   else
   5981  1.1  mrg     return vNULL;
   5982  1.1  mrg }
   5983  1.1  mrg 
   5984  1.1  mrg /* Copy known scalar values from AVALS into KNOWN_CSTS and modify the copy
   5985  1.1  mrg    according to VAL and INDEX.  If non-empty, replace KNOWN_CONTEXTS with its
   5986  1.1  mrg    copy too.  */
   5987  1.1  mrg 
   5988  1.1  mrg static void
   5989  1.1  mrg copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
   5990  1.1  mrg 			    vec<tree> *known_csts,
   5991  1.1  mrg 			    vec<ipa_polymorphic_call_context> *known_contexts,
   5992  1.1  mrg 			    ipcp_value<tree> *val, int index)
   5993  1.1  mrg {
   5994  1.1  mrg   *known_csts = avals->m_known_vals.copy ();
   5995  1.1  mrg   *known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
   5996  1.1  mrg   (*known_csts)[index] = val->value;
   5997  1.1  mrg }
   5998  1.1  mrg 
   5999  1.1  mrg /* Copy known scalar values from AVALS into KNOWN_CSTS.  Similarly, copy
   6000  1.1  mrg    contexts to KNOWN_CONTEXTS and modify the copy according to VAL and
   6001  1.1  mrg    INDEX.  */
   6002  1.1  mrg 
   6003  1.1  mrg static void
   6004  1.1  mrg copy_known_vectors_add_val (ipa_auto_call_arg_values *avals,
   6005  1.1  mrg 			    vec<tree> *known_csts,
   6006  1.1  mrg 			    vec<ipa_polymorphic_call_context> *known_contexts,
   6007  1.1  mrg 			    ipcp_value<ipa_polymorphic_call_context> *val,
   6008  1.1  mrg 			    int index)
   6009  1.1  mrg {
   6010  1.1  mrg   *known_csts = avals->m_known_vals.copy ();
   6011  1.1  mrg   *known_contexts = avals->m_known_contexts.copy ();
   6012  1.1  mrg   (*known_contexts)[index] = val->value;
   6013  1.1  mrg }
   6014  1.1  mrg 
   6015  1.1  mrg /* Return true if OFFSET indicates this was not an aggregate value or there is
   6016  1.1  mrg    a replacement equivalent to VALUE, INDEX and OFFSET among those in the
   6017  1.1  mrg    AGGVALS list.  */
   6018  1.1  mrg 
   6019  1.1  mrg DEBUG_FUNCTION bool
   6020  1.1  mrg ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *aggvals,
   6021  1.1  mrg 			       int index, HOST_WIDE_INT offset, tree value)
   6022  1.1  mrg {
   6023  1.1  mrg   if (offset == -1)
   6024  1.1  mrg     return true;
   6025  1.1  mrg 
   6026  1.1  mrg   while (aggvals)
   6027  1.1  mrg     {
   6028  1.1  mrg       if (aggvals->index == index
   6029  1.1  mrg 	  && aggvals->offset == offset
   6030  1.1  mrg 	  && values_equal_for_ipcp_p (aggvals->value, value))
   6031  1.1  mrg 	return true;
   6032  1.1  mrg       aggvals = aggvals->next;
   6033  1.1  mrg     }
   6034  1.1  mrg   return false;
   6035  1.1  mrg }
   6036  1.1  mrg 
   6037  1.1  mrg /* Return true if offset is minus one because source of a polymorphic context
   6038  1.1  mrg    cannot be an aggregate value.  */
   6039  1.1  mrg 
   6040  1.1  mrg DEBUG_FUNCTION bool
   6041  1.1  mrg ipcp_val_agg_replacement_ok_p (ipa_agg_replacement_value *,
   6042  1.1  mrg 			       int , HOST_WIDE_INT offset,
   6043  1.1  mrg 			       ipa_polymorphic_call_context)
   6044  1.1  mrg {
   6045  1.1  mrg   return offset == -1;
   6046  1.1  mrg }
   6047  1.1  mrg 
   6048  1.1  mrg /* Decide whether to create a special version of NODE for value VAL of
   6049  1.1  mrg    parameter at the given INDEX.  If OFFSET is -1, the value is for the
   6050  1.1  mrg    parameter itself, otherwise it is stored at the given OFFSET of the
   6051  1.1  mrg    parameter.  AVALS describes the other already known values.  SELF_GEN_CLONES
   6052  1.1  mrg    is a vector which contains clones created for self-recursive calls with an
   6053  1.1  mrg    arithmetic pass-through jump function.  */
   6054  1.1  mrg 
   6055  1.1  mrg template <typename valtype>
   6056  1.1  mrg static bool
   6057  1.1  mrg decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
   6058  1.1  mrg 		    ipcp_value<valtype> *val, ipa_auto_call_arg_values *avals,
   6059  1.1  mrg 		    vec<cgraph_node *> *self_gen_clones)
   6060  1.1  mrg {
   6061  1.1  mrg   struct ipa_agg_replacement_value *aggvals;
   6062  1.1  mrg   int caller_count;
   6063  1.1  mrg   sreal freq_sum;
   6064  1.1  mrg   profile_count count_sum, rec_count_sum;
   6065  1.1  mrg   vec<cgraph_edge *> callers;
   6066  1.1  mrg 
   6067  1.1  mrg   if (val->spec_node)
   6068  1.1  mrg     {
   6069  1.1  mrg       perhaps_add_new_callers (node, val);
   6070  1.1  mrg       return false;
   6071  1.1  mrg     }
   6072  1.1  mrg   else if (val->local_size_cost + overall_size > get_max_overall_size (node))
   6073  1.1  mrg     {
   6074  1.1  mrg       if (dump_file && (dump_flags & TDF_DETAILS))
   6075  1.1  mrg 	fprintf (dump_file, "   Ignoring candidate value because "
   6076  1.1  mrg 		 "maximum unit size would be reached with %li.\n",
   6077  1.1  mrg 		 val->local_size_cost + overall_size);
   6078  1.1  mrg       return false;
   6079  1.1  mrg     }
   6080  1.1  mrg   else if (!get_info_about_necessary_edges (val, node, &freq_sum, &caller_count,
   6081  1.1  mrg 					    &rec_count_sum, &count_sum))
   6082  1.1  mrg     return false;
   6083  1.1  mrg 
   6084  1.1  mrg   if (!dbg_cnt (ipa_cp_values))
   6085  1.1  mrg     return false;
   6086  1.1  mrg 
   6087  1.1  mrg   if (val->self_recursion_generated_p ())
   6088  1.1  mrg     {
   6089  1.1  mrg       /* The edge counts in this case might not have been adjusted yet.
   6090  1.1  mrg 	 Nevertleless, even if they were it would be only a guesswork which we
   6091  1.1  mrg 	 can do now.  The recursive part of the counts can be derived from the
   6092  1.1  mrg 	 count of the original node anyway.  */
   6093  1.1  mrg       if (node->count.ipa ().nonzero_p ())
   6094  1.1  mrg 	{
   6095  1.1  mrg 	  unsigned dem = self_gen_clones->length () + 1;
   6096  1.1  mrg 	  rec_count_sum = node->count.ipa ().apply_scale (1, dem);
   6097  1.1  mrg 	}
   6098  1.1  mrg       else
   6099  1.1  mrg 	rec_count_sum = profile_count::zero ();
   6100  1.1  mrg     }
   6101  1.1  mrg 
   6102  1.1  mrg   /* get_info_about_necessary_edges only sums up ipa counts.  */
   6103  1.1  mrg   count_sum += rec_count_sum;
   6104  1.1  mrg 
   6105  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   6106  1.1  mrg     {
   6107  1.1  mrg       fprintf (dump_file, " - considering value ");
   6108  1.1  mrg       print_ipcp_constant_value (dump_file, val->value);
   6109  1.1  mrg       fprintf (dump_file, " for ");
   6110  1.1  mrg       ipa_dump_param (dump_file, ipa_node_params_sum->get (node), index);
   6111  1.1  mrg       if (offset != -1)
   6112  1.1  mrg 	fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
   6113  1.1  mrg       fprintf (dump_file, " (caller_count: %i)\n", caller_count);
   6114  1.1  mrg     }
   6115  1.1  mrg 
   6116  1.1  mrg   if (!good_cloning_opportunity_p (node, val->local_time_benefit,
   6117  1.1  mrg 				   freq_sum, count_sum,
   6118  1.1  mrg 				   val->local_size_cost)
   6119  1.1  mrg       && !good_cloning_opportunity_p (node, val->prop_time_benefit,
   6120  1.1  mrg 				      freq_sum, count_sum, val->prop_size_cost))
   6121  1.1  mrg     return false;
   6122  1.1  mrg 
   6123  1.1  mrg   if (dump_file)
   6124  1.1  mrg     fprintf (dump_file, "  Creating a specialized node of %s.\n",
   6125  1.1  mrg 	     node->dump_name ());
   6126  1.1  mrg 
   6127  1.1  mrg   vec<tree> known_csts;
   6128  1.1  mrg   vec<ipa_polymorphic_call_context> known_contexts;
   6129  1.1  mrg 
   6130  1.1  mrg   callers = gather_edges_for_value (val, node, caller_count);
   6131  1.1  mrg   if (offset == -1)
   6132  1.1  mrg     copy_known_vectors_add_val (avals, &known_csts, &known_contexts, val, index);
   6133  1.1  mrg   else
   6134  1.1  mrg     {
   6135  1.1  mrg       known_csts = avals->m_known_vals.copy ();
   6136  1.1  mrg       known_contexts = copy_useful_known_contexts (avals->m_known_contexts);
   6137  1.1  mrg     }
   6138  1.1  mrg   find_more_scalar_values_for_callers_subset (node, known_csts, callers);
   6139  1.1  mrg   find_more_contexts_for_caller_subset (node, &known_contexts, callers);
   6140  1.1  mrg   aggvals = find_aggregate_values_for_callers_subset (node, callers);
   6141  1.1  mrg   gcc_checking_assert (ipcp_val_agg_replacement_ok_p (aggvals, index,
   6142  1.1  mrg 						      offset, val->value));
   6143  1.1  mrg   val->spec_node = create_specialized_node (node, known_csts, known_contexts,
   6144  1.1  mrg 					    aggvals, callers);
   6145  1.1  mrg 
   6146  1.1  mrg   if (val->self_recursion_generated_p ())
   6147  1.1  mrg     self_gen_clones->safe_push (val->spec_node);
   6148  1.1  mrg   else
   6149  1.1  mrg     update_profiling_info (node, val->spec_node);
   6150  1.1  mrg 
   6151  1.1  mrg   callers.release ();
   6152  1.1  mrg   overall_size += val->local_size_cost;
   6153  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   6154  1.1  mrg     fprintf (dump_file, "     overall size reached %li\n",
   6155  1.1  mrg 	     overall_size);
   6156  1.1  mrg 
   6157  1.1  mrg   /* TODO: If for some lattice there is only one other known value
   6158  1.1  mrg      left, make a special node for it too. */
   6159  1.1  mrg 
   6160  1.1  mrg   return true;
   6161  1.1  mrg }
   6162  1.1  mrg 
   6163  1.1  mrg /* Decide whether and what specialized clones of NODE should be created.  */
   6164  1.1  mrg 
   6165  1.1  mrg static bool
   6166  1.1  mrg decide_whether_version_node (struct cgraph_node *node)
   6167  1.1  mrg {
   6168  1.1  mrg   ipa_node_params *info = ipa_node_params_sum->get (node);
   6169  1.1  mrg   int i, count = ipa_get_param_count (info);
   6170  1.1  mrg   bool ret = false;
   6171  1.1  mrg 
   6172  1.1  mrg   if (count == 0)
   6173  1.1  mrg     return false;
   6174  1.1  mrg 
   6175  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   6176  1.1  mrg     fprintf (dump_file, "\nEvaluating opportunities for %s.\n",
   6177  1.1  mrg 	     node->dump_name ());
   6178  1.1  mrg 
   6179  1.1  mrg   auto_vec <cgraph_node *, 9> self_gen_clones;
   6180  1.1  mrg   ipa_auto_call_arg_values avals;
   6181  1.1  mrg   gather_context_independent_values (info, &avals, false, NULL);
   6182  1.1  mrg 
   6183  1.1  mrg   for (i = 0; i < count;i++)
   6184  1.1  mrg     {
   6185  1.1  mrg       class ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   6186  1.1  mrg       ipcp_lattice<tree> *lat = &plats->itself;
   6187  1.1  mrg       ipcp_lattice<ipa_polymorphic_call_context> *ctxlat = &plats->ctxlat;
   6188  1.1  mrg 
   6189  1.1  mrg       if (!lat->bottom
   6190  1.1  mrg 	  && !avals.m_known_vals[i])
   6191  1.1  mrg 	{
   6192  1.1  mrg 	  ipcp_value<tree> *val;
   6193  1.1  mrg 	  for (val = lat->values; val; val = val->next)
   6194  1.1  mrg 	    {
   6195  1.1  mrg 	      /* If some values generated for self-recursive calls with
   6196  1.1  mrg 		 arithmetic jump functions fall outside of the known
   6197  1.1  mrg 		 value_range for the parameter, we can skip them.  VR interface
   6198  1.1  mrg 		 supports this only for integers now.  */
   6199  1.1  mrg 	      if (TREE_CODE (val->value) == INTEGER_CST
   6200  1.1  mrg 		  && !plats->m_value_range.bottom_p ()
   6201  1.1  mrg 		  && !plats->m_value_range.m_vr.contains_p (val->value))
   6202  1.1  mrg 		{
   6203  1.1  mrg 		  /* This can happen also if a constant present in the source
   6204  1.1  mrg 		     code falls outside of the range of parameter's type, so we
   6205  1.1  mrg 		     cannot assert.  */
   6206  1.1  mrg 		  if (dump_file && (dump_flags & TDF_DETAILS))
   6207  1.1  mrg 		    {
   6208  1.1  mrg 		      fprintf (dump_file, " - skipping%s value ",
   6209  1.1  mrg 			       val->self_recursion_generated_p ()
   6210  1.1  mrg 			       ? " self_recursion_generated" : "");
   6211  1.1  mrg 		      print_ipcp_constant_value (dump_file, val->value);
   6212  1.1  mrg 		      fprintf (dump_file, " because it is outside known "
   6213  1.1  mrg 			       "value range.\n");
   6214  1.1  mrg 		    }
   6215  1.1  mrg 		  continue;
   6216  1.1  mrg 		}
   6217  1.1  mrg 	      ret |= decide_about_value (node, i, -1, val, &avals,
   6218  1.1  mrg 					 &self_gen_clones);
   6219  1.1  mrg 	    }
   6220  1.1  mrg 	}
   6221  1.1  mrg 
   6222  1.1  mrg       if (!plats->aggs_bottom)
   6223  1.1  mrg 	{
   6224  1.1  mrg 	  struct ipcp_agg_lattice *aglat;
   6225  1.1  mrg 	  ipcp_value<tree> *val;
   6226  1.1  mrg 	  for (aglat = plats->aggs; aglat; aglat = aglat->next)
   6227  1.1  mrg 	    if (!aglat->bottom && aglat->values
   6228  1.1  mrg 		/* If the following is false, the one value has been considered
   6229  1.1  mrg 		   for cloning for all contexts.  */
   6230  1.1  mrg 		&& (plats->aggs_contain_variable
   6231  1.1  mrg 		    || !aglat->is_single_const ()))
   6232  1.1  mrg 	      for (val = aglat->values; val; val = val->next)
   6233  1.1  mrg 		ret |= decide_about_value (node, i, aglat->offset, val, &avals,
   6234  1.1  mrg 					   &self_gen_clones);
   6235  1.1  mrg 	}
   6236  1.1  mrg 
   6237  1.1  mrg       if (!ctxlat->bottom
   6238  1.1  mrg 	  && avals.m_known_contexts[i].useless_p ())
   6239  1.1  mrg 	{
   6240  1.1  mrg 	  ipcp_value<ipa_polymorphic_call_context> *val;
   6241  1.1  mrg 	  for (val = ctxlat->values; val; val = val->next)
   6242  1.1  mrg 	    ret |= decide_about_value (node, i, -1, val, &avals,
   6243  1.1  mrg 				       &self_gen_clones);
   6244  1.1  mrg 	}
   6245  1.1  mrg     }
   6246  1.1  mrg 
   6247  1.1  mrg   if (!self_gen_clones.is_empty ())
   6248  1.1  mrg     {
   6249  1.1  mrg       self_gen_clones.safe_push (node);
   6250  1.1  mrg       update_counts_for_self_gen_clones (node, self_gen_clones);
   6251  1.1  mrg     }
   6252  1.1  mrg 
   6253  1.1  mrg   if (info->do_clone_for_all_contexts)
   6254  1.1  mrg     {
   6255  1.1  mrg       if (!dbg_cnt (ipa_cp_values))
   6256  1.1  mrg 	{
   6257  1.1  mrg 	  info->do_clone_for_all_contexts = false;
   6258  1.1  mrg 	  return ret;
   6259  1.1  mrg 	}
   6260  1.1  mrg 
   6261  1.1  mrg       struct cgraph_node *clone;
   6262  1.1  mrg       auto_vec<cgraph_edge *> callers = node->collect_callers ();
   6263  1.1  mrg 
   6264  1.1  mrg       for (int i = callers.length () - 1; i >= 0; i--)
   6265  1.1  mrg 	{
   6266  1.1  mrg 	  cgraph_edge *cs = callers[i];
   6267  1.1  mrg 	  ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   6268  1.1  mrg 
   6269  1.1  mrg 	  if (caller_info && caller_info->node_dead)
   6270  1.1  mrg 	    callers.unordered_remove (i);
   6271  1.1  mrg 	}
   6272  1.1  mrg 
   6273  1.1  mrg       if (!adjust_callers_for_value_intersection (callers, node))
   6274  1.1  mrg 	{
   6275  1.1  mrg 	  /* If node is not called by anyone, or all its caller edges are
   6276  1.1  mrg 	     self-recursive, the node is not really in use, no need to do
   6277  1.1  mrg 	     cloning.  */
   6278  1.1  mrg 	  info->do_clone_for_all_contexts = false;
   6279  1.1  mrg 	  return ret;
   6280  1.1  mrg 	}
   6281  1.1  mrg 
   6282  1.1  mrg       if (dump_file)
   6283  1.1  mrg 	fprintf (dump_file, " - Creating a specialized node of %s "
   6284  1.1  mrg 		 "for all known contexts.\n", node->dump_name ());
   6285  1.1  mrg 
   6286  1.1  mrg       vec<tree> known_csts = avals.m_known_vals.copy ();
   6287  1.1  mrg       vec<ipa_polymorphic_call_context> known_contexts
   6288  1.1  mrg 	= copy_useful_known_contexts (avals.m_known_contexts);
   6289  1.1  mrg       find_more_scalar_values_for_callers_subset (node, known_csts, callers);
   6290  1.1  mrg       find_more_contexts_for_caller_subset (node, &known_contexts, callers);
   6291  1.1  mrg       ipa_agg_replacement_value *aggvals
   6292  1.1  mrg 	= find_aggregate_values_for_callers_subset (node, callers);
   6293  1.1  mrg 
   6294  1.1  mrg       if (!known_contexts_useful_p (known_contexts))
   6295  1.1  mrg 	{
   6296  1.1  mrg 	  known_contexts.release ();
   6297  1.1  mrg 	  known_contexts = vNULL;
   6298  1.1  mrg 	}
   6299  1.1  mrg       clone = create_specialized_node (node, known_csts, known_contexts,
   6300  1.1  mrg 				       aggvals, callers);
   6301  1.1  mrg       info->do_clone_for_all_contexts = false;
   6302  1.1  mrg       ipa_node_params_sum->get (clone)->is_all_contexts_clone = true;
   6303  1.1  mrg       ret = true;
   6304  1.1  mrg     }
   6305  1.1  mrg 
   6306  1.1  mrg   return ret;
   6307  1.1  mrg }
   6308  1.1  mrg 
   6309  1.1  mrg /* Transitively mark all callees of NODE within the same SCC as not dead.  */
   6310  1.1  mrg 
   6311  1.1  mrg static void
   6312  1.1  mrg spread_undeadness (struct cgraph_node *node)
   6313  1.1  mrg {
   6314  1.1  mrg   struct cgraph_edge *cs;
   6315  1.1  mrg 
   6316  1.1  mrg   for (cs = node->callees; cs; cs = cs->next_callee)
   6317  1.1  mrg     if (ipa_edge_within_scc (cs))
   6318  1.1  mrg       {
   6319  1.1  mrg 	struct cgraph_node *callee;
   6320  1.1  mrg 	class ipa_node_params *info;
   6321  1.1  mrg 
   6322  1.1  mrg 	callee = cs->callee->function_symbol (NULL);
   6323  1.1  mrg 	info = ipa_node_params_sum->get (callee);
   6324  1.1  mrg 
   6325  1.1  mrg 	if (info && info->node_dead)
   6326  1.1  mrg 	  {
   6327  1.1  mrg 	    info->node_dead = 0;
   6328  1.1  mrg 	    spread_undeadness (callee);
   6329  1.1  mrg 	  }
   6330  1.1  mrg       }
   6331  1.1  mrg }
   6332  1.1  mrg 
   6333  1.1  mrg /* Return true if NODE has a caller from outside of its SCC that is not
   6334  1.1  mrg    dead.  Worker callback for cgraph_for_node_and_aliases.  */
   6335  1.1  mrg 
   6336  1.1  mrg static bool
   6337  1.1  mrg has_undead_caller_from_outside_scc_p (struct cgraph_node *node,
   6338  1.1  mrg 				      void *data ATTRIBUTE_UNUSED)
   6339  1.1  mrg {
   6340  1.1  mrg   struct cgraph_edge *cs;
   6341  1.1  mrg 
   6342  1.1  mrg   for (cs = node->callers; cs; cs = cs->next_caller)
   6343  1.1  mrg     if (cs->caller->thunk
   6344  1.1  mrg 	&& cs->caller->call_for_symbol_thunks_and_aliases
   6345  1.1  mrg 	  (has_undead_caller_from_outside_scc_p, NULL, true))
   6346  1.1  mrg       return true;
   6347  1.1  mrg     else if (!ipa_edge_within_scc (cs))
   6348  1.1  mrg       {
   6349  1.1  mrg 	ipa_node_params *caller_info = ipa_node_params_sum->get (cs->caller);
   6350  1.1  mrg 	if (!caller_info /* Unoptimized caller are like dead ones.  */
   6351  1.1  mrg 	    || !caller_info->node_dead)
   6352  1.1  mrg 	  return true;
   6353  1.1  mrg       }
   6354  1.1  mrg   return false;
   6355  1.1  mrg }
   6356  1.1  mrg 
   6357  1.1  mrg 
   6358  1.1  mrg /* Identify nodes within the same SCC as NODE which are no longer needed
   6359  1.1  mrg    because of new clones and will be removed as unreachable.  */
   6360  1.1  mrg 
   6361  1.1  mrg static void
   6362  1.1  mrg identify_dead_nodes (struct cgraph_node *node)
   6363  1.1  mrg {
   6364  1.1  mrg   struct cgraph_node *v;
   6365  1.1  mrg   for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
   6366  1.1  mrg     if (v->local)
   6367  1.1  mrg       {
   6368  1.1  mrg 	ipa_node_params *info = ipa_node_params_sum->get (v);
   6369  1.1  mrg 	if (info
   6370  1.1  mrg 	    && !v->call_for_symbol_thunks_and_aliases
   6371  1.1  mrg 	      (has_undead_caller_from_outside_scc_p, NULL, true))
   6372  1.1  mrg 	  info->node_dead = 1;
   6373  1.1  mrg       }
   6374  1.1  mrg 
   6375  1.1  mrg   for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
   6376  1.1  mrg     {
   6377  1.1  mrg       ipa_node_params *info = ipa_node_params_sum->get (v);
   6378  1.1  mrg       if (info && !info->node_dead)
   6379  1.1  mrg 	spread_undeadness (v);
   6380  1.1  mrg     }
   6381  1.1  mrg 
   6382  1.1  mrg   if (dump_file && (dump_flags & TDF_DETAILS))
   6383  1.1  mrg     {
   6384  1.1  mrg       for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
   6385  1.1  mrg 	if (ipa_node_params_sum->get (v)
   6386  1.1  mrg 	    && ipa_node_params_sum->get (v)->node_dead)
   6387  1.1  mrg 	  fprintf (dump_file, "  Marking node as dead: %s.\n",
   6388  1.1  mrg 		   v->dump_name ());
   6389  1.1  mrg     }
   6390  1.1  mrg }
   6391  1.1  mrg 
   6392  1.1  mrg /* The decision stage.  Iterate over the topological order of call graph nodes
   6393  1.1  mrg    TOPO and make specialized clones if deemed beneficial.  */
   6394  1.1  mrg 
   6395  1.1  mrg static void
   6396  1.1  mrg ipcp_decision_stage (class ipa_topo_info *topo)
   6397  1.1  mrg {
   6398  1.1  mrg   int i;
   6399  1.1  mrg 
   6400  1.1  mrg   if (dump_file)
   6401  1.1  mrg     fprintf (dump_file, "\nIPA decision stage:\n\n");
   6402  1.1  mrg 
   6403  1.1  mrg   for (i = topo->nnodes - 1; i >= 0; i--)
   6404  1.1  mrg     {
   6405  1.1  mrg       struct cgraph_node *node = topo->order[i];
   6406  1.1  mrg       bool change = false, iterate = true;
   6407  1.1  mrg 
   6408  1.1  mrg       while (iterate)
   6409  1.1  mrg 	{
   6410  1.1  mrg 	  struct cgraph_node *v;
   6411  1.1  mrg 	  iterate = false;
   6412  1.1  mrg 	  for (v = node; v; v = ((struct ipa_dfs_info *) v->aux)->next_cycle)
   6413  1.1  mrg 	    if (v->has_gimple_body_p ()
   6414  1.1  mrg 		&& ipcp_versionable_function_p (v))
   6415  1.1  mrg 	      iterate |= decide_whether_version_node (v);
   6416  1.1  mrg 
   6417  1.1  mrg 	  change |= iterate;
   6418  1.1  mrg 	}
   6419  1.1  mrg       if (change)
   6420  1.1  mrg 	identify_dead_nodes (node);
   6421  1.1  mrg     }
   6422  1.1  mrg }
   6423  1.1  mrg 
   6424  1.1  mrg /* Look up all the bits information that we have discovered and copy it over
   6425  1.1  mrg    to the transformation summary.  */
   6426  1.1  mrg 
   6427  1.1  mrg static void
   6428  1.1  mrg ipcp_store_bits_results (void)
   6429  1.1  mrg {
   6430  1.1  mrg   cgraph_node *node;
   6431  1.1  mrg 
   6432  1.1  mrg   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
   6433  1.1  mrg     {
   6434  1.1  mrg       ipa_node_params *info = ipa_node_params_sum->get (node);
   6435  1.1  mrg       bool dumped_sth = false;
   6436  1.1  mrg       bool found_useful_result = false;
   6437  1.1  mrg 
   6438  1.1  mrg       if (!opt_for_fn (node->decl, flag_ipa_bit_cp) || !info)
   6439  1.1  mrg 	{
   6440  1.1  mrg 	  if (dump_file)
   6441  1.1  mrg 	    fprintf (dump_file, "Not considering %s for ipa bitwise propagation "
   6442  1.1  mrg 				"; -fipa-bit-cp: disabled.\n",
   6443  1.1  mrg 				node->dump_name ());
   6444  1.1  mrg 	  continue;
   6445  1.1  mrg 	}
   6446  1.1  mrg 
   6447  1.1  mrg       if (info->ipcp_orig_node)
   6448  1.1  mrg 	info = ipa_node_params_sum->get (info->ipcp_orig_node);
   6449  1.1  mrg       if (!info->lattices)
   6450  1.1  mrg 	/* Newly expanded artificial thunks do not have lattices.  */
   6451  1.1  mrg 	continue;
   6452  1.1  mrg 
   6453  1.1  mrg       unsigned count = ipa_get_param_count (info);
   6454  1.1  mrg       for (unsigned i = 0; i < count; i++)
   6455  1.1  mrg 	{
   6456  1.1  mrg 	  ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   6457  1.1  mrg 	  if (plats->bits_lattice.constant_p ())
   6458  1.1  mrg 	    {
   6459  1.1  mrg 	      found_useful_result = true;
   6460  1.1  mrg 	      break;
   6461  1.1  mrg 	    }
   6462  1.1  mrg 	}
   6463  1.1  mrg 
   6464  1.1  mrg       if (!found_useful_result)
   6465  1.1  mrg 	continue;
   6466  1.1  mrg 
   6467  1.1  mrg       ipcp_transformation_initialize ();
   6468  1.1  mrg       ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
   6469  1.1  mrg       vec_safe_reserve_exact (ts->bits, count);
   6470  1.1  mrg 
   6471  1.1  mrg       for (unsigned i = 0; i < count; i++)
   6472  1.1  mrg 	{
   6473  1.1  mrg 	  ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   6474  1.1  mrg 	  ipa_bits *jfbits;
   6475  1.1  mrg 
   6476  1.1  mrg 	  if (plats->bits_lattice.constant_p ())
   6477  1.1  mrg 	    {
   6478  1.1  mrg 	      jfbits
   6479  1.1  mrg 		= ipa_get_ipa_bits_for_value (plats->bits_lattice.get_value (),
   6480  1.1  mrg 					      plats->bits_lattice.get_mask ());
   6481  1.1  mrg 	      if (!dbg_cnt (ipa_cp_bits))
   6482  1.1  mrg 		jfbits = NULL;
   6483  1.1  mrg 	    }
   6484  1.1  mrg 	  else
   6485  1.1  mrg 	    jfbits = NULL;
   6486  1.1  mrg 
   6487  1.1  mrg 	  ts->bits->quick_push (jfbits);
   6488  1.1  mrg 	  if (!dump_file || !jfbits)
   6489  1.1  mrg 	    continue;
   6490  1.1  mrg 	  if (!dumped_sth)
   6491  1.1  mrg 	    {
   6492  1.1  mrg 	      fprintf (dump_file, "Propagated bits info for function %s:\n",
   6493  1.1  mrg 		       node->dump_name ());
   6494  1.1  mrg 	      dumped_sth = true;
   6495  1.1  mrg 	    }
   6496  1.1  mrg 	  fprintf (dump_file, " param %i: value = ", i);
   6497  1.1  mrg 	  print_hex (jfbits->value, dump_file);
   6498  1.1  mrg 	  fprintf (dump_file, ", mask = ");
   6499  1.1  mrg 	  print_hex (jfbits->mask, dump_file);
   6500  1.1  mrg 	  fprintf (dump_file, "\n");
   6501  1.1  mrg 	}
   6502  1.1  mrg     }
   6503  1.1  mrg }
   6504  1.1  mrg 
   6505  1.1  mrg /* Look up all VR information that we have discovered and copy it over
   6506  1.1  mrg    to the transformation summary.  */
   6507  1.1  mrg 
   6508  1.1  mrg static void
   6509  1.1  mrg ipcp_store_vr_results (void)
   6510  1.1  mrg {
   6511  1.1  mrg   cgraph_node *node;
   6512  1.1  mrg 
   6513  1.1  mrg   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
   6514  1.1  mrg     {
   6515  1.1  mrg       ipa_node_params *info = ipa_node_params_sum->get (node);
   6516  1.1  mrg       bool found_useful_result = false;
   6517  1.1  mrg 
   6518  1.1  mrg       if (!info || !opt_for_fn (node->decl, flag_ipa_vrp))
   6519  1.1  mrg 	{
   6520  1.1  mrg 	  if (dump_file)
   6521  1.1  mrg 	    fprintf (dump_file, "Not considering %s for VR discovery "
   6522  1.1  mrg 		     "and propagate; -fipa-ipa-vrp: disabled.\n",
   6523  1.1  mrg 		     node->dump_name ());
   6524  1.1  mrg 	  continue;
   6525  1.1  mrg 	}
   6526  1.1  mrg 
   6527  1.1  mrg       if (info->ipcp_orig_node)
   6528  1.1  mrg 	info = ipa_node_params_sum->get (info->ipcp_orig_node);
   6529  1.1  mrg       if (!info->lattices)
   6530  1.1  mrg 	/* Newly expanded artificial thunks do not have lattices.  */
   6531  1.1  mrg 	continue;
   6532  1.1  mrg 
   6533  1.1  mrg       unsigned count = ipa_get_param_count (info);
   6534  1.1  mrg       for (unsigned i = 0; i < count; i++)
   6535  1.1  mrg 	{
   6536  1.1  mrg 	  ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   6537  1.1  mrg 	  if (!plats->m_value_range.bottom_p ()
   6538  1.1  mrg 	      && !plats->m_value_range.top_p ())
   6539  1.1  mrg 	    {
   6540  1.1  mrg 	      found_useful_result = true;
   6541  1.1  mrg 	      break;
   6542  1.1  mrg 	    }
   6543  1.1  mrg 	}
   6544  1.1  mrg       if (!found_useful_result)
   6545  1.1  mrg 	continue;
   6546  1.1  mrg 
   6547  1.1  mrg       ipcp_transformation_initialize ();
   6548  1.1  mrg       ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
   6549  1.1  mrg       vec_safe_reserve_exact (ts->m_vr, count);
   6550  1.1  mrg 
   6551  1.1  mrg       for (unsigned i = 0; i < count; i++)
   6552  1.1  mrg 	{
   6553  1.1  mrg 	  ipcp_param_lattices *plats = ipa_get_parm_lattices (info, i);
   6554  1.1  mrg 	  ipa_vr vr;
   6555  1.1  mrg 
   6556  1.1  mrg 	  if (!plats->m_value_range.bottom_p ()
   6557  1.1  mrg 	      && !plats->m_value_range.top_p ()
   6558  1.1  mrg 	      && dbg_cnt (ipa_cp_vr))
   6559  1.1  mrg 	    {
   6560  1.1  mrg 	      vr.known = true;
   6561  1.1  mrg 	      vr.type = plats->m_value_range.m_vr.kind ();
   6562  1.1  mrg 	      vr.min = wi::to_wide (plats->m_value_range.m_vr.min ());
   6563  1.1  mrg 	      vr.max = wi::to_wide (plats->m_value_range.m_vr.max ());
   6564  1.1  mrg 	    }
   6565  1.1  mrg 	  else
   6566  1.1  mrg 	    {
   6567  1.1  mrg 	      vr.known = false;
   6568  1.1  mrg 	      vr.type = VR_VARYING;
   6569  1.1  mrg 	      vr.min = vr.max = wi::zero (INT_TYPE_SIZE);
   6570  1.1  mrg 	    }
   6571  1.1  mrg 	  ts->m_vr->quick_push (vr);
   6572  1.1  mrg 	}
   6573  1.1  mrg     }
   6574  1.1  mrg }
   6575  1.1  mrg 
   6576  1.1  mrg /* The IPCP driver.  */
   6577  1.1  mrg 
   6578  1.1  mrg static unsigned int
   6579  1.1  mrg ipcp_driver (void)
   6580  1.1  mrg {
   6581  1.1  mrg   class ipa_topo_info topo;
   6582  1.1  mrg 
   6583  1.1  mrg   if (edge_clone_summaries == NULL)
   6584  1.1  mrg     edge_clone_summaries = new edge_clone_summary_t (symtab);
   6585  1.1  mrg 
   6586  1.1  mrg   ipa_check_create_node_params ();
   6587  1.1  mrg   ipa_check_create_edge_args ();
   6588  1.1  mrg   clone_num_suffixes = new hash_map<const char *, unsigned>;
   6589  1.1  mrg 
   6590  1.1  mrg   if (dump_file)
   6591  1.1  mrg     {
   6592  1.1  mrg       fprintf (dump_file, "\nIPA structures before propagation:\n");
   6593  1.1  mrg       if (dump_flags & TDF_DETAILS)
   6594  1.1  mrg 	ipa_print_all_params (dump_file);
   6595  1.1  mrg       ipa_print_all_jump_functions (dump_file);
   6596  1.1  mrg     }
   6597  1.1  mrg 
   6598  1.1  mrg   /* Topological sort.  */
   6599  1.1  mrg   build_toporder_info (&topo);
   6600  1.1  mrg   /* Do the interprocedural propagation.  */
   6601  1.1  mrg   ipcp_propagate_stage (&topo);
   6602  1.1  mrg   /* Decide what constant propagation and cloning should be performed.  */
   6603  1.1  mrg   ipcp_decision_stage (&topo);
   6604  1.1  mrg   /* Store results of bits propagation.  */
   6605  1.1  mrg   ipcp_store_bits_results ();
   6606  1.1  mrg   /* Store results of value range propagation.  */
   6607  1.1  mrg   ipcp_store_vr_results ();
   6608  1.1  mrg 
   6609  1.1  mrg   /* Free all IPCP structures.  */
   6610  1.1  mrg   delete clone_num_suffixes;
   6611  1.1  mrg   free_toporder_info (&topo);
   6612  1.1  mrg   delete edge_clone_summaries;
   6613  1.1  mrg   edge_clone_summaries = NULL;
   6614  1.1  mrg   ipa_free_all_structures_after_ipa_cp ();
   6615  1.1  mrg   if (dump_file)
   6616  1.1  mrg     fprintf (dump_file, "\nIPA constant propagation end\n");
   6617  1.1  mrg   return 0;
   6618  1.1  mrg }
   6619  1.1  mrg 
   6620  1.1  mrg /* Initialization and computation of IPCP data structures.  This is the initial
   6621  1.1  mrg    intraprocedural analysis of functions, which gathers information to be
   6622  1.1  mrg    propagated later on.  */
   6623  1.1  mrg 
   6624  1.1  mrg static void
   6625  1.1  mrg ipcp_generate_summary (void)
   6626  1.1  mrg {
   6627  1.1  mrg   struct cgraph_node *node;
   6628  1.1  mrg 
   6629  1.1  mrg   if (dump_file)
   6630  1.1  mrg     fprintf (dump_file, "\nIPA constant propagation start:\n");
   6631  1.1  mrg   ipa_register_cgraph_hooks ();
   6632  1.1  mrg 
   6633  1.1  mrg   FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
   6634  1.1  mrg     ipa_analyze_node (node);
   6635  1.1  mrg }
   6636  1.1  mrg 
   6637  1.1  mrg namespace {
   6638  1.1  mrg 
   6639  1.1  mrg const pass_data pass_data_ipa_cp =
   6640  1.1  mrg {
   6641  1.1  mrg   IPA_PASS, /* type */
   6642  1.1  mrg   "cp", /* name */
   6643  1.1  mrg   OPTGROUP_NONE, /* optinfo_flags */
   6644  1.1  mrg   TV_IPA_CONSTANT_PROP, /* tv_id */
   6645  1.1  mrg   0, /* properties_required */
   6646  1.1  mrg   0, /* properties_provided */
   6647  1.1  mrg   0, /* properties_destroyed */
   6648  1.1  mrg   0, /* todo_flags_start */
   6649  1.1  mrg   ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
   6650  1.1  mrg };
   6651  1.1  mrg 
   6652  1.1  mrg class pass_ipa_cp : public ipa_opt_pass_d
   6653  1.1  mrg {
   6654  1.1  mrg public:
   6655  1.1  mrg   pass_ipa_cp (gcc::context *ctxt)
   6656  1.1  mrg     : ipa_opt_pass_d (pass_data_ipa_cp, ctxt,
   6657  1.1  mrg 		      ipcp_generate_summary, /* generate_summary */
   6658  1.1  mrg 		      NULL, /* write_summary */
   6659  1.1  mrg 		      NULL, /* read_summary */
   6660  1.1  mrg 		      ipcp_write_transformation_summaries, /*
   6661  1.1  mrg 		      write_optimization_summary */
   6662  1.1  mrg 		      ipcp_read_transformation_summaries, /*
   6663  1.1  mrg 		      read_optimization_summary */
   6664  1.1  mrg 		      NULL, /* stmt_fixup */
   6665  1.1  mrg 		      0, /* function_transform_todo_flags_start */
   6666  1.1  mrg 		      ipcp_transform_function, /* function_transform */
   6667  1.1  mrg 		      NULL) /* variable_transform */
   6668  1.1  mrg   {}
   6669  1.1  mrg 
   6670  1.1  mrg   /* opt_pass methods: */
   6671  1.1  mrg   virtual bool gate (function *)
   6672  1.1  mrg     {
   6673  1.1  mrg       /* FIXME: We should remove the optimize check after we ensure we never run
   6674  1.1  mrg 	 IPA passes when not optimizing.  */
   6675  1.1  mrg       return (flag_ipa_cp && optimize) || in_lto_p;
   6676  1.1  mrg     }
   6677  1.1  mrg 
   6678  1.1  mrg   virtual unsigned int execute (function *) { return ipcp_driver (); }
   6679  1.1  mrg 
   6680  1.1  mrg }; // class pass_ipa_cp
   6681  1.1  mrg 
   6682  1.1  mrg } // anon namespace
   6683  1.1  mrg 
   6684  1.1  mrg ipa_opt_pass_d *
   6685  1.1  mrg make_pass_ipa_cp (gcc::context *ctxt)
   6686  1.1  mrg {
   6687  1.1  mrg   return new pass_ipa_cp (ctxt);
   6688  1.1  mrg }
   6689  1.1  mrg 
   6690  1.1  mrg /* Reset all state within ipa-cp.cc so that we can rerun the compiler
   6691  1.1  mrg    within the same process.  For use by toplev::finalize.  */
   6692  1.1  mrg 
   6693  1.1  mrg void
   6694  1.1  mrg ipa_cp_cc_finalize (void)
   6695  1.1  mrg {
   6696  1.1  mrg   base_count = profile_count::uninitialized ();
   6697  1.1  mrg   overall_size = 0;
   6698  1.1  mrg   orig_overall_size = 0;
   6699  1.1  mrg   ipcp_free_transformation_sum ();
   6700  1.1  mrg }
   6701