LCOV - code coverage report
Current view: top level - gcc - ipa-prop.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 95.1 % 3327 3165
Test Date: 2026-08-22 16:33:35 Functions: 97.5 % 159 155
Legend: Lines:     hit not hit

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