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