LCOV - code coverage report
Current view: top level - gcc - ipa-prop.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.1 % 3347 3184
Test Date: 2026-03-28 14:25:54 Functions: 97.5 % 159 155
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Interprocedural analyses.
       2              :    Copyright (C) 2005-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : #include "config.h"
      21              : #include "system.h"
      22              : #include "coretypes.h"
      23              : #include "backend.h"
      24              : #include "rtl.h"
      25              : #include "tree.h"
      26              : #include "gimple.h"
      27              : #include "alloc-pool.h"
      28              : #include "tree-pass.h"
      29              : #include "ssa.h"
      30              : #include "tree-streamer.h"
      31              : #include "cgraph.h"
      32              : #include "diagnostic.h"
      33              : #include "fold-const.h"
      34              : #include "gimple-iterator.h"
      35              : #include "gimple-fold.h"
      36              : #include "tree-eh.h"
      37              : #include "calls.h"
      38              : #include "stor-layout.h"
      39              : #include "print-tree.h"
      40              : #include "gimplify.h"
      41              : #include "gimplify-me.h"
      42              : #include "gimple-walk.h"
      43              : #include "symbol-summary.h"
      44              : #include "sreal.h"
      45              : #include "ipa-cp.h"
      46              : #include "ipa-prop.h"
      47              : #include "tree-cfg.h"
      48              : #include "tree-dfa.h"
      49              : #include "tree-inline.h"
      50              : #include "ipa-fnsummary.h"
      51              : #include "gimple-pretty-print.h"
      52              : #include "ipa-utils.h"
      53              : #include "dbgcnt.h"
      54              : #include "domwalk.h"
      55              : #include "builtins.h"
      56              : #include "tree-cfgcleanup.h"
      57              : #include "options.h"
      58              : #include "symtab-clones.h"
      59              : #include "attr-fnspec.h"
      60              : #include "gimple-range.h"
      61              : #include "value-range-storage.h"
      62              : #include "vr-values.h"
      63              : #include "lto-streamer.h"
      64              : #include "attribs.h"
      65              : #include "attr-callback.h"
      66              : 
      67              : /* Function summary where the parameter infos are actually stored. */
      68              : ipa_node_params_t *ipa_node_params_sum = NULL;
      69              : 
      70              : function_summary <ipcp_transformation *> *ipcp_transformation_sum = NULL;
      71              : 
      72              : /* Edge summary for IPA-CP edge information.  */
      73              : ipa_edge_args_sum_t *ipa_edge_args_sum;
      74              : 
      75              : /* Traits for a hash table for reusing ranges.  */
      76              : 
      77              : struct ipa_vr_ggc_hash_traits : public ggc_cache_remove <ipa_vr *>
      78              : {
      79              :   typedef ipa_vr *value_type;
      80              :   typedef const vrange *compare_type;
      81              :   static hashval_t
      82     17341048 :   hash (const ipa_vr *p)
      83              :     {
      84              :       // This never get called, except in the verification code, as
      85              :       // ipa_get_value_range() calculates the hash itself.  This
      86              :       // function is mostly here for completness' sake.
      87     17341048 :       value_range vr;
      88     17341048 :       p->get_vrange (vr);
      89     17341048 :       inchash::hash hstate;
      90     17341048 :       add_vrange (vr, hstate);
      91     17341048 :       return hstate.end ();
      92     17341048 :     }
      93              :   static bool
      94     24025493 :   equal (const ipa_vr *a, const vrange *b)
      95              :     {
      96     24025493 :       return a->equal_p (*b);
      97              :     }
      98              :   static const bool empty_zero_p = true;
      99              :   static void
     100         1595 :   mark_empty (ipa_vr *&p)
     101              :     {
     102         1595 :       p = NULL;
     103              :     }
     104              :   static bool
     105              :   is_empty (const ipa_vr *p)
     106              :     {
     107              :       return p == NULL;
     108              :     }
     109              :   static bool
     110     44267102 :   is_deleted (const ipa_vr *p)
     111              :     {
     112     44267102 :       return p == reinterpret_cast<const ipa_vr *> (1);
     113              :     }
     114              :   static void
     115       158380 :   mark_deleted (ipa_vr *&p)
     116              :     {
     117       158380 :       p = reinterpret_cast<ipa_vr *> (1);
     118              :     }
     119              : };
     120              : 
     121              : /* Hash table for avoid repeated allocations of equal ranges.  */
     122              : static GTY ((cache)) hash_table<ipa_vr_ggc_hash_traits> *ipa_vr_hash_table;
     123              : 
     124              : /* Holders of ipa cgraph hooks: */
     125              : static struct cgraph_node_hook_list *function_insertion_hook_holder;
     126              : 
     127              : /* Description of a reference to an IPA constant.  */
     128              : struct ipa_cst_ref_desc
     129              : {
     130              :   /* Edge that corresponds to the statement which took the reference.  */
     131              :   struct cgraph_edge *cs;
     132              :   /* Linked list of duplicates created when call graph edges are cloned.  */
     133              :   struct ipa_cst_ref_desc *next_duplicate;
     134              :   /* Number of references in IPA structures, IPA_UNDESCRIBED_USE if the value
     135              :      is out of control.  */
     136              :   int refcount;
     137              : };
     138              : 
     139              : /* Allocation pool for reference descriptions.  */
     140              : 
     141              : static object_allocator<ipa_cst_ref_desc> ipa_refdesc_pool
     142              :   ("IPA-PROP ref descriptions");
     143              : 
     144       655324 : ipa_vr::ipa_vr ()
     145       655324 :   : m_storage (NULL),
     146       655324 :     m_type (NULL)
     147              : {
     148       655324 : }
     149              : 
     150       750641 : ipa_vr::ipa_vr (const vrange &r)
     151       750641 :   : m_storage (ggc_alloc_vrange_storage (r)),
     152       750641 :     m_type (r.type ())
     153              : {
     154       750641 : }
     155              : 
     156              : bool
     157     24025493 : ipa_vr::equal_p (const vrange &r) const
     158              : {
     159     24025493 :   gcc_checking_assert (!r.undefined_p ());
     160     24025493 :   return (types_compatible_p (m_type, r.type ()) && m_storage->equal_p (r));
     161              : }
     162              : 
     163              : bool
     164        88642 : ipa_vr::equal_p (const ipa_vr &o) const
     165              : {
     166        88642 :   if (!known_p ())
     167            0 :     return !o.known_p ();
     168              : 
     169        88642 :   if (!types_compatible_p (m_type, o.m_type))
     170              :     return false;
     171              : 
     172        88642 :   value_range r;
     173        88642 :   o.get_vrange (r);
     174        88642 :   return m_storage->equal_p (r);
     175        88642 : }
     176              : 
     177              : void
     178     28342445 : ipa_vr::get_vrange (value_range &r) const
     179              : {
     180     28342445 :   r.set_type (m_type);
     181     28342445 :   m_storage->get_vrange (r, m_type);
     182     28342445 : }
     183              : 
     184              : void
     185         1956 : ipa_vr::set_unknown ()
     186              : {
     187         1956 :   if (m_storage)
     188         1956 :     ggc_free (m_storage);
     189              : 
     190         1956 :   m_storage = NULL;
     191         1956 : }
     192              : 
     193              : void
     194       611508 : ipa_vr::streamer_read (lto_input_block *ib, data_in *data_in)
     195              : {
     196       611508 :   struct bitpack_d bp = streamer_read_bitpack (ib);
     197       611508 :   bool known = bp_unpack_value (&bp, 1);
     198       611508 :   if (known)
     199              :     {
     200       437774 :       value_range vr;
     201       437774 :       streamer_read_value_range (ib, data_in, vr);
     202       437774 :       if (!m_storage || !m_storage->fits_p (vr))
     203              :         {
     204       437774 :           if (m_storage)
     205            0 :             ggc_free (m_storage);
     206       437774 :           m_storage = ggc_alloc_vrange_storage (vr);
     207              :         }
     208       437774 :       m_storage->set_vrange (vr);
     209       437774 :       m_type = vr.type ();
     210       437774 :     }
     211              :   else
     212              :     {
     213       173734 :       m_storage = NULL;
     214       173734 :       m_type = NULL;
     215              :     }
     216       611508 : }
     217              : 
     218              : void
     219       468593 : ipa_vr::streamer_write (output_block *ob) const
     220              : {
     221       468593 :   struct bitpack_d bp = bitpack_create (ob->main_stream);
     222       468593 :   bp_pack_value (&bp, !!m_storage, 1);
     223       468593 :   streamer_write_bitpack (&bp);
     224       468593 :   if (m_storage)
     225              :     {
     226       466077 :       value_range vr (m_type);
     227       466077 :       m_storage->get_vrange (vr, m_type);
     228       466077 :       streamer_write_vrange (ob, vr);
     229       466077 :     }
     230       468593 : }
     231              : 
     232              : void
     233          723 : ipa_vr::dump (FILE *out) const
     234              : {
     235          723 :   if (known_p ())
     236              :     {
     237          723 :       value_range vr (m_type);
     238          723 :       m_storage->get_vrange (vr, m_type);
     239          723 :       vr.dump (out);
     240          723 :     }
     241              :   else
     242            0 :     fprintf (out, "NO RANGE");
     243          723 : }
     244              : 
     245              : // These stubs are because we use an ipa_vr in a hash_traits and
     246              : // hash-traits.h defines an extern of gt_ggc_mx (T &) instead of
     247              : // picking up the gt_ggc_mx (T *) version.
     248              : void
     249            0 : gt_pch_nx (ipa_vr *&x)
     250              : {
     251            0 :   return gt_pch_nx ((ipa_vr *) x);
     252              : }
     253              : 
     254              : void
     255            0 : gt_ggc_mx (ipa_vr *&x)
     256              : {
     257            0 :   return gt_ggc_mx ((ipa_vr *) x);
     258              : }
     259              : 
     260              : /* Analysis summery of function call return value.  */
     261              : struct GTY(()) ipa_return_value_summary
     262              : {
     263              :   /* Known value range.
     264              :      This needs to be wrapped in struccture due to specific way
     265              :      we allocate ipa_vr. */
     266              :   ipa_vr *vr;
     267              : };
     268              : 
     269              : /* Function summary for return values.  */
     270              : class ipa_return_value_sum_t : public function_summary <ipa_return_value_summary *>
     271              : {
     272              : public:
     273        86020 :   ipa_return_value_sum_t (symbol_table *table, bool ggc):
     274       172040 :     function_summary <ipa_return_value_summary *> (table, ggc) { }
     275              : 
     276              :   /* Hook that is called by summary when a node is duplicated.  */
     277       579296 :   void duplicate (cgraph_node *,
     278              :                   cgraph_node *,
     279              :                   ipa_return_value_summary *data,
     280              :                   ipa_return_value_summary *data2) final override
     281              :   {
     282       579296 :     *data2=*data;
     283       579296 :   }
     284              : };
     285              : 
     286              : /* Structure holding the information that all stores to FLD_OFFSET (measured in
     287              :    bytes) of a particular record type REC_TYPE was storing a pointer to
     288              :    function FN or that there were multiple functions, which is denoted by fn
     289              :    being nullptr. */
     290              : 
     291              : struct GTY((for_user)) noted_fnptr_store
     292              : {
     293              :   tree rec_type;
     294              :   tree fn;
     295              :   unsigned fld_offset;
     296              : };
     297              : 
     298              : /* Hash traits to have a hash table of noted_fnptr_stores.  */
     299              : 
     300              : struct noted_fnptr_hasher : ggc_ptr_hash <noted_fnptr_store>
     301              : {
     302              :   static hashval_t hash (noted_fnptr_store *);
     303              :   static bool equal (noted_fnptr_store *,
     304              :                      noted_fnptr_store *);
     305              : };
     306              : 
     307              : hashval_t
     308       601172 : noted_fnptr_hasher::hash (noted_fnptr_store *val)
     309              : {
     310      1202344 :   return iterative_hash_host_wide_int (val->fld_offset,
     311       601172 :                                        TYPE_UID (val->rec_type));
     312              : }
     313              : 
     314              : bool
     315       520300 : noted_fnptr_hasher::equal (noted_fnptr_store *v1,
     316              :                            noted_fnptr_store *v2)
     317              : {
     318       520300 :   return (v1->rec_type == v2->rec_type
     319       520300 :           && v1->fld_offset == v2->fld_offset);
     320              : }
     321              : 
     322              : 
     323              : /* Structore holding the information that all stores to OFFSET of a particular
     324              :    record type RECTYPE was storing a pointer to specific function or that there
     325              :    were multiple such functions. */
     326              : 
     327              : static GTY(()) hash_table <noted_fnptr_hasher> *noted_fnptrs_in_records;
     328              : 
     329              : /* Variable hoding the return value summary.  */
     330              : static GTY(()) function_summary <ipa_return_value_summary *> *ipa_return_value_sum;
     331              : 
     332              : 
     333              : /* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
     334              :    with NODE should prevent us from analyzing it for the purposes of IPA-CP.  */
     335              : 
     336              : static bool
     337      4014657 : ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
     338              : {
     339      4014657 :   tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
     340              : 
     341      4014657 :   if (!fs_opts)
     342              :     return false;
     343       549528 :   return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
     344              : }
     345              : 
     346              : /* Return index of the formal whose tree is PTREE in function which corresponds
     347              :    to INFO.  */
     348              : 
     349              : static int
     350     42260293 : ipa_get_param_decl_index_1 (vec<ipa_param_descriptor, va_gc> *descriptors,
     351              :                             tree ptree)
     352              : {
     353     42260293 :   int i, count;
     354              : 
     355     42260293 :   count = vec_safe_length (descriptors);
     356     86609788 :   for (i = 0; i < count; i++)
     357     76164265 :     if ((*descriptors)[i].decl_or_type == ptree)
     358              :       return i;
     359              : 
     360              :   return -1;
     361              : }
     362              : 
     363              : /* Return index of the formal whose tree is PTREE in function which corresponds
     364              :    to INFO.  */
     365              : 
     366              : int
     367     26242608 : ipa_get_param_decl_index (class ipa_node_params *info, tree ptree)
     368              : {
     369     26242608 :   return ipa_get_param_decl_index_1 (info->descriptors, ptree);
     370              : }
     371              : 
     372              : static void
     373              : ipa_duplicate_jump_function (cgraph_edge *src, cgraph_edge *dst,
     374              :                              ipa_jump_func *src_jf, ipa_jump_func *dst_jf);
     375              : 
     376              : /* Populate the param_decl field in parameter DESCRIPTORS that correspond to
     377              :    NODE.  */
     378              : 
     379              : static void
     380      5407935 : ipa_populate_param_decls (struct cgraph_node *node,
     381              :                           vec<ipa_param_descriptor, va_gc> &descriptors)
     382              : {
     383      5407935 :   tree fndecl;
     384      5407935 :   tree fnargs;
     385      5407935 :   tree parm;
     386      5407935 :   int param_num;
     387              : 
     388      5407935 :   fndecl = node->decl;
     389      5407935 :   gcc_assert (gimple_has_body_p (fndecl));
     390      5407935 :   fnargs = DECL_ARGUMENTS (fndecl);
     391      5407935 :   param_num = 0;
     392     17854010 :   for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
     393              :     {
     394     12446075 :       descriptors[param_num].decl_or_type = parm;
     395     12446075 :       unsigned int cost = estimate_move_cost (TREE_TYPE (parm), true);
     396     12446075 :       descriptors[param_num].move_cost = cost;
     397              :       /* Watch overflow, move_cost is a bitfield.  */
     398     12446075 :       gcc_checking_assert (cost == descriptors[param_num].move_cost);
     399     12446075 :       param_num++;
     400              :     }
     401      5407935 : }
     402              : 
     403              : /* Return how many formal parameters FNDECL has.  */
     404              : 
     405              : int
     406     14881162 : count_formal_params (tree fndecl)
     407              : {
     408     14881162 :   tree parm;
     409     14881162 :   int count = 0;
     410     14881162 :   gcc_assert (gimple_has_body_p (fndecl));
     411              : 
     412     46057266 :   for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
     413     31176104 :     count++;
     414              : 
     415     14881162 :   return count;
     416              : }
     417              : 
     418              : /* Return the declaration of Ith formal parameter of the function corresponding
     419              :    to INFO.  Note there is no setter function as this array is built just once
     420              :    using ipa_initialize_node_params. */
     421              : 
     422              : void
     423          609 : ipa_dump_param (FILE *file, class ipa_node_params *info, int i)
     424              : {
     425          609 :   fprintf (file, "param #%i", i);
     426          609 :   if ((*info->descriptors)[i].decl_or_type)
     427              :     {
     428          609 :       fprintf (file, " ");
     429          609 :       print_generic_expr (file, (*info->descriptors)[i].decl_or_type);
     430              :     }
     431          609 : }
     432              : 
     433              : /* If necessary, allocate vector of parameter descriptors in info of NODE.
     434              :    Return true if they were allocated, false if not.  */
     435              : 
     436              : static bool
     437      6282033 : ipa_alloc_node_params (struct cgraph_node *node, int param_count)
     438              : {
     439      6282033 :   ipa_node_params *info = ipa_node_params_sum->get_create (node);
     440              : 
     441      6282033 :   if (!info->descriptors && param_count)
     442              :     {
     443      5459649 :       vec_safe_grow_cleared (info->descriptors, param_count, true);
     444      5459649 :       return true;
     445              :     }
     446              :   else
     447              :     return false;
     448              : }
     449              : 
     450              : /* Initialize the ipa_node_params structure associated with NODE by counting
     451              :    the function parameters, creating the descriptors and populating their
     452              :    param_decls.  */
     453              : 
     454              : void
     455      6204588 : ipa_initialize_node_params (struct cgraph_node *node)
     456              : {
     457      6204588 :   ipa_node_params *info = ipa_node_params_sum->get_create (node);
     458              : 
     459      6204588 :   if (!info->descriptors
     460      6204588 :       && ipa_alloc_node_params (node, count_formal_params (node->decl)))
     461      5406586 :     ipa_populate_param_decls (node, *info->descriptors);
     462      6204588 : }
     463              : 
     464              : /* Print VAL which is extracted from a jump function to F.  */
     465              : 
     466              : void
     467         1173 : ipa_print_constant_value (FILE *f, tree val)
     468              : {
     469         1173 :   print_generic_expr (f, val);
     470              : 
     471              :   /* This is in keeping with values_equal_for_ipcp_p.  */
     472         1173 :   if (TREE_CODE (val) == ADDR_EXPR
     473         1173 :       && (TREE_CODE (TREE_OPERAND (val, 0)) == CONST_DECL
     474          249 :           || (TREE_CODE (TREE_OPERAND (val, 0)) == VAR_DECL
     475          102 :               && DECL_IN_CONSTANT_POOL (TREE_OPERAND (val, 0)))))
     476              :     {
     477            0 :       fputs (" -> ", f);
     478            0 :       print_generic_expr (f, DECL_INITIAL (TREE_OPERAND (val, 0)));
     479              :     }
     480         1173 : }
     481              : 
     482              : /* Print contents of JFUNC to F.  If CTX is non-NULL, dump it too.  */
     483              : 
     484              : DEBUG_FUNCTION void
     485         1023 : ipa_dump_jump_function (FILE *f, ipa_jump_func *jump_func,
     486              :                         class ipa_polymorphic_call_context *ctx)
     487              : {
     488         1023 :   enum jump_func_type type = jump_func->type;
     489              : 
     490         1023 :   if (type == IPA_JF_UNKNOWN)
     491          251 :     fprintf (f, "UNKNOWN\n");
     492          772 :   else if (type == IPA_JF_CONST)
     493              :     {
     494          303 :       fprintf (f, "CONST: ");
     495          303 :       ipa_print_constant_value (f, jump_func->value.constant.value);
     496          303 :       fprintf (f, "\n");
     497              :     }
     498          469 :   else if (type == IPA_JF_PASS_THROUGH)
     499              :     {
     500          408 :       fprintf (f, "PASS THROUGH: ");
     501          408 :       fprintf (f, "%d, op %s",
     502              :                jump_func->value.pass_through.formal_id,
     503              :                get_tree_code_name(jump_func->value.pass_through.operation));
     504          408 :       if (jump_func->value.pass_through.operation != NOP_EXPR)
     505              :         {
     506           31 :           fprintf (f, " ");
     507           31 :           if (jump_func->value.pass_through.operand)
     508           27 :             print_generic_expr (f, jump_func->value.pass_through.operand);
     509           31 :           fprintf (f, " (in type ");
     510           31 :           print_generic_expr (f, jump_func->value.pass_through.op_type);
     511           31 :           fprintf (f, ")");
     512              :         }
     513          408 :       if (jump_func->value.pass_through.agg_preserved)
     514          134 :         fprintf (f, ", agg_preserved");
     515          408 :       if (jump_func->value.pass_through.refdesc_decremented)
     516            0 :         fprintf (f, ", refdesc_decremented");
     517          408 :       fprintf (f, "\n");
     518              :     }
     519           61 :   else if (type == IPA_JF_ANCESTOR)
     520              :     {
     521           61 :       fprintf (f, "ANCESTOR: ");
     522           61 :       fprintf (f, "%d, offset " HOST_WIDE_INT_PRINT_DEC,
     523              :                jump_func->value.ancestor.formal_id,
     524              :                jump_func->value.ancestor.offset);
     525           61 :       if (jump_func->value.ancestor.agg_preserved)
     526           29 :         fprintf (f, ", agg_preserved");
     527           61 :       if (jump_func->value.ancestor.keep_null)
     528            4 :         fprintf (f, ", keep_null");
     529           61 :       fprintf (f, "\n");
     530              :     }
     531              : 
     532         1023 :   if (jump_func->agg.items)
     533              :     {
     534           91 :       struct ipa_agg_jf_item *item;
     535           91 :       int j;
     536              : 
     537          182 :       fprintf (f, "         Aggregate passed by %s:\n",
     538           91 :                jump_func->agg.by_ref ? "reference" : "value");
     539          377 :       FOR_EACH_VEC_ELT (*jump_func->agg.items, j, item)
     540              :         {
     541          195 :           fprintf (f, "           offset: " HOST_WIDE_INT_PRINT_DEC ", ",
     542              :                    item->offset);
     543          195 :           fprintf (f, "type: ");
     544          195 :           print_generic_expr (f, item->type);
     545          195 :           fprintf (f, ", ");
     546          195 :           if (item->jftype == IPA_JF_PASS_THROUGH)
     547            7 :             fprintf (f, "PASS THROUGH: %d,",
     548              :                      item->value.pass_through.formal_id);
     549          188 :           else if (item->jftype == IPA_JF_LOAD_AGG)
     550              :             {
     551           11 :               fprintf (f, "LOAD AGG: %d",
     552              :                        item->value.pass_through.formal_id);
     553           11 :               fprintf (f, " [offset: " HOST_WIDE_INT_PRINT_DEC ", by %s],",
     554              :                        item->value.load_agg.offset,
     555           11 :                        item->value.load_agg.by_ref ? "reference"
     556              :                        : "value");
     557              :             }
     558              : 
     559          195 :           if (item->jftype == IPA_JF_PASS_THROUGH
     560          195 :               || item->jftype == IPA_JF_LOAD_AGG)
     561              :             {
     562           18 :               fprintf (f, " op %s",
     563              :                        get_tree_code_name (item->value.pass_through.operation));
     564           18 :               if (item->value.pass_through.operation != NOP_EXPR)
     565              :                 {
     566            9 :                   fprintf (f, " ");
     567            9 :                   if (item->value.pass_through.operand)
     568            8 :                     print_generic_expr (f, item->value.pass_through.operand);
     569            9 :                   fprintf (f, " (in type ");
     570            9 :                   print_generic_expr (f, jump_func->value.pass_through.op_type);
     571            9 :                   fprintf (f, ")");
     572              :                 }
     573              :             }
     574          177 :           else if (item->jftype == IPA_JF_CONST)
     575              :             {
     576          177 :               fprintf (f, "CONST: ");
     577          177 :               ipa_print_constant_value (f, item->value.constant);
     578              :             }
     579            0 :           else if (item->jftype == IPA_JF_UNKNOWN)
     580            0 :             fprintf (f, "UNKNOWN: " HOST_WIDE_INT_PRINT_DEC " bits",
     581            0 :                      tree_to_uhwi (TYPE_SIZE (item->type)));
     582          195 :           fprintf (f, "\n");
     583              :         }
     584              :     }
     585              : 
     586         1023 :   if (ctx && !ctx->useless_p ())
     587              :     {
     588          378 :       fprintf (f, "         Context: ");
     589          378 :       ctx->dump (dump_file);
     590              :     }
     591              : 
     592         1023 :   if (jump_func->m_vr)
     593              :     {
     594          723 :       fprintf (f, "         ");
     595          723 :       jump_func->m_vr->dump (f);
     596          723 :       fprintf (f, "\n");
     597              :     }
     598              :   else
     599          300 :     fprintf (f, "         Unknown VR\n");
     600         1023 : }
     601              : 
     602              : /* Print the jump functions associated with call graph edge CS to file F.  */
     603              : 
     604              : static void
     605          725 : ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
     606              : {
     607          725 :   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
     608          725 :   int count = ipa_get_cs_argument_count (args);
     609              : 
     610         1748 :   for (int i = 0; i < count; i++)
     611              :     {
     612         1023 :       struct ipa_jump_func *jump_func = ipa_get_ith_jump_func (args, i);
     613         1023 :       class ipa_polymorphic_call_context *ctx
     614         1023 :         = ipa_get_ith_polymorhic_call_context (args, i);
     615              : 
     616         1023 :       fprintf (f, "       param %d: ", i);
     617         1023 :       ipa_dump_jump_function (f, jump_func, ctx);
     618              :     }
     619          725 : }
     620              : 
     621              : 
     622              : /* Print the jump functions of all arguments on all call graph edges going from
     623              :    NODE to file F.  */
     624              : 
     625              : void
     626         1069 : ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
     627              : {
     628         1069 :   struct cgraph_edge *cs;
     629              : 
     630         1069 :   fprintf (f, "  Jump functions of caller  %s:\n", node->dump_name ());
     631         2134 :   for (cs = node->callees; cs; cs = cs->next_callee)
     632              :     {
     633              : 
     634         1065 :       fprintf (f, "    callsite  %s -> %s : \n",
     635              :                node->dump_name (),
     636         1065 :                cs->callee->dump_name ());
     637         1065 :       if (!ipa_edge_args_info_available_for_edge_p (cs))
     638          487 :         fprintf (f, "       no arg info\n");
     639              :       else
     640          578 :         ipa_print_node_jump_functions_for_edge (f, cs);
     641              :     }
     642              : 
     643         1216 :   for (cs = node->indirect_calls; cs; cs = cs->next_callee)
     644              :     {
     645          147 :       fprintf (f, "    ");
     646          147 :       cs->indirect_info->dump (f, false);
     647          147 :       if (cs->call_stmt)
     648              :         {
     649          131 :           fprintf (f, ", for stmt ");
     650          131 :           print_gimple_stmt (f, cs->call_stmt, 0, TDF_SLIM);
     651              :         }
     652              :       else
     653           16 :         fprintf (f, "\n");
     654          147 :       if (!ipa_edge_args_info_available_for_edge_p (cs))
     655            0 :         fprintf (f, "       no arg info\n");
     656              :       else
     657          147 :         ipa_print_node_jump_functions_for_edge (f, cs);
     658              :     }
     659         1069 : }
     660              : 
     661              : /* Print ipa_jump_func data structures of all nodes in the call graph to F.  */
     662              : 
     663              : void
     664          161 : ipa_print_all_jump_functions (FILE *f)
     665              : {
     666          161 :   struct cgraph_node *node;
     667              : 
     668          161 :   fprintf (f, "\nJump functions:\n");
     669         1216 :   FOR_EACH_FUNCTION (node)
     670              :     {
     671         1055 :       ipa_print_node_jump_functions (f, node);
     672              :     }
     673          161 : }
     674              : 
     675              : /* Set jfunc to be a know-really nothing jump function.  */
     676              : 
     677              : static void
     678       479068 : ipa_set_jf_unknown (struct ipa_jump_func *jfunc)
     679              : {
     680       479068 :   jfunc->type = IPA_JF_UNKNOWN;
     681       464994 : }
     682              : 
     683              : /* Set JFUNC to be a copy of another jmp (to be used by jump function
     684              :    combination code).  The two functions will share their rdesc.  */
     685              : 
     686              : static void
     687      1033452 : ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
     688              :                      struct ipa_jump_func *src)
     689              : 
     690              : {
     691      1033452 :   gcc_checking_assert (src->type == IPA_JF_CONST);
     692      1033452 :   dst->type = IPA_JF_CONST;
     693      1033452 :   dst->value.constant = src->value.constant;
     694      1033452 : }
     695              : 
     696              : /* Set JFUNC to be a constant jmp function.  */
     697              : 
     698              : static void
     699      2752371 : ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
     700              :                      struct cgraph_edge *cs)
     701              : {
     702      2752371 :   jfunc->type = IPA_JF_CONST;
     703      2752371 :   jfunc->value.constant.value = unshare_expr_without_location (constant);
     704              : 
     705      2752371 :   if (TREE_CODE (constant) == ADDR_EXPR
     706      2752371 :       && (TREE_CODE (TREE_OPERAND (constant, 0)) == FUNCTION_DECL
     707       977419 :           || (VAR_P (TREE_OPERAND (constant, 0))
     708       345700 :               && TREE_STATIC (TREE_OPERAND (constant, 0)))))
     709              :     {
     710       384417 :       struct ipa_cst_ref_desc *rdesc;
     711              : 
     712       384417 :       rdesc = ipa_refdesc_pool.allocate ();
     713       384417 :       rdesc->cs = cs;
     714       384417 :       rdesc->next_duplicate = NULL;
     715       384417 :       rdesc->refcount = 1;
     716       384417 :       jfunc->value.constant.rdesc = rdesc;
     717              :     }
     718              :   else
     719      2367954 :     jfunc->value.constant.rdesc = NULL;
     720      2752371 : }
     721              : 
     722              : /* Set JFUNC to be a simple pass-through jump function.  */
     723              : static void
     724      1380103 : ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
     725              :                                 bool agg_preserved)
     726              : {
     727      1380103 :   jfunc->type = IPA_JF_PASS_THROUGH;
     728      1380103 :   jfunc->value.pass_through.operand = NULL_TREE;
     729      1380103 :   jfunc->value.pass_through.op_type = NULL_TREE;
     730      1380103 :   jfunc->value.pass_through.formal_id = formal_id;
     731      1380103 :   jfunc->value.pass_through.operation = NOP_EXPR;
     732      1380103 :   jfunc->value.pass_through.agg_preserved = agg_preserved;
     733      1380103 :   jfunc->value.pass_through.refdesc_decremented = false;
     734      1246774 : }
     735              : 
     736              : /* Set JFUNC to be an unary pass through jump function.  */
     737              : 
     738              : static void
     739         1021 : ipa_set_jf_unary_pass_through (struct ipa_jump_func *jfunc, int formal_id,
     740              :                                enum tree_code operation, tree op_type)
     741              : {
     742         1021 :   jfunc->type = IPA_JF_PASS_THROUGH;
     743         1021 :   jfunc->value.pass_through.operand = NULL_TREE;
     744         1021 :   jfunc->value.pass_through.op_type = op_type;
     745         1021 :   jfunc->value.pass_through.formal_id = formal_id;
     746         1021 :   jfunc->value.pass_through.operation = operation;
     747         1021 :   jfunc->value.pass_through.agg_preserved = false;
     748         1021 :   jfunc->value.pass_through.refdesc_decremented = false;
     749         1021 : }
     750              : /* Set JFUNC to be an arithmetic pass through jump function.  */
     751              : 
     752              : static void
     753        41780 : ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
     754              :                                tree operand, enum tree_code operation,
     755              :                                tree op_type)
     756              : {
     757        41780 :   jfunc->type = IPA_JF_PASS_THROUGH;
     758            0 :   jfunc->value.pass_through.operand = unshare_expr_without_location (operand);
     759        41780 :   jfunc->value.pass_through.op_type = op_type;
     760        41780 :   jfunc->value.pass_through.formal_id = formal_id;
     761        41780 :   jfunc->value.pass_through.operation = operation;
     762        41780 :   jfunc->value.pass_through.agg_preserved = false;
     763        41780 :   jfunc->value.pass_through.refdesc_decremented = false;
     764        41780 : }
     765              : 
     766              : /* Set JFUNC to be an ancestor jump function.  */
     767              : 
     768              : static void
     769       181318 : ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
     770              :                      int formal_id, bool agg_preserved, bool keep_null)
     771              : {
     772       181318 :   jfunc->type = IPA_JF_ANCESTOR;
     773       181318 :   jfunc->value.ancestor.formal_id = formal_id;
     774       181318 :   jfunc->value.ancestor.offset = offset;
     775       181318 :   jfunc->value.ancestor.agg_preserved = agg_preserved;
     776       181318 :   jfunc->value.ancestor.keep_null = keep_null;
     777       180654 : }
     778              : 
     779              : /* Get IPA BB information about the given BB.  FBI is the context of analyzis
     780              :    of this function body.  */
     781              : 
     782              : static struct ipa_bb_info *
     783     33434939 : ipa_get_bb_info (struct ipa_func_body_info *fbi, basic_block bb)
     784              : {
     785     27923349 :   gcc_checking_assert (fbi);
     786     33434939 :   return &fbi->bb_infos[bb->index];
     787              : }
     788              : 
     789              : /* Structure to be passed in between detect_type_change and
     790              :    check_stmt_for_type_change.  */
     791              : 
     792              : struct prop_type_change_info
     793              : {
     794              :   /* Offset into the object where there is the virtual method pointer we are
     795              :      looking for.  */
     796              :   HOST_WIDE_INT offset;
     797              :   /* The declaration or SSA_NAME pointer of the base that we are checking for
     798              :      type change.  */
     799              :   tree object;
     800              :   /* Set to true if dynamic type change has been detected.  */
     801              :   bool type_maybe_changed;
     802              : };
     803              : 
     804              : /* Return true if STMT can modify a virtual method table pointer.
     805              : 
     806              :    This function makes special assumptions about both constructors and
     807              :    destructors which are all the functions that are allowed to alter the VMT
     808              :    pointers.  It assumes that destructors begin with assignment into all VMT
     809              :    pointers and that constructors essentially look in the following way:
     810              : 
     811              :    1) The very first thing they do is that they call constructors of ancestor
     812              :    sub-objects that have them.
     813              : 
     814              :    2) Then VMT pointers of this and all its ancestors is set to new values
     815              :    corresponding to the type corresponding to the constructor.
     816              : 
     817              :    3) Only afterwards, other stuff such as constructor of member sub-objects
     818              :    and the code written by the user is run.  Only this may include calling
     819              :    virtual functions, directly or indirectly.
     820              : 
     821              :    There is no way to call a constructor of an ancestor sub-object in any
     822              :    other way.
     823              : 
     824              :    This means that we do not have to care whether constructors get the correct
     825              :    type information because they will always change it (in fact, if we define
     826              :    the type to be given by the VMT pointer, it is undefined).
     827              : 
     828              :    The most important fact to derive from the above is that if, for some
     829              :    statement in the section 3, we try to detect whether the dynamic type has
     830              :    changed, we can safely ignore all calls as we examine the function body
     831              :    backwards until we reach statements in section 2 because these calls cannot
     832              :    be ancestor constructors or destructors (if the input is not bogus) and so
     833              :    do not change the dynamic type (this holds true only for automatically
     834              :    allocated objects but at the moment we devirtualize only these).  We then
     835              :    must detect that statements in section 2 change the dynamic type and can try
     836              :    to derive the new type.  That is enough and we can stop, we will never see
     837              :    the calls into constructors of sub-objects in this code.  Therefore we can
     838              :    safely ignore all call statements that we traverse.
     839              :   */
     840              : 
     841              : static bool
     842            9 : stmt_may_be_vtbl_ptr_store (gimple *stmt)
     843              : {
     844            9 :   if (is_gimple_call (stmt))
     845              :     return false;
     846            0 :   if (gimple_clobber_p (stmt))
     847              :     return false;
     848            0 :   else if (is_gimple_assign (stmt))
     849              :     {
     850            0 :       tree lhs = gimple_assign_lhs (stmt);
     851              : 
     852            0 :       if (!AGGREGATE_TYPE_P (TREE_TYPE (lhs)))
     853              :         {
     854            0 :           if (flag_strict_aliasing
     855            0 :               && !POINTER_TYPE_P (TREE_TYPE (lhs)))
     856              :             return false;
     857              : 
     858            0 :           if (TREE_CODE (lhs) == COMPONENT_REF
     859            0 :               && !DECL_VIRTUAL_P (TREE_OPERAND (lhs, 1)))
     860            0 :             return false;
     861              :           /* In the future we might want to use get_ref_base_and_extent to find
     862              :              if there is a field corresponding to the offset and if so, proceed
     863              :              almost like if it was a component ref.  */
     864              :         }
     865              :     }
     866              :   return true;
     867              : }
     868              : 
     869              : /* Callback of walk_aliased_vdefs and a helper function for detect_type_change
     870              :    to check whether a particular statement may modify the virtual table
     871              :    pointerIt stores its result into DATA, which points to a
     872              :    prop_type_change_info structure.  */
     873              : 
     874              : static bool
     875            9 : check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
     876              : {
     877            9 :   gimple *stmt = SSA_NAME_DEF_STMT (vdef);
     878            9 :   struct prop_type_change_info *tci = (struct prop_type_change_info *) data;
     879              : 
     880            9 :   if (stmt_may_be_vtbl_ptr_store (stmt))
     881              :     {
     882            0 :       tci->type_maybe_changed = true;
     883            0 :       return true;
     884              :     }
     885              :   else
     886              :     return false;
     887              : }
     888              : 
     889              : /* See if ARG is PARAM_DECl describing instance passed by pointer
     890              :    or reference in FUNCTION.  Return false if the dynamic type may change
     891              :    in between beggining of the function until CALL is invoked.
     892              : 
     893              :    Generally functions are not allowed to change type of such instances,
     894              :    but they call destructors.  We assume that methods cannot destroy the THIS
     895              :    pointer.  Also as a special cases, constructor and destructors may change
     896              :    type of the THIS pointer.  */
     897              : 
     898              : static bool
     899         9718 : param_type_may_change_p (tree function, tree arg, gimple *call)
     900              : {
     901              :   /* Pure functions cannot do any changes on the dynamic type;
     902              :      that require writting to memory.  */
     903         9718 :   if (flags_from_decl_or_type (function) & (ECF_PURE | ECF_CONST))
     904              :     return false;
     905              :   /* We need to check if we are within inlined consturctor
     906              :      or destructor (ideally we would have way to check that the
     907              :      inline cdtor is actually working on ARG, but we don't have
     908              :      easy tie on this, so punt on all non-pure cdtors.
     909              :      We may also record the types of cdtors and once we know type
     910              :      of the instance match them.
     911              : 
     912              :      Also code unification optimizations may merge calls from
     913              :      different blocks making return values unreliable.  So
     914              :      do nothing during late optimization.  */
     915         9718 :   if (DECL_STRUCT_FUNCTION (function)->after_inlining)
     916              :     return true;
     917         9718 :   if (TREE_CODE (arg) == SSA_NAME
     918         9718 :       && SSA_NAME_IS_DEFAULT_DEF (arg)
     919        19436 :       && TREE_CODE (SSA_NAME_VAR (arg)) == PARM_DECL)
     920              :     {
     921              :       /* Normal (non-THIS) argument.  */
     922         9718 :       if ((SSA_NAME_VAR (arg) != DECL_ARGUMENTS (function)
     923         9051 :            || TREE_CODE (TREE_TYPE (function)) != METHOD_TYPE)
     924              :           /* THIS pointer of an method - here we want to watch constructors
     925              :              and destructors as those definitely may change the dynamic
     926              :              type.  */
     927        18178 :           || (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE
     928         8460 :               && !DECL_CXX_CONSTRUCTOR_P (function)
     929         8459 :               && !DECL_CXX_DESTRUCTOR_P (function)
     930         8458 :               && (SSA_NAME_VAR (arg) == DECL_ARGUMENTS (function))))
     931              :         {
     932              :           /* Walk the inline stack and watch out for ctors/dtors.  */
     933        42824 :           for (tree block = gimple_block (call); block && TREE_CODE (block) == BLOCK;
     934        16554 :                block = BLOCK_SUPERCONTEXT (block))
     935        16569 :             if (inlined_polymorphic_ctor_dtor_block_p (block, false))
     936              :               return true;
     937              :           return false;
     938              :         }
     939              :     }
     940              :   return true;
     941              : }
     942              : 
     943              : /* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
     944              :    callsite CALL) by looking for assignments to its virtual table pointer.  If
     945              :    it is, return true.  ARG is the object itself (not a pointer
     946              :    to it, unless dereferenced).  BASE is the base of the memory access as
     947              :    returned by get_ref_base_and_extent, as is the offset.
     948              : 
     949              :    This is helper function for detect_type_change and detect_type_change_ssa
     950              :    that does the heavy work which is usually unnecesary.  */
     951              : 
     952              : static bool
     953           17 : detect_type_change_from_memory_writes (ipa_func_body_info *fbi, tree arg,
     954              :                                        tree base, tree comp_type, gcall *call,
     955              :                                        HOST_WIDE_INT offset)
     956              : {
     957           17 :   struct prop_type_change_info tci;
     958           17 :   ao_ref ao;
     959              : 
     960           17 :   gcc_checking_assert (DECL_P (arg)
     961              :                        || TREE_CODE (arg) == MEM_REF
     962              :                        || handled_component_p (arg));
     963              : 
     964           17 :   comp_type = TYPE_MAIN_VARIANT (comp_type);
     965              : 
     966              :   /* Const calls cannot call virtual methods through VMT and so type changes do
     967              :      not matter.  */
     968           17 :   if (!flag_devirtualize || !gimple_vuse (call)
     969              :       /* Be sure expected_type is polymorphic.  */
     970           17 :       || !comp_type
     971           17 :       || TREE_CODE (comp_type) != RECORD_TYPE
     972           17 :       || !TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))
     973           34 :       || !BINFO_VTABLE (TYPE_BINFO (TYPE_MAIN_VARIANT (comp_type))))
     974              :     return true;
     975              : 
     976           17 :   if (fbi->aa_walk_budget == 0)
     977              :     return false;
     978              : 
     979           17 :   ao_ref_init (&ao, arg);
     980           17 :   ao.base = base;
     981           17 :   ao.offset = offset;
     982           17 :   ao.size = POINTER_SIZE;
     983           17 :   ao.max_size = ao.size;
     984              : 
     985           17 :   tci.offset = offset;
     986           17 :   tci.object = get_base_address (arg);
     987           17 :   tci.type_maybe_changed = false;
     988              : 
     989           17 :   int walked
     990           34 :     = walk_aliased_vdefs (&ao, gimple_vuse (call), check_stmt_for_type_change,
     991              :                           &tci, NULL, NULL, fbi->aa_walk_budget);
     992           17 :   if (walked >= 0)
     993           17 :     fbi->aa_walk_budget -= walked;
     994              :   else
     995            0 :     fbi->aa_walk_budget = 0;
     996              : 
     997           17 :   if (walked >= 0 && !tci.type_maybe_changed)
     998              :     return false;
     999              : 
    1000              :   return true;
    1001              : }
    1002              : 
    1003              : /* Detect whether the dynamic type of ARG of COMP_TYPE may have changed.
    1004              :    If it is, return true.  ARG is the object itself (not a pointer
    1005              :    to it, unless dereferenced).  BASE is the base of the memory access as
    1006              :    returned by get_ref_base_and_extent, as is the offset.  */
    1007              : 
    1008              : static bool
    1009          749 : detect_type_change (ipa_func_body_info *fbi, tree arg, tree base,
    1010              :                     tree comp_type, gcall *call,
    1011              :                     HOST_WIDE_INT offset)
    1012              : {
    1013          749 :   if (!flag_devirtualize)
    1014              :     return false;
    1015              : 
    1016          749 :   if (TREE_CODE (base) == MEM_REF
    1017         1498 :       && !param_type_may_change_p (current_function_decl,
    1018          749 :                                    TREE_OPERAND (base, 0),
    1019              :                                    call))
    1020              :     return false;
    1021           12 :   return detect_type_change_from_memory_writes (fbi, arg, base, comp_type,
    1022           12 :                                                 call, offset);
    1023              : }
    1024              : 
    1025              : /* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
    1026              :    SSA name (its dereference will become the base and the offset is assumed to
    1027              :    be zero).  */
    1028              : 
    1029              : static bool
    1030         8969 : detect_type_change_ssa (ipa_func_body_info *fbi, tree arg, tree comp_type,
    1031              :                         gcall *call)
    1032              : {
    1033         8969 :   gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
    1034         8969 :   if (!flag_devirtualize
    1035         8969 :       || !POINTER_TYPE_P (TREE_TYPE (arg)))
    1036              :     return false;
    1037              : 
    1038         8969 :   if (!param_type_may_change_p (current_function_decl, arg, call))
    1039              :     return false;
    1040              : 
    1041            5 :   arg = build2 (MEM_REF, ptr_type_node, arg,
    1042              :                 build_int_cst (ptr_type_node, 0));
    1043              : 
    1044            5 :   return detect_type_change_from_memory_writes (fbi, arg, arg, comp_type,
    1045            5 :                                                 call, 0);
    1046              : }
    1047              : 
    1048              : /* Callback of walk_aliased_vdefs.  Flags that it has been invoked to the
    1049              :    boolean variable pointed to by DATA.  */
    1050              : 
    1051              : static bool
    1052      1586048 : mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
    1053              :                      void *data)
    1054              : {
    1055      1586048 :   bool *b = (bool *) data;
    1056      1586048 :   *b = true;
    1057      1586048 :   return true;
    1058              : }
    1059              : 
    1060              : /* Find the nearest valid aa status for parameter specified by INDEX that
    1061              :    dominates BB.  */
    1062              : 
    1063              : static struct ipa_param_aa_status *
    1064      4383191 : find_dominating_aa_status (struct ipa_func_body_info *fbi, basic_block bb,
    1065              :                            int index)
    1066              : {
    1067     13245294 :   while (true)
    1068              :     {
    1069     13245294 :       bb = get_immediate_dominator (CDI_DOMINATORS, bb);
    1070     13245294 :       if (!bb)
    1071              :         return NULL;
    1072     10301634 :       struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
    1073     12403365 :       if (!bi->param_aa_statuses.is_empty ()
    1074      2101731 :           && bi->param_aa_statuses[index].valid)
    1075      1439531 :         return &bi->param_aa_statuses[index];
    1076              :     }
    1077              : }
    1078              : 
    1079              : /* Get AA status structure for the given BB and parameter with INDEX.  Allocate
    1080              :    structures and/or intialize the result with a dominating description as
    1081              :    necessary.  */
    1082              : 
    1083              : static struct ipa_param_aa_status *
    1084      6609922 : parm_bb_aa_status_for_bb (struct ipa_func_body_info *fbi, basic_block bb,
    1085              :                           int index)
    1086              : {
    1087      6609922 :   gcc_checking_assert (fbi);
    1088      6609922 :   struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
    1089      6609922 :   if (bi->param_aa_statuses.is_empty ())
    1090      3773354 :     bi->param_aa_statuses.safe_grow_cleared (fbi->param_count, true);
    1091      6609922 :   struct ipa_param_aa_status *paa = &bi->param_aa_statuses[index];
    1092      6609922 :   if (!paa->valid)
    1093              :     {
    1094      4383191 :       gcc_checking_assert (!paa->parm_modified
    1095              :                            && !paa->ref_modified
    1096              :                            && !paa->pt_modified);
    1097      4383191 :       struct ipa_param_aa_status *dom_paa;
    1098      4383191 :       dom_paa = find_dominating_aa_status (fbi, bb, index);
    1099      4383191 :       if (dom_paa)
    1100      1439531 :         *paa = *dom_paa;
    1101              :       else
    1102      2943660 :         paa->valid = true;
    1103              :     }
    1104              : 
    1105      6609922 :   return paa;
    1106              : }
    1107              : 
    1108              : /* Return true if a load from a formal parameter PARM_LOAD is known to retrieve
    1109              :    a value known not to be modified in this function before reaching the
    1110              :    statement STMT.  FBI holds information about the function we have so far
    1111              :    gathered but do not survive the summary building stage.  */
    1112              : 
    1113              : static bool
    1114      1168059 : parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
    1115              :                               gimple *stmt, tree parm_load)
    1116              : {
    1117      1168059 :   struct ipa_param_aa_status *paa;
    1118      1168059 :   bool modified = false;
    1119      1168059 :   ao_ref refd;
    1120              : 
    1121      1168059 :   tree base = get_base_address (parm_load);
    1122      1168059 :   gcc_assert (TREE_CODE (base) == PARM_DECL);
    1123      1168059 :   if (TREE_READONLY (base))
    1124              :     return true;
    1125              : 
    1126      1086943 :   gcc_checking_assert (fbi);
    1127      1086943 :   paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
    1128      1086943 :   if (paa->parm_modified || fbi->aa_walk_budget == 0)
    1129              :     return false;
    1130              : 
    1131      1848996 :   gcc_checking_assert (gimple_vuse (stmt) != NULL_TREE);
    1132       924498 :   ao_ref_init (&refd, parm_load);
    1133      1848996 :   int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
    1134              :                                    &modified, NULL, NULL,
    1135              :                                    fbi->aa_walk_budget);
    1136       924498 :   if (walked < 0)
    1137              :     {
    1138            8 :       modified = true;
    1139            8 :       fbi->aa_walk_budget = 0;
    1140              :     }
    1141              :   else
    1142       924490 :     fbi->aa_walk_budget -= walked;
    1143       924498 :   if (paa && modified)
    1144       107875 :     paa->parm_modified = true;
    1145       924498 :   return !modified;
    1146              : }
    1147              : 
    1148              : /* If STMT is an assignment that loads a value from an parameter declaration,
    1149              :    return the index of the parameter in ipa_node_params which has not been
    1150              :    modified.  Otherwise return -1.  */
    1151              : 
    1152              : static int
    1153      6514634 : load_from_unmodified_param (struct ipa_func_body_info *fbi,
    1154              :                             vec<ipa_param_descriptor, va_gc> *descriptors,
    1155              :                             gimple *stmt)
    1156              : {
    1157      6514634 :   int index;
    1158      6514634 :   tree op1;
    1159              : 
    1160      6514634 :   if (!gimple_assign_single_p (stmt))
    1161              :     return -1;
    1162              : 
    1163      4343155 :   op1 = gimple_assign_rhs1 (stmt);
    1164      4343155 :   if (TREE_CODE (op1) != PARM_DECL)
    1165              :     return -1;
    1166              : 
    1167        70895 :   index = ipa_get_param_decl_index_1 (descriptors, op1);
    1168        70895 :   if (index < 0
    1169        70895 :       || !parm_preserved_before_stmt_p (fbi, index, stmt, op1))
    1170        25514 :     return -1;
    1171              : 
    1172              :   return index;
    1173              : }
    1174              : 
    1175              : /* Return true if memory reference REF (which must be a load through parameter
    1176              :    with INDEX) loads data that are known to be unmodified in this function
    1177              :    before reaching statement STMT.  */
    1178              : 
    1179              : static bool
    1180      4708101 : parm_ref_data_preserved_p (struct ipa_func_body_info *fbi,
    1181              :                            int index, gimple *stmt, tree ref)
    1182              : {
    1183      4708101 :   struct ipa_param_aa_status *paa;
    1184      4708101 :   bool modified = false;
    1185      4708101 :   ao_ref refd;
    1186              : 
    1187      4708101 :   gcc_checking_assert (fbi);
    1188      4708101 :   paa = parm_bb_aa_status_for_bb (fbi, gimple_bb (stmt), index);
    1189      4708101 :   if (paa->ref_modified || fbi->aa_walk_budget == 0)
    1190              :     return false;
    1191              : 
    1192      7343842 :   gcc_checking_assert (gimple_vuse (stmt));
    1193      3671921 :   ao_ref_init (&refd, ref);
    1194      7343842 :   int walked = walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified,
    1195              :                                    &modified, NULL, NULL,
    1196              :                                    fbi->aa_walk_budget);
    1197      3671921 :   if (walked < 0)
    1198              :     {
    1199            8 :       modified = true;
    1200            8 :       fbi->aa_walk_budget = 0;
    1201              :     }
    1202              :   else
    1203      3671913 :     fbi->aa_walk_budget -= walked;
    1204      3671921 :   if (modified)
    1205       640044 :     paa->ref_modified = true;
    1206      3671921 :   return !modified;
    1207              : }
    1208              : 
    1209              : /* Return true if the data pointed to by PARM (which is a parameter with INDEX)
    1210              :    is known to be unmodified in this function before reaching call statement
    1211              :    CALL into which it is passed.  FBI describes the function body.  */
    1212              : 
    1213              : static bool
    1214      1151843 : parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
    1215              :                               gimple *call, tree parm)
    1216              : {
    1217      1151843 :   bool modified = false;
    1218      1151843 :   ao_ref refd;
    1219              : 
    1220              :   /* It's unnecessary to calculate anything about memory contnets for a const
    1221              :      function because it is not goin to use it.  But do not cache the result
    1222              :      either.  Also, no such calculations for non-pointers.  */
    1223      1600367 :   if (!gimple_vuse (call)
    1224      1151843 :       || !POINTER_TYPE_P (TREE_TYPE (parm)))
    1225              :     return false;
    1226              : 
    1227       814878 :   struct ipa_param_aa_status *paa = parm_bb_aa_status_for_bb (fbi,
    1228              :                                                               gimple_bb (call),
    1229              :                                                               index);
    1230       814878 :   if (paa->pt_modified || fbi->aa_walk_budget == 0)
    1231              :     return false;
    1232              : 
    1233       703319 :   ao_ref_init_from_ptr_and_size (&refd, parm, NULL_TREE);
    1234      1406638 :   int walked = walk_aliased_vdefs (&refd, gimple_vuse (call), mark_modified,
    1235              :                                    &modified, NULL, NULL,
    1236              :                                    fbi->aa_walk_budget);
    1237       703319 :   if (walked < 0)
    1238              :     {
    1239            0 :       fbi->aa_walk_budget = 0;
    1240            0 :       modified = true;
    1241              :     }
    1242              :   else
    1243       703319 :     fbi->aa_walk_budget -= walked;
    1244       703319 :   if (modified)
    1245       259192 :     paa->pt_modified = true;
    1246       703319 :   return !modified;
    1247              : }
    1248              : 
    1249              : /* Return true if we can prove that OP is a memory reference loading
    1250              :    data from an aggregate passed as a parameter.
    1251              : 
    1252              :    The function works in two modes.  If GUARANTEED_UNMODIFIED is NULL, it return
    1253              :    false if it cannot prove that the value has not been modified before the
    1254              :    load in STMT.  If GUARANTEED_UNMODIFIED is not NULL, it will return true even
    1255              :    if it cannot prove the value has not been modified, in that case it will
    1256              :    store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
    1257              : 
    1258              :    INFO and PARMS_AINFO describe parameters of the current function (but the
    1259              :    latter can be NULL), STMT is the load statement.  If function returns true,
    1260              :    *INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
    1261              :    within the aggregate and whether it is a load from a value passed by
    1262              :    reference respectively.
    1263              : 
    1264              :    Return false if the offset divided by BITS_PER_UNIT would not fit into an
    1265              :    unsigned int.  */
    1266              : 
    1267              : bool
    1268     25306575 : ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
    1269              :                         vec<ipa_param_descriptor, va_gc> *descriptors,
    1270              :                         gimple *stmt, tree op, int *index_p,
    1271              :                         HOST_WIDE_INT *offset_p, poly_int64 *size_p,
    1272              :                         bool *by_ref_p, bool *guaranteed_unmodified)
    1273              : {
    1274     25306575 :   int index;
    1275     25306575 :   HOST_WIDE_INT size;
    1276     25306575 :   bool reverse;
    1277     25306575 :   tree base = get_ref_base_and_extent_hwi (op, offset_p, &size, &reverse);
    1278              : 
    1279     25306575 :   if (!base
    1280     23925154 :       || (*offset_p / BITS_PER_UNIT) > UINT_MAX)
    1281              :     return false;
    1282              : 
    1283              :   /* We can not propagate across volatile loads.  */
    1284     23925123 :   if (TREE_THIS_VOLATILE (op))
    1285              :     return false;
    1286              : 
    1287     22714500 :   if (DECL_P (base))
    1288              :     {
    1289     11124368 :       int index = ipa_get_param_decl_index_1 (descriptors, base);
    1290     11124368 :       if (index >= 0
    1291     11124368 :           && parm_preserved_before_stmt_p (fbi, index, stmt, op))
    1292              :         {
    1293       788222 :           *index_p = index;
    1294       788222 :           *by_ref_p = false;
    1295       788222 :           if (size_p)
    1296        23939 :             *size_p = size;
    1297       788222 :           if (guaranteed_unmodified)
    1298          135 :             *guaranteed_unmodified = true;
    1299       788222 :           return true;
    1300              :         }
    1301     10336146 :       return false;
    1302              :     }
    1303              : 
    1304     11590132 :   if (TREE_CODE (base) != MEM_REF
    1305     10803337 :            || TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME
    1306     22389895 :            || !integer_zerop (TREE_OPERAND (base, 1)))
    1307      1738727 :     return false;
    1308              : 
    1309      9851405 :   if (SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0)))
    1310              :     {
    1311      4822422 :       tree parm = SSA_NAME_VAR (TREE_OPERAND (base, 0));
    1312      4822422 :       index = ipa_get_param_decl_index_1 (descriptors, parm);
    1313              :     }
    1314              :   else
    1315              :     {
    1316              :       /* This branch catches situations where a pointer parameter is not a
    1317              :          gimple register, for example:
    1318              : 
    1319              :          void hip7(S*) (struct S * p)
    1320              :          {
    1321              :          void (*<T2e4>) (struct S *) D.1867;
    1322              :          struct S * p.1;
    1323              : 
    1324              :          <bb 2>:
    1325              :          p.1_1 = p;
    1326              :          D.1867_2 = p.1_1->f;
    1327              :          D.1867_2 ();
    1328              :          gdp = &p;
    1329              :       */
    1330              : 
    1331      5028983 :       gimple *def = SSA_NAME_DEF_STMT (TREE_OPERAND (base, 0));
    1332      5028983 :       index = load_from_unmodified_param (fbi, descriptors, def);
    1333              :     }
    1334              : 
    1335      9851405 :   if (index >= 0)
    1336              :     {
    1337      4707802 :       bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
    1338      4707802 :       if (!data_preserved && !guaranteed_unmodified)
    1339              :         return false;
    1340              : 
    1341      3032092 :       *index_p = index;
    1342      3032092 :       *by_ref_p = true;
    1343      3032092 :       if (size_p)
    1344        28562 :         *size_p = size;
    1345      3032092 :       if (guaranteed_unmodified)
    1346         2108 :         *guaranteed_unmodified = data_preserved;
    1347      3032092 :       return true;
    1348              :     }
    1349              :   return false;
    1350              : }
    1351              : 
    1352              : /* If STMT is an assignment that loads a value from a parameter declaration,
    1353              :    or from an aggregate passed as the parameter either by value or reference,
    1354              :    return the index of the parameter in ipa_node_params.  Otherwise return -1.
    1355              : 
    1356              :    FBI holds gathered information about the function.  INFO describes
    1357              :    parameters of the function, STMT is the assignment statement.  If it is a
    1358              :    memory load from an aggregate, *OFFSET_P is filled with offset within the
    1359              :    aggregate, and *BY_REF_P specifies whether the aggregate is passed by
    1360              :    reference.  */
    1361              : 
    1362              : static int
    1363       354104 : load_from_unmodified_param_or_agg (struct ipa_func_body_info *fbi,
    1364              :                                    class ipa_node_params *info,
    1365              :                                    gimple *stmt,
    1366              :                                    HOST_WIDE_INT *offset_p,
    1367              :                                    bool *by_ref_p)
    1368              : {
    1369       354104 :   int index = load_from_unmodified_param (fbi, info->descriptors, stmt);
    1370       354104 :   poly_int64 size;
    1371              : 
    1372              :   /* Load value from a parameter declaration.  */
    1373       354104 :   if (index >= 0)
    1374              :     {
    1375          244 :       *offset_p = -1;
    1376          244 :       return index;
    1377              :     }
    1378              : 
    1379       353860 :   if (!gimple_assign_load_p (stmt))
    1380              :     return -1;
    1381              : 
    1382       178486 :   tree rhs = gimple_assign_rhs1 (stmt);
    1383              : 
    1384              :   /* Skip memory reference containing VIEW_CONVERT_EXPR.  */
    1385       323714 :   for (tree t = rhs; handled_component_p (t); t = TREE_OPERAND (t, 0))
    1386       145285 :     if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
    1387              :       return -1;
    1388              : 
    1389              :   /* Skip memory reference containing bit-field.  */
    1390       178429 :   if (TREE_CODE (rhs) == BIT_FIELD_REF
    1391       178429 :       || contains_bitfld_component_ref_p (rhs))
    1392            0 :     return -1;
    1393              : 
    1394       178429 :   if (!ipa_load_from_parm_agg (fbi, info->descriptors, stmt, rhs, &index,
    1395              :                                offset_p, &size, by_ref_p))
    1396              :     return -1;
    1397              : 
    1398        49423 :   gcc_assert (!maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (rhs))),
    1399              :                          size));
    1400        49423 :   if (!*by_ref_p)
    1401              :     {
    1402        23247 :       tree param_type = ipa_get_type (info, index);
    1403              : 
    1404        23247 :       if (!param_type || !AGGREGATE_TYPE_P (param_type))
    1405              :         return -1;
    1406              :     }
    1407        26176 :   else if (TREE_THIS_VOLATILE (rhs))
    1408              :     return -1;
    1409              : 
    1410        47967 :   return index;
    1411              : }
    1412              : 
    1413              : /* Walk pointer adjustemnts from OP (such as POINTER_PLUS and ADDR_EXPR)
    1414              :    to find original pointer.  Initialize RET to the pointer which results from
    1415              :    the walk.
    1416              :    If offset is known return true and initialize OFFSET_RET.  */
    1417              : 
    1418              : bool
    1419     15642893 : unadjusted_ptr_and_unit_offset (tree op, tree *ret, poly_int64 *offset_ret)
    1420              : {
    1421     15642893 :   poly_int64 offset = 0;
    1422     15642893 :   bool offset_known = true;
    1423     15642893 :   int i;
    1424              : 
    1425     20229818 :   for (i = 0; i < param_ipa_jump_function_lookups; i++)
    1426              :     {
    1427     20228804 :       if (TREE_CODE (op) == ADDR_EXPR)
    1428              :         {
    1429      1569205 :           poly_int64 extra_offset;
    1430      1569205 :           tree base = get_addr_base_and_unit_offset (TREE_OPERAND (op, 0),
    1431              :                                                      &extra_offset);
    1432      1569205 :           if (!base)
    1433              :             {
    1434        27611 :               base = get_base_address (TREE_OPERAND (op, 0));
    1435        27611 :               if (TREE_CODE (base) != MEM_REF)
    1436              :                 break;
    1437              :               offset_known = false;
    1438              :             }
    1439              :           else
    1440              :             {
    1441      1541594 :               if (TREE_CODE (base) != MEM_REF)
    1442              :                 break;
    1443       260310 :               offset += extra_offset;
    1444              :             }
    1445       260310 :           op = TREE_OPERAND (base, 0);
    1446       260310 :           if (mem_ref_offset (base).to_shwi (&extra_offset))
    1447       260310 :             offset += extra_offset;
    1448              :           else
    1449              :             offset_known = false;
    1450              :         }
    1451     18659599 :       else if (TREE_CODE (op) == SSA_NAME
    1452     18659599 :                && !SSA_NAME_IS_DEFAULT_DEF (op))
    1453              :         {
    1454      6445953 :           gimple *pstmt = SSA_NAME_DEF_STMT (op);
    1455              : 
    1456      6445953 :           if (gimple_assign_single_p (pstmt))
    1457      3121024 :             op = gimple_assign_rhs1 (pstmt);
    1458      3324929 :           else if (is_gimple_assign (pstmt)
    1459      3324929 :                    && gimple_assign_rhs_code (pstmt) == POINTER_PLUS_EXPR)
    1460              :             {
    1461      1205591 :               poly_int64 extra_offset = 0;
    1462      1205591 :               if (ptrdiff_tree_p (gimple_assign_rhs2 (pstmt),
    1463              :                   &extra_offset))
    1464      1205591 :                 offset += extra_offset;
    1465              :               else
    1466              :                 offset_known = false;
    1467      1205591 :               op = gimple_assign_rhs1 (pstmt);
    1468              :             }
    1469              :           else
    1470              :             break;
    1471              :         }
    1472              :       else
    1473              :         break;
    1474              :     }
    1475     15642893 :   *ret = op;
    1476     15642893 :   *offset_ret = offset;
    1477     15642893 :   return offset_known;
    1478              : }
    1479              : 
    1480              : /* Given that an actual argument is an SSA_NAME (given in NAME) and is a result
    1481              :    of an assignment statement STMT, try to determine whether we are actually
    1482              :    handling any of the following cases and construct an appropriate jump
    1483              :    function into JFUNC if so:
    1484              : 
    1485              :    1) The passed value is loaded from a formal parameter which is not a gimple
    1486              :    register (most probably because it is addressable, the value has to be
    1487              :    scalar) and we can guarantee the value has not changed.  This case can
    1488              :    therefore be described by a simple pass-through jump function.  For example:
    1489              : 
    1490              :       foo (int a)
    1491              :       {
    1492              :         int a.0;
    1493              : 
    1494              :         a.0_2 = a;
    1495              :         bar (a.0_2);
    1496              : 
    1497              :    2) The passed value can be described by a simple arithmetic pass-through
    1498              :    jump function. E.g.
    1499              : 
    1500              :       foo (int a)
    1501              :       {
    1502              :         int D.2064;
    1503              : 
    1504              :         D.2064_4 = a.1(D) + 4;
    1505              :         bar (D.2064_4);
    1506              : 
    1507              :    This case can also occur in combination of the previous one, e.g.:
    1508              : 
    1509              :       foo (int a, int z)
    1510              :       {
    1511              :         int a.0;
    1512              :         int D.2064;
    1513              : 
    1514              :         a.0_3 = a;
    1515              :         D.2064_4 = a.0_3 + 4;
    1516              :         foo (D.2064_4);
    1517              : 
    1518              :    3) The passed value is an address of an object within another one (which
    1519              :    also passed by reference).  Such situations are described by an ancestor
    1520              :    jump function and describe situations such as:
    1521              : 
    1522              :      B::foo() (struct B * const this)
    1523              :      {
    1524              :        struct A * D.1845;
    1525              : 
    1526              :        D.1845_2 = &this_1(D)->D.1748;
    1527              :        A::bar (D.1845_2);
    1528              : 
    1529              :    INFO is the structure describing individual parameters access different
    1530              :    stages of IPA optimizations.  PARMS_AINFO contains the information that is
    1531              :    only needed for intraprocedural analysis.  */
    1532              : 
    1533              : static void
    1534      1242084 : compute_complex_assign_jump_func (struct ipa_func_body_info *fbi,
    1535              :                                   class ipa_node_params *info,
    1536              :                                   struct ipa_jump_func *jfunc,
    1537              :                                   gcall *call, gimple *stmt, tree name,
    1538              :                                   tree param_type)
    1539              : {
    1540      1242084 :   HOST_WIDE_INT offset, size;
    1541      1242084 :   tree op1, tc_ssa, base, ssa;
    1542      1242084 :   bool reverse;
    1543      1242084 :   int index;
    1544              : 
    1545      1242084 :   op1 = gimple_assign_rhs1 (stmt);
    1546              : 
    1547      1242084 :   if (TREE_CODE (op1) == SSA_NAME)
    1548              :     {
    1549       389931 :       if (SSA_NAME_IS_DEFAULT_DEF (op1))
    1550       110537 :         index = ipa_get_param_decl_index (info, SSA_NAME_VAR (op1));
    1551              :       else
    1552       279394 :         index = load_from_unmodified_param (fbi, info->descriptors,
    1553       279394 :                                             SSA_NAME_DEF_STMT (op1));
    1554              :       tc_ssa = op1;
    1555              :     }
    1556              :   else
    1557              :     {
    1558       852153 :       index = load_from_unmodified_param (fbi, info->descriptors, stmt);
    1559       852153 :       tc_ssa = gimple_assign_lhs (stmt);
    1560              :     }
    1561              : 
    1562      1242084 :   if (index >= 0)
    1563              :     {
    1564       111896 :       if (lto_variably_modified_type_p (TREE_TYPE (name)))
    1565      1080484 :         return;
    1566              : 
    1567       111850 :       switch (gimple_assign_rhs_class (stmt))
    1568              :         {
    1569        63601 :         case GIMPLE_BINARY_RHS:
    1570        63601 :           {
    1571        63601 :             tree op2 = gimple_assign_rhs2 (stmt);
    1572        63601 :             if (!is_gimple_ip_invariant (op2)
    1573        63601 :                 || ((TREE_CODE_CLASS (gimple_assign_rhs_code (stmt))
    1574              :                      != tcc_comparison)
    1575        32472 :                     && !useless_type_conversion_p (TREE_TYPE (name),
    1576        32472 :                                                    TREE_TYPE (op1))))
    1577        23279 :               return;
    1578              : 
    1579        40322 :             ipa_set_jf_arith_pass_through (jfunc, index, op2,
    1580              :                                            gimple_assign_rhs_code (stmt),
    1581        40322 :                                            TREE_TYPE (name));
    1582        40322 :             break;
    1583              :           }
    1584         1138 :         case GIMPLE_SINGLE_RHS:
    1585         1138 :           {
    1586         1138 :             bool agg_p = parm_ref_data_pass_through_p (fbi, index, call,
    1587              :                                                        tc_ssa);
    1588         1138 :             ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
    1589         1138 :             break;
    1590              :           }
    1591        47109 :         case GIMPLE_UNARY_RHS:
    1592        47109 :           if (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt)))
    1593          994 :             ipa_set_jf_unary_pass_through (jfunc, index,
    1594              :                                            gimple_assign_rhs_code (stmt),
    1595          994 :                                            TREE_TYPE (name));
    1596        88571 :         default:;
    1597              :         }
    1598        88571 :       return;
    1599              :     }
    1600              : 
    1601      1130188 :   if (TREE_CODE (op1) != ADDR_EXPR)
    1602              :     return;
    1603       236952 :   op1 = TREE_OPERAND (op1, 0);
    1604       236952 :   base = get_ref_base_and_extent_hwi (op1, &offset, &size, &reverse);
    1605       236952 :   offset_int mem_offset;
    1606       236952 :   if (!base
    1607       209935 :       || TREE_CODE (base) != MEM_REF
    1608       434944 :       || !mem_ref_offset (base).is_constant (&mem_offset))
    1609        38960 :     return;
    1610       197992 :   offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
    1611       197992 :   ssa = TREE_OPERAND (base, 0);
    1612       197992 :   if (TREE_CODE (ssa) != SSA_NAME
    1613       197992 :       || !SSA_NAME_IS_DEFAULT_DEF (ssa)
    1614       359691 :       || offset < 0)
    1615              :     return;
    1616              : 
    1617              :   /* Dynamic types are changed in constructors and destructors.  */
    1618       161600 :   index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
    1619       161600 :   if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
    1620       158801 :     ipa_set_ancestor_jf (jfunc, offset,  index,
    1621       158801 :                          parm_ref_data_pass_through_p (fbi, index, call, ssa),
    1622              :                          false);
    1623              : }
    1624              : 
    1625              : /* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
    1626              :    it looks like:
    1627              : 
    1628              :    iftmp.1_3 = &obj_2(D)->D.1762;
    1629              : 
    1630              :    The base of the MEM_REF must be a default definition SSA NAME of a
    1631              :    parameter.  Return NULL_TREE if it looks otherwise.  If case of success, the
    1632              :    whole MEM_REF expression is returned and the offset calculated from any
    1633              :    handled components and the MEM_REF itself is stored into *OFFSET.  The whole
    1634              :    RHS stripped off the ADDR_EXPR is stored into *OBJ_P.  */
    1635              : 
    1636              : static tree
    1637        16779 : get_ancestor_addr_info (gimple *assign, tree *obj_p, HOST_WIDE_INT *offset)
    1638              : {
    1639        16779 :   HOST_WIDE_INT size;
    1640        16779 :   tree expr, parm, obj;
    1641        16779 :   bool reverse;
    1642              : 
    1643        16779 :   if (!gimple_assign_single_p (assign))
    1644              :     return NULL_TREE;
    1645         9466 :   expr = gimple_assign_rhs1 (assign);
    1646              : 
    1647         9466 :   if (TREE_CODE (expr) != ADDR_EXPR)
    1648              :     return NULL_TREE;
    1649         4405 :   expr = TREE_OPERAND (expr, 0);
    1650         4405 :   obj = expr;
    1651         4405 :   expr = get_ref_base_and_extent_hwi (expr, offset, &size, &reverse);
    1652              : 
    1653         4405 :   offset_int mem_offset;
    1654         4405 :   if (!expr
    1655         4403 :       || TREE_CODE (expr) != MEM_REF
    1656         8808 :       || !mem_ref_offset (expr).is_constant (&mem_offset))
    1657            2 :     return NULL_TREE;
    1658         4403 :   parm = TREE_OPERAND (expr, 0);
    1659         4403 :   if (TREE_CODE (parm) != SSA_NAME
    1660         4403 :       || !SSA_NAME_IS_DEFAULT_DEF (parm)
    1661         5178 :       || TREE_CODE (SSA_NAME_VAR (parm)) != PARM_DECL)
    1662              :     return NULL_TREE;
    1663              : 
    1664          775 :   *offset += mem_offset.to_short_addr () * BITS_PER_UNIT;
    1665          775 :   *obj_p = obj;
    1666          775 :   return expr;
    1667              : }
    1668              : 
    1669              : 
    1670              : /* Given that an actual argument is an SSA_NAME that is a result of a phi
    1671              :    statement PHI, try to find out whether NAME is in fact a
    1672              :    multiple-inheritance typecast from a descendant into an ancestor of a formal
    1673              :    parameter and thus can be described by an ancestor jump function and if so,
    1674              :    write the appropriate function into JFUNC.
    1675              : 
    1676              :    Essentially we want to match the following pattern:
    1677              : 
    1678              :      if (obj_2(D) != 0B)
    1679              :        goto <bb 3>;
    1680              :      else
    1681              :        goto <bb 4>;
    1682              : 
    1683              :    <bb 3>:
    1684              :      iftmp.1_3 = &obj_2(D)->D.1762;
    1685              : 
    1686              :    <bb 4>:
    1687              :      # iftmp.1_1 = PHI <iftmp.1_3(3), 0B(2)>
    1688              :      D.1879_6 = middleman_1 (iftmp.1_1, i_5(D));
    1689              :      return D.1879_6;  */
    1690              : 
    1691              : static void
    1692        94021 : compute_complex_ancestor_jump_func (struct ipa_func_body_info *fbi,
    1693              :                                     class ipa_node_params *info,
    1694              :                                     struct ipa_jump_func *jfunc,
    1695              :                                     gcall *call, gphi *phi)
    1696              : {
    1697        94021 :   HOST_WIDE_INT offset;
    1698        94021 :   gimple *assign;
    1699        94021 :   basic_block phi_bb, assign_bb, cond_bb;
    1700        94021 :   tree tmp, parm, expr, obj;
    1701        94021 :   int index, i;
    1702              : 
    1703        94021 :   if (gimple_phi_num_args (phi) != 2)
    1704        94007 :     return;
    1705              : 
    1706        76629 :   if (integer_zerop (PHI_ARG_DEF (phi, 1)))
    1707         4078 :     tmp = PHI_ARG_DEF (phi, 0);
    1708        72551 :   else if (integer_zerop (PHI_ARG_DEF (phi, 0)))
    1709        13278 :     tmp = PHI_ARG_DEF (phi, 1);
    1710              :   else
    1711              :     return;
    1712        17356 :   if (TREE_CODE (tmp) != SSA_NAME
    1713        15232 :       || SSA_NAME_IS_DEFAULT_DEF (tmp)
    1714        15121 :       || !POINTER_TYPE_P (TREE_TYPE (tmp))
    1715        20563 :       || TREE_CODE (TREE_TYPE (TREE_TYPE (tmp))) != RECORD_TYPE)
    1716              :     return;
    1717              : 
    1718         1129 :   assign = SSA_NAME_DEF_STMT (tmp);
    1719         1129 :   assign_bb = gimple_bb (assign);
    1720        94718 :   if (!single_pred_p (assign_bb))
    1721              :     return;
    1722          711 :   expr = get_ancestor_addr_info (assign, &obj, &offset);
    1723          711 :   if (!expr)
    1724              :     return;
    1725           26 :   parm = TREE_OPERAND (expr, 0);
    1726           26 :   index = ipa_get_param_decl_index (info, SSA_NAME_VAR (parm));
    1727           26 :   if (index < 0)
    1728              :     return;
    1729              : 
    1730           26 :   cond_bb = single_pred (assign_bb);
    1731           52 :   gcond *cond = safe_dyn_cast <gcond *> (*gsi_last_bb (cond_bb));
    1732           26 :   if (!cond
    1733           26 :       || gimple_cond_code (cond) != NE_EXPR
    1734           26 :       || gimple_cond_lhs (cond) != parm
    1735           14 :       || !integer_zerop (gimple_cond_rhs (cond)))
    1736           12 :     return;
    1737              : 
    1738           14 :   phi_bb = gimple_bb (phi);
    1739           42 :   for (i = 0; i < 2; i++)
    1740              :     {
    1741           28 :       basic_block pred = EDGE_PRED (phi_bb, i)->src;
    1742           28 :       if (pred != assign_bb && pred != cond_bb)
    1743              :         return;
    1744              :     }
    1745              : 
    1746           14 :   ipa_set_ancestor_jf (jfunc, offset, index,
    1747           14 :                        parm_ref_data_pass_through_p (fbi, index, call, parm),
    1748              :                        true);
    1749              : }
    1750              : 
    1751              : /* Inspect the given TYPE and return true iff it has the same structure (the
    1752              :    same number of fields of the same types) as a C++ member pointer.  If
    1753              :    METHOD_PTR and DELTA are non-NULL, store the trees representing the
    1754              :    corresponding fields there.  */
    1755              : 
    1756              : static bool
    1757          876 : type_like_member_ptr_p (tree type, tree *method_ptr, tree *delta)
    1758              : {
    1759          876 :   tree fld;
    1760              : 
    1761          876 :   if (TREE_CODE (type) != RECORD_TYPE)
    1762              :     return false;
    1763              : 
    1764          876 :   fld = TYPE_FIELDS (type);
    1765          876 :   if (!fld || !POINTER_TYPE_P (TREE_TYPE (fld))
    1766          876 :       || TREE_CODE (TREE_TYPE (TREE_TYPE (fld))) != METHOD_TYPE
    1767         1752 :       || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
    1768              :     return false;
    1769              : 
    1770          876 :   if (method_ptr)
    1771          876 :     *method_ptr = fld;
    1772              : 
    1773          876 :   fld = DECL_CHAIN (fld);
    1774          876 :   if (!fld || INTEGRAL_TYPE_P (fld)
    1775         1752 :       || !tree_fits_uhwi_p (DECL_FIELD_OFFSET (fld)))
    1776              :     return false;
    1777          876 :   if (delta)
    1778          876 :     *delta = fld;
    1779              : 
    1780          876 :   if (DECL_CHAIN (fld))
    1781              :     return false;
    1782              : 
    1783              :   return true;
    1784              : }
    1785              : 
    1786              : /* If RHS is an SSA_NAME and it is defined by a simple copy assign statement,
    1787              :    return the rhs of its defining statement, and this statement is stored in
    1788              :    *RHS_STMT.  Otherwise return RHS as it is.  */
    1789              : 
    1790              : static inline tree
    1791       126295 : get_ssa_def_if_simple_copy (tree rhs, gimple **rhs_stmt)
    1792              : {
    1793       167688 :   while (TREE_CODE (rhs) == SSA_NAME && !SSA_NAME_IS_DEFAULT_DEF (rhs))
    1794              :     {
    1795        90904 :       gimple *def_stmt = SSA_NAME_DEF_STMT (rhs);
    1796              : 
    1797        90904 :       if (gimple_assign_single_p (def_stmt))
    1798        41393 :         rhs = gimple_assign_rhs1 (def_stmt);
    1799              :       else
    1800              :         break;
    1801        41393 :       *rhs_stmt = def_stmt;
    1802              :     }
    1803       126295 :   return rhs;
    1804              : }
    1805              : 
    1806              : /* Simple linked list, describing contents of an aggregate before call.  */
    1807              : 
    1808              : struct ipa_known_agg_contents_list
    1809              : {
    1810              :   /* Offset and size of the described part of the aggregate.  */
    1811              :   HOST_WIDE_INT offset, size;
    1812              : 
    1813              :   /* Type of the described part of the aggregate.  */
    1814              :   tree type;
    1815              : 
    1816              :   /* Known constant value or jump function data describing contents.  */
    1817              :   struct ipa_load_agg_data value;
    1818              : 
    1819              :   /* Pointer to the next structure in the list.  */
    1820              :   struct ipa_known_agg_contents_list *next;
    1821              : };
    1822              : 
    1823              : /* Add an aggregate content item into a linked list of
    1824              :    ipa_known_agg_contents_list structure, in which all elements
    1825              :    are sorted ascendingly by offset.  */
    1826              : 
    1827              : static inline void
    1828      2722459 : add_to_agg_contents_list (struct ipa_known_agg_contents_list **plist,
    1829              :                           struct ipa_known_agg_contents_list *item)
    1830              : {
    1831      2722459 :   struct ipa_known_agg_contents_list *list = *plist;
    1832              : 
    1833      5024360 :   for (; list; list = list->next)
    1834              :     {
    1835      3828164 :       if (list->offset >= item->offset)
    1836              :         break;
    1837              : 
    1838      2301901 :       plist = &list->next;
    1839              :     }
    1840              : 
    1841      2722459 :   item->next = list;
    1842      2722459 :   *plist = item;
    1843              : }
    1844              : 
    1845              : /* Check whether a given aggregate content is clobbered by certain element in
    1846              :    a linked list of ipa_known_agg_contents_list.  */
    1847              : 
    1848              : static inline bool
    1849      1055543 : clobber_by_agg_contents_list_p (struct ipa_known_agg_contents_list *list,
    1850              :                                 struct ipa_known_agg_contents_list *item)
    1851              : {
    1852      2247127 :   for (; list; list = list->next)
    1853              :     {
    1854      1816384 :       if (list->offset >= item->offset)
    1855       612200 :         return list->offset < item->offset + item->size;
    1856              : 
    1857      1204184 :       if (list->offset + list->size > item->offset)
    1858              :         return true;
    1859              :     }
    1860              : 
    1861              :   return false;
    1862              : }
    1863              : 
    1864              : /* Build aggregate jump function from LIST, assuming there are exactly
    1865              :    VALUE_COUNT entries there and that offset of the passed argument
    1866              :    is ARG_OFFSET and store it into JFUNC.  */
    1867              : 
    1868              : static void
    1869       342675 : build_agg_jump_func_from_list (struct ipa_known_agg_contents_list *list,
    1870              :                                int value_count, HOST_WIDE_INT arg_offset,
    1871              :                                struct ipa_jump_func *jfunc)
    1872              : {
    1873       342675 :   vec_safe_reserve (jfunc->agg.items, value_count, true);
    1874      1337431 :   for (; list; list = list->next)
    1875              :     {
    1876       994756 :       struct ipa_agg_jf_item item;
    1877       994756 :       tree operand = list->value.pass_through.operand;
    1878              : 
    1879       994756 :       if (list->value.pass_through.formal_id >= 0)
    1880              :         {
    1881              :           /* Content value is derived from some formal paramerter.  */
    1882        87368 :           if (list->value.offset >= 0)
    1883        46428 :             item.jftype = IPA_JF_LOAD_AGG;
    1884              :           else
    1885        40940 :             item.jftype = IPA_JF_PASS_THROUGH;
    1886              : 
    1887        87368 :           item.value.load_agg = list->value;
    1888        87368 :           if (operand)
    1889         8958 :             item.value.pass_through.operand
    1890         8958 :               = unshare_expr_without_location (operand);
    1891              :         }
    1892       907388 :       else if (operand)
    1893              :         {
    1894              :           /* Content value is known constant.  */
    1895       907388 :           item.jftype = IPA_JF_CONST;
    1896       907388 :           item.value.constant = unshare_expr_without_location (operand);
    1897              :         }
    1898              :       else
    1899            0 :         continue;
    1900              : 
    1901       994756 :       item.type = list->type;
    1902       994756 :       gcc_assert (tree_to_shwi (TYPE_SIZE (list->type)) == list->size);
    1903              : 
    1904       994756 :       item.offset = list->offset - arg_offset;
    1905       994756 :       gcc_assert ((item.offset % BITS_PER_UNIT) == 0);
    1906              : 
    1907       994756 :       jfunc->agg.items->quick_push (item);
    1908              :     }
    1909       342675 : }
    1910              : 
    1911              : /* Given an assignment statement STMT, try to collect information into
    1912              :    AGG_VALUE that will be used to construct jump function for RHS of the
    1913              :    assignment, from which content value of an aggregate part comes.
    1914              : 
    1915              :    Besides constant and simple pass-through jump functions, also try to
    1916              :    identify whether it matches the following pattern that can be described by
    1917              :    a load-value-from-aggregate jump function, which is a derivative of simple
    1918              :    pass-through jump function.
    1919              : 
    1920              :      foo (int *p)
    1921              :      {
    1922              :        ...
    1923              : 
    1924              :        *(q_5 + 4) = *(p_3(D) + 28) op 1;
    1925              :        bar (q_5);
    1926              :      }
    1927              : 
    1928              :    Here IPA_LOAD_AGG_DATA data structure is informative enough to describe
    1929              :    constant, simple pass-through and load-vale-from-aggregate. If value
    1930              :    is constant, it will be kept in field OPERAND, and field FORMAL_ID is
    1931              :    set to -1. For simple pass-through and load-value-from-aggregate, field
    1932              :    FORMAL_ID specifies the related formal parameter index, and field
    1933              :    OFFSET can be used to distinguish them, -1 means simple pass-through,
    1934              :    otherwise means load-value-from-aggregate.  */
    1935              : 
    1936              : static void
    1937      1729934 : analyze_agg_content_value (struct ipa_func_body_info *fbi,
    1938              :                            struct ipa_load_agg_data *agg_value,
    1939              :                            gimple *stmt)
    1940              : {
    1941      1729934 :   tree lhs = gimple_assign_lhs (stmt);
    1942      1729934 :   tree rhs1 = gimple_assign_rhs1 (stmt);
    1943      1729934 :   enum tree_code code;
    1944      1729934 :   int index = -1;
    1945              : 
    1946              :   /* Initialize jump function data for the aggregate part.  */
    1947      1729934 :   memset (agg_value, 0, sizeof (*agg_value));
    1948      1729934 :   agg_value->pass_through.operation = NOP_EXPR;
    1949      1729934 :   agg_value->pass_through.formal_id = -1;
    1950      1729934 :   agg_value->offset = -1;
    1951              : 
    1952      1729934 :   if (AGGREGATE_TYPE_P (TREE_TYPE (lhs))  /* TODO: Support aggregate type.  */
    1953      1539339 :       || TREE_THIS_VOLATILE (lhs)
    1954      1538671 :       || TREE_CODE (lhs) == BIT_FIELD_REF
    1955      1538663 :       || contains_bitfld_component_ref_p (lhs))
    1956       200592 :     return;
    1957              : 
    1958              :   /* Skip SSA copies.  */
    1959      1805703 :   while (gimple_assign_rhs_class (stmt) == GIMPLE_SINGLE_RHS)
    1960              :     {
    1961      1716694 :       if (TREE_CODE (rhs1) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (rhs1))
    1962              :         break;
    1963              : 
    1964       371451 :       stmt = SSA_NAME_DEF_STMT (rhs1);
    1965       371451 :       if (!is_gimple_assign (stmt))
    1966              :         break;
    1967              : 
    1968       276361 :       lhs = gimple_assign_lhs (stmt);
    1969       276361 :       rhs1 = gimple_assign_rhs1 (stmt);
    1970              :     }
    1971              : 
    1972      1529342 :   if (gphi *phi = dyn_cast<gphi *> (stmt))
    1973              :     {
    1974              :       /* Also special case like the following (a is a formal parameter):
    1975              : 
    1976              :            _12 = *a_11(D).dim[0].stride;
    1977              :            ...
    1978              :            # iftmp.22_9 = PHI <_12(2), 1(3)>
    1979              :            ...
    1980              :            parm.6.dim[0].stride = iftmp.22_9;
    1981              :            ...
    1982              :            __x_MOD_foo (&parm.6, b_31(D));
    1983              : 
    1984              :          The aggregate function describing parm.6.dim[0].stride is encoded as a
    1985              :          PASS-THROUGH jump function with ASSERT_EXPR operation whith operand 1
    1986              :          (the constant from the PHI node).  */
    1987              : 
    1988        36616 :       if (gimple_phi_num_args (phi) != 2
    1989        36616 :           || lto_variably_modified_type_p (TREE_TYPE (lhs)))
    1990         9051 :         return;
    1991        27565 :       tree arg0 = gimple_phi_arg_def (phi, 0);
    1992        27565 :       tree arg1 = gimple_phi_arg_def (phi, 1);
    1993        27565 :       tree operand;
    1994              : 
    1995        27565 :       if (is_gimple_ip_invariant (arg1))
    1996              :         {
    1997              :           operand = arg1;
    1998              :           rhs1 = arg0;
    1999              :         }
    2000        22695 :       else if (is_gimple_ip_invariant (arg0))
    2001              :         {
    2002              :           operand = arg0;
    2003              :           rhs1 = arg1;
    2004              :         }
    2005              :       else
    2006              :         return;
    2007              : 
    2008        10248 :       rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
    2009        10248 :       if (!is_gimple_assign (stmt))
    2010              :         return;
    2011              : 
    2012         4452 :       code = ASSERT_EXPR;
    2013         4452 :       agg_value->pass_through.operand = operand;
    2014         4452 :       agg_value->pass_through.op_type = TREE_TYPE (lhs);
    2015              :     }
    2016      1492726 :   else if (is_gimple_assign (stmt))
    2017              :     {
    2018      1434252 :       code = gimple_assign_rhs_code (stmt);
    2019      1434252 :       switch (gimple_assign_rhs_class (stmt))
    2020              :         {
    2021      1345243 :         case GIMPLE_SINGLE_RHS:
    2022      1345243 :           if (is_gimple_ip_invariant (rhs1))
    2023              :             {
    2024       966351 :               agg_value->pass_through.operand = rhs1;
    2025       966351 :               return;
    2026              :             }
    2027              :           code = NOP_EXPR;
    2028              :           break;
    2029              : 
    2030        31551 :         case GIMPLE_UNARY_RHS:
    2031              :           /* NOTE: A GIMPLE_UNARY_RHS operation might not be tcc_unary
    2032              :              (truth_not_expr is example), GIMPLE_BINARY_RHS does not imply
    2033              :              tcc_binary, this subtleness is somewhat misleading.
    2034              : 
    2035              :              Since tcc_unary is widely used in IPA-CP code to check an operation
    2036              :              with one operand, here we only allow tc_unary operation to avoid
    2037              :              possible problem.  Then we can use (opclass == tc_unary) or not to
    2038              :              distinguish unary and binary.  */
    2039        31551 :           if (TREE_CODE_CLASS (code) != tcc_unary || CONVERT_EXPR_CODE_P (code)
    2040        33674 :               || lto_variably_modified_type_p (TREE_TYPE (lhs)))
    2041        29428 :             return;
    2042              : 
    2043         2123 :           rhs1 = get_ssa_def_if_simple_copy (rhs1, &stmt);
    2044         2123 :           agg_value->pass_through.op_type = TREE_TYPE (lhs);
    2045         2123 :           break;
    2046              : 
    2047        56966 :         case GIMPLE_BINARY_RHS:
    2048        56966 :           {
    2049        56966 :             gimple *rhs1_stmt = stmt;
    2050        56966 :             gimple *rhs2_stmt = stmt;
    2051        56966 :             tree rhs2 = gimple_assign_rhs2 (stmt);
    2052              : 
    2053        56966 :             if (lto_variably_modified_type_p (TREE_TYPE (lhs)))
    2054        29318 :               return;
    2055              : 
    2056        56962 :             rhs1 = get_ssa_def_if_simple_copy (rhs1, &rhs1_stmt);
    2057        56962 :             rhs2 = get_ssa_def_if_simple_copy (rhs2, &rhs2_stmt);
    2058              : 
    2059        56962 :             if (is_gimple_ip_invariant (rhs2))
    2060              :               {
    2061        27648 :                 agg_value->pass_through.operand = rhs2;
    2062        27648 :                 agg_value->pass_through.op_type = TREE_TYPE (lhs);
    2063        27648 :                 stmt = rhs1_stmt;
    2064              :               }
    2065        29314 :             else if (is_gimple_ip_invariant (rhs1))
    2066              :               {
    2067         2190 :                 if (TREE_CODE_CLASS (code) == tcc_comparison)
    2068            0 :                   code = swap_tree_comparison (code);
    2069         2190 :                 else if (!commutative_tree_code (code))
    2070              :                   return;
    2071              : 
    2072            0 :                 agg_value->pass_through.operand = rhs1;
    2073            0 :                 agg_value->pass_through.op_type = TREE_TYPE (lhs);
    2074            0 :                 stmt = rhs2_stmt;
    2075            0 :                 rhs1 = rhs2;
    2076              :               }
    2077              :             else
    2078              :               return;
    2079              : 
    2080        27648 :             if (TREE_CODE_CLASS (code) != tcc_comparison
    2081        54756 :                 && !useless_type_conversion_p (TREE_TYPE (lhs),
    2082        27108 :                                                TREE_TYPE (rhs1)))
    2083              :               return;
    2084              :           }
    2085        27648 :           break;
    2086              : 
    2087              :         default:
    2088              :           return;
    2089              :         }
    2090              :     }
    2091              :   else
    2092              :     return;
    2093              : 
    2094       413115 :   if (TREE_CODE (rhs1) != SSA_NAME)
    2095       354104 :     index = load_from_unmodified_param_or_agg (fbi, fbi->info, stmt,
    2096              :                                                &agg_value->offset,
    2097              :                                                &agg_value->by_ref);
    2098        59011 :   else if (SSA_NAME_IS_DEFAULT_DEF (rhs1))
    2099        44664 :     index = ipa_get_param_decl_index (fbi->info, SSA_NAME_VAR (rhs1));
    2100              : 
    2101       398768 :   if (index >= 0)
    2102              :     {
    2103        89192 :       if (agg_value->offset >= 0)
    2104        47967 :         agg_value->type = TREE_TYPE (rhs1);
    2105        89192 :       agg_value->pass_through.formal_id = index;
    2106        89192 :       agg_value->pass_through.operation = code;
    2107              :     }
    2108              :   else
    2109       323923 :     agg_value->pass_through.operand = NULL_TREE;
    2110              : }
    2111              : 
    2112              : /* If STMT is a memory store to the object whose address is BASE, extract
    2113              :    information (offset, size, and value) into CONTENT, and return true,
    2114              :    otherwise we conservatively assume the whole object is modified with
    2115              :    unknown content, and return false.  CHECK_REF means that access to object
    2116              :    is expected to be in form of MEM_REF expression.  */
    2117              : 
    2118              : static bool
    2119      2807460 : extract_mem_content (struct ipa_func_body_info *fbi,
    2120              :                      gimple *stmt, tree base, bool check_ref,
    2121              :                      struct ipa_known_agg_contents_list *content)
    2122              : {
    2123      2807460 :   HOST_WIDE_INT lhs_offset, lhs_size;
    2124      2807460 :   bool reverse;
    2125              : 
    2126      2807460 :   if (!is_gimple_assign (stmt))
    2127              :     return false;
    2128              : 
    2129      1842864 :   tree lhs = gimple_assign_lhs (stmt);
    2130      1842864 :   tree lhs_base = get_ref_base_and_extent_hwi (lhs, &lhs_offset, &lhs_size,
    2131              :                                                &reverse);
    2132      1842864 :   if (!lhs_base)
    2133              :     return false;
    2134              : 
    2135      1841199 :   if (check_ref)
    2136              :     {
    2137       146414 :       if (TREE_CODE (lhs_base) != MEM_REF
    2138       115816 :           || TREE_OPERAND (lhs_base, 0) != base
    2139       191825 :           || !integer_zerop (TREE_OPERAND (lhs_base, 1)))
    2140       107277 :         return false;
    2141              :     }
    2142      1694785 :   else if (lhs_base != base)
    2143              :     return false;
    2144              : 
    2145      1729934 :   content->offset = lhs_offset;
    2146      1729934 :   content->size = lhs_size;
    2147      1729934 :   content->type = TREE_TYPE (lhs);
    2148      1729934 :   content->next = NULL;
    2149              : 
    2150      1729934 :   analyze_agg_content_value (fbi, &content->value, stmt);
    2151      1729934 :   return true;
    2152              : }
    2153              : 
    2154              : /* Traverse statements from CALL backwards, scanning whether an aggregate given
    2155              :    in ARG is filled in constants or values that are derived from caller's
    2156              :    formal parameter in the way described by some kinds of jump functions.  FBI
    2157              :    is the context of the caller function for interprocedural analysis.  ARG can
    2158              :    either be an aggregate expression or a pointer to an aggregate.  ARG_TYPE is
    2159              :    the type of the aggregate, JFUNC is the jump function for the aggregate.  */
    2160              : 
    2161              : static void
    2162      3343504 : determine_known_aggregate_parts (struct ipa_func_body_info *fbi,
    2163              :                                  gcall *call, tree arg,
    2164              :                                  tree arg_type,
    2165              :                                  struct ipa_jump_func *jfunc)
    2166              : {
    2167      3343504 :   struct ipa_known_agg_contents_list *list = NULL, *all_list = NULL;
    2168      3343504 :   bitmap visited = NULL;
    2169      3343504 :   int item_count = 0, value_count = 0;
    2170      3343504 :   HOST_WIDE_INT arg_offset, arg_size;
    2171      3343504 :   tree arg_base;
    2172      3343504 :   bool check_ref, by_ref;
    2173      3343504 :   ao_ref r;
    2174      3343504 :   int max_agg_items = opt_for_fn (fbi->node->decl, param_ipa_max_agg_items);
    2175              : 
    2176      3343504 :   if (max_agg_items == 0)
    2177       840629 :     return;
    2178              : 
    2179              :   /* The function operates in three stages.  First, we prepare check_ref, r,
    2180              :      arg_base and arg_offset based on what is actually passed as an actual
    2181              :      argument.  */
    2182              : 
    2183      3343504 :   if (POINTER_TYPE_P (arg_type))
    2184              :     {
    2185      2982613 :       by_ref = true;
    2186      2982613 :       if (TREE_CODE (arg) == SSA_NAME)
    2187              :         {
    2188      1091574 :           tree type_size;
    2189      1091574 :           if (!tree_fits_uhwi_p (TYPE_SIZE (TREE_TYPE (arg_type)))
    2190      1091574 :               || !POINTER_TYPE_P (TREE_TYPE (arg)))
    2191              :             return;
    2192       774176 :           check_ref = true;
    2193       774176 :           arg_base = arg;
    2194       774176 :           arg_offset = 0;
    2195       774176 :           type_size = TYPE_SIZE (TREE_TYPE (arg_type));
    2196       774176 :           arg_size = tree_to_uhwi (type_size);
    2197       774176 :           ao_ref_init_from_ptr_and_size (&r, arg_base, NULL_TREE);
    2198              :         }
    2199      1891039 :       else if (TREE_CODE (arg) == ADDR_EXPR)
    2200              :         {
    2201      1815456 :           bool reverse;
    2202              : 
    2203      1815456 :           arg = TREE_OPERAND (arg, 0);
    2204      1815456 :           arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
    2205              :                                                   &arg_size, &reverse);
    2206      1815456 :           if (!arg_base)
    2207       447572 :             return;
    2208      1814241 :           if (DECL_P (arg_base))
    2209              :             {
    2210      1367884 :               check_ref = false;
    2211      1367884 :               ao_ref_init (&r, arg_base);
    2212              :             }
    2213              :           else
    2214              :             return;
    2215              :         }
    2216              :       else
    2217              :         return;
    2218              :     }
    2219              :   else
    2220              :     {
    2221       360891 :       bool reverse;
    2222              : 
    2223       360891 :       gcc_checking_assert (AGGREGATE_TYPE_P (TREE_TYPE (arg)));
    2224              : 
    2225       360891 :       by_ref = false;
    2226       360891 :       check_ref = false;
    2227       360891 :       arg_base = get_ref_base_and_extent_hwi (arg, &arg_offset,
    2228              :                                               &arg_size, &reverse);
    2229       360891 :       if (!arg_base)
    2230           76 :         return;
    2231              : 
    2232       360815 :       ao_ref_init (&r, arg);
    2233              :     }
    2234              : 
    2235              :   /* Second stage traverses virtual SSA web backwards starting from the call
    2236              :      statement, only looks at individual dominating virtual operand (its
    2237              :      definition dominates the call), as long as it is confident that content
    2238              :      of the aggregate is affected by definition of the virtual operand, it
    2239              :      builds a sorted linked list of ipa_agg_jf_list describing that.  */
    2240              : 
    2241      2502875 :   for (tree dom_vuse = gimple_vuse (call);
    2242     24460820 :        dom_vuse && fbi->aa_walk_budget > 0;)
    2243              :     {
    2244     23962932 :       gimple *stmt = SSA_NAME_DEF_STMT (dom_vuse);
    2245              : 
    2246     23962932 :       if (gphi *phi = dyn_cast <gphi *> (stmt))
    2247              :         {
    2248      2367488 :           dom_vuse = get_continuation_for_phi (phi, &r, true,
    2249      1183744 :                                                fbi->aa_walk_budget,
    2250              :                                                &visited, false, NULL, NULL);
    2251      1183744 :           continue;
    2252              :         }
    2253              : 
    2254     22779188 :       fbi->aa_walk_budget--;
    2255     22779188 :       if (stmt_may_clobber_ref_p_1 (stmt, &r))
    2256              :         {
    2257      2807460 :           struct ipa_known_agg_contents_list *content
    2258      2807460 :                         = XALLOCA (struct ipa_known_agg_contents_list);
    2259              : 
    2260      2807460 :           if (!extract_mem_content (fbi, stmt, arg_base, check_ref, content))
    2261              :             break;
    2262              : 
    2263              :           /* Now we get a dominating virtual operand, and need to check
    2264              :              whether its value is clobbered any other dominating one.  */
    2265      1729934 :           if ((content->value.pass_through.formal_id >= 0
    2266      1640742 :                || content->value.pass_through.operand)
    2267      1055543 :               && !clobber_by_agg_contents_list_p (all_list, content)
    2268              :               /* Since IPA-CP stores results with unsigned int offsets, we can
    2269              :                  discard those which would not fit now before we stream them to
    2270              :                  WPA.  */
    2271      2724828 :               && (content->offset + content->size - arg_offset
    2272              :                   <= (HOST_WIDE_INT) UINT_MAX * BITS_PER_UNIT))
    2273              :             {
    2274       994756 :               struct ipa_known_agg_contents_list *copy
    2275       994756 :                         = XALLOCA (struct ipa_known_agg_contents_list);
    2276              : 
    2277              :               /* Add to the list consisting of only dominating virtual
    2278              :                  operands, whose definitions can finally reach the call.  */
    2279       994756 :               add_to_agg_contents_list (&list, (*copy = *content, copy));
    2280              : 
    2281       994756 :               if (++value_count == max_agg_items)
    2282              :                 break;
    2283              :             }
    2284              : 
    2285              :           /* Add to the list consisting of all dominating virtual operands.  */
    2286      1727703 :           add_to_agg_contents_list (&all_list, content);
    2287              : 
    2288      1727703 :           if (++item_count == 2 * max_agg_items)
    2289              :             break;
    2290              :         }
    2291     42472432 :       dom_vuse = gimple_vuse (stmt);
    2292              :    }
    2293              : 
    2294      2502875 :   if (visited)
    2295       616078 :     BITMAP_FREE (visited);
    2296              : 
    2297              :   /* Third stage just goes over the list and creates an appropriate vector of
    2298              :      ipa_agg_jf_item structures out of it, of course only if there are
    2299              :      any meaningful items to begin with.  */
    2300              : 
    2301      2502875 :   if (value_count)
    2302              :     {
    2303       342675 :       jfunc->agg.by_ref = by_ref;
    2304       342675 :       build_agg_jump_func_from_list (list, value_count, arg_offset, jfunc);
    2305              :     }
    2306              : }
    2307              : 
    2308              : 
    2309              : /* Return the Ith param type of callee associated with call graph
    2310              :    edge E.  */
    2311              : 
    2312              : tree
    2313      6229319 : ipa_get_callee_param_type (struct cgraph_edge *e, int i)
    2314              : {
    2315      6229319 :   int n;
    2316      6229319 :   tree type = (e->callee
    2317      6229319 :                ? TREE_TYPE (e->callee->decl)
    2318      6229319 :                : gimple_call_fntype (e->call_stmt));
    2319      6229319 :   tree t = TYPE_ARG_TYPES (type);
    2320              : 
    2321     12828567 :   for (n = 0; n < i; n++)
    2322              :     {
    2323      6852004 :       if (!t)
    2324              :         break;
    2325      6599248 :       t = TREE_CHAIN (t);
    2326              :     }
    2327      6229319 :   if (t && t != void_list_node)
    2328      5883492 :     return TREE_VALUE (t);
    2329       345827 :   if (!e->callee)
    2330              :     return NULL;
    2331       324156 :   t = DECL_ARGUMENTS (e->callee->decl);
    2332       850823 :   for (n = 0; n < i; n++)
    2333              :     {
    2334       806328 :       if (!t)
    2335              :         return NULL;
    2336       526667 :       t = TREE_CHAIN (t);
    2337              :     }
    2338        44495 :   if (t)
    2339         2193 :     return TREE_TYPE (t);
    2340              :   return NULL;
    2341              : }
    2342              : 
    2343              : /* Return a pointer to an ipa_vr just like TMP, but either find it in
    2344              :    ipa_vr_hash_table or allocate it in GC memory.  */
    2345              : 
    2346              : static ipa_vr *
    2347      5693776 : ipa_get_value_range (const vrange &tmp)
    2348              : {
    2349      5693776 :   inchash::hash hstate;
    2350      5693776 :   inchash::add_vrange (tmp, hstate);
    2351      5693776 :   hashval_t hash = hstate.end ();
    2352      5693776 :   ipa_vr **slot = ipa_vr_hash_table->find_slot_with_hash (&tmp, hash, INSERT);
    2353      5693776 :   if (*slot)
    2354              :     return *slot;
    2355              : 
    2356       631339 :   ipa_vr *vr = new (ggc_alloc<ipa_vr> ()) ipa_vr (tmp);
    2357       631339 :   *slot = vr;
    2358       631339 :   return vr;
    2359              : }
    2360              : 
    2361              : /* Assign to JF a pointer to a range just like TMP but either fetch a
    2362              :    copy from ipa_vr_hash_table or allocate a new on in GC memory.  */
    2363              : 
    2364              : static void
    2365      4940047 : ipa_set_jfunc_vr (ipa_jump_func *jf, const vrange &tmp)
    2366              : {
    2367      1874356 :   jf->m_vr = ipa_get_value_range (tmp);
    2368      3065691 : }
    2369              : 
    2370              : static void
    2371       603879 : ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
    2372              : {
    2373       603879 :   value_range tmp;
    2374       603879 :   vr.get_vrange (tmp);
    2375       603879 :   ipa_set_jfunc_vr (jf, tmp);
    2376       603879 : }
    2377              : 
    2378              : /* Given VAL that conforms to is_gimple_ip_invariant, produce a VRANGE that
    2379              :    represents it as a range.  CONTEXT_NODE is the call graph node representing
    2380              :    the function for which optimization flags should be evaluated.  */
    2381              : 
    2382              : void
    2383      1393818 : ipa_get_range_from_ip_invariant (vrange &r, tree val, cgraph_node *context_node)
    2384              : {
    2385      1393818 :   if (TREE_CODE (val) == ADDR_EXPR)
    2386              :     {
    2387         1043 :       symtab_node *symbol;
    2388         1043 :       tree base = TREE_OPERAND (val, 0);
    2389         1043 :       if (!DECL_P (base))
    2390              :         {
    2391          182 :           r.set_varying (TREE_TYPE (val));
    2392          182 :           return;
    2393              :         }
    2394          861 :       if (!decl_in_symtab_p (base))
    2395              :         {
    2396            0 :           r.set_nonzero (TREE_TYPE (val));
    2397            0 :           return;
    2398              :         }
    2399          861 :       if (!(symbol = symtab_node::get (base)))
    2400              :         {
    2401            0 :           r.set_varying (TREE_TYPE (val));
    2402            0 :           return;
    2403              :         }
    2404              : 
    2405          861 :       bool delete_null_pointer_checks
    2406          861 :         = opt_for_fn (context_node->decl, flag_delete_null_pointer_checks);
    2407          861 :       if (symbol->nonzero_address (delete_null_pointer_checks))
    2408          861 :         r.set_nonzero (TREE_TYPE (val));
    2409              :       else
    2410            0 :         r.set_varying (TREE_TYPE (val));
    2411              :     }
    2412              :   else
    2413      1392775 :     r.set (val, val);
    2414              : }
    2415              : 
    2416              : /* If T is an SSA_NAME that is the result of a simple type conversion statement
    2417              :    from an integer type to another integer type which is known to be able to
    2418              :    represent the values the operand of the conversion can hold, return the
    2419              :    operand of that conversion, otherwise return T.  */
    2420              : 
    2421              : static tree
    2422      6229319 : skip_a_safe_conversion_op (tree t)
    2423              : {
    2424      6229319 :   if (TREE_CODE (t) != SSA_NAME
    2425      6229319 :       || SSA_NAME_IS_DEFAULT_DEF (t))
    2426              :     return t;
    2427              : 
    2428      1534467 :   gimple *def = SSA_NAME_DEF_STMT (t);
    2429      1534467 :   if (!is_gimple_assign (def)
    2430      1265860 :       || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def))
    2431       246905 :       || !INTEGRAL_TYPE_P (TREE_TYPE (t))
    2432      1716093 :       || !INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs1 (def))))
    2433              :     return t;
    2434              : 
    2435       173544 :   tree rhs1 = gimple_assign_rhs1 (def);
    2436       173544 :   if (TYPE_PRECISION (TREE_TYPE (t))
    2437       173544 :       >= TYPE_PRECISION (TREE_TYPE (rhs1)))
    2438              :     return gimple_assign_rhs1 (def);
    2439              : 
    2440         8692 :   value_range vr (TREE_TYPE (rhs1));
    2441        17384 :   if (!get_range_query (cfun)->range_of_expr (vr, rhs1, def)
    2442         8692 :       || vr.undefined_p ())
    2443              :     return t;
    2444              : 
    2445         8674 :   irange &ir = as_a <irange> (vr);
    2446         8674 :   if (range_fits_type_p (&ir, TYPE_PRECISION (TREE_TYPE (t)),
    2447         8674 :                          TYPE_SIGN (TREE_TYPE (t))))
    2448         4421 :       return gimple_assign_rhs1 (def);
    2449              : 
    2450              :   return t;
    2451         8692 : }
    2452              : 
    2453              : /* Initializes ipa_edge_args summary of CBE given its callback-carrying edge.
    2454              :    This primarily means allocating the correct amount of jump functions.  */
    2455              : 
    2456              : static inline void
    2457        15082 : init_callback_edge_summary (struct cgraph_edge *cbe, tree attr)
    2458              : {
    2459        15082 :   ipa_edge_args *cb_args = ipa_edge_args_sum->get_create (cbe);
    2460        15082 :   size_t jf_vec_length = callback_num_args(attr);
    2461        15082 :   vec_safe_grow_cleared (cb_args->jump_functions,
    2462              :                          jf_vec_length, true);
    2463        15082 : }
    2464              : 
    2465              : /* Compute jump function for all arguments of callsite CS and insert the
    2466              :    information in the jump_functions array in the ipa_edge_args corresponding
    2467              :    to this callsite.  */
    2468              : 
    2469              : static void
    2470      2936372 : ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
    2471              :                                      struct cgraph_edge *cs)
    2472              : {
    2473      2936372 :   ipa_node_params *info = ipa_node_params_sum->get (cs->caller);
    2474      2936372 :   ipa_edge_args *args = ipa_edge_args_sum->get_create (cs);
    2475      2936372 :   gcall *call = cs->call_stmt;
    2476      2936372 :   int n, arg_num = gimple_call_num_args (call);
    2477      2936372 :   bool useful_context = false;
    2478              : 
    2479      2936372 :   if (arg_num == 0 || args->jump_functions)
    2480       272545 :     return;
    2481      2663827 :   vec_safe_grow_cleared (args->jump_functions, arg_num, true);
    2482      2663827 :   if (flag_devirtualize)
    2483      2483522 :     vec_safe_grow_cleared (args->polymorphic_call_contexts, arg_num, true);
    2484              : 
    2485      2663827 :   if (gimple_call_internal_p (call))
    2486              :     return;
    2487      2663827 :   if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
    2488              :     return;
    2489              : 
    2490      2663827 :   auto_vec<cgraph_edge*> callback_edges;
    2491      8893146 :   for (n = 0; n < arg_num; n++)
    2492              :     {
    2493      6229319 :       struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
    2494      6229319 :       tree arg = gimple_call_arg (call, n);
    2495      6229319 :       tree param_type = ipa_get_callee_param_type (cs, n);
    2496      6229319 :       if (flag_devirtualize && POINTER_TYPE_P (TREE_TYPE (arg)))
    2497              :         {
    2498      3192174 :           tree instance;
    2499      3192174 :           class ipa_polymorphic_call_context context (cs->caller->decl,
    2500      3192174 :                                                        arg, cs->call_stmt,
    2501      3192174 :                                                        &instance);
    2502      3192174 :           context.get_dynamic_type (instance, arg, NULL, cs->call_stmt,
    2503              :                                     &fbi->aa_walk_budget);
    2504      3192174 :           *ipa_get_ith_polymorhic_call_context (args, n) = context;
    2505      6384348 :           if (!context.useless_p ())
    2506              :             useful_context = true;
    2507              :         }
    2508              : 
    2509      6229319 :       value_range vr (TREE_TYPE (arg));
    2510      6229319 :       if (POINTER_TYPE_P (TREE_TYPE (arg)))
    2511              :         {
    2512      6894548 :           if (!get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
    2513      3447274 :               || vr.varying_p ()
    2514      5989148 :               || vr.undefined_p ())
    2515              :             {
    2516       905812 :               bool strict_overflow = false;
    2517       905812 :               if (tree_single_nonzero_warnv_p (arg, &strict_overflow))
    2518            0 :                 vr.set_nonzero (TREE_TYPE (arg));
    2519              :               else
    2520       905812 :                 vr.set_varying (TREE_TYPE (arg));
    2521              :             }
    2522      3447274 :           gcc_assert (!vr.undefined_p ());
    2523      3447274 :           unsigned HOST_WIDE_INT bitpos;
    2524      3447274 :           unsigned align = BITS_PER_UNIT;
    2525              : 
    2526      3447274 :           if (!vr.singleton_p ())
    2527      3372108 :             get_pointer_alignment_1 (arg, &align, &bitpos);
    2528              : 
    2529      3447274 :           if (align > BITS_PER_UNIT
    2530      3447274 :               && opt_for_fn (cs->caller->decl, flag_ipa_bit_cp))
    2531              :             {
    2532      1270477 :               unsigned prec = TYPE_PRECISION (TREE_TYPE (arg));
    2533      1270477 :               wide_int mask
    2534      2540954 :                 = wi::bit_and_not (wi::mask (prec, false, prec),
    2535      1270477 :                                    wide_int::from (align / BITS_PER_UNIT - 1,
    2536      1270477 :                                                    prec, UNSIGNED));
    2537      1270477 :               wide_int value = wide_int::from (bitpos / BITS_PER_UNIT, prec,
    2538      1270477 :                                                UNSIGNED);
    2539      1270477 :               irange_bitmask bm (value, mask);
    2540      1270477 :               vr.update_bitmask (bm);
    2541      1270477 :               ipa_set_jfunc_vr (jfunc, vr);
    2542      1270477 :             }
    2543      2176797 :           else if (!vr.varying_p ())
    2544      1333714 :             ipa_set_jfunc_vr (jfunc, vr);
    2545              :           else
    2546       843083 :             gcc_assert (!jfunc->m_vr);
    2547              :         }
    2548              :       else
    2549              :         {
    2550      2782045 :           if (param_type
    2551      2471822 :               && ipa_vr_supported_type_p (TREE_TYPE (arg))
    2552      2782183 :               && ipa_vr_supported_type_p (param_type)
    2553      3688646 :               && get_range_query (cfun)->range_of_expr (vr, arg, cs->call_stmt)
    2554      4626368 :               && !vr.undefined_p ())
    2555              :             {
    2556      1844185 :               value_range resvr (vr);
    2557      1844185 :               range_cast (resvr, param_type);
    2558      1844185 :               if (!resvr.undefined_p () && !resvr.varying_p ())
    2559      1468003 :                 ipa_set_jfunc_vr (jfunc, resvr);
    2560              :               else
    2561       376182 :                 gcc_assert (!jfunc->m_vr);
    2562      1844185 :             }
    2563              :           else
    2564       937860 :             gcc_assert (!jfunc->m_vr);
    2565              :         }
    2566              : 
    2567      6229319 :       arg = skip_a_safe_conversion_op (arg);
    2568      6229319 :       if (is_gimple_ip_invariant (arg)
    2569      6229319 :           || (VAR_P (arg) && is_global_var (arg) && TREE_READONLY (arg)))
    2570              :         {
    2571      2303981 :           ipa_set_jf_constant (jfunc, arg, cs);
    2572      2303981 :           if (TREE_CODE (arg) == ADDR_EXPR)
    2573              :             {
    2574       861810 :               tree pointee = TREE_OPERAND (arg, 0);
    2575       861810 :               if (TREE_CODE (pointee) == FUNCTION_DECL && !cs->callback
    2576        44145 :                   && cs->callee)
    2577              :                 {
    2578              :                   /* Argument is a pointer to a function. Look for a callback
    2579              :                      attribute describing this argument.  */
    2580        43795 :                   tree callback_attr
    2581        43795 :                     = lookup_attribute (CALLBACK_ATTR_IDENT,
    2582        43795 :                                         DECL_ATTRIBUTES (cs->callee->decl));
    2583        87590 :                   for (; callback_attr;
    2584              :                        callback_attr
    2585            0 :                        = lookup_attribute (CALLBACK_ATTR_IDENT,
    2586            0 :                                            TREE_CHAIN (callback_attr)))
    2587        13312 :                     if (callback_get_fn_index (callback_attr) == n)
    2588              :                       break;
    2589              : 
    2590              :                   /* If no callback attribute is found, check if the function is
    2591              :                      a special case.  */
    2592        43795 :                   if (!callback_attr
    2593        43795 :                       && callback_is_special_cased (cs->callee->decl, call))
    2594              :                     {
    2595         1770 :                       callback_attr
    2596         1770 :                         = callback_special_case_attr (cs->callee->decl);
    2597              :                       /* Check if the special attribute describes the correct
    2598              :                          attribute, as a special cased function might have
    2599              :                          multiple callbacks.  */
    2600         1770 :                       if (callback_get_fn_index (callback_attr) != n)
    2601              :                         callback_attr = NULL;
    2602              :                     }
    2603              : 
    2604              :                   /* If a callback attribute describing this pointer is found,
    2605              :                            create a callback edge to the pointee function to
    2606              :                      allow for further optimizations.  */
    2607        43795 :                   if (callback_attr)
    2608              :                     {
    2609        15082 :                       cgraph_node *kernel_node
    2610        15082 :                         = cgraph_node::get_create (pointee);
    2611        15082 :                       unsigned callback_id = n;
    2612        15082 :                       cgraph_edge *cbe
    2613        15082 :                         = cs->make_callback (kernel_node, callback_id);
    2614        15082 :                       init_callback_edge_summary (cbe, callback_attr);
    2615        15082 :                       callback_edges.safe_push (cbe);
    2616              :                     }
    2617              :                 }
    2618              :             }
    2619              :         }
    2620      3925338 :       else if (!is_gimple_reg_type (TREE_TYPE (arg))
    2621      3925338 :                && TREE_CODE (arg) == PARM_DECL)
    2622              :         {
    2623        79879 :           int index = ipa_get_param_decl_index (info, arg);
    2624              : 
    2625        79879 :           gcc_assert (index >=0);
    2626              :           /* Aggregate passed by value, check for pass-through, otherwise we
    2627              :              will attempt to fill in aggregate contents later in this
    2628              :              for cycle.  */
    2629        79879 :           if (parm_preserved_before_stmt_p (fbi, index, call, arg))
    2630              :             {
    2631        63997 :               ipa_set_jf_simple_pass_through (jfunc, index, false);
    2632        63997 :               continue;
    2633              :             }
    2634              :         }
    2635      3845459 :       else if (TREE_CODE (arg) == SSA_NAME)
    2636              :         {
    2637      2524252 :           if (SSA_NAME_IS_DEFAULT_DEF (arg))
    2638              :             {
    2639      1001457 :               int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
    2640      1001457 :               if (index >= 0)
    2641              :                 {
    2642       991890 :                   bool agg_p;
    2643       991890 :                   agg_p = parm_ref_data_pass_through_p (fbi, index, call, arg);
    2644       991890 :                   ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
    2645              :                 }
    2646              :             }
    2647              :           else
    2648              :             {
    2649      1522795 :               gimple *stmt = SSA_NAME_DEF_STMT (arg);
    2650      1522795 :               if (is_gimple_assign (stmt))
    2651      1242084 :                 compute_complex_assign_jump_func (fbi, info, jfunc,
    2652              :                                                   call, stmt, arg, param_type);
    2653       280711 :               else if (gimple_code (stmt) == GIMPLE_PHI)
    2654        94021 :                 compute_complex_ancestor_jump_func (fbi, info, jfunc,
    2655              :                                                     call,
    2656              :                                                     as_a <gphi *> (stmt));
    2657              :             }
    2658              :         }
    2659              : 
    2660              :       /* If ARG is pointer, we cannot use its type to determine the type of aggregate
    2661              :          passed (because type conversions are ignored in gimple).  Usually we can
    2662              :          safely get type from function declaration, but in case of K&R prototypes or
    2663              :          variadic functions we can try our luck with type of the pointer passed.
    2664              :          TODO: Since we look for actual initialization of the memory object, we may better
    2665              :          work out the type based on the memory stores we find.  */
    2666      6165322 :       if (!param_type)
    2667       343632 :         param_type = TREE_TYPE (arg);
    2668              : 
    2669      6165322 :       if ((jfunc->type != IPA_JF_PASS_THROUGH
    2670      1034344 :               || !ipa_get_jf_pass_through_agg_preserved (jfunc))
    2671      5782189 :           && (jfunc->type != IPA_JF_ANCESTOR
    2672       158815 :               || !ipa_get_jf_ancestor_agg_preserved (jfunc))
    2673     11886517 :           && (AGGREGATE_TYPE_P (TREE_TYPE (arg))
    2674      5360244 :               || POINTER_TYPE_P (param_type)))
    2675      3343504 :         determine_known_aggregate_parts (fbi, call, arg, param_type, jfunc);
    2676      6229319 :     }
    2677              : 
    2678      2663827 :   if (!callback_edges.is_empty ())
    2679              :     {
    2680              :       /* For every callback edge, fetch jump functions of arguments
    2681              :          passed to them and copy them over to their respective summaries.
    2682              :          This avoids recalculating them for every callback edge, since their
    2683              :          arguments are just passed through.  */
    2684              :       unsigned j;
    2685        30164 :       for (j = 0; j < callback_edges.length (); j++)
    2686              :         {
    2687        15082 :           cgraph_edge *callback_edge = callback_edges[j];
    2688        15082 :           ipa_edge_args *cb_summary
    2689        15082 :             = ipa_edge_args_sum->get_create (callback_edge);
    2690        15082 :           auto_vec<int> arg_mapping
    2691        15082 :             = callback_get_arg_mapping (callback_edge, cs);
    2692        15082 :           unsigned i;
    2693        30164 :           for (i = 0; i < arg_mapping.length (); i++)
    2694              :             {
    2695        15082 :               if (arg_mapping[i] == -1)
    2696            0 :                 continue;
    2697        15082 :               class ipa_jump_func *src
    2698        15082 :                 = ipa_get_ith_jump_func (args, arg_mapping[i]);
    2699        15082 :               class ipa_jump_func *dst = ipa_get_ith_jump_func (cb_summary, i);
    2700        15082 :               ipa_duplicate_jump_function (cs, callback_edge, src, dst);
    2701              :             }
    2702        15082 :         }
    2703              :     }
    2704              : 
    2705      2663827 :   if (!useful_context)
    2706      4639487 :     vec_free (args->polymorphic_call_contexts);
    2707      2663827 : }
    2708              : 
    2709              : /* Compute jump functions for all edges - both direct and indirect - outgoing
    2710              :    from BB.  */
    2711              : 
    2712              : static void
    2713     11011793 : ipa_compute_jump_functions_for_bb (struct ipa_func_body_info *fbi, basic_block bb)
    2714              : {
    2715     11011793 :   struct ipa_bb_info *bi = ipa_get_bb_info (fbi, bb);
    2716     11011793 :   int i;
    2717     11011793 :   struct cgraph_edge *cs;
    2718              : 
    2719     20557386 :   FOR_EACH_VEC_ELT_REVERSE (bi->cg_edges, i, cs)
    2720              :     {
    2721      5511590 :       struct cgraph_node *callee = cs->callee;
    2722              : 
    2723      5511590 :       if (callee)
    2724              :         {
    2725      5371501 :           callee = callee->ultimate_alias_target ();
    2726              :           /* We do not need to bother analyzing calls to unknown functions
    2727              :              unless they may become known during lto/whopr.  */
    2728      3529336 :           if (!callee->definition && !flag_lto
    2729      5386570 :               && !gimple_call_fnspec (cs->call_stmt).known_p ()
    2730      7961788 :               && !callback_edge_callee_has_attr (cs))
    2731      2575218 :             continue;
    2732              :         }
    2733      2936372 :       ipa_compute_jump_functions_for_edge (fbi, cs);
    2734              :     }
    2735     11011793 : }
    2736              : 
    2737              : /* If REF is a memory access that loads a function pointer (but not a method
    2738              :    pointer) from a RECORD_TYPE, return true and store the type of the RECORD to
    2739              :    *REC_TYPE and the byte offset of the field to *FLD_OFFSET.  Otherwise return
    2740              :    false.  OHS es the "other hand side" which is used to check type
    2741              :    compatibility with field in question, when possible.  */
    2742              : 
    2743              : static bool
    2744       118290 : is_func_ptr_from_record (tree ref, tree *rec_type, unsigned *fld_offset,
    2745              :                          tree ohs)
    2746              : {
    2747       118302 :   if (!POINTER_TYPE_P (TREE_TYPE (ref))
    2748       118302 :       || TREE_CODE (TREE_TYPE (TREE_TYPE (ref))) != FUNCTION_TYPE)
    2749              :     return false;
    2750              : 
    2751       103172 :   if (TREE_CODE (ref) == COMPONENT_REF
    2752       103172 :       && TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == RECORD_TYPE)
    2753              :     {
    2754        55412 :       gcc_assert (POINTER_TYPE_P (TREE_TYPE (ohs)));
    2755        55412 :       ohs = TREE_TYPE (TREE_TYPE (ohs));
    2756        55412 :       tree ftype = TREE_TYPE (TREE_OPERAND (ref, 1));
    2757        55412 :       if (!POINTER_TYPE_P (ftype))
    2758              :         return false;
    2759        55412 :       ftype = TREE_TYPE (ftype);
    2760        55412 :       if (!types_compatible_p (ohs, ftype))
    2761              :         return false;
    2762              : 
    2763        55283 :       tree tree_off = bit_position (TREE_OPERAND (ref, 1));
    2764        55283 :       if (!tree_fits_shwi_p (tree_off))
    2765              :         return false;
    2766        55283 :       HOST_WIDE_INT bit_offset = tree_to_shwi (tree_off);
    2767        55283 :       if (bit_offset % BITS_PER_UNIT)
    2768              :         return false;
    2769        55283 :       HOST_WIDE_INT unit_offset = bit_offset / BITS_PER_UNIT;
    2770        55283 :       if (unit_offset > UINT_MAX)
    2771              :         return false;
    2772        55283 :       *rec_type = TREE_TYPE (TREE_OPERAND (ref, 0));
    2773        55283 :       *fld_offset = unit_offset;
    2774        55283 :       return true;
    2775              :     }
    2776        47760 :   else if (TREE_CODE (ref) == MEM_REF
    2777         4881 :            && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0)))
    2778         4881 :            && (TREE_CODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0))))
    2779              :                == RECORD_TYPE)
    2780        49907 :            && tree_fits_shwi_p (TREE_OPERAND (ref, 1)))
    2781              :     {
    2782         2147 :       HOST_WIDE_INT unit_offset = tree_to_shwi (TREE_OPERAND (ref, 1));
    2783         2147 :       if (unit_offset > UINT_MAX)
    2784              :         return false;
    2785         2147 :       *rec_type = TREE_TYPE (TREE_TYPE (TREE_OPERAND (ref, 0)));
    2786         2147 :       *fld_offset = unit_offset;
    2787         2147 :       return true;
    2788              :     }
    2789              :   return false;
    2790              : }
    2791              : 
    2792              : /* If STMT looks like a statement loading a value from a member pointer formal
    2793              :    parameter, return that parameter and store the offset of the field to
    2794              :    *OFFSET_P, if it is non-NULL.  Otherwise return NULL (but *OFFSET_P still
    2795              :    might be clobbered).  If USE_DELTA, then we look for a use of the delta
    2796              :    field rather than the pfn.  */
    2797              : 
    2798              : static tree
    2799         2164 : ipa_get_stmt_member_ptr_load_param (gimple *stmt, bool use_delta,
    2800              :                                     HOST_WIDE_INT *offset_p)
    2801              : {
    2802         2164 :   tree rhs, fld, ptr_field, delta_field;
    2803         2164 :   tree ref_field = NULL_TREE;
    2804         2164 :   tree ref_offset = NULL_TREE;
    2805              : 
    2806         2164 :   if (!gimple_assign_single_p (stmt))
    2807              :     return NULL_TREE;
    2808              : 
    2809         2164 :   rhs = gimple_assign_rhs1 (stmt);
    2810         2164 :   if (TREE_CODE (rhs) == COMPONENT_REF)
    2811              :     {
    2812         1301 :       ref_field = TREE_OPERAND (rhs, 1);
    2813         1301 :       rhs = TREE_OPERAND (rhs, 0);
    2814              :     }
    2815              : 
    2816         2164 :   if (TREE_CODE (rhs) == MEM_REF)
    2817              :     {
    2818         1463 :       ref_offset = TREE_OPERAND (rhs, 1);
    2819         1463 :       if (ref_field && integer_nonzerop (ref_offset))
    2820              :         return NULL_TREE;
    2821              :     }
    2822          701 :   else if (!ref_field)
    2823              :     return NULL_TREE;
    2824              : 
    2825         2164 :   if (TREE_CODE (rhs) == MEM_REF
    2826         1463 :       && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
    2827         3627 :       && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (rhs, 0)))
    2828              :     {
    2829          598 :       rhs = TREE_OPERAND (rhs, 0);
    2830          598 :       if (TREE_CODE (SSA_NAME_VAR (rhs)) != PARM_DECL
    2831          598 :           || !type_like_member_ptr_p (TREE_TYPE (TREE_TYPE (rhs)), &ptr_field,
    2832              :                                       &delta_field))
    2833            0 :         return NULL_TREE;
    2834              :     }
    2835              :   else
    2836              :     {
    2837         1566 :       if (TREE_CODE (rhs) == MEM_REF
    2838         1566 :           && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR)
    2839            0 :         rhs = TREE_OPERAND (TREE_OPERAND (rhs, 0), 0);
    2840         1566 :       if (TREE_CODE (rhs) != PARM_DECL
    2841         1566 :           || !type_like_member_ptr_p (TREE_TYPE (rhs), &ptr_field,
    2842              :                                       &delta_field))
    2843         1288 :         return NULL_TREE;
    2844              :     }
    2845              : 
    2846          876 :   if (use_delta)
    2847            0 :     fld = delta_field;
    2848              :   else
    2849          876 :     fld = ptr_field;
    2850              : 
    2851          876 :   if (ref_field)
    2852              :     {
    2853          876 :       if (ref_field != fld)
    2854              :         return NULL_TREE;
    2855              :     }
    2856            0 :   else if (!tree_int_cst_equal (byte_position (fld), ref_offset))
    2857              :     return NULL_TREE;
    2858              : 
    2859          876 :   if (offset_p)
    2860          438 :     *offset_p = int_bit_position (fld);
    2861              :   return rhs;
    2862              : }
    2863              : 
    2864              : /* Returns true iff T is an SSA_NAME defined by a statement.  */
    2865              : 
    2866              : static bool
    2867         3040 : ipa_is_ssa_with_stmt_def (tree t)
    2868              : {
    2869         3040 :   if (TREE_CODE (t) == SSA_NAME
    2870         3040 :       && !SSA_NAME_IS_DEFAULT_DEF (t))
    2871              :     return true;
    2872              :   else
    2873            0 :     return false;
    2874              : }
    2875              : 
    2876              : /* Analyze the CALL and examine uses of formal parameters of the caller NODE
    2877              :    (described by INFO).  PARMS_AINFO is a pointer to a vector containing
    2878              :    intermediate information about each formal parameter.  Currently it checks
    2879              :    whether the call calls a pointer that is a formal parameter and if so, the
    2880              :    parameter is marked with the called flag and an indirect call graph edge
    2881              :    describing the call is created.  This is very simple for ordinary pointers
    2882              :    represented in SSA but not-so-nice when it comes to member pointers.  The
    2883              :    ugly part of this function does nothing more than trying to match the
    2884              :    pattern of such a call.  Look up the documentation of macro
    2885              :    TARGET_PTRMEMFUNC_VBIT_LOCATION for details.  An example of such a pattern
    2886              :    is the gimple dump below, the call is on the last line:
    2887              : 
    2888              :      <bb 2>:
    2889              :        f$__delta_5 = f.__delta;
    2890              :        f$__pfn_24 = f.__pfn;
    2891              : 
    2892              :    or
    2893              :      <bb 2>:
    2894              :        f$__delta_5 = MEM[(struct  *)&f];
    2895              :        f$__pfn_24 = MEM[(struct  *)&f + 4B];
    2896              : 
    2897              :    and a few lines below:
    2898              : 
    2899              :      <bb 5>
    2900              :        D.2496_3 = (int) f$__pfn_24;
    2901              :        D.2497_4 = D.2496_3 & 1;
    2902              :        if (D.2497_4 != 0)
    2903              :          goto <bb 3>;
    2904              :        else
    2905              :          goto <bb 4>;
    2906              : 
    2907              :      <bb 6>:
    2908              :        D.2500_7 = (unsigned int) f$__delta_5;
    2909              :        D.2501_8 = &S + D.2500_7;
    2910              :        D.2502_9 = (int (*__vtbl_ptr_type) (void) * *) D.2501_8;
    2911              :        D.2503_10 = *D.2502_9;
    2912              :        D.2504_12 = f$__pfn_24 + -1;
    2913              :        D.2505_13 = (unsigned int) D.2504_12;
    2914              :        D.2506_14 = D.2503_10 + D.2505_13;
    2915              :        D.2507_15 = *D.2506_14;
    2916              :        iftmp.11_16 = (String:: *) D.2507_15;
    2917              : 
    2918              :      <bb 7>:
    2919              :        # iftmp.11_1 = PHI <iftmp.11_16(3), f$__pfn_24(2)>
    2920              :        D.2500_19 = (unsigned int) f$__delta_5;
    2921              :        D.2508_20 = &S + D.2500_19;
    2922              :        D.2493_21 = iftmp.11_1 (D.2508_20, 4);
    2923              : 
    2924              :    Such patterns are results of simple calls to a member pointer:
    2925              : 
    2926              :      int doprinting (int (MyString::* f)(int) const)
    2927              :      {
    2928              :        MyString S ("somestring");
    2929              : 
    2930              :        return (S.*f)(4);
    2931              :      }
    2932              : 
    2933              :    Moreover, the function also looks for called pointers loaded from aggregates
    2934              :    passed by value or reference.  */
    2935              : 
    2936              : static void
    2937       114360 : ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
    2938              :                                 tree target)
    2939              : {
    2940       114360 :   class ipa_node_params *info = fbi->info;
    2941       114360 :   HOST_WIDE_INT offset;
    2942       114360 :   bool by_ref;
    2943              : 
    2944       114360 :   if (SSA_NAME_IS_DEFAULT_DEF (target))
    2945              :     {
    2946         3789 :       tree var = SSA_NAME_VAR (target);
    2947         3789 :       int index = ipa_get_param_decl_index (info, var);
    2948         3789 :       if (index >= 0)
    2949              :         {
    2950         3787 :           cgraph_edge *cs = fbi->node->get_edge (call);
    2951         3787 :           cgraph_simple_indirect_info *sii =
    2952         3787 :             as_a <cgraph_simple_indirect_info *> (cs->indirect_info);
    2953         3787 :           sii->param_index = index;
    2954         3787 :           gcc_assert (!sii->agg_contents && !sii->member_ptr);
    2955         3787 :           ipa_set_param_used_by_indirect_call (info, index, true);
    2956              :         }
    2957         3789 :       return;
    2958              :     }
    2959              : 
    2960       110571 :   int index;
    2961       110571 :   gimple *def = SSA_NAME_DEF_STMT (target);
    2962       110571 :   bool guaranteed_unmodified;
    2963       110571 :   if (gimple_assign_single_p (def))
    2964              :     {
    2965        87994 :       cgraph_edge *cs = fbi->node->get_edge (call);
    2966        87994 :       cgraph_simple_indirect_info *sii =
    2967        87994 :         as_a <cgraph_simple_indirect_info *> (cs->indirect_info);
    2968        87994 :       tree rectype;
    2969        87994 :       unsigned fldoff;
    2970        87994 :       if (is_func_ptr_from_record (gimple_assign_rhs1 (def), &rectype, &fldoff,
    2971              :                                    target))
    2972              :         {
    2973        46273 :           sii->fnptr_loaded_from_record = 1;
    2974        46273 :           sii->fld_offset = fldoff;
    2975        46273 :           sii->rec_type = rectype;
    2976              :         }
    2977        87994 :       if (ipa_load_from_parm_agg (fbi, info->descriptors, def,
    2978              :                                   gimple_assign_rhs1 (def), &index, &offset,
    2979              :                                   NULL, &by_ref, &guaranteed_unmodified))
    2980              :         {
    2981         2243 :           sii->param_index = index;
    2982         2243 :           sii->offset = offset;
    2983         2243 :           sii->agg_contents = 1;
    2984         2243 :           sii->by_ref = by_ref;
    2985         2243 :           sii->guaranteed_unmodified = guaranteed_unmodified;
    2986         2243 :           ipa_set_param_used_by_indirect_call (info, index, true);
    2987         2243 :           return;
    2988              :         }
    2989              :     }
    2990              : 
    2991              :   /* Now we need to try to match the complex pattern of calling a member
    2992              :      pointer. */
    2993       108328 :   if (gimple_code (def) != GIMPLE_PHI
    2994         1143 :       || gimple_phi_num_args (def) != 2
    2995         1135 :       || !POINTER_TYPE_P (TREE_TYPE (target))
    2996       109463 :       || TREE_CODE (TREE_TYPE (TREE_TYPE (target))) != METHOD_TYPE)
    2997              :     return;
    2998              : 
    2999              :   /* First, we need to check whether one of these is a load from a member
    3000              :      pointer that is a parameter to this function. */
    3001          863 :   tree n1 = PHI_ARG_DEF (def, 0);
    3002          863 :   tree n2 = PHI_ARG_DEF (def, 1);
    3003         1726 :   if (!ipa_is_ssa_with_stmt_def (n1) || !ipa_is_ssa_with_stmt_def (n2))
    3004              :     return;
    3005          863 :   gimple *d1 = SSA_NAME_DEF_STMT (n1);
    3006          863 :   gimple *d2 = SSA_NAME_DEF_STMT (n2);
    3007              : 
    3008          863 :   tree rec;
    3009          863 :   basic_block bb, virt_bb;
    3010          863 :   basic_block join = gimple_bb (def);
    3011          863 :   if ((rec = ipa_get_stmt_member_ptr_load_param (d1, false, &offset)))
    3012              :     {
    3013            0 :       if (ipa_get_stmt_member_ptr_load_param (d2, false, NULL))
    3014              :         return;
    3015              : 
    3016            0 :       bb = EDGE_PRED (join, 0)->src;
    3017            0 :       virt_bb = gimple_bb (d2);
    3018              :     }
    3019          863 :   else if ((rec = ipa_get_stmt_member_ptr_load_param (d2, false, &offset)))
    3020              :     {
    3021          438 :       bb = EDGE_PRED (join, 1)->src;
    3022          438 :       virt_bb = gimple_bb (d1);
    3023              :     }
    3024              :   else
    3025              :     return;
    3026              : 
    3027              :   /* Second, we need to check that the basic blocks are laid out in the way
    3028              :      corresponding to the pattern. */
    3029              : 
    3030          876 :   if (!single_pred_p (virt_bb) || !single_succ_p (virt_bb)
    3031          876 :       || single_succ (virt_bb) != join)
    3032              :     return;
    3033              : 
    3034              : 
    3035          438 :   if (single_pred (virt_bb) != bb)
    3036              :     {
    3037              :       /* In cases when the distinction between a normal and a virtual
    3038              :          function is encoded in the delta field, the load of the
    3039              :          actual non-virtual function pointer can be in its own BB.  */
    3040              : 
    3041            0 :       if (!single_pred_p (bb) || !single_succ_p (bb))
    3042              :         return;
    3043            0 :       bb = single_pred (bb);
    3044            0 :       if (bb != single_pred (virt_bb))
    3045              :         return;
    3046              :     }
    3047              : 
    3048              :   /* Third, let's see that the branching is done depending on the least
    3049              :      significant bit of the pfn. */
    3050              : 
    3051          876 :   gcond *branch = safe_dyn_cast <gcond *> (*gsi_last_bb (bb));
    3052          438 :   if (!branch)
    3053              :     return;
    3054              : 
    3055          438 :   if ((gimple_cond_code (branch) != NE_EXPR
    3056            0 :        && gimple_cond_code (branch) != EQ_EXPR)
    3057          438 :       || !integer_zerop (gimple_cond_rhs (branch)))
    3058            0 :     return;
    3059              : 
    3060          438 :   tree cond = gimple_cond_lhs (branch);
    3061          438 :   if (!ipa_is_ssa_with_stmt_def (cond))
    3062              :     return;
    3063              : 
    3064          438 :   def = SSA_NAME_DEF_STMT (cond);
    3065          438 :   if (!is_gimple_assign (def)
    3066          438 :       || gimple_assign_rhs_code (def) != BIT_AND_EXPR
    3067          876 :       || !integer_onep (gimple_assign_rhs2 (def)))
    3068            0 :     return;
    3069              : 
    3070          438 :   cond = gimple_assign_rhs1 (def);
    3071          438 :   if (!ipa_is_ssa_with_stmt_def (cond))
    3072              :     return;
    3073              : 
    3074          438 :   def = SSA_NAME_DEF_STMT (cond);
    3075              : 
    3076          438 :   if (is_gimple_assign (def)
    3077          438 :       && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
    3078              :     {
    3079          438 :       cond = gimple_assign_rhs1 (def);
    3080          438 :       if (!ipa_is_ssa_with_stmt_def (cond))
    3081              :         return;
    3082          438 :       def = SSA_NAME_DEF_STMT (cond);
    3083              :     }
    3084              : 
    3085          438 :   tree rec2;
    3086          438 :   rec2 = ipa_get_stmt_member_ptr_load_param (def,
    3087              :                                              (TARGET_PTRMEMFUNC_VBIT_LOCATION
    3088              :                                               == ptrmemfunc_vbit_in_delta),
    3089              :                                              NULL);
    3090          438 :   if (rec != rec2)
    3091              :     return;
    3092              : 
    3093          438 :   if (TREE_CODE (rec) == SSA_NAME)
    3094              :     {
    3095          299 :       index = ipa_get_param_decl_index (info, SSA_NAME_VAR (rec));
    3096          299 :       if (index < 0
    3097          299 :           || !parm_ref_data_preserved_p (fbi, index, call,
    3098              :                                          gimple_assign_rhs1 (def)))
    3099            4 :         return;
    3100          295 :       by_ref = true;
    3101              :     }
    3102              :   else
    3103              :     {
    3104          139 :       index = ipa_get_param_decl_index (info, rec);
    3105          139 :       if (index < 0
    3106          139 :           || !parm_preserved_before_stmt_p (fbi, index, call, rec))
    3107            0 :         return;
    3108          139 :       by_ref = false;
    3109              :     }
    3110              : 
    3111          434 :   cgraph_edge *cs = fbi->node->get_edge (call);
    3112          434 :   cgraph_simple_indirect_info *sii =
    3113          434 :     as_a <cgraph_simple_indirect_info *> (cs->indirect_info);
    3114          434 :   sii->param_index = index;
    3115          434 :   sii->offset = offset;
    3116          434 :   sii->agg_contents = 1;
    3117          434 :   sii->member_ptr = 1;
    3118          434 :   sii->by_ref = by_ref;
    3119          434 :   sii->guaranteed_unmodified = 1;
    3120          434 :   ipa_set_param_used_by_indirect_call (info, index, true);
    3121          434 :   return;
    3122              : }
    3123              : 
    3124              : /* Analyze a CALL to an OBJ_TYPE_REF which is passed in TARGET and if the
    3125              :    object referenced in the expression is a formal parameter of the caller
    3126              :    FBI->node (described by FBI->info), create a call note for the
    3127              :    statement.  */
    3128              : 
    3129              : static void
    3130        25657 : ipa_analyze_virtual_call_uses (struct ipa_func_body_info *fbi,
    3131              :                                gcall *call, tree target)
    3132              : {
    3133        25657 :   tree obj = OBJ_TYPE_REF_OBJECT (target);
    3134        25657 :   int index;
    3135        25657 :   HOST_WIDE_INT anc_offset;
    3136              : 
    3137        25657 :   if (!flag_devirtualize)
    3138        15939 :     return;
    3139              : 
    3140        25396 :   if (TREE_CODE (obj) != SSA_NAME)
    3141              :     return;
    3142              : 
    3143        25037 :   class ipa_node_params *info = fbi->info;
    3144        25037 :   if (SSA_NAME_IS_DEFAULT_DEF (obj))
    3145              :     {
    3146         8969 :       if (TREE_CODE (SSA_NAME_VAR (obj)) != PARM_DECL)
    3147              :         return;
    3148              : 
    3149         8969 :       anc_offset = 0;
    3150         8969 :       index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
    3151         8969 :       gcc_assert (index >= 0);
    3152         8969 :       if (detect_type_change_ssa (fbi, obj, obj_type_ref_class (target),
    3153              :                                   call))
    3154              :         return;
    3155              :     }
    3156              :   else
    3157              :     {
    3158        16068 :       gimple *stmt = SSA_NAME_DEF_STMT (obj);
    3159        16068 :       tree expr;
    3160              : 
    3161        16068 :       expr = get_ancestor_addr_info (stmt, &obj, &anc_offset);
    3162        16068 :       if (!expr)
    3163              :         return;
    3164          749 :       index = ipa_get_param_decl_index (info,
    3165          749 :                                         SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
    3166          749 :       gcc_assert (index >= 0);
    3167          749 :       if (detect_type_change (fbi, obj, expr, obj_type_ref_class (target),
    3168              :                               call, anc_offset))
    3169              :         return;
    3170              :     }
    3171              : 
    3172         9718 :   cgraph_edge *cs = fbi->node->get_edge (call);
    3173         9718 :   cgraph_polymorphic_indirect_info *pii =
    3174         9718 :     as_a <cgraph_polymorphic_indirect_info *> (cs->indirect_info);
    3175         9718 :   pii->param_index = index;
    3176         9718 :   pii->offset = anc_offset;
    3177         9718 :   gcc_assert (pii->otr_token == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
    3178         9718 :   gcc_assert (pii->otr_type = obj_type_ref_class (target));
    3179         9718 :   ipa_set_param_used_by_indirect_call (info, index, true);
    3180         9718 :   ipa_set_param_used_by_polymorphic_call (info, index, true);
    3181              : }
    3182              : 
    3183              : /* Analyze a call statement CALL whether and how it utilizes formal parameters
    3184              :    of the caller (described by INFO).  PARMS_AINFO is a pointer to a vector
    3185              :    containing intermediate information about each formal parameter.  */
    3186              : 
    3187              : static void
    3188      5733628 : ipa_analyze_call_uses (struct ipa_func_body_info *fbi, gcall *call)
    3189              : {
    3190      5733628 :   tree target = gimple_call_fn (call);
    3191              : 
    3192      5733628 :   if (!target
    3193      5733628 :       || (TREE_CODE (target) != SSA_NAME
    3194      5397230 :           && !virtual_method_call_p (target)))
    3195      5593609 :     return;
    3196              : 
    3197       140019 :   struct cgraph_edge *cs = fbi->node->get_edge (call);
    3198              :   /* If we previously turned the call into a direct call, there is
    3199              :      no need to analyze.  */
    3200       140019 :   if (cs && !cs->indirect_unknown_callee)
    3201              :     return;
    3202              : 
    3203       140017 :   cgraph_polymorphic_indirect_info *pii;
    3204       140017 :   if (flag_devirtualize
    3205       140017 :       && (pii
    3206       135777 :           = dyn_cast <cgraph_polymorphic_indirect_info *> (cs->indirect_info)))
    3207              :     {
    3208        25396 :       tree instance;
    3209        25396 :       tree target = gimple_call_fn (call);
    3210        25396 :       ipa_polymorphic_call_context context (current_function_decl,
    3211        25396 :                                             target, call, &instance);
    3212              : 
    3213        25396 :       gcc_checking_assert (pii->otr_type == obj_type_ref_class (target));
    3214        25396 :       gcc_checking_assert (pii->otr_token
    3215              :                            == tree_to_shwi (OBJ_TYPE_REF_TOKEN (target)));
    3216              : 
    3217        25396 :       pii->vptr_changed
    3218        50792 :         = !context.get_dynamic_type (instance,
    3219        25396 :                                      OBJ_TYPE_REF_OBJECT (target),
    3220              :                                      obj_type_ref_class (target), call,
    3221              :                                      &fbi->aa_walk_budget);
    3222        25396 :       pii->context = context;
    3223              :     }
    3224              : 
    3225       140017 :   if (TREE_CODE (target) == SSA_NAME)
    3226       114360 :     ipa_analyze_indirect_call_uses (fbi, call, target);
    3227        25657 :   else if (virtual_method_call_p (target))
    3228        25657 :     ipa_analyze_virtual_call_uses (fbi, call, target);
    3229              : }
    3230              : 
    3231              : /* Store that that there was a store of FN to a record of type REC_TYPE and
    3232              :    FLD_OFFSET.  */
    3233              : 
    3234              : static void
    3235        63281 : note_fnptr_in_record (tree rec_type, unsigned fld_offset, tree fn)
    3236              : {
    3237        63281 :   gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
    3238        63281 :   gcc_assert (TREE_CODE (rec_type) == RECORD_TYPE);
    3239        63281 :   if (!noted_fnptrs_in_records)
    3240         6724 :     noted_fnptrs_in_records = hash_table<noted_fnptr_hasher>::create_ggc (37);
    3241              : 
    3242        63281 :   noted_fnptr_store repr;
    3243        63281 :   repr.rec_type = rec_type;
    3244        63281 :   repr.fld_offset = fld_offset;
    3245              : 
    3246        63281 :   noted_fnptr_store **slot = noted_fnptrs_in_records->find_slot (&repr,
    3247              :                                                                 NO_INSERT);
    3248        63281 :   if (slot)
    3249              :     {
    3250         7574 :       if ((*slot)->fn && (*slot)->fn != fn)
    3251          804 :         (*slot)->fn = nullptr;
    3252         7574 :       return;
    3253              :     }
    3254              : 
    3255        55707 :   slot = noted_fnptrs_in_records->find_slot (&repr, INSERT);
    3256        55707 :   *slot = ggc_cleared_alloc<noted_fnptr_store> ();
    3257        55707 :   (*slot)->rec_type = rec_type;
    3258        55707 :   (*slot)->fn = fn;
    3259        55707 :   (*slot)->fld_offset = fld_offset;
    3260              : 
    3261        55707 :   return;
    3262              : }
    3263              : 
    3264              : /* Dump contents of noted_fnptrs_in_records to F in humad readable form.  */
    3265              : 
    3266              : void DEBUG_FUNCTION
    3267           41 : ipa_dump_noted_record_fnptrs (FILE *f)
    3268              : {
    3269           41 :   if (!noted_fnptrs_in_records)
    3270              :     {
    3271           38 :       fprintf (f, "No noted function pointers stored in records.\n\n");
    3272           38 :       return;
    3273              :     }
    3274              : 
    3275            3 :   fprintf (f, "Noted function pointers stored in records:\n");
    3276            7 :   for (auto iter = noted_fnptrs_in_records->begin ();
    3277            7 :        iter != noted_fnptrs_in_records->end ();
    3278            4 :        ++iter)
    3279              :     {
    3280            4 :       const noted_fnptr_store *elem = *iter;
    3281            4 :       fprintf (f, "  Type:");
    3282            4 :       print_generic_expr (f, elem->rec_type);
    3283            4 :       fprintf (f, ", offset %ul, function: ", elem->fld_offset);
    3284            4 :       print_generic_expr (f, elem->fn);
    3285            4 :       fprintf (f, "\n");
    3286              :     }
    3287            3 :   fprintf (f, "\n");
    3288              : }
    3289              : 
    3290              : /* Dump contents of noted_fnptrs_in_records to stderr in humad readable
    3291              :    form.  */
    3292              : 
    3293              : void DEBUG_FUNCTION
    3294            0 : ipa_debug_noted_record_fnptrs (void)
    3295              : {
    3296            0 :   ipa_dump_noted_record_fnptrs (stderr);
    3297            0 : }
    3298              : 
    3299              : 
    3300              : /* If we have noticed a single function pointer stored into a record of type
    3301              :    REC_TYPE at the given FLD_OFFSET (measured in bytes), return its
    3302              :    declaration.  Otherwise return NULL_TREE.  */
    3303              : 
    3304              : tree
    3305        37294 : ipa_single_noted_fnptr_in_record (tree rec_type, unsigned fld_offset)
    3306              : {
    3307        37294 :   if (!noted_fnptrs_in_records)
    3308              :     return NULL_TREE;
    3309              : 
    3310        35187 :   noted_fnptr_store repr;
    3311        35187 :   repr.rec_type = rec_type;
    3312        35187 :   repr.fld_offset = fld_offset;
    3313              : 
    3314        35187 :   noted_fnptr_store **slot = noted_fnptrs_in_records->find_slot (&repr,
    3315              :                                                                 NO_INSERT);
    3316        35187 :   if (!slot)
    3317              :     return NULL_TREE;
    3318         3269 :   return (*slot)->fn;
    3319              : }
    3320              : 
    3321              : /* Free the hash table storing the information about function pointers stored
    3322              :    to a particular position in record typed strucutres.  */
    3323              : 
    3324              : void
    3325       127711 : ipa_free_noted_fnptr_calls ()
    3326              : {
    3327       127711 :   if (noted_fnptrs_in_records)
    3328              :     {
    3329         6363 :       noted_fnptrs_in_records->empty ();
    3330         6363 :       noted_fnptrs_in_records = nullptr;
    3331              :     }
    3332       127711 : }
    3333              : 
    3334              : /* Analyze the call statement STMT with respect to formal parameters (described
    3335              :    in INFO) of caller given by FBI->NODE.  Also note any stores of function
    3336              :    pointers to record typed memory.   */
    3337              : 
    3338              : static void
    3339     31416898 : ipa_analyze_stmt_uses (struct ipa_func_body_info *fbi, gimple *stmt)
    3340              : {
    3341     31416898 :   if (is_gimple_call (stmt))
    3342      5733628 :     ipa_analyze_call_uses (fbi, as_a <gcall *> (stmt));
    3343     25683270 :   else if (gimple_assign_single_p (stmt)
    3344     13500525 :            && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR
    3345     26919009 :            && (TREE_CODE (TREE_OPERAND (gimple_assign_rhs1 (stmt), 0))
    3346              :                == FUNCTION_DECL))
    3347              :     {
    3348        30296 :       tree rec_type;
    3349        30296 :       unsigned fld_offset;
    3350        30296 :       if (is_func_ptr_from_record (gimple_assign_lhs (stmt), &rec_type,
    3351              :                                    &fld_offset, gimple_assign_rhs1 (stmt)))
    3352        11157 :         note_fnptr_in_record (rec_type, fld_offset,
    3353        11157 :                               TREE_OPERAND (gimple_assign_rhs1 (stmt), 0));
    3354              :     }
    3355     31416898 : }
    3356              : 
    3357              : /* Callback of walk_stmt_load_store_addr_ops for the visit_load.
    3358              :    If OP is a parameter declaration, mark it as used in the info structure
    3359              :    passed in DATA.  */
    3360              : 
    3361              : static bool
    3362     19606367 : visit_ref_for_mod_analysis (gimple *, tree op, tree, void *data)
    3363              : {
    3364     19606367 :   class ipa_node_params *info = (class ipa_node_params *) data;
    3365              : 
    3366     19606367 :   op = get_base_address (op);
    3367     19606367 :   if (op
    3368     19606367 :       && TREE_CODE (op) == PARM_DECL)
    3369              :     {
    3370       467898 :       int index = ipa_get_param_decl_index (info, op);
    3371       467898 :       gcc_assert (index >= 0);
    3372       467898 :       ipa_set_param_used (info, index, true);
    3373              :     }
    3374              : 
    3375     19606367 :   return false;
    3376              : }
    3377              : 
    3378              : /* Scan the statements in BB and inspect the uses of formal parameters.  Store
    3379              :    the findings in various structures of the associated ipa_node_params
    3380              :    structure, such as parameter flags, notes etc.  FBI holds various data about
    3381              :    the function being analyzed.  */
    3382              : 
    3383              : static void
    3384     11011793 : ipa_analyze_params_uses_in_bb (struct ipa_func_body_info *fbi, basic_block bb)
    3385              : {
    3386     11011793 :   gimple_stmt_iterator gsi;
    3387     76668462 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3388              :     {
    3389     54644876 :       gimple *stmt = gsi_stmt (gsi);
    3390              : 
    3391     54644876 :       if (is_gimple_debug (stmt))
    3392     23227978 :         continue;
    3393              : 
    3394     31416898 :       ipa_analyze_stmt_uses (fbi, stmt);
    3395     31416898 :       walk_stmt_load_store_addr_ops (stmt, fbi->info,
    3396              :                                      visit_ref_for_mod_analysis,
    3397              :                                      visit_ref_for_mod_analysis,
    3398              :                                      visit_ref_for_mod_analysis);
    3399              :     }
    3400     14001954 :   for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    3401      2990161 :     walk_stmt_load_store_addr_ops (gsi_stmt (gsi), fbi->info,
    3402              :                                    visit_ref_for_mod_analysis,
    3403              :                                    visit_ref_for_mod_analysis,
    3404              :                                    visit_ref_for_mod_analysis);
    3405     11011793 : }
    3406              : 
    3407              : /* Return true EXPR is a load from a dereference of SSA_NAME NAME.  */
    3408              : 
    3409              : static bool
    3410      4177530 : load_from_dereferenced_name (tree expr, tree name)
    3411              : {
    3412      4177530 :   tree base = get_base_address (expr);
    3413      4177530 :   return (TREE_CODE (base) == MEM_REF
    3414      4177530 :           && TREE_OPERAND (base, 0) == name);
    3415              : }
    3416              : 
    3417              : /* Calculate controlled uses of parameters of NODE.  */
    3418              : 
    3419              : static void
    3420      1349874 : ipa_analyze_controlled_uses (struct cgraph_node *node)
    3421              : {
    3422      1349874 :   ipa_node_params *info = ipa_node_params_sum->get (node);
    3423              : 
    3424      7377791 :   for (int i = 0; i < ipa_get_param_count (info); i++)
    3425              :     {
    3426      2465140 :       tree parm = ipa_get_param (info, i);
    3427      2465140 :       int call_uses = 0;
    3428      2465140 :       bool load_dereferenced = false;
    3429              : 
    3430              :       /* For SSA regs see if parameter is used.  For non-SSA we compute
    3431              :          the flag during modification analysis.  */
    3432      2465140 :       if (is_gimple_reg (parm))
    3433              :         {
    3434      2237878 :           tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl),
    3435              :                                        parm);
    3436      2237878 :           if (ddef && !has_zero_uses (ddef))
    3437              :             {
    3438      1959495 :               imm_use_iterator imm_iter;
    3439      1959495 :               gimple *stmt;
    3440              : 
    3441      1959495 :               ipa_set_param_used (info, i, true);
    3442      6718156 :               FOR_EACH_IMM_USE_STMT (stmt, imm_iter, ddef)
    3443              :                 {
    3444      3914873 :                   if (is_gimple_debug (stmt))
    3445       735143 :                     continue;
    3446              : 
    3447      3179730 :                   int all_stmt_uses = 0;
    3448      3179730 :                   use_operand_p use_p;
    3449      6387456 :                   FOR_EACH_IMM_USE_ON_STMT (use_p, imm_iter)
    3450      3207726 :                     all_stmt_uses++;
    3451              : 
    3452      3179730 :                   if (is_gimple_call (stmt))
    3453              :                     {
    3454      1198317 :                       if (gimple_call_internal_p (stmt))
    3455              :                         {
    3456              :                           call_uses = IPA_UNDESCRIBED_USE;
    3457              :                           break;
    3458              :                         }
    3459      1143663 :                       int recognized_stmt_uses;
    3460      1143663 :                       if (gimple_call_fn (stmt) == ddef)
    3461              :                         recognized_stmt_uses = 1;
    3462              :                       else
    3463      1139941 :                         recognized_stmt_uses = 0;
    3464      1143663 :                       unsigned arg_count = gimple_call_num_args (stmt);
    3465      5087539 :                       for (unsigned i = 0; i < arg_count; i++)
    3466              :                         {
    3467      3943876 :                           tree arg = gimple_call_arg (stmt, i);
    3468      3943876 :                           if (arg == ddef)
    3469      1129803 :                             recognized_stmt_uses++;
    3470      2814073 :                           else if (load_from_dereferenced_name (arg, ddef))
    3471              :                             {
    3472        16296 :                               load_dereferenced = true;
    3473        16296 :                               recognized_stmt_uses++;
    3474              :                             }
    3475              :                         }
    3476              : 
    3477      1143663 :                       if (recognized_stmt_uses != all_stmt_uses)
    3478              :                         {
    3479              :                           call_uses = IPA_UNDESCRIBED_USE;
    3480              :                           break;
    3481              :                         }
    3482      1135948 :                       if (call_uses >= 0)
    3483      1135948 :                         call_uses += all_stmt_uses;
    3484              :                     }
    3485      1981413 :                   else if (gimple_assign_single_p (stmt))
    3486              :                     {
    3487      1364310 :                       tree rhs = gimple_assign_rhs1 (stmt);
    3488      1364310 :                       if (all_stmt_uses != 1
    3489      1364310 :                           || !load_from_dereferenced_name (rhs, ddef))
    3490              :                         {
    3491              :                           call_uses = IPA_UNDESCRIBED_USE;
    3492              :                           break;
    3493              :                         }
    3494              :                       load_dereferenced = true;
    3495              :                     }
    3496              :                   else
    3497              :                     {
    3498              :                       call_uses = IPA_UNDESCRIBED_USE;
    3499              :                       break;
    3500              :                     }
    3501      1959495 :                 }
    3502              :             }
    3503              :           else
    3504              :             call_uses = 0;
    3505              :         }
    3506              :       else
    3507              :         call_uses = IPA_UNDESCRIBED_USE;
    3508      2465140 :       ipa_set_controlled_uses (info, i, call_uses);
    3509      2465140 :       ipa_set_param_load_dereferenced (info, i, load_dereferenced);
    3510              :     }
    3511      1349874 : }
    3512              : 
    3513              : /* Free stuff in BI.  */
    3514              : 
    3515              : static void
    3516     63132157 : free_ipa_bb_info (struct ipa_bb_info *bi)
    3517              : {
    3518            0 :   bi->cg_edges.release ();
    3519     63132157 :   bi->param_aa_statuses.release ();
    3520            0 : }
    3521              : 
    3522              : /* Dominator walker driving the analysis.  */
    3523              : 
    3524      2699748 : class analysis_dom_walker : public dom_walker
    3525              : {
    3526              : public:
    3527      1349874 :   analysis_dom_walker (struct ipa_func_body_info *fbi)
    3528      2699748 :     : dom_walker (CDI_DOMINATORS), m_fbi (fbi) {}
    3529              : 
    3530              :   edge before_dom_children (basic_block) final override;
    3531              : 
    3532              : private:
    3533              :   struct ipa_func_body_info *m_fbi;
    3534              : };
    3535              : 
    3536              : edge
    3537     11011793 : analysis_dom_walker::before_dom_children (basic_block bb)
    3538              : {
    3539     11011793 :   ipa_analyze_params_uses_in_bb (m_fbi, bb);
    3540     11011793 :   ipa_compute_jump_functions_for_bb (m_fbi, bb);
    3541     11011793 :   return NULL;
    3542              : }
    3543              : 
    3544              : /* Release body info FBI.  */
    3545              : 
    3546              : void
    3547      8478670 : ipa_release_body_info (struct ipa_func_body_info *fbi)
    3548              : {
    3549      8478670 :   int i;
    3550      8478670 :   struct ipa_bb_info *bi;
    3551              : 
    3552     71586502 :   FOR_EACH_VEC_ELT (fbi->bb_infos, i, bi)
    3553    126215664 :     free_ipa_bb_info (bi);
    3554      8478670 :   fbi->bb_infos.release ();
    3555      8478670 : }
    3556              : 
    3557              : /* Initialize the array describing properties of formal parameters
    3558              :    of NODE, analyze their uses and compute jump functions associated
    3559              :    with actual arguments of calls from within NODE.  */
    3560              : 
    3561              : void
    3562      2647000 : ipa_analyze_node (struct cgraph_node *node)
    3563              : {
    3564      2647000 :   struct ipa_func_body_info fbi;
    3565      2647000 :   class ipa_node_params *info;
    3566              : 
    3567      2647000 :   ipa_check_create_node_params ();
    3568      2647000 :   ipa_check_create_edge_args ();
    3569      2647000 :   info = ipa_node_params_sum->get_create (node);
    3570              : 
    3571      2647000 :   if (info->analysis_done)
    3572      1297126 :     return;
    3573      1350830 :   info->analysis_done = 1;
    3574              : 
    3575      1350830 :   if (ipa_func_spec_opts_forbid_analysis_p (node)
    3576      1350830 :       || (count_formal_params (node->decl)
    3577              :           >= (1 << IPA_PROP_ARG_INDEX_LIMIT_BITS)))
    3578              :     {
    3579      1297126 :       gcc_assert (!ipa_get_param_count (info));
    3580              :       return;
    3581              :     }
    3582              : 
    3583      1349874 :   struct function *func = DECL_STRUCT_FUNCTION (node->decl);
    3584      1349874 :   push_cfun (func);
    3585      1349874 :   calculate_dominance_info (CDI_DOMINATORS);
    3586      1349874 :   ipa_initialize_node_params (node);
    3587      1349874 :   ipa_analyze_controlled_uses (node);
    3588              : 
    3589      1349874 :   fbi.node = node;
    3590      1349874 :   fbi.info = info;
    3591      1349874 :   fbi.bb_infos = vNULL;
    3592      1349874 :   fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
    3593      1349874 :   fbi.param_count = ipa_get_param_count (info);
    3594      1349874 :   fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
    3595              : 
    3596      6721375 :   for (struct cgraph_edge *cs = node->callees; cs; cs = cs->next_callee)
    3597              :     {
    3598      5371501 :       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
    3599      5371501 :       bi->cg_edges.safe_push (cs);
    3600              :     }
    3601              : 
    3602      1489963 :   for (struct cgraph_edge *cs = node->indirect_calls; cs; cs = cs->next_callee)
    3603              :     {
    3604       140089 :       ipa_bb_info *bi = ipa_get_bb_info (&fbi, gimple_bb (cs->call_stmt));
    3605       140089 :       bi->cg_edges.safe_push (cs);
    3606              :     }
    3607              : 
    3608      1349874 :   enable_ranger (cfun, false);
    3609      1349874 :   analysis_dom_walker (&fbi).walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    3610      1349874 :   disable_ranger (cfun);
    3611              : 
    3612      1349874 :   ipa_release_body_info (&fbi);
    3613      1349874 :   free_dominance_info (CDI_DOMINATORS);
    3614      1349874 :   pop_cfun ();
    3615              : }
    3616              : 
    3617              : /* Analyze NODE and note any function pointers in record-typed static
    3618              :    initializers.
    3619              : 
    3620              :    TODO: The current implementation does not traverse the initializers to scan
    3621              :    records nested inside other types.  It should catch the most basic way of
    3622              :    writing "virtual functions" in C but can be extended, of course.
    3623              : */
    3624              : 
    3625              : void
    3626      1667467 : ipa_analyze_var_static_initializer (varpool_node *node)
    3627              : {
    3628      1667467 :   tree decl = node->decl;
    3629      1667467 :   tree rec_type = TREE_TYPE (decl);
    3630      1667467 :   if (TREE_CODE (rec_type) != RECORD_TYPE
    3631      1667467 :       || TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR)
    3632              :     return;
    3633              : 
    3634              :   unsigned ix;
    3635              :   tree index, val;
    3636      3832470 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (DECL_INITIAL (decl)), ix, index,
    3637              :                             val)
    3638              :     {
    3639      5347008 :       if (TREE_CODE (val) != ADDR_EXPR
    3640      1001876 :           || TREE_CODE (TREE_OPERAND (val, 0)) != FUNCTION_DECL
    3641              :           /* ObjC can produce constructor elements with NULL indices.  */
    3642      2750694 :           || !index)
    3643      2647774 :         continue;
    3644        51460 :       HOST_WIDE_INT elt_offset = int_bit_position (index);
    3645        51460 :       if ((elt_offset % BITS_PER_UNIT) != 0)
    3646            0 :         continue;
    3647        51460 :       elt_offset = elt_offset / BITS_PER_UNIT;
    3648        51460 :       if (elt_offset > UINT_MAX)
    3649            0 :         continue;
    3650        51460 :       note_fnptr_in_record (rec_type, elt_offset, TREE_OPERAND (val, 0));
    3651              :     }
    3652              : }
    3653              : 
    3654              : /* Update the jump functions associated with call graph edge E when the call
    3655              :    graph edge CS is being inlined, assuming that E->caller is already (possibly
    3656              :    indirectly) inlined into CS->callee and that E has not been inlined.  */
    3657              : 
    3658              : static void
    3659      2616418 : update_jump_functions_after_inlining (struct cgraph_edge *cs,
    3660              :                                       struct cgraph_edge *e)
    3661              : {
    3662      2616418 :   ipa_edge_args *top = ipa_edge_args_sum->get (cs);
    3663      2616418 :   ipa_edge_args *args = ipa_edge_args_sum->get (e);
    3664      2616418 :   if (!args)
    3665              :     return;
    3666      1461831 :   ipa_node_params *old_inline_root_info = ipa_node_params_sum->get (cs->callee);
    3667      1461831 :   ipa_node_params *new_inline_root_info
    3668      1461831 :     = ipa_node_params_sum->get (cs->caller->inlined_to
    3669              :                                 ? cs->caller->inlined_to : cs->caller);
    3670      1461831 :   int count = ipa_get_cs_argument_count (args);
    3671      1461831 :   int i;
    3672              : 
    3673      4329030 :   for (i = 0; i < count; i++)
    3674              :     {
    3675      2867199 :       struct ipa_jump_func *dst = ipa_get_ith_jump_func (args, i);
    3676      2867199 :       class ipa_polymorphic_call_context *dst_ctx
    3677      2867199 :         = ipa_get_ith_polymorhic_call_context (args, i);
    3678              : 
    3679      2867199 :       if (dst->agg.items)
    3680              :         {
    3681              :           struct ipa_agg_jf_item *item;
    3682              :           int j;
    3683              : 
    3684       259384 :           FOR_EACH_VEC_ELT (*dst->agg.items, j, item)
    3685              :             {
    3686       177030 :               int dst_fid;
    3687       177030 :               struct ipa_jump_func *src;
    3688              : 
    3689       317002 :               if (item->jftype != IPA_JF_PASS_THROUGH
    3690       177030 :                   && item->jftype != IPA_JF_LOAD_AGG)
    3691       139972 :                 continue;
    3692              : 
    3693        37058 :               dst_fid = item->value.pass_through.formal_id;
    3694        74113 :               if (!top || dst_fid >= ipa_get_cs_argument_count (top))
    3695              :                 {
    3696            3 :                   item->jftype = IPA_JF_UNKNOWN;
    3697            3 :                   continue;
    3698              :                 }
    3699              : 
    3700        37055 :               item->value.pass_through.formal_id = -1;
    3701        37055 :               src = ipa_get_ith_jump_func (top, dst_fid);
    3702        37055 :               if (src->type == IPA_JF_CONST)
    3703              :                 {
    3704         2424 :                   if (item->jftype == IPA_JF_PASS_THROUGH
    3705         2152 :                       && item->value.pass_through.operation == NOP_EXPR)
    3706              :                     {
    3707         2089 :                       item->jftype = IPA_JF_CONST;
    3708         2089 :                       item->value.constant = src->value.constant.value;
    3709         2089 :                       continue;
    3710              :                     }
    3711              :                 }
    3712        34631 :               else if (src->type == IPA_JF_PASS_THROUGH
    3713         5429 :                        && src->value.pass_through.operation == NOP_EXPR)
    3714              :                 {
    3715         5281 :                   if (item->jftype == IPA_JF_PASS_THROUGH
    3716         3568 :                       || !item->value.load_agg.by_ref
    3717         2369 :                       || src->value.pass_through.agg_preserved)
    3718         3697 :                     item->value.pass_through.formal_id
    3719         3697 :                                 = src->value.pass_through.formal_id;
    3720              :                 }
    3721        29350 :               else if (src->type == IPA_JF_ANCESTOR)
    3722              :                 {
    3723         4638 :                   if (item->jftype == IPA_JF_PASS_THROUGH)
    3724              :                     {
    3725          988 :                       if (!src->value.ancestor.offset)
    3726          689 :                         item->value.pass_through.formal_id
    3727          689 :                                 = src->value.ancestor.formal_id;
    3728              :                     }
    3729         3650 :                   else if (src->value.ancestor.agg_preserved)
    3730              :                     {
    3731         1440 :                       gcc_checking_assert (item->value.load_agg.by_ref);
    3732              : 
    3733         1440 :                       item->value.pass_through.formal_id
    3734         1440 :                                  = src->value.ancestor.formal_id;
    3735         1440 :                       item->value.load_agg.offset
    3736         1440 :                                 += src->value.ancestor.offset;
    3737              :                     }
    3738              :                 }
    3739              : 
    3740        34966 :               if (item->value.pass_through.formal_id < 0)
    3741        29140 :                 item->jftype = IPA_JF_UNKNOWN;
    3742              :             }
    3743              :         }
    3744              : 
    3745      2867199 :       if (!top)
    3746              :         {
    3747        13242 :           ipa_set_jf_unknown (dst);
    3748        13242 :           continue;
    3749              :         }
    3750              : 
    3751      2853957 :       if (dst->type == IPA_JF_ANCESTOR)
    3752              :         {
    3753       132596 :           struct ipa_jump_func *src;
    3754       132596 :           int dst_fid = dst->value.ancestor.formal_id;
    3755       132596 :           class ipa_polymorphic_call_context *src_ctx
    3756       132596 :             = ipa_get_ith_polymorhic_call_context (top, dst_fid);
    3757              : 
    3758              :           /* Variable number of arguments can cause havoc if we try to access
    3759              :              one that does not exist in the inlined edge.  So make sure we
    3760              :              don't.  */
    3761       265192 :           if (dst_fid >= ipa_get_cs_argument_count (top))
    3762              :             {
    3763            0 :               ipa_set_jf_unknown (dst);
    3764            0 :               continue;
    3765              :             }
    3766              : 
    3767       132596 :           src = ipa_get_ith_jump_func (top, dst_fid);
    3768              : 
    3769       132596 :           if (src_ctx && !src_ctx->useless_p ())
    3770              :             {
    3771        42587 :               class ipa_polymorphic_call_context ctx = *src_ctx;
    3772              : 
    3773              :               /* TODO: Make type preserved safe WRT contexts.  */
    3774        42587 :               if (!ipa_get_jf_ancestor_type_preserved (dst))
    3775        28302 :                 ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
    3776        42587 :               ctx.offset_by (dst->value.ancestor.offset);
    3777        85174 :               if (!ctx.useless_p ())
    3778              :                 {
    3779        37460 :                   if (!dst_ctx)
    3780              :                     {
    3781         4477 :                       vec_safe_grow_cleared (args->polymorphic_call_contexts,
    3782              :                                              count, true);
    3783         4477 :                       dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
    3784              :                     }
    3785              : 
    3786        37460 :                   dst_ctx->combine_with (ctx);
    3787              :                 }
    3788              :             }
    3789              : 
    3790              :           /* Parameter and argument in ancestor jump function must be pointer
    3791              :              type, which means access to aggregate must be by-reference.  */
    3792       132596 :           gcc_assert (!src->agg.items || src->agg.by_ref);
    3793              : 
    3794       132596 :           if (src->agg.items && dst->value.ancestor.agg_preserved)
    3795              :             {
    3796         1595 :               struct ipa_agg_jf_item *item;
    3797         1595 :               int j;
    3798              : 
    3799              :               /* Currently we do not produce clobber aggregate jump functions,
    3800              :                  replace with merging when we do.  */
    3801         1595 :               gcc_assert (!dst->agg.items);
    3802              : 
    3803         1595 :               dst->agg.items = vec_safe_copy (src->agg.items);
    3804         1595 :               dst->agg.by_ref = src->agg.by_ref;
    3805         5484 :               FOR_EACH_VEC_SAFE_ELT (dst->agg.items, j, item)
    3806         3889 :                 item->offset -= dst->value.ancestor.offset;
    3807              :             }
    3808              : 
    3809       132596 :           if (src->type == IPA_JF_PASS_THROUGH
    3810        24299 :               && src->value.pass_through.operation == NOP_EXPR)
    3811              :             {
    3812        24295 :               dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
    3813        24295 :               dst->value.ancestor.agg_preserved &=
    3814        24295 :                 src->value.pass_through.agg_preserved;
    3815              :             }
    3816       108301 :           else if (src->type == IPA_JF_ANCESTOR)
    3817              :             {
    3818         8361 :               dst->value.ancestor.formal_id = src->value.ancestor.formal_id;
    3819         8361 :               dst->value.ancestor.offset += src->value.ancestor.offset;
    3820         8361 :               dst->value.ancestor.agg_preserved &=
    3821         8361 :                 src->value.ancestor.agg_preserved;
    3822         8361 :               dst->value.ancestor.keep_null |= src->value.ancestor.keep_null;
    3823              :             }
    3824              :           else
    3825        99940 :             ipa_set_jf_unknown (dst);
    3826              :         }
    3827      2721361 :       else if (dst->type == IPA_JF_PASS_THROUGH)
    3828              :         {
    3829       740550 :           struct ipa_jump_func *src;
    3830              :           /* We must check range due to calls with variable number of arguments
    3831              :              and we cannot combine jump functions with operations.  */
    3832       740550 :           if (dst->value.pass_through.operation == NOP_EXPR
    3833       740550 :               && (top && dst->value.pass_through.formal_id
    3834       707621 :                   < ipa_get_cs_argument_count (top)))
    3835              :             {
    3836       707607 :               int dst_fid = dst->value.pass_through.formal_id;
    3837       707607 :               src = ipa_get_ith_jump_func (top, dst_fid);
    3838       707607 :               bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
    3839       707607 :               class ipa_polymorphic_call_context *src_ctx
    3840       807231 :                 = ipa_get_ith_polymorhic_call_context (top, dst_fid);
    3841              : 
    3842        99624 :               if (src_ctx && !src_ctx->useless_p ())
    3843              :                 {
    3844        60484 :                   class ipa_polymorphic_call_context ctx = *src_ctx;
    3845              : 
    3846              :                   /* TODO: Make type preserved safe WRT contexts.  */
    3847        60484 :                   if (!ipa_get_jf_pass_through_type_preserved (dst))
    3848        26785 :                     ctx.possible_dynamic_type_change (e->in_polymorphic_cdtor);
    3849       120968 :                   if (!ctx.useless_p ())
    3850              :                     {
    3851        58005 :                       if (!dst_ctx)
    3852              :                         {
    3853        10349 :                           vec_safe_grow_cleared (args->polymorphic_call_contexts,
    3854              :                                                  count, true);
    3855        10349 :                           dst_ctx = ipa_get_ith_polymorhic_call_context (args, i);
    3856              :                         }
    3857        58005 :                       dst_ctx->combine_with (ctx);
    3858              :                     }
    3859              :                 }
    3860       707607 :               switch (src->type)
    3861              :                 {
    3862       281583 :                 case IPA_JF_UNKNOWN:
    3863       281583 :                   ipa_set_jf_unknown (dst);
    3864       281583 :                   break;
    3865       148655 :                 case IPA_JF_CONST:
    3866       148655 :                   {
    3867       148655 :                     bool rd = ipa_get_jf_pass_through_refdesc_decremented (dst);
    3868       148655 :                     ipa_set_jf_cst_copy (dst, src);
    3869       148655 :                     if (rd)
    3870           25 :                       ipa_zap_jf_refdesc (dst);
    3871              :                   }
    3872              : 
    3873              :                   break;
    3874              : 
    3875       255516 :                 case IPA_JF_PASS_THROUGH:
    3876       255516 :                   {
    3877       255516 :                     int formal_id = ipa_get_jf_pass_through_formal_id (src);
    3878       255516 :                     enum tree_code operation;
    3879       255516 :                     operation = ipa_get_jf_pass_through_operation (src);
    3880              : 
    3881       255516 :                     tree old_ir_ptype = ipa_get_type (old_inline_root_info,
    3882              :                                                       dst_fid);
    3883       255516 :                     tree new_ir_ptype = ipa_get_type (new_inline_root_info,
    3884              :                                                       formal_id);
    3885       255516 :                     if (!useless_type_conversion_p (old_ir_ptype, new_ir_ptype))
    3886              :                       {
    3887              :                         /* Jump-function construction now permits type-casts
    3888              :                            from an integer to another if the latter can hold
    3889              :                            all values or has at least the same precision.
    3890              :                            However, as we're combining multiple pass-through
    3891              :                            functions together, we are losing information about
    3892              :                            signedness and thus if conversions should sign or
    3893              :                            zero extend.  Therefore we must prevent combining
    3894              :                            such jump-function if signednesses do not match.  */
    3895         1808 :                         if (!INTEGRAL_TYPE_P (old_ir_ptype)
    3896          976 :                             || !INTEGRAL_TYPE_P (new_ir_ptype)
    3897         1952 :                             || (TYPE_UNSIGNED (new_ir_ptype)
    3898          976 :                                 != TYPE_UNSIGNED (old_ir_ptype)))
    3899              :                           {
    3900          832 :                             ipa_set_jf_unknown (dst);
    3901          832 :                             continue;
    3902              :                           }
    3903              :                       }
    3904              : 
    3905       254684 :                     if (operation == NOP_EXPR)
    3906              :                       {
    3907       253746 :                         bool agg_p;
    3908       507492 :                         agg_p = dst_agg_p
    3909       253746 :                           && ipa_get_jf_pass_through_agg_preserved (src);
    3910       253746 :                         ipa_set_jf_simple_pass_through (dst, formal_id, agg_p);
    3911              :                       }
    3912          938 :                     else if (TREE_CODE_CLASS (operation) == tcc_unary)
    3913              :                       {
    3914            8 :                         tree op_t = ipa_get_jf_pass_through_op_type (src);
    3915            8 :                         ipa_set_jf_unary_pass_through (dst, formal_id, operation,
    3916              :                                                        op_t);
    3917              :                       }
    3918              :                     else
    3919              :                       {
    3920          930 :                         tree operand = ipa_get_jf_pass_through_operand (src);
    3921          930 :                         tree op_t = ipa_get_jf_pass_through_op_type (src);
    3922          930 :                         ipa_set_jf_arith_pass_through (dst, formal_id, operand,
    3923              :                                                        operation, op_t);
    3924              :                       }
    3925              :                     break;
    3926              :                   }
    3927        21853 :                 case IPA_JF_ANCESTOR:
    3928        21853 :                   {
    3929        21853 :                     bool agg_p;
    3930        43706 :                     agg_p = dst_agg_p
    3931        21853 :                       && ipa_get_jf_ancestor_agg_preserved (src);
    3932        21853 :                     ipa_set_ancestor_jf (dst,
    3933              :                                          ipa_get_jf_ancestor_offset (src),
    3934              :                                          ipa_get_jf_ancestor_formal_id (src),
    3935              :                                          agg_p,
    3936        21853 :                                          ipa_get_jf_ancestor_keep_null (src));
    3937        21853 :                     break;
    3938              :                   }
    3939            0 :                 default:
    3940            0 :                   gcc_unreachable ();
    3941              :                 }
    3942              : 
    3943       706775 :               if (src->m_vr && src->m_vr->known_p ())
    3944              :                 {
    3945       478515 :                   value_range svr (src->m_vr->type ());
    3946       478515 :                   if (!dst->m_vr || !dst->m_vr->known_p ())
    3947       205656 :                     ipa_set_jfunc_vr (dst, *src->m_vr);
    3948       272859 :                   else if (ipa_vr_operation_and_type_effects (svr, *src->m_vr,
    3949              :                                                            NOP_EXPR,
    3950       272859 :                                                            dst->m_vr->type (),
    3951       272859 :                                                            src->m_vr->type ()))
    3952              :                     {
    3953       272851 :                       value_range dvr;
    3954       272851 :                       dst->m_vr->get_vrange (dvr);
    3955       272851 :                       dvr.intersect (svr);
    3956       272851 :                       if (!dvr.undefined_p ())
    3957       263974 :                         ipa_set_jfunc_vr (dst, dvr);
    3958       272851 :                     }
    3959       478515 :                 }
    3960              : 
    3961       706775 :               if (src->agg.items
    3962        27985 :                   && (dst_agg_p || !src->agg.by_ref))
    3963              :                 {
    3964              :                   /* Currently we do not produce clobber aggregate jump
    3965              :                      functions, replace with merging when we do.  */
    3966        22201 :                   gcc_assert (!dst->agg.items);
    3967              : 
    3968        22201 :                   dst->agg.by_ref = src->agg.by_ref;
    3969        22201 :                   dst->agg.items = vec_safe_copy (src->agg.items);
    3970              :                 }
    3971              :             }
    3972              :           else
    3973        32943 :             ipa_set_jf_unknown (dst);
    3974              :         }
    3975              :     }
    3976              : }
    3977              : 
    3978              : /* If TARGET is an addr_expr of a function declaration, make it the
    3979              :    (SPECULATIVE)destination of an indirect edge IE and return the edge.
    3980              :    Otherwise, return NULL.  */
    3981              : 
    3982              : struct cgraph_edge *
    3983         4234 : ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
    3984              :                                 bool speculative)
    3985              : {
    3986         4234 :   struct cgraph_node *callee;
    3987         4234 :   bool unreachable = false;
    3988              : 
    3989         4234 :   if (TREE_CODE (target) == ADDR_EXPR)
    3990         1317 :     target = TREE_OPERAND (target, 0);
    3991         4234 :   if (TREE_CODE (target) != FUNCTION_DECL)
    3992              :     {
    3993           17 :       target = canonicalize_constructor_val (target, NULL);
    3994           17 :       if (!target || TREE_CODE (target) != FUNCTION_DECL)
    3995              :         {
    3996           17 :           cgraph_simple_indirect_info *sii
    3997           17 :             = dyn_cast <cgraph_simple_indirect_info *> (ie->indirect_info);
    3998              :           /* Member pointer call that goes through a VMT lookup.  */
    3999           17 :           if ((sii && sii->member_ptr)
    4000              :               /* Or if target is not an invariant expression and we do not
    4001              :                  know if it will evaulate to function at runtime.
    4002              :                  This can happen when folding through &VAR, where &VAR
    4003              :                  is IP invariant, but VAR itself is not.
    4004              : 
    4005              :                  TODO: It seems that we may try to fold the expression and see
    4006              :                  if VAR is readonly.  */
    4007           11 :               || !is_gimple_ip_invariant (target))
    4008              :             {
    4009            6 :               if (dump_enabled_p ())
    4010              :                 {
    4011            0 :                   dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
    4012              :                                    "discovered direct call non-invariant %s\n",
    4013            0 :                                    ie->caller->dump_name ());
    4014              :                 }
    4015            6 :               return NULL;
    4016              :             }
    4017              : 
    4018              : 
    4019           11 :           if (dump_enabled_p ())
    4020              :             {
    4021            0 :               dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
    4022              :                                "discovered direct call to non-function in %s, "
    4023              :                                "making it __builtin_unreachable\n",
    4024            0 :                                ie->caller->dump_name ());
    4025              :             }
    4026              : 
    4027           11 :           target = builtin_decl_unreachable ();
    4028           11 :           callee = cgraph_node::get_create (target);
    4029           11 :           unreachable = true;
    4030           11 :         }
    4031              :       else
    4032            0 :         callee = cgraph_node::get (target);
    4033              :     }
    4034              :   else
    4035         4217 :     callee = cgraph_node::get (target);
    4036              : 
    4037              :   /* Because may-edges are not explicitly represented and vtable may be external,
    4038              :      we may create the first reference to the object in the unit.  */
    4039         4228 :   if (!callee || callee->inlined_to)
    4040              :     {
    4041              : 
    4042              :       /* We are better to ensure we can refer to it.
    4043              :          In the case of static functions we are out of luck, since we already
    4044              :          removed its body.  In the case of public functions we may or may
    4045              :          not introduce the reference.  */
    4046            0 :       if (!canonicalize_constructor_val (target, NULL)
    4047            0 :           || !TREE_PUBLIC (target))
    4048              :         {
    4049            0 :           if (dump_file)
    4050            0 :             fprintf (dump_file, "ipa-prop: Discovered call to a known target "
    4051              :                      "(%s -> %s) but cannot refer to it.  Giving up.\n",
    4052            0 :                      ie->caller->dump_name (),
    4053            0 :                      ie->callee->dump_name ());
    4054            0 :           return NULL;
    4055              :         }
    4056            0 :       callee = cgraph_node::get_create (target);
    4057              :     }
    4058              : 
    4059              :   /* If the edge is already speculated.  */
    4060         4228 :   if (speculative && ie->speculative)
    4061              :     {
    4062            0 :       if (dump_file)
    4063              :         {
    4064            0 :           cgraph_edge *e2 = ie->speculative_call_for_target (callee);
    4065            0 :           if (!e2)
    4066              :             {
    4067            0 :               if (dump_file)
    4068            0 :                 fprintf (dump_file, "ipa-prop: Discovered call to a "
    4069              :                          "speculative target (%s -> %s) but the call is "
    4070              :                          "already speculated to different target.  "
    4071              :                          "Giving up.\n",
    4072            0 :                          ie->caller->dump_name (), callee->dump_name ());
    4073              :             }
    4074              :           else
    4075              :             {
    4076            0 :               if (dump_file)
    4077            0 :                 fprintf (dump_file,
    4078              :                          "ipa-prop: Discovered call to a speculative target "
    4079              :                          "(%s -> %s) this agree with previous speculation.\n",
    4080            0 :                          ie->caller->dump_name (), callee->dump_name ());
    4081              :             }
    4082              :         }
    4083            0 :       return NULL;
    4084              :     }
    4085              : 
    4086         4228 :   if (!dbg_cnt (devirt))
    4087              :     return NULL;
    4088              : 
    4089         4228 :   ipa_check_create_node_params ();
    4090              : 
    4091              :   /* We cannot make edges to inline clones.  It is bug that someone removed
    4092              :      the cgraph node too early.  */
    4093         4228 :   gcc_assert (!callee->inlined_to);
    4094              : 
    4095         4228 :   if (dump_file && !unreachable)
    4096              :     {
    4097          402 :       fprintf (dump_file, "ipa-prop: Discovered %s call to a %s target "
    4098              :                "(%s -> %s), for stmt ",
    4099          402 :                is_a <cgraph_polymorphic_indirect_info *> (ie->indirect_info)
    4100              :                ? "a virtual" : "an indirect",
    4101              :                speculative ? "speculative" : "known",
    4102          201 :                ie->caller->dump_name (),
    4103              :                callee->dump_name ());
    4104          201 :       if (ie->call_stmt)
    4105          193 :         print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
    4106              :       else
    4107            8 :         fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
    4108              :      }
    4109         4228 :   if (dump_enabled_p ())
    4110              :     {
    4111          402 :       dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, ie->call_stmt,
    4112              :                        "converting indirect call in %s to direct call to %s\n",
    4113          201 :                        ie->caller->dump_name (), callee->dump_name ());
    4114              :     }
    4115         4228 :   if (!speculative)
    4116              :     {
    4117         4201 :       struct cgraph_edge *orig = ie;
    4118         4201 :       ie = cgraph_edge::make_direct (ie, callee);
    4119              :       /* If we resolved speculative edge the cost is already up to date
    4120              :          for direct call (adjusted by inline_edge_duplication_hook).  */
    4121         4201 :       if (ie == orig)
    4122              :         {
    4123         3157 :           ipa_call_summary *es = ipa_call_summaries->get (ie);
    4124         3157 :           es->call_stmt_size -= (eni_size_weights.indirect_call_cost
    4125         3157 :                                  - eni_size_weights.call_cost);
    4126         3157 :           es->call_stmt_time -= (eni_time_weights.indirect_call_cost
    4127         3157 :                                  - eni_time_weights.call_cost);
    4128              :         }
    4129              :     }
    4130              :   else
    4131              :     {
    4132           27 :       if (!callee->can_be_discarded_p ())
    4133              :         {
    4134            4 :           cgraph_node *alias;
    4135            4 :           alias = dyn_cast<cgraph_node *> (callee->noninterposable_alias ());
    4136              :           if (alias)
    4137           27 :             callee = alias;
    4138              :         }
    4139              :       /* make_speculative will update ie's cost to direct call cost. */
    4140           27 :       ie = ie->make_speculative
    4141           27 :              (callee, ie->count.apply_scale (8, 10));
    4142              :     }
    4143              : 
    4144              :   return ie;
    4145              : }
    4146              : 
    4147              : /* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
    4148              :    CONSTRUCTOR and return it.  Return NULL if the search fails for some
    4149              :    reason.  */
    4150              : 
    4151              : static tree
    4152        11038 : find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
    4153              : {
    4154        16398 :   tree type = TREE_TYPE (constructor);
    4155        16398 :   if (TREE_CODE (type) != ARRAY_TYPE
    4156        16398 :       && TREE_CODE (type) != RECORD_TYPE)
    4157              :     return NULL;
    4158              : 
    4159        16386 :   unsigned ix;
    4160        16386 :   tree index, val;
    4161        22495 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
    4162              :     {
    4163        21823 :       HOST_WIDE_INT elt_offset;
    4164        21823 :       if (TREE_CODE (type) == ARRAY_TYPE)
    4165              :        {
    4166          290 :          offset_int off;
    4167          290 :          tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
    4168          290 :          gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
    4169              : 
    4170          290 :          if (index)
    4171              :            {
    4172          290 :              if (TREE_CODE (index) == RANGE_EXPR)
    4173           60 :                off = wi::to_offset (TREE_OPERAND (index, 0));
    4174              :              else
    4175          230 :                off = wi::to_offset (index);
    4176          290 :              if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
    4177              :                {
    4178          290 :                  tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
    4179          290 :                  gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
    4180          290 :                  off = wi::sext (off - wi::to_offset (low_bound),
    4181          290 :                                  TYPE_PRECISION (TREE_TYPE (index)));
    4182              :                }
    4183          290 :              off *= wi::to_offset (unit_size);
    4184              :              /* ???  Handle more than just the first index of a
    4185              :                 RANGE_EXPR.  */
    4186              :            }
    4187              :          else
    4188            0 :            off = wi::to_offset (unit_size) * ix;
    4189              : 
    4190          290 :          off = wi::lshift (off, LOG2_BITS_PER_UNIT);
    4191          290 :          if (!wi::fits_shwi_p (off) || wi::neg_p (off))
    4192            0 :            continue;
    4193          290 :          elt_offset = off.to_shwi ();
    4194              :        }
    4195        21533 :       else if (TREE_CODE (type) == RECORD_TYPE)
    4196              :        {
    4197        21533 :          gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
    4198        21533 :          if (DECL_BIT_FIELD (index))
    4199            0 :            continue;
    4200        21533 :          elt_offset = int_bit_position (index);
    4201              :        }
    4202              :       else
    4203            0 :        gcc_unreachable ();
    4204              : 
    4205        21823 :       if (elt_offset > req_offset)
    4206              :         return NULL;
    4207              : 
    4208        21823 :       if (TREE_CODE (val) == CONSTRUCTOR)
    4209         5360 :         return find_constructor_constant_at_offset (val,
    4210         5360 :                                                     req_offset - elt_offset);
    4211              : 
    4212        16463 :       if (elt_offset == req_offset
    4213        11026 :           && is_gimple_reg_type (TREE_TYPE (val))
    4214        27489 :           && is_gimple_ip_invariant (val))
    4215              :         return val;
    4216              :     }
    4217              :   return NULL;
    4218              : }
    4219              : 
    4220              : /* Check whether SCALAR could be used to look up an aggregate interprocedural
    4221              :    invariant from a static constructor and if so, return it.  Otherwise return
    4222              :    NULL. */
    4223              : 
    4224              : tree
    4225     13080377 : ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
    4226              : {
    4227     13080377 :   if (by_ref)
    4228              :     {
    4229     13065286 :       if (TREE_CODE (scalar) != ADDR_EXPR)
    4230              :         return NULL;
    4231      4253560 :       scalar = TREE_OPERAND (scalar, 0);
    4232              :     }
    4233              : 
    4234      4268651 :   if (!VAR_P (scalar)
    4235      2773226 :       || !is_global_var (scalar)
    4236       249571 :       || !TREE_READONLY (scalar)
    4237        15587 :       || !DECL_INITIAL (scalar)
    4238      4281810 :       || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
    4239              :     return NULL;
    4240              : 
    4241        11038 :   return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
    4242              : }
    4243              : 
    4244              : /* Retrieve value from AGG_JFUNC for the given OFFSET or return NULL if there
    4245              :    is none.  BY_REF specifies whether the value has to be passed by reference
    4246              :    or by value.  */
    4247              : 
    4248              : static tree
    4249        26233 : ipa_find_agg_cst_from_jfunc_items (struct ipa_agg_jump_function *agg_jfunc,
    4250              :                                    ipa_node_params *src_info,
    4251              :                                    cgraph_node *src_node,
    4252              :                                    HOST_WIDE_INT offset, bool by_ref)
    4253              : {
    4254        26233 :   if (by_ref != agg_jfunc->by_ref)
    4255              :     return NULL_TREE;
    4256              : 
    4257         4811 :   for (const ipa_agg_jf_item &item : agg_jfunc->items)
    4258         1692 :     if (item.offset == offset)
    4259         1277 :       return ipa_agg_value_from_jfunc (src_info, src_node, &item);
    4260              : 
    4261              :   return NULL_TREE;
    4262              : }
    4263              : 
    4264              : /* Remove a reference to SYMBOL from the list of references of a node given by
    4265              :    reference description RDESC.  Return true if the reference has been
    4266              :    successfully found and removed.  */
    4267              : 
    4268              : static bool
    4269         7827 : remove_described_reference (symtab_node *symbol, struct ipa_cst_ref_desc *rdesc)
    4270              : {
    4271         7827 :   struct ipa_ref *to_del;
    4272         7827 :   struct cgraph_edge *origin;
    4273              : 
    4274         7827 :   origin = rdesc->cs;
    4275         7827 :   if (!origin)
    4276              :     return false;
    4277         7827 :   to_del = origin->caller->find_reference (symbol, origin->call_stmt,
    4278              :                                            origin->lto_stmt_uid, IPA_REF_ADDR);
    4279         7827 :   if (!to_del)
    4280              :     return false;
    4281              : 
    4282         7827 :   to_del->remove_reference ();
    4283         7827 :   if (dump_file)
    4284           26 :     fprintf (dump_file, "ipa-prop: Removed a reference from %s to %s.\n",
    4285           13 :              origin->caller->dump_name (), symbol->dump_name ());
    4286              :   return true;
    4287              : }
    4288              : 
    4289              : /* If JFUNC has a reference description with refcount different from
    4290              :    IPA_UNDESCRIBED_USE, return the reference description, otherwise return
    4291              :    NULL.  JFUNC must be a constant jump function.  */
    4292              : 
    4293              : static struct ipa_cst_ref_desc *
    4294      1313895 : jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
    4295              : {
    4296      1313895 :   struct ipa_cst_ref_desc *rdesc = ipa_get_jf_constant_rdesc (jfunc);
    4297      1313895 :   if (rdesc && rdesc->refcount != IPA_UNDESCRIBED_USE)
    4298              :     return rdesc;
    4299              :   else
    4300      1125123 :     return NULL;
    4301              : }
    4302              : 
    4303              : /* If the value of constant jump function JFUNC is an address of a function
    4304              :    declaration, return the associated call graph node.  Otherwise return
    4305              :    NULL.  */
    4306              : 
    4307              : static symtab_node *
    4308         1778 : symtab_node_for_jfunc (struct ipa_jump_func *jfunc)
    4309              : {
    4310         1778 :   gcc_checking_assert (jfunc->type == IPA_JF_CONST);
    4311         1778 :   tree cst = ipa_get_jf_constant (jfunc);
    4312         1778 :   if (TREE_CODE (cst) != ADDR_EXPR
    4313         1778 :       || (TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL
    4314           31 :           && TREE_CODE (TREE_OPERAND (cst, 0)) != VAR_DECL))
    4315              :     return NULL;
    4316              : 
    4317         1768 :   return symtab_node::get (TREE_OPERAND (cst, 0));
    4318              : }
    4319              : 
    4320              : 
    4321              : /* If JFUNC is a constant jump function with a usable rdesc, decrement its
    4322              :    refcount and if it hits zero, remove reference to SYMBOL from the caller of
    4323              :    the edge specified in the rdesc.  Return false if either the symbol or the
    4324              :    reference could not be found, otherwise return true.  */
    4325              : 
    4326              : static bool
    4327          967 : try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
    4328              : {
    4329          967 :   struct ipa_cst_ref_desc *rdesc;
    4330          967 :   if (jfunc->type == IPA_JF_CONST
    4331          967 :       && (rdesc = jfunc_rdesc_usable (jfunc))
    4332         1907 :       && --rdesc->refcount == 0)
    4333              :     {
    4334          776 :       symtab_node *symbol = symtab_node_for_jfunc (jfunc);
    4335          776 :       if (!symbol)
    4336              :         return false;
    4337              : 
    4338          776 :       return remove_described_reference (symbol, rdesc);
    4339              :     }
    4340              :   return true;
    4341              : }
    4342              : 
    4343              : /* Try to find a destination for indirect edge IE that corresponds to a simple
    4344              :    call or a call of a member function pointer and where the destination is a
    4345              :    pointer formal parameter described by jump function JFUNC.  TARGET_TYPE is
    4346              :    the type of the parameter to which the result of JFUNC is passed.  If it can
    4347              :    be determined, return the newly direct edge, otherwise return NULL.
    4348              :    NEW_ROOT and NEW_ROOT_INFO is the node and its info that JFUNC lattices are
    4349              :    relative to.  */
    4350              : 
    4351              : static struct cgraph_edge *
    4352        10358 : try_make_edge_direct_simple_call (struct cgraph_edge *ie,
    4353              :                                   struct ipa_jump_func *jfunc, tree target_type,
    4354              :                                   struct cgraph_node *new_root,
    4355              :                                   class ipa_node_params *new_root_info)
    4356              : {
    4357        10358 :   tree target = NULL_TREE;
    4358        10358 :   cgraph_simple_indirect_info *sii
    4359        10358 :     = as_a <cgraph_simple_indirect_info *> (ie->indirect_info);
    4360        10358 :   bool agg_contents = sii->agg_contents;
    4361        10358 :   tree scalar = ipa_value_from_jfunc (new_root_info, jfunc, target_type);
    4362        10358 :   if (agg_contents)
    4363              :     {
    4364         8253 :       if (scalar)
    4365           14 :         target = ipa_find_agg_cst_from_init (scalar, sii->offset, sii->by_ref);
    4366         8253 :       if (!target && sii->guaranteed_unmodified)
    4367         7094 :         target = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
    4368              :                                                     new_root, sii->offset,
    4369              :                                                     sii->by_ref);
    4370              :     }
    4371              :   else
    4372              :     target = scalar;
    4373        10357 :   if (!target)
    4374              :     return NULL;
    4375         1334 :   cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target);
    4376              : 
    4377         1334 :   if (cs && !agg_contents)
    4378              :     {
    4379          967 :       bool ok;
    4380          967 :       gcc_checking_assert (cs->callee
    4381              :                            && (cs != ie
    4382              :                                || jfunc->type != IPA_JF_CONST
    4383              :                                || !symtab_node_for_jfunc (jfunc)
    4384              :                                || cs->callee == symtab_node_for_jfunc (jfunc)));
    4385          967 :       ok = try_decrement_rdesc_refcount (jfunc);
    4386          967 :       gcc_checking_assert (ok);
    4387              :     }
    4388              : 
    4389              :   return cs;
    4390              : }
    4391              : 
    4392              : /* Return the target to be used in cases of impossible devirtualization.  IE
    4393              :    and target (the latter can be NULL) are dumped when dumping is enabled.  */
    4394              : 
    4395              : tree
    4396          508 : ipa_impossible_devirt_target (struct cgraph_edge *ie, tree target)
    4397              : {
    4398          508 :   if (dump_file)
    4399              :     {
    4400           57 :       if (target)
    4401           18 :         fprintf (dump_file,
    4402              :                  "Type inconsistent devirtualization: %s->%s\n",
    4403           18 :                  ie->caller->dump_name (),
    4404           18 :                  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (target)));
    4405              :       else
    4406           39 :         fprintf (dump_file,
    4407              :                  "No devirtualization target in %s\n",
    4408           39 :                  ie->caller->dump_name ());
    4409              :     }
    4410          508 :   tree new_target = builtin_decl_unreachable ();
    4411          508 :   cgraph_node::get_create (new_target);
    4412          508 :   return new_target;
    4413              : }
    4414              : 
    4415              : /* Try to find a destination for indirect edge IE that corresponds to a virtual
    4416              :    call based on a formal parameter which is described by jump function JFUNC
    4417              :    and if it can be determined, make it direct and return the direct edge.
    4418              :    Otherwise, return NULL.  CTX describes the polymorphic context that the
    4419              :    parameter the call is based on brings along with it.  NEW_ROOT and
    4420              :    NEW_ROOT_INFO is the node and its info that JFUNC lattices are relative
    4421              :    to.  */
    4422              : 
    4423              : static struct cgraph_edge *
    4424        19142 : try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
    4425              :                                    struct ipa_jump_func *jfunc,
    4426              :                                    class ipa_polymorphic_call_context ctx,
    4427              :                                    struct cgraph_node *new_root,
    4428              :                                    class ipa_node_params *new_root_info)
    4429              : {
    4430        19142 :   tree target = NULL;
    4431        19142 :   bool speculative = false;
    4432              : 
    4433        19142 :   if (!opt_for_fn (ie->caller->decl, flag_devirtualize))
    4434              :     return NULL;
    4435        19142 :   cgraph_polymorphic_indirect_info *pii
    4436        19142 :     = as_a <cgraph_polymorphic_indirect_info *> (ie->indirect_info);
    4437        19142 :   if (!pii->usable_p ())
    4438              :     return nullptr;
    4439              : 
    4440              :   /* Try to do lookup via known virtual table pointer value.  */
    4441        19142 :   if (!pii->vptr_changed
    4442        19142 :       || opt_for_fn (ie->caller->decl, flag_devirtualize_speculatively))
    4443              :     {
    4444        19142 :       tree vtable;
    4445        19142 :       unsigned HOST_WIDE_INT offset;
    4446        19142 :       tree t = NULL_TREE;
    4447        19142 :       if (jfunc->type == IPA_JF_CONST)
    4448          330 :         t = ipa_find_agg_cst_from_init (ipa_get_jf_constant (jfunc),
    4449              :                                         pii->offset, true);
    4450          330 :       if (!t)
    4451        19139 :         t = ipa_find_agg_cst_from_jfunc_items (&jfunc->agg, new_root_info,
    4452              :                                                new_root, pii->offset, true);
    4453        19142 :       if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
    4454              :         {
    4455          893 :           bool can_refer;
    4456          893 :           t = gimple_get_virt_method_for_vtable (pii->otr_token, vtable, offset,
    4457              :                                                  &can_refer);
    4458          893 :           if (can_refer)
    4459              :             {
    4460          876 :               if (!t
    4461          876 :                   || fndecl_built_in_p (t, BUILT_IN_UNREACHABLE,
    4462              :                                            BUILT_IN_UNREACHABLE_TRAP)
    4463         1704 :                   || !possible_polymorphic_call_target_p
    4464          828 :                        (ie, cgraph_node::get (t)))
    4465              :                 {
    4466              :                   /* Do not speculate builtin_unreachable, it is stupid!  */
    4467           90 :                   if (!pii->vptr_changed)
    4468           90 :                     target = ipa_impossible_devirt_target (ie, target);
    4469              :                   else
    4470              :                     target = NULL;
    4471              :                 }
    4472              :               else
    4473              :                 {
    4474          786 :                   target = t;
    4475          786 :                   speculative = pii->vptr_changed;
    4476              :                 }
    4477              :             }
    4478              :         }
    4479              :     }
    4480              : 
    4481        19142 :   ipa_polymorphic_call_context ie_context (ie);
    4482        19142 :   vec <cgraph_node *>targets;
    4483        19142 :   bool final;
    4484              : 
    4485        19142 :   ctx.offset_by (pii->offset);
    4486        19142 :   if (pii->vptr_changed)
    4487         6532 :     ctx.possible_dynamic_type_change (ie->in_polymorphic_cdtor,
    4488              :                                       pii->otr_type);
    4489        19142 :   ctx.combine_with (ie_context, pii->otr_type);
    4490        19142 :   targets = possible_polymorphic_call_targets (pii->otr_type, pii->otr_token,
    4491              :                                                ctx, &final);
    4492        21448 :   if (final && targets.length () <= 1)
    4493              :     {
    4494         2287 :       speculative = false;
    4495         2287 :       if (targets.length () == 1)
    4496         2236 :         target = targets[0]->decl;
    4497              :       else
    4498           51 :         target = ipa_impossible_devirt_target (ie, NULL_TREE);
    4499              :     }
    4500        16847 :   else if (!target && opt_for_fn (ie->caller->decl,
    4501              :                                   flag_devirtualize_speculatively)
    4502        33620 :            && !ie->speculative && ie->maybe_hot_p ())
    4503              :     {
    4504         9556 :       cgraph_node *n;
    4505         9556 :       n = try_speculative_devirtualization (pii->otr_type, pii->otr_token,
    4506              :                                             pii->context);
    4507         9556 :       if (n)
    4508              :         {
    4509           18 :           target = n->decl;
    4510           18 :           speculative = true;
    4511              :         }
    4512              :     }
    4513              : 
    4514        19142 :   if (target)
    4515              :     {
    4516         2313 :       if (!possible_polymorphic_call_target_p
    4517         2313 :           (ie, cgraph_node::get_create (target)))
    4518              :         {
    4519           51 :           if (speculative)
    4520              :             return NULL;
    4521           51 :           target = ipa_impossible_devirt_target (ie, target);
    4522              :         }
    4523         2313 :       return ipa_make_edge_direct_to_target (ie, target, speculative);
    4524              :     }
    4525              :   else
    4526              :     return NULL;
    4527              : }
    4528              : 
    4529              : /* Update the param called notes associated with NODE when CS is being inlined,
    4530              :    assuming NODE is (potentially indirectly) inlined into CS->callee.
    4531              :    Moreover, if the callee is discovered to be constant, create a new cgraph
    4532              :    edge for it.  Newly discovered indirect edges will be added to *NEW_EDGES,
    4533              :    unless NEW_EDGES is NULL.  Return true iff a new edge(s) were created.  */
    4534              : 
    4535              : static bool
    4536      1566836 : update_indirect_edges_after_inlining (struct cgraph_edge *cs,
    4537              :                                       struct cgraph_node *node,
    4538              :                                       vec<cgraph_edge *> *new_edges)
    4539              : {
    4540      1566836 :   bool res = false;
    4541              : 
    4542      1566836 :   ipa_check_create_edge_args ();
    4543      1566836 :   class ipa_edge_args *top = ipa_edge_args_sum->get (cs);
    4544      1115781 :   cgraph_node *new_root
    4545      1566836 :     = cs->caller->inlined_to ? cs->caller->inlined_to : cs->caller;
    4546      1566836 :   ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
    4547      1566836 :   ipa_node_params *inlined_node_info
    4548      1566836 :     = ipa_node_params_sum->get (cs->callee->function_symbol ());
    4549              : 
    4550      1566836 :   cgraph_edge *next_ie;
    4551      1639460 :   for (cgraph_edge *ie = node->indirect_calls; ie; ie = next_ie)
    4552              :     {
    4553        72624 :       next_ie = ie->next_callee;
    4554              : 
    4555       115564 :       if (!top
    4556        72500 :           || ie->indirect_info->param_index < 0
    4557       131996 :           || ie->indirect_info->param_index >= ipa_get_cs_argument_count (top))
    4558              :         {
    4559        42940 :           ie->indirect_info->param_index = -1;
    4560        46557 :           continue;
    4561              :         }
    4562              : 
    4563        29684 :       int param_index = ie->indirect_info->param_index;
    4564        29684 :       cgraph_polymorphic_indirect_info *pii
    4565        29684 :         = dyn_cast <cgraph_polymorphic_indirect_info *> (ie->indirect_info);
    4566        29684 :       cgraph_simple_indirect_info *sii
    4567        29684 :         = dyn_cast <cgraph_simple_indirect_info *> (ie->indirect_info);
    4568        29684 :       struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (top, param_index);
    4569              : 
    4570        29684 :       auto_vec<cgraph_node *, 4> spec_targets;
    4571        29684 :       if (ie->speculative)
    4572         8340 :         for (cgraph_edge *direct = ie->first_speculative_call_target ();
    4573        21352 :              direct;
    4574        13012 :              direct = direct->next_speculative_call_target ())
    4575        13012 :           spec_targets.safe_push (direct->callee);
    4576              : 
    4577        29684 :       cgraph_edge *new_direct_edge;
    4578        29684 :       if (!opt_for_fn (node->decl, flag_indirect_inlining))
    4579          184 :         new_direct_edge = NULL;
    4580        29500 :       else if (pii)
    4581              :         {
    4582        19142 :           ipa_polymorphic_call_context ctx;
    4583        19142 :           ctx = ipa_context_from_jfunc (new_root_info, cs, param_index, jfunc);
    4584        19142 :           new_direct_edge = try_make_edge_direct_virtual_call (ie, jfunc, ctx,
    4585              :                                                                new_root,
    4586              :                                                                new_root_info);
    4587              :         }
    4588        10358 :       else if (sii)
    4589              :         {
    4590        10358 :           tree target_type =  ipa_get_type (inlined_node_info, param_index);
    4591        10358 :           new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
    4592              :                                                               target_type,
    4593              :                                                               new_root,
    4594              :                                                               new_root_info);
    4595              :         }
    4596              :       else
    4597            0 :         gcc_unreachable ();
    4598              : 
    4599              :       /* If speculation was removed, then we need to do nothing.  */
    4600         3641 :       if (new_direct_edge && new_direct_edge != ie
    4601        30656 :           && spec_targets.contains (new_direct_edge->callee))
    4602              :         {
    4603          948 :           new_direct_edge->indirect_inlining_edge = 1;
    4604          948 :           res = true;
    4605          948 :           if (!new_direct_edge->speculative)
    4606          948 :             continue;
    4607              :         }
    4608        28736 :       else if (new_direct_edge)
    4609              :         {
    4610         2693 :           new_direct_edge->indirect_inlining_edge = 1;
    4611         2693 :           if (new_edges)
    4612              :             {
    4613         2685 :               new_edges->safe_push (new_direct_edge);
    4614         2685 :               res = true;
    4615              :             }
    4616              :           /* If speculative edge was introduced we still need to update
    4617              :              call info of the indirect edge.  */
    4618         2693 :           if (!new_direct_edge->speculative)
    4619         2669 :             continue;
    4620              :         }
    4621        26067 :       if (jfunc->type == IPA_JF_PASS_THROUGH
    4622        26067 :           && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
    4623              :         {
    4624         5922 :           if (!pii
    4625         2600 :               && sii->agg_contents
    4626         7431 :               && !ipa_get_jf_pass_through_agg_preserved (jfunc))
    4627          981 :             ie->indirect_info->param_index = -1;
    4628              :           else
    4629              :             {
    4630         4941 :               param_index = ipa_get_jf_pass_through_formal_id (jfunc);
    4631         4941 :               ie->indirect_info->param_index = param_index;
    4632         4941 :               ipa_set_param_used_by_indirect_call (new_root_info, param_index,
    4633              :                                                    true);
    4634         4941 :               if (pii)
    4635              :                 {
    4636         3322 :                   if (!ipa_get_jf_pass_through_type_preserved (jfunc))
    4637         2146 :                     pii->vptr_changed = true;
    4638         3322 :                   ipa_set_param_used_by_polymorphic_call (new_root_info,
    4639              :                                                           param_index, true);
    4640              :                 }
    4641              :             }
    4642              :         }
    4643        20145 :       else if (jfunc->type == IPA_JF_ANCESTOR)
    4644              :         {
    4645          522 :           if (!pii
    4646          158 :               && sii->agg_contents
    4647          680 :               && !ipa_get_jf_ancestor_agg_preserved (jfunc))
    4648           56 :             ie->indirect_info->param_index = -1;
    4649              :           else
    4650              :             {
    4651          466 :               param_index = ipa_get_jf_ancestor_formal_id (jfunc);
    4652          466 :               ie->indirect_info->param_index = param_index;
    4653          466 :               ipa_set_param_used_by_indirect_call (new_root_info, param_index,
    4654              :                                                    true);
    4655          466 :               if (pii)
    4656              :                 {
    4657          364 :                   pii->offset += ipa_get_jf_ancestor_offset (jfunc);
    4658          364 :                   if (!ipa_get_jf_ancestor_type_preserved (jfunc))
    4659          324 :                     pii->vptr_changed = true;
    4660          364 :                   ipa_set_param_used_by_polymorphic_call (new_root_info,
    4661              :                                                           param_index, true);
    4662              :                 }
    4663              :               else
    4664          102 :                 sii->offset += ipa_get_jf_ancestor_offset (jfunc);
    4665              :             }
    4666              :         }
    4667              :       else
    4668              :         /* Either we can find a destination for this edge now or never. */
    4669        19623 :         ie->indirect_info->param_index = -1;
    4670        29684 :     }
    4671              : 
    4672      1566836 :   return res;
    4673              : }
    4674              : 
    4675              : /* Recursively traverse subtree of NODE (including node) made of inlined
    4676              :    cgraph_edges when CS has been inlined and invoke
    4677              :    update_indirect_edges_after_inlining on all nodes and
    4678              :    update_jump_functions_after_inlining on all non-inlined edges that lead out
    4679              :    of this subtree.  Newly discovered indirect edges will be added to
    4680              :    *NEW_EDGES, unless NEW_EDGES is NULL.  Return true iff a new edge(s) were
    4681              :    created.  */
    4682              : 
    4683              : static bool
    4684      1566836 : propagate_info_to_inlined_callees (struct cgraph_edge *cs,
    4685              :                                    struct cgraph_node *node,
    4686              :                                    vec<cgraph_edge *> *new_edges)
    4687              : {
    4688      1566836 :   struct cgraph_edge *e;
    4689      1566836 :   bool res;
    4690              : 
    4691      1566836 :   res = update_indirect_edges_after_inlining (cs, node, new_edges);
    4692              : 
    4693      4778970 :   for (e = node->callees; e; e = e->next_callee)
    4694      3212134 :     if (!e->inline_failed)
    4695       664723 :       res |= propagate_info_to_inlined_callees (cs, e->callee, new_edges);
    4696              :     else
    4697      2547411 :       update_jump_functions_after_inlining (cs, e);
    4698      1635843 :   for (e = node->indirect_calls; e; e = e->next_callee)
    4699        69007 :     update_jump_functions_after_inlining (cs, e);
    4700              : 
    4701      1566836 :   return res;
    4702              : }
    4703              : 
    4704              : /* Combine two controlled uses counts as done during inlining.  */
    4705              : 
    4706              : static int
    4707       392429 : combine_controlled_uses_counters (int c, int d)
    4708              : {
    4709            0 :   if (c == IPA_UNDESCRIBED_USE || d == IPA_UNDESCRIBED_USE)
    4710              :     return IPA_UNDESCRIBED_USE;
    4711              :   else
    4712       104352 :     return c + d - 1;
    4713              : }
    4714              : 
    4715              : /* Propagate number of controlled users from CS->caleee to the new root of the
    4716              :    tree of inlined nodes.  */
    4717              : 
    4718              : static void
    4719       902113 : propagate_controlled_uses (struct cgraph_edge *cs)
    4720              : {
    4721       902113 :   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
    4722       902113 :   if (!args)
    4723              :     return;
    4724       666827 :   struct cgraph_node *new_root = cs->caller->inlined_to
    4725       900360 :     ? cs->caller->inlined_to : cs->caller;
    4726       900360 :   ipa_node_params *new_root_info = ipa_node_params_sum->get (new_root);
    4727       900360 :   ipa_node_params *old_root_info = ipa_node_params_sum->get (cs->callee);
    4728       900360 :   int count, i;
    4729              : 
    4730       900360 :   if (!old_root_info)
    4731              :     return;
    4732              : 
    4733      1747739 :   count = MIN (ipa_get_cs_argument_count (args),
    4734              :                ipa_get_param_count (old_root_info));
    4735      2738712 :   for (i = 0; i < count; i++)
    4736              :     {
    4737      1838432 :       struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
    4738      1838432 :       struct ipa_cst_ref_desc *rdesc;
    4739              : 
    4740      1838432 :       if (jf->type == IPA_JF_PASS_THROUGH
    4741      1838432 :           && !ipa_get_jf_pass_through_refdesc_decremented (jf))
    4742              :         {
    4743       337344 :           int src_idx, c, d;
    4744       337344 :           src_idx = ipa_get_jf_pass_through_formal_id (jf);
    4745       337344 :           c = ipa_get_controlled_uses (new_root_info, src_idx);
    4746       337344 :           d = ipa_get_controlled_uses (old_root_info, i);
    4747              : 
    4748       337344 :           gcc_checking_assert (ipa_get_jf_pass_through_operation (jf)
    4749              :                                == NOP_EXPR || c == IPA_UNDESCRIBED_USE);
    4750       337344 :           c = combine_controlled_uses_counters (c, d);
    4751       337344 :           ipa_set_controlled_uses (new_root_info, src_idx, c);
    4752       337344 :           bool lderef = true;
    4753       337344 :           if (c != IPA_UNDESCRIBED_USE)
    4754              :             {
    4755        93550 :               lderef = (ipa_get_param_load_dereferenced (new_root_info, src_idx)
    4756        93550 :                         || ipa_get_param_load_dereferenced (old_root_info, i));
    4757        93550 :               ipa_set_param_load_dereferenced (new_root_info, src_idx, lderef);
    4758              :             }
    4759              : 
    4760       337344 :           if (c == 0 && !lderef && new_root_info->ipcp_orig_node)
    4761              :             {
    4762          195 :               struct cgraph_node *n;
    4763          195 :               struct ipa_ref *ref;
    4764          195 :               tree t = new_root_info->known_csts[src_idx];
    4765              : 
    4766          167 :               if (t && TREE_CODE (t) == ADDR_EXPR
    4767          145 :                   && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
    4768            9 :                   && (n = cgraph_node::get (TREE_OPERAND (t, 0)))
    4769          204 :                   && (ref = new_root->find_reference (n, NULL, 0,
    4770              :                                                       IPA_REF_ADDR)))
    4771              :                 {
    4772            9 :                   if (dump_file)
    4773            1 :                     fprintf (dump_file, "ipa-prop: Removing cloning-created "
    4774              :                              "reference from %s to %s.\n",
    4775              :                              new_root->dump_name (),
    4776              :                              n->dump_name ());
    4777            9 :                   ref->remove_reference ();
    4778              :                 }
    4779              :             }
    4780              :         }
    4781      1501088 :       else if (jf->type == IPA_JF_CONST
    4782      1501088 :                && (rdesc = jfunc_rdesc_usable (jf)))
    4783              :         {
    4784        55085 :           int d = ipa_get_controlled_uses (old_root_info, i);
    4785        55085 :           int c = rdesc->refcount;
    4786        55085 :           tree cst = ipa_get_jf_constant (jf);
    4787        55085 :           rdesc->refcount = combine_controlled_uses_counters (c, d);
    4788        55085 :           if (rdesc->refcount != IPA_UNDESCRIBED_USE
    4789        10802 :               && ipa_get_param_load_dereferenced (old_root_info, i)
    4790         2259 :               && TREE_CODE (cst) == ADDR_EXPR
    4791        57344 :               && VAR_P (TREE_OPERAND (cst, 0)))
    4792              :             {
    4793         2258 :               symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
    4794         2258 :               new_root->create_reference (n, IPA_REF_LOAD, NULL);
    4795         2258 :               if (dump_file)
    4796            3 :                 fprintf (dump_file, "ipa-prop: Address IPA constant will reach "
    4797              :                          "a load so adding LOAD reference from %s to %s.\n",
    4798              :                          new_root->dump_name (), n->dump_name ());
    4799              :             }
    4800        55085 :           if (rdesc->refcount == 0)
    4801              :             {
    4802         7051 :               gcc_checking_assert (TREE_CODE (cst) == ADDR_EXPR
    4803              :                                    && ((TREE_CODE (TREE_OPERAND (cst, 0))
    4804              :                                         == FUNCTION_DECL)
    4805              :                                        || VAR_P (TREE_OPERAND (cst, 0))));
    4806              : 
    4807         7051 :               symtab_node *n = symtab_node::get (TREE_OPERAND (cst, 0));
    4808         7051 :               if (n)
    4809              :                 {
    4810         7051 :                   remove_described_reference (n, rdesc);
    4811         7051 :                   cgraph_node *clone = cs->caller;
    4812         7051 :                   while (clone->inlined_to
    4813         1635 :                          && clone->ipcp_clone
    4814         7281 :                          && clone != rdesc->cs->caller)
    4815              :                     {
    4816           94 :                       struct ipa_ref *ref;
    4817           94 :                       ref = clone->find_reference (n, NULL, 0, IPA_REF_ADDR);
    4818           94 :                       if (ref)
    4819              :                         {
    4820           91 :                           if (dump_file)
    4821            1 :                             fprintf (dump_file, "ipa-prop: Removing "
    4822              :                                      "cloning-created reference "
    4823              :                                      "from %s to %s.\n",
    4824              :                                      clone->dump_name (),
    4825              :                                      n->dump_name ());
    4826           91 :                           ref->remove_reference ();
    4827              :                         }
    4828           94 :                       clone = clone->callers->caller;
    4829              :                     }
    4830              :                 }
    4831              :             }
    4832              :         }
    4833              :     }
    4834              : 
    4835      1747840 :   for (i = ipa_get_param_count (old_root_info);
    4836      1748407 :        i < ipa_get_cs_argument_count (args);
    4837              :        i++)
    4838              :     {
    4839          334 :       struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
    4840              : 
    4841          334 :       if (jf->type == IPA_JF_CONST)
    4842              :         {
    4843          298 :           struct ipa_cst_ref_desc *rdesc = jfunc_rdesc_usable (jf);
    4844          298 :           if (rdesc)
    4845          235 :             rdesc->refcount = IPA_UNDESCRIBED_USE;
    4846              :         }
    4847           36 :       else if (jf->type == IPA_JF_PASS_THROUGH)
    4848            5 :         ipa_set_controlled_uses (new_root_info,
    4849              :                                  jf->value.pass_through.formal_id,
    4850              :                                  IPA_UNDESCRIBED_USE);
    4851              :     }
    4852              : }
    4853              : 
    4854              : /* Update jump functions and call note functions on inlining the call site CS.
    4855              :    CS is expected to lead to a node already cloned by
    4856              :    cgraph_clone_inline_nodes.  Newly discovered indirect edges will be added to
    4857              :    *NEW_EDGES, unless NEW_EDGES is NULL.  Return true iff a new edge(s) were +
    4858              :    created.  */
    4859              : 
    4860              : bool
    4861      3859640 : ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
    4862              :                                    vec<cgraph_edge *> *new_edges)
    4863              : {
    4864      3859640 :   bool changed;
    4865              :   /* Do nothing if the preparation phase has not been carried out yet
    4866              :      (i.e. during early inlining).  */
    4867      3859640 :   if (!ipa_node_params_sum)
    4868              :     return false;
    4869       902113 :   gcc_assert (ipa_edge_args_sum);
    4870              : 
    4871       902113 :   propagate_controlled_uses (cs);
    4872       902113 :   changed = propagate_info_to_inlined_callees (cs, cs->callee, new_edges);
    4873       902113 :   ipa_node_params_sum->remove (cs->callee);
    4874              : 
    4875       902113 :   ipa_edge_args *args = ipa_edge_args_sum->get (cs);
    4876       902113 :   if (args)
    4877              :     {
    4878       900360 :       bool ok = true;
    4879       900360 :       if (args->jump_functions)
    4880              :         {
    4881              :           struct ipa_jump_func *jf;
    4882              :           int i;
    4883      2494998 :           FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
    4884      1705538 :             if (jf->type == IPA_JF_CONST
    4885      1705538 :                 && ipa_get_jf_constant_rdesc (jf))
    4886              :               {
    4887              :                 ok = false;
    4888              :                 break;
    4889              :               }
    4890              :         }
    4891       847539 :       if (ok)
    4892       842281 :         ipa_edge_args_sum->remove (cs);
    4893              :     }
    4894       902113 :   if (ipcp_transformation_sum)
    4895       633516 :     ipcp_transformation_sum->remove (cs->callee);
    4896              : 
    4897              :   return changed;
    4898              : }
    4899              : 
    4900              : /* Ensure that array of edge arguments infos is big enough to accommodate a
    4901              :    structure for all edges and reallocates it if not.  Also, allocate
    4902              :    associated hash tables is they do not already exist.  */
    4903              : 
    4904              : void
    4905      4734769 : ipa_check_create_edge_args (void)
    4906              : {
    4907      4734769 :   if (!ipa_edge_args_sum)
    4908       244495 :     ipa_edge_args_sum
    4909       244495 :       = (new (ggc_alloc_no_dtor<ipa_edge_args_sum_t> ())
    4910       244495 :          ipa_edge_args_sum_t (symtab, true));
    4911      4734769 :   if (!ipa_vr_hash_table)
    4912       172095 :     ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
    4913      4734769 : }
    4914              : 
    4915              : /* Free all ipa_edge structures.  */
    4916              : 
    4917              : void
    4918       464387 : ipa_free_all_edge_args (void)
    4919              : {
    4920       464387 :   if (!ipa_edge_args_sum)
    4921              :     return;
    4922              : 
    4923       232280 :   ggc_delete (ipa_edge_args_sum);
    4924       232280 :   ipa_edge_args_sum = NULL;
    4925              : }
    4926              : 
    4927              : /* Free all ipa_node_params structures.  */
    4928              : 
    4929              : void
    4930      5319087 : ipa_free_all_node_params (void)
    4931              : {
    4932      5319087 :   if (ipa_node_params_sum)
    4933      5086980 :     ggc_delete (ipa_node_params_sum);
    4934      5319087 :   ipa_node_params_sum = NULL;
    4935      5319087 : }
    4936              : 
    4937              : /* Initialize IPA CP transformation summary and also allocate any necessary hash
    4938              :    tables if they do not already exist.  */
    4939              : 
    4940              : void
    4941        95632 : ipcp_transformation_initialize (void)
    4942              : {
    4943        95632 :   if (!ipa_vr_hash_table)
    4944         1888 :     ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
    4945        95632 :   if (ipcp_transformation_sum == NULL)
    4946              :     {
    4947        19771 :       ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
    4948        19771 :       ipcp_transformation_sum->disable_insertion_hook ();
    4949              :     }
    4950        95632 : }
    4951              : 
    4952              : /* Release the IPA CP transformation summary.  */
    4953              : 
    4954              : void
    4955       258766 : ipcp_free_transformation_sum (void)
    4956              : {
    4957       258766 :   if (!ipcp_transformation_sum)
    4958              :     return;
    4959              : 
    4960        19762 :   ipcp_transformation_sum->~function_summary<ipcp_transformation *> ();
    4961        19762 :   ggc_free (ipcp_transformation_sum);
    4962        19762 :   ipcp_transformation_sum = NULL;
    4963              : }
    4964              : 
    4965              : /* Set the aggregate replacements of NODE to be AGGVALS.  */
    4966              : 
    4967              : void
    4968        22486 : ipa_set_node_agg_value_chain (struct cgraph_node *node,
    4969              :                               vec<ipa_argagg_value, va_gc> *aggs)
    4970              : {
    4971        22486 :   ipcp_transformation_initialize ();
    4972        22486 :   ipcp_transformation *s = ipcp_transformation_sum->get_create (node);
    4973        22486 :   s->m_agg_values = aggs;
    4974        22486 : }
    4975              : 
    4976              : /* Hook that is called by cgraph.cc when an edge is removed.  Adjust reference
    4977              :    count data structures accordingly.  */
    4978              : 
    4979              : void
    4980            0 : ipa_edge_args_sum_t::remove (cgraph_edge *cs, ipa_edge_args *args)
    4981              : {
    4982            0 :   if (args->jump_functions)
    4983              :     {
    4984              :       struct ipa_jump_func *jf;
    4985              :       int i;
    4986            0 :       FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
    4987              :         {
    4988            0 :           struct ipa_cst_ref_desc *rdesc;
    4989            0 :           try_decrement_rdesc_refcount (jf);
    4990            0 :           if (jf->type == IPA_JF_CONST
    4991            0 :               && (rdesc = ipa_get_jf_constant_rdesc (jf))
    4992            0 :               && rdesc->cs == cs)
    4993            0 :             rdesc->cs = NULL;
    4994              :         }
    4995              :     }
    4996            0 : }
    4997              : 
    4998              : /* Copy information from SRC_JF to DST_JF which correstpond to call graph edges
    4999              :    SRC and DST.  */
    5000              : 
    5001              : static void
    5002      2705629 : ipa_duplicate_jump_function (cgraph_edge *src, cgraph_edge *dst,
    5003              :                              ipa_jump_func *src_jf, ipa_jump_func *dst_jf)
    5004              : {
    5005      2705629 :   dst_jf->agg.items = vec_safe_copy (src_jf->agg.items);
    5006      2705629 :   dst_jf->agg.by_ref = src_jf->agg.by_ref;
    5007              : 
    5008              :   /* We can avoid calling ipa_set_jfunc_vr since it would only look up the
    5009              :      place in the hash_table where the source m_vr resides.  */
    5010      2705629 :   dst_jf->m_vr = src_jf->m_vr;
    5011              : 
    5012      2705629 :   if (src_jf->type == IPA_JF_CONST)
    5013              :     {
    5014       884797 :       ipa_set_jf_cst_copy (dst_jf, src_jf);
    5015       884797 :       struct ipa_cst_ref_desc *src_rdesc = jfunc_rdesc_usable (src_jf);
    5016              : 
    5017       884797 :       if (!src_rdesc)
    5018       753225 :         dst_jf->value.constant.rdesc = NULL;
    5019       131572 :       else if (src->caller == dst->caller)
    5020              :         {
    5021              :           /* Creation of a speculative edge.  If the source edge is the one
    5022              :              grabbing a reference, we must create a new (duplicate)
    5023              :              reference description.  Otherwise they refer to the same
    5024              :              description corresponding to a reference taken in a function
    5025              :              src->caller is inlined to.  In that case we just must
    5026              :              increment the refcount.  */
    5027           37 :           if (src_rdesc->cs == src)
    5028              :             {
    5029           37 :               symtab_node *n = symtab_node_for_jfunc (src_jf);
    5030           37 :               gcc_checking_assert (n);
    5031           37 :               ipa_ref *ref
    5032           37 :                 = src->caller->find_reference (n, src->call_stmt,
    5033              :                                                src->lto_stmt_uid,
    5034              :                                                IPA_REF_ADDR);
    5035           37 :               gcc_checking_assert (ref);
    5036           37 :               dst->caller->clone_reference (ref, ref->stmt);
    5037              : 
    5038           37 :               ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
    5039           37 :               dst_rdesc->cs = dst;
    5040           37 :               dst_rdesc->refcount = src_rdesc->refcount;
    5041           37 :               dst_rdesc->next_duplicate = NULL;
    5042           37 :               dst_jf->value.constant.rdesc = dst_rdesc;
    5043              :             }
    5044              :           else
    5045              :             {
    5046            0 :               src_rdesc->refcount++;
    5047            0 :               dst_jf->value.constant.rdesc = src_rdesc;
    5048              :             }
    5049              :         }
    5050       131535 :       else if (src_rdesc->cs == src)
    5051              :         {
    5052       131268 :           struct ipa_cst_ref_desc *dst_rdesc = ipa_refdesc_pool.allocate ();
    5053       131268 :           dst_rdesc->cs = dst;
    5054       131268 :           dst_rdesc->refcount = src_rdesc->refcount;
    5055       131268 :           dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
    5056       131268 :           src_rdesc->next_duplicate = dst_rdesc;
    5057       131268 :           dst_jf->value.constant.rdesc = dst_rdesc;
    5058              :         }
    5059              :       else
    5060              :         {
    5061          267 :           struct ipa_cst_ref_desc *dst_rdesc;
    5062              :           /* This can happen during inlining, when a JFUNC can refer to a
    5063              :              reference taken in a function up in the tree of inline clones.
    5064              :              We need to find the duplicate that refers to our tree of
    5065              :              inline clones.  */
    5066              : 
    5067          267 :           gcc_assert (dst->caller->inlined_to);
    5068          267 :           for (dst_rdesc = src_rdesc->next_duplicate;
    5069          267 :                dst_rdesc;
    5070            0 :                dst_rdesc = dst_rdesc->next_duplicate)
    5071              :             {
    5072          267 :               struct cgraph_node *top;
    5073            0 :               top = dst_rdesc->cs->caller->inlined_to
    5074          267 :                 ? dst_rdesc->cs->caller->inlined_to
    5075              :                 : dst_rdesc->cs->caller;
    5076          267 :               if (dst->caller->inlined_to == top)
    5077              :                 break;
    5078              :             }
    5079          267 :           gcc_assert (dst_rdesc);
    5080          267 :           dst_jf->value.constant.rdesc = dst_rdesc;
    5081              :         }
    5082              :     }
    5083      1820832 :   else if (src_jf->type == IPA_JF_PASS_THROUGH)
    5084              :     {
    5085       650801 :       dst_jf->type = IPA_JF_PASS_THROUGH;
    5086       650801 :       dst_jf->value.pass_through = src_jf->value.pass_through;
    5087       650801 :       if (src->caller == dst->caller)
    5088              :         {
    5089        10804 :           struct cgraph_node *inline_root = dst->caller->inlined_to
    5090        10827 :             ? dst->caller->inlined_to : dst->caller;
    5091        10827 :           ipa_node_params *root_info = ipa_node_params_sum->get (inline_root);
    5092        10827 :           int idx = ipa_get_jf_pass_through_formal_id (dst_jf);
    5093              : 
    5094        10827 :           int c = ipa_get_controlled_uses (root_info, idx);
    5095        10827 :           if (c != IPA_UNDESCRIBED_USE)
    5096              :             {
    5097         2538 :               c++;
    5098         2538 :               ipa_set_controlled_uses (root_info, idx, c);
    5099              :             }
    5100              :         }
    5101              :     }
    5102      1170031 :   else if (src_jf->type == IPA_JF_ANCESTOR)
    5103              :     {
    5104        89774 :       dst_jf->type = IPA_JF_ANCESTOR;
    5105        89774 :       dst_jf->value.ancestor = src_jf->value.ancestor;
    5106              :     }
    5107              :   else
    5108      1080257 :     gcc_assert (src_jf->type == IPA_JF_UNKNOWN);
    5109      2705629 : }
    5110              : 
    5111              : /* Method invoked when an edge is duplicated.  Copy ipa_edge_args and adjust
    5112              :    reference count data strucutres accordingly.  */
    5113              : 
    5114              : void
    5115      1221835 : ipa_edge_args_sum_t::duplicate (cgraph_edge *src, cgraph_edge *dst,
    5116              :                                 ipa_edge_args *old_args, ipa_edge_args *new_args)
    5117              : {
    5118      1221835 :   unsigned int i;
    5119              : 
    5120      1221835 :   if (old_args->polymorphic_call_contexts)
    5121       144707 :     new_args->polymorphic_call_contexts
    5122       144707 :       = vec_safe_copy (old_args->polymorphic_call_contexts);
    5123              : 
    5124      1221835 :   if (!vec_safe_length (old_args->jump_functions))
    5125              :     {
    5126        51724 :       new_args->jump_functions = NULL;
    5127        51724 :       return;
    5128              :     }
    5129      1170111 :   vec_safe_grow_cleared (new_args->jump_functions,
    5130      1170111 :                          old_args->jump_functions->length (), true);
    5131              : 
    5132      3860658 :   for (i = 0; i < vec_safe_length (old_args->jump_functions); i++)
    5133              :     {
    5134      2690547 :       struct ipa_jump_func *src_jf = ipa_get_ith_jump_func (old_args, i);
    5135      2690547 :       struct ipa_jump_func *dst_jf = ipa_get_ith_jump_func (new_args, i);
    5136              : 
    5137      2690547 :       ipa_duplicate_jump_function (src, dst, src_jf, dst_jf);
    5138              :     }
    5139              : }
    5140              : 
    5141              : /* Analyze newly added function into callgraph.  */
    5142              : 
    5143              : static void
    5144        40523 : ipa_add_new_function (cgraph_node *node, void *data ATTRIBUTE_UNUSED)
    5145              : {
    5146        40523 :   if (node->has_gimple_body_p ())
    5147        40523 :     ipa_analyze_node (node);
    5148        40523 : }
    5149              : 
    5150              : /* Hook that is called by summary when a node is duplicated.  */
    5151              : 
    5152              : void
    5153       731187 : ipa_node_params_t::duplicate(cgraph_node *, cgraph_node *,
    5154              :                              ipa_node_params *old_info,
    5155              :                              ipa_node_params *new_info)
    5156              : {
    5157       731187 :   new_info->descriptors = vec_safe_copy (old_info->descriptors);
    5158       731187 :   gcc_assert (new_info->lattices.is_empty ());
    5159       731187 :   new_info->ipcp_orig_node = old_info->ipcp_orig_node;
    5160       731187 :   new_info->known_csts = old_info->known_csts.copy ();
    5161       731187 :   new_info->known_contexts = old_info->known_contexts.copy ();
    5162              : 
    5163       731187 :   new_info->analysis_done = old_info->analysis_done;
    5164       731187 :   new_info->node_enqueued = old_info->node_enqueued;
    5165       731187 :   new_info->versionable = old_info->versionable;
    5166       731187 : }
    5167              : 
    5168              : /* Duplication of ipcp transformation summaries.  */
    5169              : 
    5170              : void
    5171        58785 : ipcp_transformation_t::duplicate(cgraph_node *, cgraph_node *dst,
    5172              :                                  ipcp_transformation *src_trans,
    5173              :                                  ipcp_transformation *dst_trans)
    5174              : {
    5175              :   /* Avoid redundant work of duplicating vectors we will never use.  */
    5176        58785 :   if (dst->inlined_to)
    5177              :     return;
    5178         8564 :   dst_trans->m_agg_values = vec_safe_copy (src_trans->m_agg_values);
    5179        15837 :   dst_trans->m_vr = vec_safe_copy (src_trans->m_vr);
    5180              : }
    5181              : 
    5182              : /* Register our cgraph hooks if they are not already there.  */
    5183              : 
    5184              : void
    5185       380965 : ipa_register_cgraph_hooks (void)
    5186              : {
    5187       380965 :   ipa_check_create_node_params ();
    5188       380965 :   ipa_check_create_edge_args ();
    5189              : 
    5190       761930 :   function_insertion_hook_holder =
    5191       380965 :       symtab->add_cgraph_insertion_hook (&ipa_add_new_function, NULL);
    5192       380965 : }
    5193              : 
    5194              : /* Unregister our cgraph hooks if they are not already there.  */
    5195              : 
    5196              : static void
    5197       464387 : ipa_unregister_cgraph_hooks (void)
    5198              : {
    5199       464387 :   if (function_insertion_hook_holder)
    5200       232280 :     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
    5201       464387 :   function_insertion_hook_holder = NULL;
    5202       464387 : }
    5203              : 
    5204              : /* Free all ipa_node_params and all ipa_edge_args structures if they are no
    5205              :    longer needed after ipa-cp.  */
    5206              : 
    5207              : void
    5208       127757 : ipa_free_all_structures_after_ipa_cp (void)
    5209              : {
    5210       127757 :   if (!optimize && !in_lto_p)
    5211              :     {
    5212            0 :       ipa_free_all_edge_args ();
    5213            0 :       ipa_free_all_node_params ();
    5214            0 :       ipcp_sources_pool.release ();
    5215            0 :       ipcp_cst_values_pool.release ();
    5216            0 :       ipcp_poly_ctx_values_pool.release ();
    5217            0 :       ipcp_agg_lattice_pool.release ();
    5218            0 :       ipa_unregister_cgraph_hooks ();
    5219            0 :       ipa_refdesc_pool.release ();
    5220              :     }
    5221       127757 : }
    5222              : 
    5223              : /* Free all ipa_node_params and all ipa_edge_args structures if they are no
    5224              :    longer needed after indirect inlining.  */
    5225              : 
    5226              : void
    5227       464387 : ipa_free_all_structures_after_iinln (void)
    5228              : {
    5229       464387 :   ipa_free_all_edge_args ();
    5230       464387 :   ipa_free_all_node_params ();
    5231       464387 :   ipa_unregister_cgraph_hooks ();
    5232       464387 :   ipcp_sources_pool.release ();
    5233       464387 :   ipcp_cst_values_pool.release ();
    5234       464387 :   ipcp_poly_ctx_values_pool.release ();
    5235       464387 :   ipcp_agg_lattice_pool.release ();
    5236       464387 :   ipa_refdesc_pool.release ();
    5237       464387 : }
    5238              : 
    5239              : /* Print ipa_tree_map data structures of all functions in the
    5240              :    callgraph to F.  */
    5241              : 
    5242              : void
    5243          240 : ipa_print_node_params (FILE *f, struct cgraph_node *node)
    5244              : {
    5245          240 :   int i, count;
    5246          240 :   class ipa_node_params *info;
    5247              : 
    5248          240 :   if (!node->definition)
    5249              :     return;
    5250          181 :   info = ipa_node_params_sum->get (node);
    5251          181 :   fprintf (f, "  function  %s parameter descriptors:\n", node->dump_name ());
    5252          181 :   if (!info)
    5253              :     {
    5254            0 :       fprintf (f, " no params return\n");
    5255            0 :       return;
    5256              :     }
    5257          181 :   count = ipa_get_param_count (info);
    5258          367 :   for (i = 0; i < count; i++)
    5259              :     {
    5260          186 :       int c;
    5261              : 
    5262          186 :       fprintf (f, "    ");
    5263          186 :       ipa_dump_param (f, info, i);
    5264          186 :       if (ipa_is_param_used (info, i))
    5265          178 :         fprintf (f, " used");
    5266          186 :       if (ipa_is_param_used_by_ipa_predicates (info, i))
    5267          108 :         fprintf (f, " used_by_ipa_predicates");
    5268          186 :       if (ipa_is_param_used_by_indirect_call (info, i))
    5269           10 :         fprintf (f, " used_by_indirect_call");
    5270          186 :       if (ipa_is_param_used_by_polymorphic_call (info, i))
    5271            0 :         fprintf (f, " used_by_polymorphic_call");
    5272          186 :       c = ipa_get_controlled_uses (info, i);
    5273          186 :       if (c == IPA_UNDESCRIBED_USE)
    5274          108 :         fprintf (f, " undescribed_use");
    5275              :       else
    5276          134 :         fprintf (f, "  controlled_uses=%i %s", c,
    5277           78 :                  ipa_get_param_load_dereferenced (info, i)
    5278              :                  ? "(load_dereferenced)" : "");
    5279          186 :       fprintf (f, "\n");
    5280              :     }
    5281              : }
    5282              : 
    5283              : /* Print ipa_tree_map data structures of all functions in the
    5284              :    callgraph to F.  */
    5285              : 
    5286              : void
    5287           48 : ipa_print_all_params (FILE * f)
    5288              : {
    5289           48 :   struct cgraph_node *node;
    5290              : 
    5291           48 :   fprintf (f, "\nFunction parameters:\n");
    5292          274 :   FOR_EACH_FUNCTION (node)
    5293          226 :     ipa_print_node_params (f, node);
    5294           48 : }
    5295              : 
    5296              : /* Stream out jump function JUMP_FUNC to OB.  */
    5297              : 
    5298              : static void
    5299       608550 : ipa_write_jump_function (struct output_block *ob,
    5300              :                          struct ipa_jump_func *jump_func)
    5301              : {
    5302       608550 :   struct ipa_agg_jf_item *item;
    5303       608550 :   struct bitpack_d bp;
    5304       608550 :   int i, count;
    5305       608550 :   int flag = 0;
    5306              : 
    5307              :   /* ADDR_EXPRs are very comon IP invariants; save some streamer data
    5308              :      as well as WPA memory by handling them specially.  */
    5309       608550 :   if (jump_func->type == IPA_JF_CONST
    5310       464713 :       && TREE_CODE (jump_func->value.constant.value) == ADDR_EXPR)
    5311       608550 :     flag = 1;
    5312              : 
    5313       608550 :   streamer_write_uhwi (ob, jump_func->type * 2 + flag);
    5314       608550 :   switch (jump_func->type)
    5315              :     {
    5316              :     case IPA_JF_UNKNOWN:
    5317              :       break;
    5318       464713 :     case IPA_JF_CONST:
    5319       464713 :       gcc_assert (
    5320              :           EXPR_LOCATION (jump_func->value.constant.value) == UNKNOWN_LOCATION);
    5321       464713 :       stream_write_tree (ob,
    5322              :                          flag
    5323              :                          ? TREE_OPERAND (jump_func->value.constant.value, 0)
    5324              :                          : jump_func->value.constant.value, true);
    5325       464713 :       break;
    5326        76629 :     case IPA_JF_PASS_THROUGH:
    5327        76629 :       streamer_write_uhwi (ob, jump_func->value.pass_through.operation);
    5328        76629 :       if (jump_func->value.pass_through.operation == NOP_EXPR)
    5329              :         {
    5330        75809 :           streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
    5331        75809 :           bp = bitpack_create (ob->main_stream);
    5332        75809 :           bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
    5333        75809 :           gcc_assert (!jump_func->value.pass_through.refdesc_decremented);
    5334        75809 :           streamer_write_bitpack (&bp);
    5335              :         }
    5336          820 :       else if (TREE_CODE_CLASS (jump_func->value.pass_through.operation)
    5337              :                == tcc_unary)
    5338              :         {
    5339           39 :           stream_write_tree (ob, jump_func->value.pass_through.op_type, true);
    5340           39 :           streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
    5341              :         }
    5342              :       else
    5343              :         {
    5344          781 :           stream_write_tree (ob, jump_func->value.pass_through.op_type, true);
    5345          781 :           stream_write_tree (ob, jump_func->value.pass_through.operand, true);
    5346          781 :           streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
    5347              :         }
    5348              :       break;
    5349         1309 :     case IPA_JF_ANCESTOR:
    5350         1309 :       streamer_write_uhwi (ob, jump_func->value.ancestor.offset);
    5351         1309 :       streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
    5352         1309 :       bp = bitpack_create (ob->main_stream);
    5353         1309 :       bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
    5354         1309 :       bp_pack_value (&bp, jump_func->value.ancestor.keep_null, 1);
    5355         1309 :       streamer_write_bitpack (&bp);
    5356         1309 :       break;
    5357            0 :     default:
    5358            0 :       fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
    5359              :     }
    5360              : 
    5361       608550 :   count = vec_safe_length (jump_func->agg.items);
    5362       608550 :   streamer_write_uhwi (ob, count);
    5363       608550 :   if (count)
    5364              :     {
    5365         3276 :       bp = bitpack_create (ob->main_stream);
    5366         3276 :       bp_pack_value (&bp, jump_func->agg.by_ref, 1);
    5367         3276 :       streamer_write_bitpack (&bp);
    5368              :     }
    5369              : 
    5370       615098 :   FOR_EACH_VEC_SAFE_ELT (jump_func->agg.items, i, item)
    5371              :     {
    5372         6548 :       stream_write_tree (ob, item->type, true);
    5373         6548 :       streamer_write_uhwi (ob, item->offset);
    5374         6548 :       streamer_write_uhwi (ob, item->jftype);
    5375         6548 :       switch (item->jftype)
    5376              :         {
    5377              :         case IPA_JF_UNKNOWN:
    5378              :           break;
    5379         6023 :         case IPA_JF_CONST:
    5380         6023 :           stream_write_tree (ob, item->value.constant, true);
    5381         6023 :           break;
    5382          525 :         case IPA_JF_PASS_THROUGH:
    5383          525 :         case IPA_JF_LOAD_AGG:
    5384          525 :           streamer_write_uhwi (ob, item->value.pass_through.operation);
    5385          525 :           streamer_write_uhwi (ob, item->value.pass_through.formal_id);
    5386          525 :           if (item->value.pass_through.operation != NOP_EXPR)
    5387            4 :             stream_write_tree (ob, item->value.pass_through.op_type, true);
    5388          525 :           if (TREE_CODE_CLASS (item->value.pass_through.operation)
    5389              :                                                         != tcc_unary)
    5390            4 :             stream_write_tree (ob, item->value.pass_through.operand, true);
    5391          525 :           if (item->jftype == IPA_JF_LOAD_AGG)
    5392              :             {
    5393           85 :               stream_write_tree (ob, item->value.load_agg.type, true);
    5394           85 :               streamer_write_uhwi (ob, item->value.load_agg.offset);
    5395           85 :               bp = bitpack_create (ob->main_stream);
    5396           85 :               bp_pack_value (&bp, item->value.load_agg.by_ref, 1);
    5397           85 :               streamer_write_bitpack (&bp);
    5398              :             }
    5399              :           break;
    5400            0 :         default:
    5401            0 :           fatal_error (UNKNOWN_LOCATION,
    5402              :                        "invalid jump function in LTO stream");
    5403              :         }
    5404              :     }
    5405              : 
    5406       608550 :   bp = bitpack_create (ob->main_stream);
    5407       608550 :   if (jump_func->m_vr)
    5408       423010 :     jump_func->m_vr->streamer_write (ob);
    5409              :   else
    5410              :     {
    5411       185540 :       bp_pack_value (&bp, false, 1);
    5412       185540 :       streamer_write_bitpack (&bp);
    5413              :     }
    5414       608550 : }
    5415              : 
    5416              : /* Read in jump function JUMP_FUNC from IB.  */
    5417              : 
    5418              : static void
    5419       569447 : ipa_read_jump_function (class lto_input_block *ib,
    5420              :                         struct ipa_jump_func *jump_func,
    5421              :                         struct cgraph_edge *cs,
    5422              :                         class data_in *data_in,
    5423              :                         bool prevails)
    5424              : {
    5425       569447 :   enum jump_func_type jftype;
    5426       569447 :   enum tree_code operation;
    5427       569447 :   int i, count;
    5428       569447 :   int val = streamer_read_uhwi (ib);
    5429       569447 :   bool flag = val & 1;
    5430              : 
    5431       569447 :   jftype = (enum jump_func_type) (val / 2);
    5432       569447 :   switch (jftype)
    5433              :     {
    5434        50528 :     case IPA_JF_UNKNOWN:
    5435        50528 :       ipa_set_jf_unknown (jump_func);
    5436        50528 :       break;
    5437       448390 :     case IPA_JF_CONST:
    5438       448390 :       {
    5439       448390 :         tree t = stream_read_tree (ib, data_in);
    5440       448390 :         if (flag && prevails)
    5441       161595 :           t = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (t)), t);
    5442       448390 :         ipa_set_jf_constant (jump_func, t, cs);
    5443              :       }
    5444       448390 :       break;
    5445        69879 :     case IPA_JF_PASS_THROUGH:
    5446        69879 :       operation = (enum tree_code) streamer_read_uhwi (ib);
    5447        69879 :       if (operation == NOP_EXPR)
    5448              :         {
    5449        69332 :           int formal_id =  streamer_read_uhwi (ib);
    5450        69332 :           struct bitpack_d bp = streamer_read_bitpack (ib);
    5451        69332 :           bool agg_preserved = bp_unpack_value (&bp, 1);
    5452        69332 :           ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
    5453              :         }
    5454          547 :       else if (TREE_CODE_CLASS (operation) == tcc_unary)
    5455              :         {
    5456           19 :           tree op_type = stream_read_tree (ib, data_in);
    5457           19 :           int formal_id =  streamer_read_uhwi (ib);
    5458           19 :           ipa_set_jf_unary_pass_through (jump_func, formal_id, operation,
    5459              :                                          op_type);
    5460              :         }
    5461              :       else
    5462              :         {
    5463          528 :           tree op_type = stream_read_tree (ib, data_in);
    5464          528 :           tree operand = stream_read_tree (ib, data_in);
    5465          528 :           int formal_id =  streamer_read_uhwi (ib);
    5466          528 :           ipa_set_jf_arith_pass_through (jump_func, formal_id, operand,
    5467              :                                          operation, op_type);
    5468              :         }
    5469              :       break;
    5470          650 :     case IPA_JF_ANCESTOR:
    5471          650 :       {
    5472          650 :         HOST_WIDE_INT offset = streamer_read_uhwi (ib);
    5473          650 :         int formal_id = streamer_read_uhwi (ib);
    5474          650 :         struct bitpack_d bp = streamer_read_bitpack (ib);
    5475          650 :         bool agg_preserved = bp_unpack_value (&bp, 1);
    5476          650 :         bool keep_null = bp_unpack_value (&bp, 1);
    5477          650 :         ipa_set_ancestor_jf (jump_func, offset, formal_id, agg_preserved,
    5478              :                              keep_null);
    5479          650 :         break;
    5480              :       }
    5481            0 :     default:
    5482            0 :       fatal_error (UNKNOWN_LOCATION, "invalid jump function in LTO stream");
    5483              :     }
    5484              : 
    5485       569447 :   count = streamer_read_uhwi (ib);
    5486       569447 :   if (prevails)
    5487              :     {
    5488       569441 :       jump_func->agg.items = NULL;
    5489       569441 :       vec_safe_reserve (jump_func->agg.items, count, true);
    5490              :     }
    5491       569447 :   if (count)
    5492              :     {
    5493         2922 :       struct bitpack_d bp = streamer_read_bitpack (ib);
    5494         2922 :       jump_func->agg.by_ref = bp_unpack_value (&bp, 1);
    5495              :     }
    5496       575413 :   for (i = 0; i < count; i++)
    5497              :     {
    5498         5966 :       struct ipa_agg_jf_item item;
    5499         5966 :       item.type = stream_read_tree (ib, data_in);
    5500         5966 :       item.offset = streamer_read_uhwi (ib);
    5501         5966 :       item.jftype = (enum jump_func_type) streamer_read_uhwi (ib);
    5502              : 
    5503         5966 :       switch (item.jftype)
    5504              :         {
    5505              :         case IPA_JF_UNKNOWN:
    5506              :           break;
    5507         5527 :         case IPA_JF_CONST:
    5508         5527 :           item.value.constant = stream_read_tree (ib, data_in);
    5509         5527 :           break;
    5510          439 :         case IPA_JF_PASS_THROUGH:
    5511          439 :         case IPA_JF_LOAD_AGG:
    5512          439 :           operation = (enum tree_code) streamer_read_uhwi (ib);
    5513          439 :           item.value.pass_through.operation = operation;
    5514          439 :           item.value.pass_through.formal_id = streamer_read_uhwi (ib);
    5515          439 :           if (operation != NOP_EXPR)
    5516            0 :             item.value.pass_through.op_type = stream_read_tree (ib, data_in);
    5517              :           else
    5518          439 :             item.value.pass_through.op_type = NULL_TREE;
    5519          439 :           if (TREE_CODE_CLASS (operation) == tcc_unary)
    5520          439 :             item.value.pass_through.operand = NULL_TREE;
    5521              :           else
    5522            0 :             item.value.pass_through.operand = stream_read_tree (ib, data_in);
    5523          439 :           if (item.jftype == IPA_JF_LOAD_AGG)
    5524              :             {
    5525           47 :               struct bitpack_d bp;
    5526           47 :               item.value.load_agg.type = stream_read_tree (ib, data_in);
    5527           47 :               item.value.load_agg.offset = streamer_read_uhwi (ib);
    5528           47 :               bp = streamer_read_bitpack (ib);
    5529           47 :               item.value.load_agg.by_ref = bp_unpack_value (&bp, 1);
    5530              :             }
    5531              :           break;
    5532            0 :         default:
    5533            0 :           fatal_error (UNKNOWN_LOCATION,
    5534              :                        "invalid jump function in LTO stream");
    5535              :         }
    5536         5966 :       if (prevails)
    5537         5966 :         jump_func->agg.items->quick_push (item);
    5538              :     }
    5539              : 
    5540       569447 :   ipa_vr vr;
    5541       569447 :   vr.streamer_read (ib, data_in);
    5542       569447 :   if (vr.known_p ())
    5543              :     {
    5544       398229 :       if (prevails)
    5545       398223 :         ipa_set_jfunc_vr (jump_func, vr);
    5546              :     }
    5547              :   else
    5548       171218 :     jump_func->m_vr = NULL;
    5549       569447 : }
    5550              : 
    5551              : /* Stream out parts of cgraph_indirect_call_info corresponding to CS that are
    5552              :    relevant to indirect inlining to OB.  */
    5553              : 
    5554              : static void
    5555         2608 : ipa_write_indirect_edge_info (struct output_block *ob,
    5556              :                               struct cgraph_edge *cs)
    5557              : {
    5558         2608 :   struct bitpack_d bp;
    5559              : 
    5560         2608 :   bp = bitpack_create (ob->main_stream);
    5561         2608 :   bp_pack_enum (&bp, cgraph_indirect_info_kind, CIIK_N_KINDS,
    5562              :                 cs->indirect_info->kind);
    5563         2608 :   streamer_write_bitpack (&bp);
    5564              : 
    5565         2608 :   if (cgraph_polymorphic_indirect_info *pii
    5566         2608 :       = dyn_cast <cgraph_polymorphic_indirect_info *> (cs->indirect_info))
    5567              :     {
    5568         1023 :       bp = bitpack_create (ob->main_stream);
    5569         1023 :       bp_pack_value (&bp, pii->vptr_changed, 1);
    5570         1023 :       streamer_write_bitpack (&bp);
    5571              : 
    5572         1023 :       streamer_write_hwi (ob, pii->param_index);
    5573         1023 :       pii->context.stream_out (ob);
    5574         1023 :       streamer_write_hwi (ob, pii->otr_token);
    5575         1023 :       stream_write_tree (ob, pii->otr_type, true);
    5576         1023 :       streamer_write_hwi (ob, pii->offset);
    5577              :     }
    5578         1585 :   else if (cgraph_simple_indirect_info *sii
    5579         1585 :            = dyn_cast <cgraph_simple_indirect_info *> (cs->indirect_info))
    5580              :     {
    5581         1566 :       bp = bitpack_create (ob->main_stream);
    5582         1566 :       bp_pack_value (&bp, sii->agg_contents, 1);
    5583         1566 :       bp_pack_value (&bp, sii->member_ptr, 1);
    5584         1566 :       bp_pack_value (&bp, sii->fnptr_loaded_from_record, 1);
    5585         1566 :       bp_pack_value (&bp, sii->by_ref, 1);
    5586         1566 :       bp_pack_value (&bp, sii->guaranteed_unmodified, 1);
    5587         1566 :       streamer_write_bitpack (&bp);
    5588              : 
    5589         1566 :       streamer_write_hwi (ob, sii->param_index);
    5590         1566 :       if (sii->agg_contents)
    5591           55 :         streamer_write_hwi (ob, sii->offset);
    5592              :       else
    5593         1511 :         gcc_assert (sii->offset == 0);
    5594         1566 :       if (sii->fnptr_loaded_from_record)
    5595              :         {
    5596          128 :           stream_write_tree (ob, sii->rec_type, true);
    5597          128 :           streamer_write_uhwi (ob, sii->fld_offset);
    5598              :         }
    5599              :     }
    5600              :   else
    5601           19 :     gcc_assert (cs->indirect_info->param_index == -1);
    5602         2608 : }
    5603              : 
    5604              : /* Read in parts of cgraph_indirect_call_info corresponding to CS that are
    5605              :    relevant to indirect inlining from IB.  */
    5606              : 
    5607              : static void
    5608         1415 : ipa_read_indirect_edge_info (class lto_input_block *ib,
    5609              :                              class data_in *data_in,
    5610              :                              struct cgraph_edge *cs,
    5611              :                              class ipa_node_params *info)
    5612              : {
    5613         1415 :   struct bitpack_d bp;
    5614              : 
    5615         1415 :   bp = streamer_read_bitpack (ib);
    5616         1415 :   enum cgraph_indirect_info_kind ii_kind
    5617         1415 :     = bp_unpack_enum (&bp, cgraph_indirect_info_kind, CIIK_N_KINDS);
    5618         1415 :   gcc_assert (ii_kind == cs->indirect_info->kind);
    5619              : 
    5620         1415 :   if (cgraph_polymorphic_indirect_info *pii
    5621         1415 :       = dyn_cast <cgraph_polymorphic_indirect_info *> (cs->indirect_info))
    5622              :     {
    5623           93 :       bp = streamer_read_bitpack (ib);
    5624           93 :       pii->vptr_changed = bp_unpack_value (&bp, 1);
    5625              : 
    5626           93 :       pii->param_index = (int) streamer_read_hwi (ib);
    5627           93 :       pii->context.stream_in (ib, data_in);
    5628           93 :       pii->otr_token = (HOST_WIDE_INT) streamer_read_hwi (ib);
    5629           93 :       pii->otr_type = stream_read_tree (ib, data_in);
    5630           93 :       pii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
    5631              : 
    5632           93 :       if (info && pii->param_index >= 0)
    5633              :         {
    5634           70 :           ipa_set_param_used_by_polymorphic_call (info, pii->param_index, true);
    5635           70 :           ipa_set_param_used_by_indirect_call (info, pii->param_index, true);
    5636              :         }
    5637              :     }
    5638         1322 :   else if (cgraph_simple_indirect_info *sii
    5639         1322 :            = dyn_cast <cgraph_simple_indirect_info *> (cs->indirect_info))
    5640              :     {
    5641         1317 :       bp = streamer_read_bitpack (ib);
    5642         1317 :       sii->agg_contents = bp_unpack_value (&bp, 1);
    5643         1317 :       sii->member_ptr = bp_unpack_value (&bp, 1);
    5644         1317 :       sii->fnptr_loaded_from_record = bp_unpack_value (&bp, 1);
    5645         1317 :       sii->by_ref = bp_unpack_value (&bp, 1);
    5646         1317 :       sii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
    5647              : 
    5648         1317 :       sii->param_index = (int) streamer_read_hwi (ib);
    5649         1317 :       if (sii->agg_contents)
    5650           31 :         sii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
    5651              :       else
    5652         1286 :         sii->offset = 0;
    5653         1317 :       if (sii->fnptr_loaded_from_record)
    5654              :         {
    5655           66 :           sii->rec_type = stream_read_tree (ib, data_in);
    5656           66 :           sii->fld_offset = (unsigned) streamer_read_uhwi (ib);
    5657              :         }
    5658         1317 :       if (info && sii->param_index >= 0)
    5659          263 :         ipa_set_param_used_by_indirect_call (info, sii->param_index, true);
    5660              :     }
    5661              :   else
    5662            5 :     cs->indirect_info->param_index = -1;
    5663         1415 : }
    5664              : 
    5665              : /* Stream out NODE info to OB.  */
    5666              : 
    5667              : static void
    5668        92724 : ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
    5669              : {
    5670        92724 :   int node_ref;
    5671        92724 :   lto_symtab_encoder_t encoder;
    5672        92724 :   ipa_node_params *info = ipa_node_params_sum->get (node);
    5673        92724 :   int j;
    5674        92724 :   struct cgraph_edge *e;
    5675        92724 :   struct bitpack_d bp;
    5676              : 
    5677        92724 :   encoder = ob->decl_state->symtab_node_encoder;
    5678        92724 :   node_ref = lto_symtab_encoder_encode (encoder, node);
    5679        92724 :   streamer_write_uhwi (ob, node_ref);
    5680              : 
    5681        92724 :   streamer_write_uhwi (ob, ipa_get_param_count (info));
    5682       449355 :   for (j = 0; j < ipa_get_param_count (info); j++)
    5683       100706 :     streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
    5684        92724 :   bp = bitpack_create (ob->main_stream);
    5685        92724 :   gcc_assert (info->analysis_done
    5686              :               || ipa_get_param_count (info) == 0);
    5687        92724 :   gcc_assert (!info->node_enqueued);
    5688        92724 :   gcc_assert (!info->ipcp_orig_node);
    5689       356631 :   for (j = 0; j < ipa_get_param_count (info); j++)
    5690              :     {
    5691              :       /* TODO: We could just not stream the bit in the undescribed case. */
    5692       100706 :       bool d = (ipa_get_controlled_uses (info, j) != IPA_UNDESCRIBED_USE)
    5693       100706 :         ? ipa_get_param_load_dereferenced (info, j) : true;
    5694       100706 :       bp_pack_value (&bp, d, 1);
    5695       100706 :       bp_pack_value (&bp, ipa_is_param_used (info, j), 1);
    5696              :     }
    5697        92724 :   streamer_write_bitpack (&bp);
    5698       449355 :   for (j = 0; j < ipa_get_param_count (info); j++)
    5699              :     {
    5700       100706 :       streamer_write_hwi (ob, ipa_get_controlled_uses (info, j));
    5701       100706 :       stream_write_tree (ob, ipa_get_type (info, j), true);
    5702              :     }
    5703       455588 :   for (e = node->callees; e; e = e->next_callee)
    5704              :     {
    5705       362864 :       ipa_edge_args *args = ipa_edge_args_sum->get (e);
    5706              : 
    5707       362864 :       if (!args)
    5708              :         {
    5709          786 :           streamer_write_uhwi (ob, 0);
    5710          786 :           continue;
    5711              :         }
    5712              : 
    5713       362078 :       streamer_write_uhwi (ob,
    5714       362078 :                            ipa_get_cs_argument_count (args) * 2
    5715       362078 :                            + (args->polymorphic_call_contexts != NULL));
    5716      2187982 :       for (j = 0; j < ipa_get_cs_argument_count (args); j++)
    5717              :         {
    5718       605426 :           ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
    5719       605426 :           if (args->polymorphic_call_contexts != NULL)
    5720         2379 :             ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
    5721              :         }
    5722              :     }
    5723        95332 :   for (e = node->indirect_calls; e; e = e->next_callee)
    5724              :     {
    5725         2608 :       ipa_edge_args *args = ipa_edge_args_sum->get (e);
    5726         2608 :       if (!args)
    5727            6 :         streamer_write_uhwi (ob, 0);
    5728              :       else
    5729              :         {
    5730         2602 :           streamer_write_uhwi (ob,
    5731         2602 :                                ipa_get_cs_argument_count (args) * 2
    5732         2602 :                                + (args->polymorphic_call_contexts != NULL));
    5733        13912 :           for (j = 0; j < ipa_get_cs_argument_count (args); j++)
    5734              :             {
    5735         3124 :               ipa_write_jump_function (ob, ipa_get_ith_jump_func (args, j));
    5736         3124 :               if (args->polymorphic_call_contexts != NULL)
    5737         1321 :                 ipa_get_ith_polymorhic_call_context (args, j)->stream_out (ob);
    5738              :             }
    5739              :         }
    5740         2608 :       ipa_write_indirect_edge_info (ob, e);
    5741              :     }
    5742        92724 : }
    5743              : 
    5744              : /* Stream in edge E from IB.  */
    5745              : 
    5746              : static void
    5747       334751 : ipa_read_edge_info (class lto_input_block *ib,
    5748              :                     class data_in *data_in,
    5749              :                     struct cgraph_edge *e, bool prevails)
    5750              : {
    5751       334751 :   int count = streamer_read_uhwi (ib);
    5752       334751 :   bool contexts_computed = count & 1;
    5753              : 
    5754       334751 :   count /= 2;
    5755       334751 :   if (!count)
    5756              :     return;
    5757       234151 :   if (prevails
    5758       234151 :       && (e->possibly_call_in_translation_unit_p ()
    5759              :           /* Also stream in jump functions to builtins in hope that they
    5760              :              will get fnspecs.  */
    5761       115737 :           || fndecl_built_in_p (e->callee->decl, BUILT_IN_NORMAL)))
    5762              :     {
    5763       222984 :       ipa_edge_args *args = ipa_edge_args_sum->get_create (e);
    5764       222984 :       vec_safe_grow_cleared (args->jump_functions, count, true);
    5765       222984 :       if (contexts_computed)
    5766          612 :         vec_safe_grow_cleared (args->polymorphic_call_contexts, count, true);
    5767       774554 :       for (int k = 0; k < count; k++)
    5768              :         {
    5769       551570 :           ipa_read_jump_function (ib, ipa_get_ith_jump_func (args, k), e,
    5770              :                                   data_in, prevails);
    5771       551570 :           if (contexts_computed)
    5772          944 :             ipa_get_ith_polymorhic_call_context (args, k)->stream_in
    5773          944 :                                                              (ib, data_in);
    5774              :         }
    5775              :     }
    5776              :   else
    5777              :     {
    5778        29044 :       for (int k = 0; k < count; k++)
    5779              :         {
    5780        17877 :           struct ipa_jump_func dummy;
    5781        17877 :           ipa_read_jump_function (ib, &dummy, e,
    5782              :                                   data_in, prevails);
    5783        17877 :           if (contexts_computed)
    5784              :             {
    5785          447 :               class ipa_polymorphic_call_context ctx;
    5786          447 :               ctx.stream_in (ib, data_in);
    5787              :             }
    5788              :         }
    5789              :     }
    5790              : }
    5791              : 
    5792              : /* Stream in NODE info from IB.  */
    5793              : 
    5794              : static void
    5795        77463 : ipa_read_node_info (class lto_input_block *ib, struct cgraph_node *node,
    5796              :                     class data_in *data_in)
    5797              : {
    5798        77463 :   int k;
    5799        77463 :   struct cgraph_edge *e;
    5800        77463 :   struct bitpack_d bp;
    5801        77463 :   bool prevails = node->prevailing_p ();
    5802        77463 :   ipa_node_params *info
    5803        77463 :     = prevails ? ipa_node_params_sum->get_create (node) : NULL;
    5804              : 
    5805        77463 :   int param_count = streamer_read_uhwi (ib);
    5806        77463 :   if (prevails)
    5807              :     {
    5808        77445 :       ipa_alloc_node_params (node, param_count);
    5809       232983 :       for (k = 0; k < param_count; k++)
    5810        78093 :         (*info->descriptors)[k].move_cost = streamer_read_uhwi (ib);
    5811        77445 :       if (ipa_get_param_count (info) != 0)
    5812        53063 :         info->analysis_done = true;
    5813        77445 :       info->node_enqueued = false;
    5814              :     }
    5815              :   else
    5816           27 :     for (k = 0; k < param_count; k++)
    5817            9 :       streamer_read_uhwi (ib);
    5818              : 
    5819        77463 :   bp = streamer_read_bitpack (ib);
    5820       155565 :   for (k = 0; k < param_count; k++)
    5821              :     {
    5822        78102 :       bool load_dereferenced = bp_unpack_value (&bp, 1);
    5823        78102 :       bool used = bp_unpack_value (&bp, 1);
    5824              : 
    5825        78102 :       if (prevails)
    5826              :         {
    5827        78093 :           ipa_set_param_load_dereferenced (info, k, load_dereferenced);
    5828        78093 :           ipa_set_param_used (info, k, used);
    5829              :         }
    5830              :     }
    5831       155565 :   for (k = 0; k < param_count; k++)
    5832              :     {
    5833        78102 :       int nuses = streamer_read_hwi (ib);
    5834        78102 :       tree type = stream_read_tree (ib, data_in);
    5835              : 
    5836        78102 :       if (prevails)
    5837              :         {
    5838        78093 :           ipa_set_controlled_uses (info, k, nuses);
    5839        78093 :           (*info->descriptors)[k].decl_or_type = type;
    5840              :         }
    5841              :     }
    5842       410799 :   for (e = node->callees; e; e = e->next_callee)
    5843       333336 :     ipa_read_edge_info (ib, data_in, e, prevails);
    5844        78878 :   for (e = node->indirect_calls; e; e = e->next_callee)
    5845              :     {
    5846         1415 :       ipa_read_edge_info (ib, data_in, e, prevails);
    5847         1415 :       ipa_read_indirect_edge_info (ib, data_in, e, info);
    5848              :     }
    5849        77463 : }
    5850              : 
    5851              : /* Stream out ipa_return_summary.  */
    5852              : static void
    5853        31189 : ipa_write_return_summaries (output_block *ob)
    5854              : {
    5855        31189 :   if (!ipa_return_value_sum)
    5856              :     {
    5857        14791 :       streamer_write_uhwi (ob, 0);
    5858        14791 :       return;
    5859              :     }
    5860              : 
    5861        16398 :   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
    5862        16398 :   unsigned int count = 0;
    5863       436922 :   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    5864              :     {
    5865       202063 :       toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
    5866       404126 :       cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
    5867       166518 :       ipa_return_value_summary *v;
    5868              : 
    5869       166518 :       if (cnode && cnode->definition && !cnode->alias
    5870       122568 :           && (v = ipa_return_value_sum->get (cnode))
    5871        25126 :           && v->vr)
    5872        25126 :         count++;
    5873              :     }
    5874        16398 :   streamer_write_uhwi (ob, count);
    5875              : 
    5876       436922 :   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    5877              :     {
    5878       202063 :       toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
    5879       404126 :       cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
    5880       166518 :       ipa_return_value_summary *v;
    5881              : 
    5882       166518 :       if (cnode && cnode->definition && !cnode->alias
    5883       122568 :           && (v = ipa_return_value_sum->get (cnode))
    5884        25126 :           && v->vr)
    5885              :         {
    5886        25126 :           streamer_write_uhwi
    5887        25126 :             (ob,
    5888        25126 :              lto_symtab_encoder_encode (encoder, cnode));
    5889        25126 :           v->vr->streamer_write (ob);
    5890              :         }
    5891              :     }
    5892              : }
    5893              : 
    5894              : /* Write jump functions for nodes in SET.  */
    5895              : 
    5896              : void
    5897        22999 : ipa_prop_write_jump_functions (void)
    5898              : {
    5899        22999 :   struct output_block *ob;
    5900        22999 :   unsigned int count = 0;
    5901        22999 :   lto_symtab_encoder_iterator lsei;
    5902        22999 :   lto_symtab_encoder_t encoder;
    5903              : 
    5904        22999 :   if (!ipa_node_params_sum || !ipa_edge_args_sum)
    5905            0 :     return;
    5906              : 
    5907        22999 :   ob = create_output_block (LTO_section_jump_functions);
    5908        22999 :   encoder = ob->decl_state->symtab_node_encoder;
    5909        22999 :   ob->symbol = NULL;
    5910       127664 :   for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
    5911       104665 :        lsei_next_function_in_partition (&lsei))
    5912              :     {
    5913       104665 :       cgraph_node *node = lsei_cgraph_node (lsei);
    5914       104665 :       if (node->has_gimple_body_p ()
    5915       104665 :           && ipa_node_params_sum->get (node) != NULL)
    5916        92724 :         count++;
    5917              :     }
    5918              : 
    5919        22999 :   streamer_write_uhwi (ob, count);
    5920              : 
    5921              :   /* Process all of the functions.  */
    5922       127664 :   for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
    5923       104665 :        lsei_next_function_in_partition (&lsei))
    5924              :     {
    5925       104665 :       cgraph_node *node = lsei_cgraph_node (lsei);
    5926       104665 :       if (node->has_gimple_body_p ()
    5927       104665 :           && ipa_node_params_sum->get (node) != NULL)
    5928        92724 :         ipa_write_node_info (ob, node);
    5929              :     }
    5930        22999 :   ipa_write_return_summaries (ob);
    5931              : 
    5932        22999 :   if (noted_fnptrs_in_records)
    5933              :     {
    5934          338 :       count = 0;
    5935         1063 :       for (auto iter = noted_fnptrs_in_records->begin ();
    5936         1063 :            iter != noted_fnptrs_in_records->end();
    5937          725 :            ++iter)
    5938          725 :         if ((*iter)->fn)
    5939          717 :           count++;
    5940          338 :       streamer_write_uhwi (ob, count);
    5941              : 
    5942         1063 :       for (auto iter = noted_fnptrs_in_records->begin ();
    5943         1401 :            iter != noted_fnptrs_in_records->end();
    5944          725 :            ++iter)
    5945          725 :         if ((*iter)->fn)
    5946              :           {
    5947          717 :             stream_write_tree (ob, (*iter)->rec_type, true);
    5948          717 :             stream_write_tree (ob, (*iter)->fn, true);
    5949          717 :             streamer_write_uhwi (ob, (*iter)->fld_offset);
    5950              :           }
    5951              :     }
    5952              :   else
    5953        22661 :     streamer_write_uhwi (ob, 0);
    5954              : 
    5955        22999 :   produce_asm (ob);
    5956        22999 :   destroy_output_block (ob);
    5957              : }
    5958              : 
    5959              : /* Record that return value range of N is VAL.  */
    5960              : 
    5961              : static void
    5962       753729 : ipa_record_return_value_range_1 (cgraph_node *n, value_range val)
    5963              : {
    5964       753729 :   if (!ipa_return_value_sum)
    5965              :     {
    5966        86020 :       if (!ipa_vr_hash_table)
    5967        75315 :         ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
    5968        86020 :       ipa_return_value_sum = new (ggc_alloc_no_dtor <ipa_return_value_sum_t> ())
    5969        86020 :               ipa_return_value_sum_t (symtab, true);
    5970        86020 :       ipa_return_value_sum->disable_insertion_hook ();
    5971              :     }
    5972       753729 :   ipa_return_value_sum->get_create (n)->vr = ipa_get_value_range (val);
    5973       753729 :   if (dump_file && (dump_flags & TDF_DETAILS))
    5974              :     {
    5975           21 :       fprintf (dump_file, "Recording return range of %s:", n->dump_name ());
    5976           21 :       val.dump (dump_file);
    5977           21 :       fprintf (dump_file, "\n");
    5978              :     }
    5979       753729 : }
    5980              : 
    5981              : /* Stream out ipa_return_summary.  */
    5982              : static void
    5983        21456 : ipa_read_return_summaries (lto_input_block *ib,
    5984              :                            struct lto_file_decl_data *file_data,
    5985              :                            class data_in *data_in)
    5986              : {
    5987        21456 :   unsigned int f_count = streamer_read_uhwi (ib);
    5988        43060 :   for (unsigned int i = 0; i < f_count; i++)
    5989              :     {
    5990        21604 :       unsigned int index = streamer_read_uhwi (ib);
    5991        21604 :       lto_symtab_encoder_t encoder = file_data->symtab_node_encoder;
    5992        21604 :       struct cgraph_node *node
    5993              :               = dyn_cast <cgraph_node *>
    5994        21604 :                   (lto_symtab_encoder_deref (encoder, index));
    5995        21604 :       ipa_vr rvr;
    5996        21604 :       rvr.streamer_read (ib, data_in);
    5997        21604 :       if (node->prevailing_p ())
    5998              :         {
    5999        21602 :           value_range tmp;
    6000        21602 :           rvr.get_vrange (tmp);
    6001        21602 :           ipa_record_return_value_range_1 (node, tmp);
    6002        21602 :         }
    6003              :     }
    6004        21456 : }
    6005              : 
    6006              : /* Read section in file FILE_DATA of length LEN with data DATA.  */
    6007              : 
    6008              : static void
    6009        13266 : ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
    6010              :                        size_t len)
    6011              : {
    6012        13266 :   const struct lto_function_header *header =
    6013              :     (const struct lto_function_header *) data;
    6014        13266 :   const int cfg_offset = sizeof (struct lto_function_header);
    6015        13266 :   const int main_offset = cfg_offset + header->cfg_size;
    6016        13266 :   const int string_offset = main_offset + header->main_size;
    6017        13266 :   class data_in *data_in;
    6018        13266 :   unsigned int i;
    6019        13266 :   unsigned int count;
    6020              : 
    6021        13266 :   lto_input_block ib_main ((const char *) data + main_offset,
    6022        13266 :                            header->main_size, file_data);
    6023              : 
    6024        13266 :   data_in =
    6025        26532 :     lto_data_in_create (file_data, (const char *) data + string_offset,
    6026        13266 :                         header->string_size, vNULL);
    6027        13266 :   count = streamer_read_uhwi (&ib_main);
    6028              : 
    6029        90729 :   for (i = 0; i < count; i++)
    6030              :     {
    6031        77463 :       unsigned int index;
    6032        77463 :       struct cgraph_node *node;
    6033        77463 :       lto_symtab_encoder_t encoder;
    6034              : 
    6035        77463 :       index = streamer_read_uhwi (&ib_main);
    6036        77463 :       encoder = file_data->symtab_node_encoder;
    6037        77463 :       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
    6038              :                                                                 index));
    6039        77463 :       gcc_assert (node->definition);
    6040        77463 :       ipa_read_node_info (&ib_main, node, data_in);
    6041              :     }
    6042        13266 :   ipa_read_return_summaries (&ib_main, file_data, data_in);
    6043              : 
    6044        13266 :   count = streamer_read_uhwi (&ib_main);
    6045        13930 :   for (i = 0; i < count; i++)
    6046              :     {
    6047          664 :       tree rec_type = stream_read_tree (&ib_main, data_in);
    6048          664 :       tree fn = stream_read_tree (&ib_main, data_in);
    6049          664 :       unsigned fld_offset = (unsigned) streamer_read_uhwi (&ib_main);
    6050          664 :       note_fnptr_in_record (rec_type, fld_offset, fn);
    6051              :     }
    6052              : 
    6053        13266 :   lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
    6054              :                          len);
    6055        13266 :   lto_data_in_delete (data_in);
    6056        13266 : }
    6057              : 
    6058              : /* Read ipcp jump functions.  */
    6059              : 
    6060              : void
    6061        12211 : ipa_prop_read_jump_functions (void)
    6062              : {
    6063        12211 :   struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    6064        12211 :   struct lto_file_decl_data *file_data;
    6065        12211 :   unsigned int j = 0;
    6066              : 
    6067        12211 :   ipa_check_create_node_params ();
    6068        12211 :   ipa_check_create_edge_args ();
    6069        12211 :   ipa_register_cgraph_hooks ();
    6070              : 
    6071        37688 :   while ((file_data = file_data_vec[j++]))
    6072              :     {
    6073        13266 :       size_t len;
    6074        13266 :       const char *data
    6075        13266 :         = lto_get_summary_section_data (file_data, LTO_section_jump_functions,
    6076              :                                         &len);
    6077        13266 :       if (data)
    6078        13266 :         ipa_prop_read_section (file_data, data, len);
    6079              :     }
    6080        12211 : }
    6081              : 
    6082              : /* Return true if the IPA-CP transformation summary TS is non-NULL and contains
    6083              :    useful info.  */
    6084              : static bool
    6085       165884 : useful_ipcp_transformation_info_p (ipcp_transformation *ts)
    6086              : {
    6087       165884 :   if (!ts)
    6088              :     return false;
    6089        24324 :   if (!vec_safe_is_empty (ts->m_agg_values)
    6090        23914 :       || !vec_safe_is_empty (ts->m_vr))
    6091        24038 :     return true;
    6092              :   return false;
    6093              : }
    6094              : 
    6095              : /* Write into OB IPA-CP transfromation summary TS describing NODE.  */
    6096              : 
    6097              : void
    6098        12001 : write_ipcp_transformation_info (output_block *ob, cgraph_node *node,
    6099              :                                 ipcp_transformation *ts)
    6100              : {
    6101        12001 :   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
    6102        12001 :   int node_ref = lto_symtab_encoder_encode (encoder, node);
    6103        12001 :   streamer_write_uhwi (ob, node_ref);
    6104              : 
    6105        12203 :   streamer_write_uhwi (ob, vec_safe_length (ts->m_agg_values));
    6106        13643 :   for (const ipa_argagg_value &av : ts->m_agg_values)
    6107              :     {
    6108         1238 :       struct bitpack_d bp;
    6109              : 
    6110         1238 :       stream_write_tree (ob, av.value, true);
    6111         1238 :       streamer_write_uhwi (ob, av.unit_offset);
    6112         1238 :       streamer_write_uhwi (ob, av.index);
    6113              : 
    6114         1238 :       bp = bitpack_create (ob->main_stream);
    6115         1238 :       bp_pack_value (&bp, av.by_ref, 1);
    6116         1238 :       bp_pack_value (&bp, av.killed, 1);
    6117         1238 :       streamer_write_bitpack (&bp);
    6118              :     }
    6119              : 
    6120              :   /* If all instances of this node are inlined, ipcp info is not useful.  */
    6121        12001 :   if (!lto_symtab_encoder_only_for_inlining_p (encoder, node))
    6122              :     {
    6123        21756 :       streamer_write_uhwi (ob, vec_safe_length (ts->m_vr));
    6124        53089 :       for (const ipa_vr &parm_vr : ts->m_vr)
    6125        20457 :         parm_vr.streamer_write (ob);
    6126              :     }
    6127              :   else
    6128         1121 :     streamer_write_uhwi (ob, 0);
    6129        12001 : }
    6130              : 
    6131              : /* Stream in the aggregate value replacement chain for NODE from IB.  */
    6132              : 
    6133              : static void
    6134        12001 : read_ipcp_transformation_info (lto_input_block *ib, cgraph_node *node,
    6135              :                                data_in *data_in)
    6136              : {
    6137        12001 :   unsigned int count, i;
    6138        12001 :   ipcp_transformation_initialize ();
    6139        12001 :   ipcp_transformation *ts = ipcp_transformation_sum->get_create (node);
    6140              : 
    6141        12001 :   count = streamer_read_uhwi (ib);
    6142        12001 :   if (count > 0)
    6143              :     {
    6144          202 :       vec_safe_grow_cleared (ts->m_agg_values, count, true);
    6145         1440 :       for (i = 0; i <count; i++)
    6146              :         {
    6147         1238 :           ipa_argagg_value *av = &(*ts->m_agg_values)[i];;
    6148              : 
    6149         1238 :           av->value = stream_read_tree (ib, data_in);
    6150         1238 :           av->unit_offset = streamer_read_uhwi (ib);
    6151         1238 :           av->index = streamer_read_uhwi (ib);
    6152              : 
    6153         1238 :           bitpack_d bp = streamer_read_bitpack (ib);
    6154         1238 :           av->by_ref = bp_unpack_value (&bp, 1);
    6155         1238 :           av->killed = bp_unpack_value (&bp, 1);
    6156              :         }
    6157              :     }
    6158              : 
    6159        12001 :   count = streamer_read_uhwi (ib);
    6160        12001 :   if (count > 0)
    6161              :     {
    6162        10876 :       vec_safe_grow_cleared (ts->m_vr, count, true);
    6163        31333 :       for (i = 0; i < count; i++)
    6164              :         {
    6165        20457 :           ipa_vr *parm_vr;
    6166        20457 :           parm_vr = &(*ts->m_vr)[i];
    6167        20457 :           parm_vr->streamer_read (ib, data_in);
    6168              :         }
    6169              :     }
    6170        12001 : }
    6171              : 
    6172              : 
    6173              : /* Write all aggregate replacement for nodes in set.  */
    6174              : 
    6175              : void
    6176         8190 : ipcp_write_transformation_summaries (void)
    6177              : {
    6178         8190 :   struct output_block *ob;
    6179         8190 :   unsigned int count = 0;
    6180         8190 :   lto_symtab_encoder_t encoder;
    6181              : 
    6182         8190 :   ob = create_output_block (LTO_section_ipcp_transform);
    6183         8190 :   encoder = ob->decl_state->symtab_node_encoder;
    6184         8190 :   ob->symbol = NULL;
    6185              : 
    6186       231954 :   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    6187              :     {
    6188       107791 :       toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
    6189       107791 :       cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
    6190       107791 :       if (!cnode)
    6191        24849 :         continue;
    6192        82942 :       ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
    6193        82942 :       if (useful_ipcp_transformation_info_p (ts)
    6194        82942 :           && lto_symtab_encoder_encode_body_p (encoder, cnode))
    6195        12001 :         count++;
    6196              :     }
    6197              : 
    6198         8190 :   streamer_write_uhwi (ob, count);
    6199              : 
    6200       231954 :   for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    6201              :     {
    6202       107791 :       toplevel_node *tnode = lto_symtab_encoder_deref (encoder, i);
    6203       107791 :       cgraph_node *cnode = dyn_cast <cgraph_node *> (tnode);
    6204       107791 :       if (!cnode)
    6205        24849 :         continue;
    6206        82942 :       ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
    6207        82942 :       if (useful_ipcp_transformation_info_p (ts)
    6208        82942 :           && lto_symtab_encoder_encode_body_p (encoder, cnode))
    6209        12001 :         write_ipcp_transformation_info (ob, cnode, ts);
    6210              :     }
    6211         8190 :   ipa_write_return_summaries (ob);
    6212         8190 :   produce_asm (ob);
    6213         8190 :   destroy_output_block (ob);
    6214         8190 : }
    6215              : 
    6216              : /* Read replacements section in file FILE_DATA of length LEN with data
    6217              :    DATA.  */
    6218              : 
    6219              : static void
    6220         8190 : read_replacements_section (struct lto_file_decl_data *file_data,
    6221              :                            const char *data,
    6222              :                            size_t len)
    6223              : {
    6224         8190 :   const struct lto_function_header *header =
    6225              :     (const struct lto_function_header *) data;
    6226         8190 :   const int cfg_offset = sizeof (struct lto_function_header);
    6227         8190 :   const int main_offset = cfg_offset + header->cfg_size;
    6228         8190 :   const int string_offset = main_offset + header->main_size;
    6229         8190 :   class data_in *data_in;
    6230         8190 :   unsigned int i;
    6231         8190 :   unsigned int count;
    6232              : 
    6233         8190 :   lto_input_block ib_main ((const char *) data + main_offset,
    6234         8190 :                            header->main_size, file_data);
    6235              : 
    6236         8190 :   data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
    6237         8190 :                                 header->string_size, vNULL);
    6238         8190 :   count = streamer_read_uhwi (&ib_main);
    6239              : 
    6240        20191 :   for (i = 0; i < count; i++)
    6241              :     {
    6242        12001 :       unsigned int index;
    6243        12001 :       struct cgraph_node *node;
    6244        12001 :       lto_symtab_encoder_t encoder;
    6245              : 
    6246        12001 :       index = streamer_read_uhwi (&ib_main);
    6247        12001 :       encoder = file_data->symtab_node_encoder;
    6248        12001 :       node = dyn_cast<cgraph_node *> (lto_symtab_encoder_deref (encoder,
    6249              :                                                                 index));
    6250        12001 :       read_ipcp_transformation_info (&ib_main, node, data_in);
    6251              :     }
    6252         8190 :   ipa_read_return_summaries (&ib_main, file_data, data_in);
    6253         8190 :   lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
    6254              :                          len);
    6255         8190 :   lto_data_in_delete (data_in);
    6256         8190 : }
    6257              : 
    6258              : /* Read IPA-CP aggregate replacements.  */
    6259              : 
    6260              : void
    6261         8190 : ipcp_read_transformation_summaries (void)
    6262              : {
    6263         8190 :   struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    6264         8190 :   struct lto_file_decl_data *file_data;
    6265         8190 :   unsigned int j = 0;
    6266              : 
    6267        24570 :   while ((file_data = file_data_vec[j++]))
    6268              :     {
    6269         8190 :       size_t len;
    6270         8190 :       const char *data
    6271         8190 :         = lto_get_summary_section_data (file_data, LTO_section_ipcp_transform,
    6272              :                                         &len);
    6273         8190 :       if (data)
    6274         8190 :         read_replacements_section (file_data, data, len);
    6275              :     }
    6276         8190 : }
    6277              : 
    6278              : /* Adjust the aggregate replacements in TS to reflect any parameter removals
    6279              :    which might have already taken place.  If after adjustments there are no
    6280              :    aggregate replacements left, the m_agg_values will be set to NULL.  In other
    6281              :    cases, it may be shrunk.  */
    6282              : 
    6283              : static void
    6284         1903 : adjust_agg_replacement_values (cgraph_node *node, ipcp_transformation *ts)
    6285              : {
    6286         1903 :   clone_info *cinfo = clone_info::get (node);
    6287         1903 :   if (!cinfo || !cinfo->param_adjustments)
    6288              :     return;
    6289              : 
    6290          925 :   auto_vec<int, 16> new_indices;
    6291          925 :   cinfo->param_adjustments->get_updated_indices (&new_indices);
    6292          925 :   bool removed_item = false;
    6293          925 :   unsigned dst_index = 0;
    6294          925 :   unsigned count = ts->m_agg_values->length ();
    6295         5070 :   for (unsigned i = 0; i < count; i++)
    6296              :     {
    6297         4145 :       ipa_argagg_value *v = &(*ts->m_agg_values)[i];
    6298         4145 :       gcc_checking_assert (v->index >= 0);
    6299              : 
    6300         4145 :       int new_idx = -1;
    6301         4145 :       if ((unsigned) v->index < new_indices.length ())
    6302         2513 :         new_idx = new_indices[v->index];
    6303              : 
    6304         2513 :       if (new_idx >= 0)
    6305              :         {
    6306         1674 :           v->index = new_idx;
    6307         1674 :           if (removed_item)
    6308           23 :             (*ts->m_agg_values)[dst_index] = *v;
    6309         1674 :           dst_index++;
    6310              :         }
    6311              :       else
    6312              :         removed_item = true;
    6313              :     }
    6314              : 
    6315          925 :   if (dst_index == 0)
    6316              :     {
    6317          554 :       ggc_free (ts->m_agg_values);
    6318          554 :       ts->m_agg_values = NULL;
    6319              :     }
    6320          371 :   else if (removed_item)
    6321           35 :     ts->m_agg_values->truncate (dst_index);
    6322              : 
    6323          925 :   return;
    6324          925 : }
    6325              : 
    6326              : /* Dominator walker driving the ipcp modification phase.  */
    6327              : 
    6328              : class ipcp_modif_dom_walker : public dom_walker
    6329              : {
    6330              : public:
    6331         1349 :   ipcp_modif_dom_walker (struct ipa_func_body_info *fbi,
    6332              :                          vec<ipa_param_descriptor, va_gc> *descs,
    6333              :                          ipcp_transformation *ts, bool *sc)
    6334         2698 :     : dom_walker (CDI_DOMINATORS), m_fbi (fbi), m_descriptors (descs),
    6335         1349 :       m_ts (ts), m_something_changed (sc) {}
    6336              : 
    6337              :   edge before_dom_children (basic_block) final override;
    6338         1349 :   bool cleanup_eh ()
    6339         1349 :     { return gimple_purge_all_dead_eh_edges (m_need_eh_cleanup); }
    6340              : 
    6341              : private:
    6342              :   struct ipa_func_body_info *m_fbi;
    6343              :   vec<ipa_param_descriptor, va_gc> *m_descriptors;
    6344              :   ipcp_transformation *m_ts;
    6345              :   bool *m_something_changed;
    6346              :   auto_bitmap m_need_eh_cleanup;
    6347              : };
    6348              : 
    6349              : edge
    6350        22976 : ipcp_modif_dom_walker::before_dom_children (basic_block bb)
    6351              : {
    6352        22976 :   gimple_stmt_iterator gsi;
    6353       127865 :   for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
    6354              :     {
    6355        81913 :       gimple *stmt = gsi_stmt (gsi);
    6356        81913 :       tree rhs, val, t;
    6357        81913 :       HOST_WIDE_INT bit_offset;
    6358        81913 :       poly_int64 size;
    6359        81913 :       int index;
    6360        81913 :       bool by_ref, vce;
    6361              : 
    6362        81913 :       if (!gimple_assign_load_p (stmt))
    6363        80341 :         continue;
    6364        12100 :       rhs = gimple_assign_rhs1 (stmt);
    6365        12100 :       if (!is_gimple_reg_type (TREE_TYPE (rhs)))
    6366          647 :         continue;
    6367              : 
    6368        26845 :       vce = false;
    6369              :       t = rhs;
    6370        26845 :       while (handled_component_p (t))
    6371              :         {
    6372              :           /* V_C_E can do things like convert an array of integers to one
    6373              :              bigger integer and similar things we do not handle below.  */
    6374        15392 :           if (TREE_CODE (t) == VIEW_CONVERT_EXPR)
    6375              :             {
    6376              :               vce = true;
    6377              :               break;
    6378              :             }
    6379        15392 :           t = TREE_OPERAND (t, 0);
    6380              :         }
    6381        11453 :       if (vce)
    6382            0 :         continue;
    6383              : 
    6384        11453 :       if (!ipa_load_from_parm_agg (m_fbi, m_descriptors, stmt, rhs, &index,
    6385              :                                    &bit_offset, &size, &by_ref))
    6386         8375 :         continue;
    6387         3078 :       unsigned unit_offset = bit_offset / BITS_PER_UNIT;
    6388         3078 :       ipa_argagg_value_list avl (m_ts);
    6389         3078 :       tree v = avl.get_value (index, unit_offset, by_ref);
    6390              : 
    6391         4584 :       if (!v
    6392         3078 :           || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), size))
    6393         1506 :         continue;
    6394              : 
    6395         1572 :       gcc_checking_assert (is_gimple_ip_invariant (v));
    6396         1572 :       if (!useless_type_conversion_p (TREE_TYPE (rhs), TREE_TYPE (v)))
    6397              :         {
    6398            0 :           if (fold_convertible_p (TREE_TYPE (rhs), v))
    6399            0 :             val = fold_build1 (NOP_EXPR, TREE_TYPE (rhs), v);
    6400            0 :           else if (TYPE_SIZE (TREE_TYPE (rhs))
    6401            0 :                    == TYPE_SIZE (TREE_TYPE (v)))
    6402            0 :             val = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (rhs), v);
    6403              :           else
    6404              :             {
    6405            0 :               if (dump_file)
    6406              :                 {
    6407            0 :                   fprintf (dump_file, "    const ");
    6408            0 :                   print_generic_expr (dump_file, v);
    6409            0 :                   fprintf (dump_file, "  can't be converted to type of ");
    6410            0 :                   print_generic_expr (dump_file, rhs);
    6411            0 :                   fprintf (dump_file, "\n");
    6412              :                 }
    6413            0 :               continue;
    6414              :             }
    6415              :         }
    6416              :       else
    6417              :         val = v;
    6418              : 
    6419         1572 :       if (dump_file && (dump_flags & TDF_DETAILS))
    6420              :         {
    6421           41 :           fprintf (dump_file, "Modifying stmt:\n  ");
    6422           41 :           print_gimple_stmt (dump_file, stmt, 0);
    6423              :         }
    6424         1572 :       gimple_assign_set_rhs_from_tree (&gsi, val);
    6425         1572 :       update_stmt (stmt);
    6426              : 
    6427         1572 :       if (dump_file && (dump_flags & TDF_DETAILS))
    6428              :         {
    6429           41 :           fprintf (dump_file, "into:\n  ");
    6430           41 :           print_gimple_stmt (dump_file, stmt, 0);
    6431           41 :           fprintf (dump_file, "\n");
    6432              :         }
    6433              : 
    6434         1572 :       *m_something_changed = true;
    6435         1572 :       if (maybe_clean_eh_stmt (stmt))
    6436            9 :         bitmap_set_bit (m_need_eh_cleanup, bb->index);
    6437              :     }
    6438        22976 :   return NULL;
    6439              : }
    6440              : 
    6441              : /* If IPA-CP discovered a constant in parameter PARM at OFFSET of a given SIZE
    6442              :    - whether passed by reference or not is given by BY_REF - return that
    6443              :    constant.  Otherwise return NULL_TREE.  The is supposed to be used only
    6444              :    after clone materialization and transformation is done (because it asserts
    6445              :    that killed constants have been pruned). */
    6446              : 
    6447              : tree
    6448      4230042 : ipcp_get_aggregate_const (struct function *func, tree parm, bool by_ref,
    6449              :                           HOST_WIDE_INT bit_offset, HOST_WIDE_INT bit_size)
    6450              : {
    6451      4230042 :   cgraph_node *node = cgraph_node::get (func->decl);
    6452      4230042 :   ipcp_transformation *ts = ipcp_get_transformation_summary (node);
    6453              : 
    6454      4230042 :   if (!ts || !ts->m_agg_values)
    6455              :     return NULL_TREE;
    6456              : 
    6457        10421 :   int index = ts->get_param_index (func->decl, parm);
    6458        10421 :   if (index < 0)
    6459              :     return NULL_TREE;
    6460              : 
    6461        10368 :   ipa_argagg_value_list avl (ts);
    6462        10368 :   unsigned unit_offset = bit_offset / BITS_PER_UNIT;
    6463        10368 :   const ipa_argagg_value *av = avl.get_elt (index, unit_offset);
    6464        10368 :   if (!av || av->by_ref != by_ref)
    6465              :     return NULL_TREE;
    6466         1924 :   gcc_assert (!av->killed);
    6467         1924 :   tree v = av->value;
    6468         1924 :   if (!v
    6469         1924 :       || maybe_ne (tree_to_poly_int64 (TYPE_SIZE (TREE_TYPE (v))), bit_size))
    6470          688 :     return NULL_TREE;
    6471              : 
    6472              :   return v;
    6473              : }
    6474              : 
    6475              : /* Return true if we have recorded VALUE and MASK about PARM.
    6476              :    Set VALUE and MASk accordingly.  */
    6477              : 
    6478              : bool
    6479      7539980 : ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask)
    6480              : {
    6481      7539980 :   cgraph_node *cnode = cgraph_node::get (current_function_decl);
    6482      7539980 :   ipcp_transformation *ts = ipcp_get_transformation_summary (cnode);
    6483      7539980 :   if (!ts
    6484       122782 :       || vec_safe_length (ts->m_vr) == 0
    6485      7696695 :       || !ipa_vr_supported_type_p (TREE_TYPE (parm)))
    6486              :     return false;
    6487              : 
    6488       115658 :   int i = ts->get_param_index (current_function_decl, parm);
    6489       115658 :   if (i < 0)
    6490              :     return false;
    6491       114263 :   clone_info *cinfo = clone_info::get (cnode);
    6492       114263 :   if (cinfo && cinfo->param_adjustments)
    6493              :     {
    6494        33435 :       i = cinfo->param_adjustments->get_original_index (i);
    6495        33435 :       if (i < 0)
    6496              :         return false;
    6497              :     }
    6498              : 
    6499       105410 :   vec<ipa_vr, va_gc> &vr = *ts->m_vr;
    6500       105410 :   if (!vr[i].known_p ())
    6501              :     return false;
    6502        84007 :   value_range tmp;
    6503        84007 :   vr[i].get_vrange (tmp);
    6504        84007 :   if (tmp.undefined_p () || tmp.varying_p ())
    6505              :     return false;
    6506        84007 :   irange_bitmask bm;
    6507        84007 :   bm = tmp.get_bitmask ();
    6508        84007 :   *mask = widest_int::from (bm.mask (), TYPE_SIGN (TREE_TYPE (parm)));
    6509        84007 :   *value = wide_int_to_tree (TREE_TYPE (parm), bm.value ());
    6510        84007 :   return true;
    6511        84007 : }
    6512              : 
    6513              : /* Update value range of formal parameters of NODE as described in TS.  */
    6514              : 
    6515              : static void
    6516        23203 : ipcp_update_vr (struct cgraph_node *node, ipcp_transformation *ts)
    6517              : {
    6518        23203 :   if (vec_safe_is_empty (ts->m_vr))
    6519          549 :     return;
    6520        22654 :   const vec<ipa_vr, va_gc> &vr = *ts->m_vr;
    6521        22654 :   unsigned count = vr.length ();
    6522        22654 :   if (!count)
    6523              :     return;
    6524              : 
    6525        22654 :   auto_vec<int, 16> new_indices;
    6526        22654 :   bool need_remapping = false;
    6527        22654 :   clone_info *cinfo = clone_info::get (node);
    6528        22654 :   if (cinfo && cinfo->param_adjustments)
    6529              :     {
    6530         7935 :       cinfo->param_adjustments->get_updated_indices (&new_indices);
    6531         7935 :       need_remapping = true;
    6532              :     }
    6533        22654 :   auto_vec <tree, 16> parm_decls;
    6534        22654 :   push_function_arg_decls (&parm_decls, node->decl);
    6535              : 
    6536        79449 :   for (unsigned i = 0; i < count; ++i)
    6537              :     {
    6538        56795 :       tree parm;
    6539        56795 :       int remapped_idx;
    6540        56795 :       if (need_remapping)
    6541              :         {
    6542        23602 :           if (i >= new_indices.length ())
    6543        11566 :             continue;
    6544        12036 :           remapped_idx = new_indices[i];
    6545        12036 :           if (remapped_idx < 0)
    6546         2548 :             continue;
    6547              :         }
    6548              :       else
    6549        33193 :         remapped_idx = i;
    6550              : 
    6551        42681 :       parm = parm_decls[remapped_idx];
    6552              : 
    6553        42681 :       gcc_checking_assert (parm);
    6554        42681 :       tree ddef = ssa_default_def (DECL_STRUCT_FUNCTION (node->decl), parm);
    6555              : 
    6556        42681 :       if (!ddef || !is_gimple_reg (parm))
    6557         6554 :         continue;
    6558              : 
    6559        36127 :       if (vr[i].known_p ())
    6560              :         {
    6561        28012 :           value_range tmp;
    6562        28012 :           vr[i].get_vrange (tmp);
    6563              : 
    6564        28012 :           if (!tmp.undefined_p () && !tmp.varying_p ())
    6565              :             {
    6566        28012 :               if (dump_file)
    6567              :                 {
    6568          112 :                   fprintf (dump_file, "Setting value range of param %u "
    6569              :                            "(now %i) ", i, remapped_idx);
    6570          112 :                   tmp.dump (dump_file);
    6571          112 :                   fprintf (dump_file, "]\n");
    6572              :                 }
    6573        28012 :               set_range_info (ddef, tmp);
    6574              : 
    6575        43223 :               if (POINTER_TYPE_P (TREE_TYPE (parm))
    6576        31248 :                   && opt_for_fn (node->decl, flag_ipa_bit_cp))
    6577              :                 {
    6578        16036 :                   irange_bitmask bm = tmp.get_bitmask ();
    6579        16036 :                   unsigned tem = bm.mask ().to_uhwi ();
    6580        16036 :                   unsigned HOST_WIDE_INT bitpos = bm.value ().to_uhwi ();
    6581        16036 :                   unsigned align = tem & -tem;
    6582        16036 :                   unsigned misalign = bitpos & (align - 1);
    6583              : 
    6584        16036 :                   if (align > 1)
    6585              :                     {
    6586        13230 :                       if (dump_file)
    6587              :                         {
    6588           85 :                           fprintf (dump_file,
    6589              :                                    "Adjusting mask for param %u to ", i);
    6590           85 :                           print_hex (bm.mask (), dump_file);
    6591           85 :                           fprintf (dump_file, "\n");
    6592              :                         }
    6593              : 
    6594        13230 :                       if (dump_file)
    6595           85 :                         fprintf (dump_file,
    6596              :                                  "Adjusting align: %u, misalign: %u\n",
    6597              :                                  align, misalign);
    6598              : 
    6599        13230 :                       unsigned old_align, old_misalign;
    6600        13230 :                       struct ptr_info_def *pi = get_ptr_info (ddef);
    6601        13230 :                       bool old_known = get_ptr_info_alignment (pi, &old_align,
    6602              :                                                                &old_misalign);
    6603              : 
    6604        13230 :                       if (old_known && old_align > align)
    6605              :                         {
    6606            0 :                           if (dump_file)
    6607              :                             {
    6608            0 :                               fprintf (dump_file,
    6609              :                                        "But alignment was already %u.\n",
    6610              :                                        old_align);
    6611            0 :                               if ((old_misalign & (align - 1)) != misalign)
    6612            0 :                                 fprintf (dump_file,
    6613              :                                          "old_misalign (%u) and misalign "
    6614              :                                          "(%u) mismatch\n",
    6615              :                                          old_misalign, misalign);
    6616              :                             }
    6617            0 :                           continue;
    6618              :                         }
    6619              : 
    6620        13230 :                       if (dump_file
    6621           85 :                           && old_known
    6622            0 :                           && ((misalign & (old_align - 1)) != old_misalign))
    6623            0 :                         fprintf (dump_file,
    6624              :                                  "old_misalign (%u) and misalign (%u) "
    6625              :                                  "mismatch\n",
    6626              :                                  old_misalign, misalign);
    6627              : 
    6628        13230 :                       set_ptr_info_alignment (pi, align, misalign);
    6629              :                     }
    6630        16036 :                 }
    6631        11976 :               else if (dump_file && INTEGRAL_TYPE_P (TREE_TYPE (parm)))
    6632              :                 {
    6633           23 :                   irange &r = as_a<irange> (tmp);
    6634           23 :                   irange_bitmask bm = r.get_bitmask ();
    6635           23 :                   unsigned prec = TYPE_PRECISION (TREE_TYPE (parm));
    6636           23 :                   if (wi::ne_p (bm.mask (), wi::shwi (-1, prec)))
    6637              :                     {
    6638           16 :                       fprintf (dump_file,
    6639              :                                "Adjusting mask for param %u to ", i);
    6640           16 :                       print_hex (bm.mask (), dump_file);
    6641           16 :                       fprintf (dump_file, "\n");
    6642              :                     }
    6643           23 :                 }
    6644              :             }
    6645        28012 :         }
    6646              :     }
    6647        22654 : }
    6648              : 
    6649              : /* IPCP transformation phase doing propagation of aggregate values.  */
    6650              : 
    6651              : unsigned int
    6652       963353 : ipcp_transform_function (struct cgraph_node *node)
    6653              : {
    6654       963353 :   struct ipa_func_body_info fbi;
    6655       963353 :   int param_count;
    6656              : 
    6657       963353 :   gcc_checking_assert (cfun);
    6658       963353 :   gcc_checking_assert (current_function_decl);
    6659              : 
    6660       963353 :   if (dump_file)
    6661          693 :     fprintf (dump_file, "Modification phase of node %s\n",
    6662              :              node->dump_name ());
    6663              : 
    6664       963353 :   ipcp_transformation *ts = ipcp_get_transformation_summary (node);
    6665       963353 :   if (!ts
    6666       963353 :       || (vec_safe_is_empty (ts->m_agg_values)
    6667        22179 :           && vec_safe_is_empty (ts->m_vr)))
    6668              :     return 0;
    6669              : 
    6670        23203 :   ts->maybe_create_parm_idx_map (cfun->decl);
    6671        23203 :   ipcp_update_vr (node, ts);
    6672       964182 :   if (vec_safe_is_empty (ts->m_agg_values))
    6673              :       return 0;
    6674         2178 :   param_count = count_formal_params (node->decl);
    6675         2178 :   if (param_count == 0)
    6676              :     return 0;
    6677              : 
    6678         1903 :   adjust_agg_replacement_values (node, ts);
    6679         1903 :   if (vec_safe_is_empty (ts->m_agg_values))
    6680              :     {
    6681          554 :       if (dump_file)
    6682            4 :         fprintf (dump_file, "  All affected aggregate parameters were either "
    6683              :                  "removed or converted into scalars, phase done.\n");
    6684          554 :       return 0;
    6685              :     }
    6686         1349 :   if (dump_file)
    6687              :     {
    6688           49 :       fprintf (dump_file, "     Aggregate replacements:");
    6689           49 :       ipa_argagg_value_list avs (ts);
    6690           49 :       avs.dump (dump_file);
    6691              :     }
    6692              : 
    6693         1349 :   fbi.node = node;
    6694         1349 :   fbi.info = NULL;
    6695         1349 :   fbi.bb_infos = vNULL;
    6696         1349 :   fbi.bb_infos.safe_grow_cleared (last_basic_block_for_fn (cfun), true);
    6697         1349 :   fbi.param_count = param_count;
    6698         1349 :   fbi.aa_walk_budget = opt_for_fn (node->decl, param_ipa_max_aa_steps);
    6699              : 
    6700         1349 :   vec<ipa_param_descriptor, va_gc> *descriptors = NULL;
    6701         1349 :   vec_safe_grow_cleared (descriptors, param_count, true);
    6702         1349 :   ipa_populate_param_decls (node, *descriptors);
    6703         1349 :   bool modified_mem_access = false;
    6704         1349 :   calculate_dominance_info (CDI_DOMINATORS);
    6705         1349 :   ipcp_modif_dom_walker walker (&fbi, descriptors, ts, &modified_mem_access);
    6706         1349 :   walker.walk (ENTRY_BLOCK_PTR_FOR_FN (cfun));
    6707         1349 :   free_dominance_info (CDI_DOMINATORS);
    6708         1349 :   bool cfg_changed = walker.cleanup_eh ();
    6709              : 
    6710         1349 :   int i;
    6711         1349 :   struct ipa_bb_info *bi;
    6712        27023 :   FOR_EACH_VEC_ELT (fbi.bb_infos, i, bi)
    6713        48650 :     free_ipa_bb_info (bi);
    6714         1349 :   fbi.bb_infos.release ();
    6715              : 
    6716         1349 :   ts->remove_argaggs_if ([](const ipa_argagg_value &v)
    6717              :     {
    6718         5079 :       return v.killed;
    6719              :     });
    6720              : 
    6721         1349 :   vec_free (descriptors);
    6722         1349 :   if (cfg_changed)
    6723            1 :     delete_unreachable_blocks_update_callgraph (node, false);
    6724              : 
    6725         1349 :   return modified_mem_access ? TODO_update_ssa_only_virtuals : 0;
    6726         1349 : }
    6727              : 
    6728              : /* Record that current function return value range is VAL.  */
    6729              : 
    6730              : void
    6731       732127 : ipa_record_return_value_range (value_range val)
    6732              : {
    6733       732127 :   ipa_record_return_value_range_1
    6734       732127 :           (cgraph_node::get (current_function_decl), val);
    6735       732127 : }
    6736              : 
    6737              : /* Return true if value range of DECL is known and if so initialize RANGE.  */
    6738              : 
    6739              : bool
    6740     11959235 : ipa_return_value_range (value_range &range, tree decl)
    6741              : {
    6742     11959235 :   cgraph_node *n = cgraph_node::get (decl);
    6743     11959235 :   if (!n || !ipa_return_value_sum)
    6744              :     return false;
    6745      9719426 :   enum availability avail;
    6746      9719426 :   n = n->ultimate_alias_target (&avail);
    6747      9719426 :   if (avail < AVAIL_AVAILABLE)
    6748              :     return false;
    6749      2123349 :   if (n->decl != decl && !useless_type_conversion_p (TREE_TYPE (decl), TREE_TYPE (n->decl)))
    6750              :     return false;
    6751      2123349 :   ipa_return_value_summary *v = ipa_return_value_sum->get (n);
    6752      2123349 :   if (!v)
    6753              :     return false;
    6754       621046 :   v->vr->get_vrange (range);
    6755       621046 :   return true;
    6756              : }
    6757              : 
    6758              : /* Reset all state within ipa-prop.cc so that we can rerun the compiler
    6759              :    within the same process.  For use by toplev::finalize.  */
    6760              : 
    6761              : void
    6762       258766 : ipa_prop_cc_finalize (void)
    6763              : {
    6764       258766 :   if (function_insertion_hook_holder)
    6765        11884 :     symtab->remove_cgraph_insertion_hook (function_insertion_hook_holder);
    6766       258766 :   function_insertion_hook_holder = NULL;
    6767              : 
    6768       258766 :   if (ipa_edge_args_sum)
    6769        12210 :     ggc_delete (ipa_edge_args_sum);
    6770       258766 :   ipa_edge_args_sum = NULL;
    6771              : 
    6772       258766 :   if (ipa_node_params_sum)
    6773        12210 :     ggc_delete (ipa_node_params_sum);
    6774       258766 :   ipa_node_params_sum = NULL;
    6775       258766 : }
    6776              : 
    6777              : /* Return true if the two pass_through components of two jump functions are
    6778              :    known to be equivalent.  AGG_JF denotes whether they are part of aggregate
    6779              :    functions or not.  The function can be used before the IPA phase of IPA-CP
    6780              :    or inlining because it cannot cope with refdesc changes these passes can
    6781              :    carry out.  */
    6782              : 
    6783              : static bool
    6784        46113 : ipa_agg_pass_through_jf_equivalent_p (ipa_pass_through_data *ipt1,
    6785              :                                       ipa_pass_through_data *ipt2,
    6786              :                                       bool agg_jf)
    6787              : 
    6788              : {
    6789        46113 :   gcc_assert (agg_jf ||
    6790              :               (!ipt1->refdesc_decremented && !ipt2->refdesc_decremented));
    6791        46113 :   if (ipt1->operation != ipt2->operation
    6792        46113 :       || ipt1->formal_id != ipt2->formal_id
    6793        46113 :       || (!agg_jf && (ipt1->agg_preserved != ipt2->agg_preserved)))
    6794              :     return false;
    6795        46113 :   if (ipt1->operation != NOP_EXPR
    6796        46113 :       && (TYPE_MAIN_VARIANT (ipt1->op_type)
    6797         6387 :           != TYPE_MAIN_VARIANT (ipt2->op_type)))
    6798              :     return false;
    6799        46105 :   if (((ipt1->operand != NULL_TREE) != (ipt2->operand != NULL_TREE))
    6800        46105 :       || (ipt1->operand
    6801         6379 :           && !values_equal_for_ipcp_p (ipt1->operand, ipt2->operand)))
    6802            0 :     return false;
    6803              :   return true;
    6804              : }
    6805              : 
    6806              : /* Return true if the two aggregate jump functions are known to be equivalent.
    6807              :    The function can be used before the IPA phase of IPA-CP or inlining because
    6808              :    it cannot cope with refdesc changes these passes can carry out.  */
    6809              : 
    6810              : static bool
    6811         3633 : ipa_agg_jump_functions_equivalent_p (ipa_agg_jf_item *ajf1,
    6812              :                                      ipa_agg_jf_item *ajf2)
    6813              : {
    6814         3633 :   if (ajf1->offset != ajf2->offset
    6815         3633 :       || ajf1->jftype != ajf2->jftype
    6816         7266 :       || !types_compatible_p (ajf1->type, ajf2->type))
    6817            0 :     return false;
    6818              : 
    6819         3633 :   switch (ajf1->jftype)
    6820              :     {
    6821         2108 :     case IPA_JF_CONST:
    6822         2108 :       if (!values_equal_for_ipcp_p (ajf1->value.constant,
    6823              :                                     ajf2->value.constant))
    6824              :         return false;
    6825              :       break;
    6826          762 :     case IPA_JF_PASS_THROUGH:
    6827          762 :       {
    6828          762 :         ipa_pass_through_data *ipt1 = &ajf1->value.pass_through;
    6829          762 :         ipa_pass_through_data *ipt2 = &ajf2->value.pass_through;
    6830          762 :         if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, true))
    6831              :           return false;
    6832              :       }
    6833              :       break;
    6834          763 :     case IPA_JF_LOAD_AGG:
    6835          763 :       {
    6836          763 :         ipa_load_agg_data *ila1 = &ajf1->value.load_agg;
    6837          763 :         ipa_load_agg_data *ila2 = &ajf2->value.load_agg;
    6838          763 :         if (!ipa_agg_pass_through_jf_equivalent_p (&ila1->pass_through,
    6839              :                                                    &ila2->pass_through, true))
    6840              :           return false;
    6841          763 :         if (ila1->offset != ila2->offset
    6842          763 :             || ila1->by_ref != ila2->by_ref
    6843         1526 :             || !types_compatible_p (ila1->type, ila2->type))
    6844            0 :           return false;
    6845              :       }
    6846              :       break;
    6847            0 :     default:
    6848            0 :         gcc_unreachable ();
    6849              :     }
    6850              :   return true;
    6851              : }
    6852              : 
    6853              : /* Return true if the two jump functions are known to be equivalent.  The
    6854              :    function can be used before the IPA phase of IPA-CP or inlining because it
    6855              :    cannot cope with refdesc changes these passes can carry out.  */
    6856              : 
    6857              : bool
    6858       125428 : ipa_jump_functions_equivalent_p (ipa_jump_func *jf1, ipa_jump_func *jf2)
    6859              : {
    6860       125428 :   if (jf1->type != jf2->type)
    6861              :     return false;
    6862              : 
    6863       125428 :   switch (jf1->type)
    6864              :     {
    6865              :     case IPA_JF_UNKNOWN:
    6866              :       break;
    6867        25269 :     case IPA_JF_CONST:
    6868        25269 :       {
    6869        25269 :         tree cst1 = ipa_get_jf_constant (jf1);
    6870        25269 :         tree cst2 = ipa_get_jf_constant (jf2);
    6871        25269 :         if (!values_equal_for_ipcp_p (cst1, cst2))
    6872              :           return false;
    6873              : 
    6874        25268 :         ipa_cst_ref_desc *rd1 = jfunc_rdesc_usable (jf1);
    6875        25268 :         ipa_cst_ref_desc *rd2 = jfunc_rdesc_usable (jf2);
    6876        25268 :         if (rd1 && rd2)
    6877              :           {
    6878          470 :             gcc_assert (rd1->refcount == 1
    6879              :                         && rd2->refcount == 1);
    6880          470 :             gcc_assert (!rd1->next_duplicate && !rd2->next_duplicate);
    6881              :           }
    6882        24798 :         else if (rd1)
    6883              :           return false;
    6884        24798 :         else if (rd2)
    6885              :           return false;
    6886              :       }
    6887              :       break;
    6888        44588 :     case IPA_JF_PASS_THROUGH:
    6889        44588 :       {
    6890        44588 :         ipa_pass_through_data *ipt1 = &jf1->value.pass_through;
    6891        44588 :         ipa_pass_through_data *ipt2 = &jf2->value.pass_through;
    6892        44588 :         if (!ipa_agg_pass_through_jf_equivalent_p (ipt1, ipt2, false))
    6893              :           return false;
    6894              :       }
    6895              :       break;
    6896        13987 :     case IPA_JF_ANCESTOR:
    6897        13987 :       {
    6898        13987 :         ipa_ancestor_jf_data *ia1 = &jf1->value.ancestor;
    6899        13987 :         ipa_ancestor_jf_data *ia2 = &jf2->value.ancestor;
    6900              : 
    6901        13987 :         if (ia1->formal_id != ia2->formal_id
    6902        13987 :             || ia1->agg_preserved != ia2->agg_preserved
    6903        13987 :             || ia1->keep_null != ia2->keep_null
    6904        13987 :             || ia1->offset != ia2->offset)
    6905              :           return false;
    6906              :       }
    6907              :       break;
    6908            0 :     default:
    6909            0 :       gcc_unreachable ();
    6910              :     }
    6911              : 
    6912       125419 :   if (((jf1->m_vr != nullptr) != (jf2->m_vr != nullptr))
    6913       125419 :       || (jf1->m_vr && !jf1->m_vr->equal_p (*jf2->m_vr)))
    6914            6 :     return false;
    6915              : 
    6916       125413 :   unsigned alen = vec_safe_length (jf1->agg.items);
    6917       127808 :   if (vec_safe_length (jf2->agg.items) != alen)
    6918              :     return false;
    6919              : 
    6920       125412 :   if (!alen)
    6921              :     return true;
    6922              : 
    6923         2395 :   if (jf1->agg.by_ref != jf2->agg.by_ref)
    6924              :     return false;
    6925              : 
    6926         6028 :   for (unsigned i = 0 ; i < alen; i++)
    6927         3633 :     if (!ipa_agg_jump_functions_equivalent_p (&(*jf1->agg.items)[i],
    6928         3633 :                                               &(*jf2->agg.items)[i]))
    6929              :       return false;
    6930              : 
    6931              :   return true;
    6932              : }
    6933              : 
    6934              : #include "gt-ipa-prop.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.