LCOV - code coverage report
Current view: top level - gcc - ipa-icf.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 91.3 % 1786 1631
Test Date: 2026-09-19 16:22:48 Functions: 97.0 % 100 97
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Interprocedural Identical Code Folding pass
       2              :    Copyright (C) 2014-2026 Free Software Foundation, Inc.
       3              : 
       4              :    Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : /* Interprocedural Identical Code Folding for functions and
      23              :    read-only variables.
      24              : 
      25              :    The goal of this transformation is to discover functions and read-only
      26              :    variables which do have exactly the same semantics.
      27              : 
      28              :    In case of functions,
      29              :    we could either create a virtual clone or do a simple function wrapper
      30              :    that will call equivalent function. If the function is just locally visible,
      31              :    all function calls can be redirected. For read-only variables, we create
      32              :    aliases if possible.
      33              : 
      34              :    Optimization pass arranges as follows:
      35              :    1) All functions and read-only variables are visited and internal
      36              :       data structure, either sem_function or sem_variables is created.
      37              :    2) For every symbol from the previous step, VAR_DECL and FUNCTION_DECL are
      38              :       saved and matched to corresponding sem_items.
      39              :    3) These declaration are ignored for equality check and are solved
      40              :       by Value Numbering algorithm published by Alpert, Zadeck in 1992.
      41              :    4) We compute hash value for each symbol.
      42              :    5) Congruence classes are created based on hash value. If hash value are
      43              :       equal, equals function is called and symbols are deeply compared.
      44              :       We must prove that all SSA names, declarations and other items
      45              :       correspond.
      46              :    6) Value Numbering is executed for these classes. At the end of the process
      47              :       all symbol members in remaining classes can be merged.
      48              :    7) Merge operation creates alias in case of read-only variables. For
      49              :       callgraph node, we must decide if we can redirect local calls,
      50              :       create an alias or a thunk.
      51              : 
      52              : */
      53              : 
      54              : #include "config.h"
      55              : #include "system.h"
      56              : #include "coretypes.h"
      57              : #include "backend.h"
      58              : #include "target.h"
      59              : #include "rtl.h"
      60              : #include "tree.h"
      61              : #include "gimple.h"
      62              : #include "alloc-pool.h"
      63              : #include "tree-pass.h"
      64              : #include "ssa.h"
      65              : #include "cgraph.h"
      66              : #include "coverage.h"
      67              : #include "gimple-pretty-print.h"
      68              : #include "data-streamer.h"
      69              : #include "tree-streamer.h"
      70              : #include "fold-const.h"
      71              : #include "calls.h"
      72              : #include "varasm.h"
      73              : #include "gimple-iterator.h"
      74              : #include "tree-cfg.h"
      75              : #include "symbol-summary.h"
      76              : #include "sreal.h"
      77              : #include "ipa-cp.h"
      78              : #include "ipa-prop.h"
      79              : #include "ipa-fnsummary.h"
      80              : #include "except.h"
      81              : #include "attribs.h"
      82              : #include "print-tree.h"
      83              : #include "ipa-utils.h"
      84              : #include "tree-ssa-alias-compare.h"
      85              : #include "ipa-icf-gimple.h"
      86              : #include "fibonacci_heap.h"
      87              : #include "ipa-icf.h"
      88              : #include "stor-layout.h"
      89              : #include "dbgcnt.h"
      90              : #include "tree-vector-builder.h"
      91              : #include "symtab-thunks.h"
      92              : #include "alias.h"
      93              : #include "asan.h"
      94              : 
      95              : using namespace ipa_icf_gimple;
      96              : 
      97              : namespace ipa_icf {
      98              : 
      99              : /* Initialization and computation of symtab node hash, there data
     100              :    are propagated later on.  */
     101              : 
     102              : static sem_item_optimizer *optimizer = NULL;
     103              : 
     104              : /* Constructor.  */
     105              : 
     106      1266736 : symbol_compare_collection::symbol_compare_collection (symtab_node *node)
     107              : {
     108      1266736 :   m_references.create (0);
     109      1266736 :   m_interposables.create (0);
     110              : 
     111      1266736 :   ipa_ref *ref;
     112              : 
     113      2279984 :   if (is_a <varpool_node *> (node) && DECL_VIRTUAL_P (node->decl))
     114      1266736 :     return;
     115              : 
     116      1605411 :   for (unsigned i = 0; node->iterate_reference (i, ref); i++)
     117              :     {
     118       339005 :       if (ref->address_matters_p ())
     119       313952 :         m_references.safe_push (ref->referred);
     120              : 
     121       339005 :       if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE)
     122              :         {
     123       291696 :           if (ref->address_matters_p ())
     124       288345 :             m_references.safe_push (ref->referred);
     125              :           else
     126         3351 :             m_interposables.safe_push (ref->referred);
     127              :         }
     128              :     }
     129              : 
     130      1266406 :   if (is_a <cgraph_node *> (node))
     131              :     {
     132       253488 :       cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
     133              : 
     134       505923 :       for (cgraph_edge *e = cnode->callees; e; e = e->next_callee)
     135       252435 :         if (e->callee->get_availability () <= AVAIL_INTERPOSABLE)
     136        71064 :           m_interposables.safe_push (e->callee);
     137              :     }
     138              : }
     139              : 
     140              : /* Constructor for key value pair, where _ITEM is key and _INDEX is a target.  */
     141              : 
     142     33156888 : sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index)
     143     33156888 : : item (_item), index (_index)
     144              : {
     145     33156888 : }
     146              : 
     147            0 : sem_item::sem_item (sem_item_type _type, bitmap_obstack *stack)
     148            0 : : type (_type), referenced_by_count (0), m_hash (-1), m_hash_set (false)
     149              : {
     150            0 :   setup (stack);
     151            0 : }
     152              : 
     153      3377390 : sem_item::sem_item (sem_item_type _type, symtab_node *_node,
     154              :                     bitmap_obstack *stack)
     155      6754780 : : type (_type), node (_node), referenced_by_count (0), m_hash (-1),
     156      3377390 :   m_hash_set (false)
     157              : {
     158      3377390 :   decl = node->decl;
     159      3377390 :   setup (stack);
     160      3377390 : }
     161              : 
     162              : /* Add reference to a semantic TARGET.  */
     163              : 
     164              : void
     165      4053858 : sem_item::add_reference (ref_map *refs,
     166              :                          sem_item *target)
     167              : {
     168      4053858 :   unsigned index = reference_count++;
     169      4053858 :   bool existed;
     170              : 
     171      4053858 :   sem_usage_pair *pair = new sem_usage_pair (target, index);
     172      4053858 :   vec<sem_item *> &v = refs->get_or_insert (pair, &existed);
     173      4053858 :   if (existed)
     174      1084293 :     delete pair;
     175              : 
     176      4053858 :   v.safe_push (this);
     177      4053858 :   bitmap_set_bit (target->usage_index_bitmap, index);
     178      4053858 :   refs_set.add (target->node);
     179      4053858 :   ++target->referenced_by_count;
     180      4053858 : }
     181              : 
     182              : /* Initialize internal data structures. Bitmap STACK is used for
     183              :    bitmap memory allocation process.  */
     184              : 
     185              : void
     186      3377390 : sem_item::setup (bitmap_obstack *stack)
     187              : {
     188      3377390 :   gcc_checking_assert (node);
     189              : 
     190      3377390 :   reference_count = 0;
     191      3377390 :   tree_refs.create (0);
     192      3377390 :   usage_index_bitmap = BITMAP_ALLOC (stack);
     193      3377390 : }
     194              : 
     195      3221918 : sem_item::~sem_item ()
     196              : {
     197      3221918 :   tree_refs.release ();
     198              : 
     199      3221918 :   BITMAP_FREE (usage_index_bitmap);
     200      3221918 : }
     201              : 
     202              : /* Dump function for debugging purpose.  */
     203              : 
     204              : DEBUG_FUNCTION void
     205            0 : sem_item::dump (void)
     206              : {
     207            0 :   if (dump_file)
     208              :     {
     209            0 :       fprintf (dump_file, "[%s] %s (tree:%p)\n", type == FUNC ? "func" : "var",
     210            0 :                node->dump_name (), (void *) node->decl);
     211            0 :       fprintf (dump_file, "  hash: %u\n", get_hash ());
     212              :     }
     213            0 : }
     214              : 
     215              : /* Return true if target supports alias symbols.  */
     216              : 
     217              : bool
     218       434605 : sem_item::target_supports_symbol_aliases_p (void)
     219              : {
     220              : #if !defined (ASM_OUTPUT_DEF) || (!defined(ASM_OUTPUT_WEAK_ALIAS) && !defined (ASM_WEAKEN_DECL))
     221              :   return false;
     222              : #else
     223       434605 :   gcc_checking_assert (TARGET_SUPPORTS_ALIASES);
     224       434605 :   return true;
     225              : #endif
     226              : }
     227              : 
     228      9467096 : void sem_item::set_hash (hashval_t hash)
     229              : {
     230      9467096 :   m_hash = hash;
     231      9467096 :   m_hash_set = true;
     232      9467096 : }
     233              : 
     234              : hash_map<const_tree, hashval_t> sem_item::m_type_hash_cache;
     235              : 
     236      1069082 : sem_function::sem_function (cgraph_node *node, bitmap_obstack *stack)
     237      1069082 :   : sem_item (FUNC, node, stack), memory_access_types (),
     238      1069082 :     m_alias_sets_hash (0), m_checker (NULL), m_compared_func (NULL)
     239              : {
     240      1069082 :   bb_sizes.create (0);
     241      1069082 :   bb_sorted.create (0);
     242      1069082 : }
     243              : 
     244      2055516 : sem_function::~sem_function ()
     245              : {
     246      7673673 :   for (unsigned i = 0; i < bb_sorted.length (); i++)
     247      6645915 :     delete (bb_sorted[i]);
     248              : 
     249      1027758 :   bb_sizes.release ();
     250      1027758 :   bb_sorted.release ();
     251      2055516 : }
     252              : 
     253              : /* Calculates hash value based on a BASIC_BLOCK.  */
     254              : 
     255              : hashval_t
     256      6472960 : sem_function::get_bb_hash (const sem_bb *basic_block)
     257              : {
     258      6472960 :   inchash::hash hstate;
     259              : 
     260      6472960 :   hstate.add_int (basic_block->nondbg_stmt_count);
     261      6472960 :   hstate.add_int (basic_block->edge_count);
     262              : 
     263      6472960 :   return hstate.end ();
     264              : }
     265              : 
     266              : /* References independent hash function.  */
     267              : 
     268              : hashval_t
     269     11020064 : sem_function::get_hash (void)
     270              : {
     271     11020064 :   if (!m_hash_set)
     272              :     {
     273       991066 :       inchash::hash hstate;
     274       991066 :       hstate.add_int (177454); /* Random number for function type.  */
     275              : 
     276       991066 :       hstate.add_int (arg_count);
     277       991066 :       hstate.add_int (cfg_checksum);
     278       991066 :       hstate.add_int (gcode_hash);
     279              : 
     280     14928052 :       for (unsigned i = 0; i < bb_sorted.length (); i++)
     281      6472960 :         hstate.merge_hash (get_bb_hash (bb_sorted[i]));
     282              : 
     283      7464026 :       for (unsigned i = 0; i < bb_sizes.length (); i++)
     284      6472960 :         hstate.add_int (bb_sizes[i]);
     285              : 
     286              :       /* Add common features of declaration itself.  */
     287       991066 :       if (DECL_FUNCTION_SPECIFIC_TARGET (decl))
     288       127085 :         hstate.add_hwi
     289       127085 :          (cl_target_option_hash
     290       127085 :            (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl))));
     291       991066 :       if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))
     292       132540 :         hstate.add_hwi
     293       132540 :          (cl_optimization_hash
     294       132540 :            (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl))));
     295       991066 :       hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl));
     296       991066 :       hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl));
     297       991066 :       hstate.add_flag (DECL_STATIC_CHAIN (decl));
     298              : 
     299       991066 :       set_hash (hstate.end ());
     300              :     }
     301              : 
     302     11020064 :   return m_hash;
     303              : }
     304              : 
     305              : /* Compare properties of symbols N1 and N2 that does not affect semantics of
     306              :    symbol itself but affects semantics of its references from USED_BY (which
     307              :    may be NULL if it is unknown).  If comparison is false, symbols
     308              :    can still be merged but any symbols referring them can't.
     309              : 
     310              :    If ADDRESS is true, do extra checking needed for IPA_REF_ADDR.
     311              : 
     312              :    TODO: We can also split attributes to those that determine codegen of
     313              :    a function body/variable constructor itself and those that are used when
     314              :    referring to it.  */
     315              : 
     316              : bool
     317       363359 : sem_item::compare_referenced_symbol_properties (symtab_node *used_by,
     318              :                                                 symtab_node *n1,
     319              :                                                 symtab_node *n2,
     320              :                                                 bool address)
     321              : {
     322       363359 :   if (is_a <cgraph_node *> (n1))
     323              :     {
     324              :       /* Inline properties matters: we do now want to merge uses of inline
     325              :          function to uses of normal function because inline hint would be lost.
     326              :          We however can merge inline function to noinline because the alias
     327              :          will keep its DECL_DECLARED_INLINE flag.
     328              : 
     329              :          Also ignore inline flag when optimizing for size or when function
     330              :          is known to not be inlinable.
     331              : 
     332              :          TODO: the optimize_size checks can also be assumed to be true if
     333              :          unit has no !optimize_size functions. */
     334              : 
     335       969495 :       if ((!used_by || address || !is_a <cgraph_node *> (used_by)
     336       248587 :            || !opt_for_fn (used_by->decl, optimize_size))
     337       359559 :           && !opt_for_fn (n1->decl, optimize_size)
     338       355644 :           && n1->get_availability () > AVAIL_INTERPOSABLE
     339       501707 :           && (!DECL_UNINLINABLE (n1->decl) || !DECL_UNINLINABLE (n2->decl)))
     340              :         {
     341       103322 :           if (DECL_DISREGARD_INLINE_LIMITS (n1->decl)
     342        51661 :               != DECL_DISREGARD_INLINE_LIMITS (n2->decl))
     343            0 :             return return_false_with_msg
     344              :                      ("DECL_DISREGARD_INLINE_LIMITS are different");
     345              : 
     346        51661 :           if (DECL_DECLARED_INLINE_P (n1->decl)
     347        51661 :               != DECL_DECLARED_INLINE_P (n2->decl))
     348          347 :             return return_false_with_msg ("inline attributes are different");
     349              :         }
     350              : 
     351       361002 :       if (DECL_IS_OPERATOR_NEW_P (n1->decl)
     352       361002 :           != DECL_IS_OPERATOR_NEW_P (n2->decl))
     353            0 :         return return_false_with_msg ("operator new flags are different");
     354              : 
     355       361002 :       if (DECL_IS_REPLACEABLE_OPERATOR (n1->decl)
     356       361002 :           != DECL_IS_REPLACEABLE_OPERATOR (n2->decl))
     357            0 :         return return_false_with_msg ("replaceable operator flags are different");
     358              :     }
     359              : 
     360              :   /* Merging two definitions with a reference to equivalent vtables, but
     361              :      belonging to a different type may result in ipa-polymorphic-call analysis
     362              :      giving a wrong answer about the dynamic type of instance.  */
     363       363012 :   if (is_a <varpool_node *> (n1))
     364              :     {
     365         3774 :       if ((DECL_VIRTUAL_P (n1->decl) || DECL_VIRTUAL_P (n2->decl))
     366          246 :           && (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl)
     367          246 :               || !types_must_be_same_for_odr (DECL_CONTEXT (n1->decl),
     368          246 :                                               DECL_CONTEXT (n2->decl)))
     369         2381 :           && (!used_by || !is_a <cgraph_node *> (used_by) || address
     370          125 :               || opt_for_fn (used_by->decl, flag_devirtualize)))
     371          246 :         return return_false_with_msg
     372              :                  ("references to virtual tables cannot be merged");
     373              : 
     374         1764 :       if (address && DECL_ALIGN (n1->decl) != DECL_ALIGN (n2->decl))
     375            0 :         return return_false_with_msg ("alignment mismatch");
     376              : 
     377              :       /* For functions we compare attributes in equals_wpa, because we do
     378              :          not know what attributes may cause codegen differences, but for
     379              :          variables just compare attributes for references - the codegen
     380              :          for constructors is affected only by those attributes that we lower
     381              :          to explicit representation (such as DECL_ALIGN or DECL_SECTION).  */
     382         1764 :       if (!attribute_list_equal (DECL_ATTRIBUTES (n1->decl),
     383         1764 :                                  DECL_ATTRIBUTES (n2->decl)))
     384            0 :         return return_false_with_msg ("different var decl attributes");
     385         1764 :       if (comp_type_attributes (TREE_TYPE (n1->decl),
     386         1764 :                                 TREE_TYPE (n2->decl)) != 1)
     387            0 :         return return_false_with_msg ("different var type attributes");
     388              :     }
     389              : 
     390              :   /* When matching virtual tables, be sure to also match information
     391              :      relevant for polymorphic call analysis.  */
     392       730002 :   if (used_by && is_a <varpool_node *> (used_by)
     393       366643 :       && DECL_VIRTUAL_P (used_by->decl))
     394              :     {
     395         3873 :       if (DECL_VIRTUAL_P (n1->decl) != DECL_VIRTUAL_P (n2->decl))
     396            0 :         return return_false_with_msg ("virtual flag mismatch");
     397         3873 :       if (DECL_VIRTUAL_P (n1->decl) && is_a <cgraph_node *> (n1)
     398         6118 :           && (DECL_FINAL_P (n1->decl) != DECL_FINAL_P (n2->decl)))
     399           73 :         return return_false_with_msg ("final flag mismatch");
     400              :     }
     401              :   return true;
     402              : }
     403              : 
     404              : /* Hash properties that are compared by compare_referenced_symbol_properties. */
     405              : 
     406              : void
     407      6059550 : sem_item::hash_referenced_symbol_properties (symtab_node *ref,
     408              :                                              inchash::hash &hstate,
     409              :                                              bool address)
     410              : {
     411      6059550 :   if (is_a <cgraph_node *> (ref))
     412              :     {
     413      1703926 :       if ((type != FUNC || address || !opt_for_fn (decl, optimize_size))
     414      1936017 :           && !opt_for_fn (ref->decl, optimize_size)
     415      3910018 :           && !DECL_UNINLINABLE (ref->decl))
     416              :         {
     417      1530482 :           hstate.add_flag (DECL_DISREGARD_INLINE_LIMITS (ref->decl));
     418      1530482 :           hstate.add_flag (DECL_DECLARED_INLINE_P (ref->decl));
     419              :         }
     420      1979677 :       hstate.add_flag (DECL_IS_OPERATOR_NEW_P (ref->decl));
     421              :     }
     422      4079873 :   else if (is_a <varpool_node *> (ref))
     423              :     {
     424      4079873 :       hstate.add_flag (DECL_VIRTUAL_P (ref->decl));
     425      4079873 :       if (address)
     426      2990016 :         hstate.add_int (DECL_ALIGN (ref->decl));
     427              :     }
     428      6059550 : }
     429              : 
     430              : 
     431              : /* For a given symbol table nodes N1 and N2, we check that FUNCTION_DECLs
     432              :    point to a same function. Comparison can be skipped if IGNORED_NODES
     433              :    contains these nodes.  ADDRESS indicate if address is taken.  */
     434              : 
     435              : bool
     436       521337 : sem_item::compare_symbol_references (
     437              :     hash_map <symtab_node *, sem_item *> &ignored_nodes,
     438              :     symtab_node *n1, symtab_node *n2, bool address)
     439              : {
     440       521337 :   enum availability avail1, avail2;
     441              : 
     442       521337 :   if (n1 == n2)
     443              :     return true;
     444              : 
     445              :   /* Never match variable and function.  */
     446       758577 :   if (is_a <varpool_node *> (n1) != is_a <varpool_node *> (n2))
     447              :     return false;
     448              : 
     449       252859 :   if (!compare_referenced_symbol_properties (node, n1, n2, address))
     450              :     return false;
     451       252207 :   if (address && n1->equal_address_to (n2) == 1)
     452              :     return true;
     453       252207 :   if (!address && n1->semantically_equivalent_p (n2))
     454              :     return true;
     455              : 
     456       252206 :   n1 = n1->ultimate_alias_target (&avail1);
     457       252206 :   n2 = n2->ultimate_alias_target (&avail2);
     458              : 
     459        39537 :   if (avail1 > AVAIL_INTERPOSABLE && ignored_nodes.get (n1)
     460       291743 :       && avail2 > AVAIL_INTERPOSABLE && ignored_nodes.get (n2))
     461              :     return true;
     462              : 
     463       212784 :   return return_false_with_msg ("different references");
     464              : }
     465              : 
     466              : /* If cgraph edges E1 and E2 are indirect calls, verify that
     467              :    ECF flags are the same.  */
     468              : 
     469       154377 : bool sem_function::compare_edge_flags (cgraph_edge *e1, cgraph_edge *e2)
     470              : {
     471       154377 :   if (e1->indirect_info && e2->indirect_info)
     472              :     {
     473          719 :       int e1_flags = e1->indirect_info->ecf_flags;
     474          719 :       int e2_flags = e2->indirect_info->ecf_flags;
     475              : 
     476          719 :       if (e1_flags != e2_flags)
     477            0 :         return return_false_with_msg ("ICF flags are different");
     478              :     }
     479       153658 :   else if (e1->indirect_info || e2->indirect_info)
     480            0 :     return false;
     481              : 
     482              :   return true;
     483              : }
     484              : 
     485              : /* Return true if parameter I may be used.  */
     486              : 
     487              : bool
     488      1468674 : sem_function::param_used_p (unsigned int i)
     489              : {
     490      1468674 :   if (ipa_node_params_sum == NULL)
     491              :     return true;
     492              : 
     493      1468674 :   ipa_node_params *parms_info = ipa_node_params_sum->get (get_node ());
     494              : 
     495      1468674 :   if (!parms_info || vec_safe_length (parms_info->descriptors) <= i)
     496              :     return true;
     497              : 
     498      1144136 :   return ipa_is_param_used (parms_info, i);
     499              : }
     500              : 
     501              : /* Perform additional check needed to match types function parameters that are
     502              :    used.  Unlike for normal decls it matters if type is TYPE_RESTRICT and we
     503              :    make an assumption that REFERENCE_TYPE parameters are always non-NULL.  */
     504              : 
     505              : bool
     506      1299571 : sem_function::compatible_parm_types_p (tree parm1, tree parm2)
     507              : {
     508              :   /* Be sure that parameters are TBAA compatible.  */
     509      1299571 :   if (!func_checker::compatible_types_p (parm1, parm2))
     510          349 :     return return_false_with_msg ("parameter type is not compatible");
     511              : 
     512      1299222 :   if (POINTER_TYPE_P (parm1)
     513      1299222 :       && (TYPE_RESTRICT (parm1) != TYPE_RESTRICT (parm2)))
     514            0 :     return return_false_with_msg ("argument restrict flag mismatch");
     515              : 
     516              :   /* nonnull_arg_p implies non-zero range to REFERENCE types.  */
     517      1299222 :   if (POINTER_TYPE_P (parm1)
     518       128341 :       && TREE_CODE (parm1) != TREE_CODE (parm2)
     519      1299222 :       && opt_for_fn (decl, flag_delete_null_pointer_checks))
     520            0 :     return return_false_with_msg ("pointer wrt reference mismatch");
     521              : 
     522              :   return true;
     523              : }
     524              : 
     525              : /* Fast equality function based on knowledge known in WPA.  */
     526              : 
     527              : bool
     528      1722107 : sem_function::equals_wpa (sem_item *item,
     529              :                           hash_map <symtab_node *, sem_item *> &ignored_nodes)
     530              : {
     531      1722107 :   gcc_assert (item->type == FUNC);
     532      1722107 :   cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
     533      1722107 :   cgraph_node *cnode2 = dyn_cast <cgraph_node *> (item->node);
     534              : 
     535      1722107 :   m_compared_func = static_cast<sem_function *> (item);
     536              : 
     537      1722107 :   if (cnode->must_remain_in_tu_name || cnode2->must_remain_in_tu_name
     538      1722107 :       || cnode->must_remain_in_tu_body || cnode2->must_remain_in_tu_body)
     539            3 :     return return_false_with_msg ("must remain in TU");
     540              : 
     541      1722104 :   if (cnode->thunk != cnode2->thunk)
     542            0 :     return return_false_with_msg ("thunk mismatch");
     543      1722104 :   if (cnode->former_thunk_p () != cnode2->former_thunk_p ())
     544            4 :     return return_false_with_msg ("former_thunk_p mismatch");
     545              : 
     546      1722100 :   if ((cnode->thunk || cnode->former_thunk_p ())
     547      1722100 :       && thunk_info::get (cnode) != thunk_info::get (cnode2))
     548            0 :     return return_false_with_msg ("thunk_info mismatch");
     549              : 
     550              :   /* Compare special function DECL attributes.  */
     551      1722100 :   if (DECL_FUNCTION_PERSONALITY (decl)
     552      1722100 :       != DECL_FUNCTION_PERSONALITY (item->decl))
     553            0 :     return return_false_with_msg ("function personalities are different");
     554              : 
     555      1722100 :   if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl)
     556      1722100 :        != DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (item->decl))
     557            0 :     return return_false_with_msg ("instrument function entry exit "
     558              :                                   "attributes are different");
     559              : 
     560      1722100 :   if (DECL_NO_LIMIT_STACK (decl) != DECL_NO_LIMIT_STACK (item->decl))
     561            0 :     return return_false_with_msg ("no stack limit attributes are different");
     562              : 
     563      1722100 :   if (DECL_CXX_CONSTRUCTOR_P (decl) != DECL_CXX_CONSTRUCTOR_P (item->decl))
     564          403 :     return return_false_with_msg ("DECL_CXX_CONSTRUCTOR mismatch");
     565              : 
     566      1721697 :   if (DECL_CXX_DESTRUCTOR_P (decl) != DECL_CXX_DESTRUCTOR_P (item->decl))
     567          117 :     return return_false_with_msg ("DECL_CXX_DESTRUCTOR mismatch");
     568              : 
     569              :   /* TODO: pure/const flags mostly matters only for references, except for
     570              :      the fact that codegen takes LOOPING flag as a hint that loops are
     571              :      finite.  We may arrange the code to always pick leader that has least
     572              :      specified flags and then this can go into comparing symbol properties.  */
     573      1721580 :   if (flags_from_decl_or_type (decl) != flags_from_decl_or_type (item->decl))
     574       119758 :     return return_false_with_msg ("decl_or_type flags are different");
     575              : 
     576              :   /* Do not match polymorphic constructors of different types.  They calls
     577              :      type memory location for ipa-polymorphic-call and we do not want
     578              :      it to get confused by wrong type.  */
     579      1601822 :   if (DECL_CXX_CONSTRUCTOR_P (decl)
     580         2622 :       && opt_for_fn (decl, flag_devirtualize)
     581      1604444 :       && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
     582              :     {
     583         2569 :       if (TREE_CODE (TREE_TYPE (item->decl)) != METHOD_TYPE)
     584            0 :         return return_false_with_msg ("DECL_CXX_CONSTRUCTOR type mismatch");
     585         2569 :       else if (!func_checker::compatible_polymorphic_types_p
     586         2569 :                  (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
     587         2569 :                   TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
     588            0 :         return return_false_with_msg ("ctor polymorphic type mismatch");
     589              :     }
     590              : 
     591              :   /* Checking function TARGET and OPTIMIZATION flags.  */
     592      1601822 :   cl_target_option *tar1 = target_opts_for_fn (decl);
     593      1601822 :   cl_target_option *tar2 = target_opts_for_fn (item->decl);
     594              : 
     595      1601822 :   if (tar1 != tar2 && !cl_target_option_eq (tar1, tar2))
     596              :     {
     597            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     598              :         {
     599            0 :           fprintf (dump_file, "target flags difference");
     600            0 :           cl_target_option_print_diff (dump_file, 2, tar1, tar2);
     601              :         }
     602              : 
     603            0 :       return return_false_with_msg ("Target flags are different");
     604              :     }
     605              : 
     606      1601822 :   cl_optimization *opt1 = opts_for_fn (decl);
     607      1601822 :   cl_optimization *opt2 = opts_for_fn (item->decl);
     608              : 
     609      1601822 :   if (opt1 != opt2 && !cl_optimization_option_eq (opt1, opt2))
     610              :     {
     611            0 :       if (dump_file && (dump_flags & TDF_DETAILS))
     612              :         {
     613            0 :           fprintf (dump_file, "optimization flags difference");
     614            0 :           cl_optimization_print_diff (dump_file, 2, opt1, opt2);
     615              :         }
     616              : 
     617            0 :       return return_false_with_msg ("optimization flags are different");
     618              :     }
     619              : 
     620              :   /* Result type checking.  */
     621      1601822 :   if (!func_checker::compatible_types_p
     622      1601822 :          (TREE_TYPE (TREE_TYPE (decl)),
     623      1601822 :           TREE_TYPE (TREE_TYPE (m_compared_func->decl))))
     624      1041976 :     return return_false_with_msg ("result types are different");
     625              : 
     626              :   /* Checking types of arguments.  */
     627       559846 :   tree list1 = TYPE_ARG_TYPES (TREE_TYPE (decl)),
     628       559846 :        list2 = TYPE_ARG_TYPES (TREE_TYPE (m_compared_func->decl));
     629      1743264 :   for (unsigned i = 0; list1 && list2;
     630      1183418 :        list1 = TREE_CHAIN (list1), list2 = TREE_CHAIN (list2), i++)
     631              :     {
     632      1414257 :       tree parm1 = TREE_VALUE (list1);
     633      1414257 :       tree parm2 = TREE_VALUE (list2);
     634              : 
     635              :       /* This guard is here for function pointer with attributes (pr59927.c).  */
     636      1414257 :       if (!parm1 || !parm2)
     637            0 :         return return_false_with_msg ("NULL argument type");
     638              : 
     639              :       /* Verify that types are compatible to ensure that both functions
     640              :          have same calling conventions.  */
     641      1414257 :       if (!types_compatible_p (parm1, parm2))
     642       230490 :         return return_false_with_msg ("parameter types are not compatible");
     643              : 
     644      1183767 :       if (!param_used_p (i))
     645        49608 :         continue;
     646              : 
     647              :       /* Perform additional checks for used parameters.  */
     648      1134159 :       if (!compatible_parm_types_p (parm1, parm2))
     649              :         return false;
     650              :     }
     651              : 
     652       329007 :   if (list1 || list2)
     653            5 :     return return_false_with_msg ("mismatched number of parameters");
     654              : 
     655       329002 :   if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (item->decl))
     656            0 :     return return_false_with_msg ("static chain mismatch");
     657              : 
     658       362940 :   if (node->num_references () != item->node->num_references ())
     659            0 :     return return_false_with_msg ("different number of references");
     660              : 
     661              :   /* Checking function attributes.
     662              :      This is quadratic in number of attributes.
     663              :      comp_type_attributes only considers attributes that affect type
     664              :      identity, but an attribute that leaves the type alone can still let
     665              :      the body assume something, nonnull being one, so compare the lists
     666              :      the same way the decl attributes are compared below.  */
     667       329002 :   if (!attribute_list_equal (TYPE_ATTRIBUTES (TREE_TYPE (decl)),
     668       329002 :                              TYPE_ATTRIBUTES (TREE_TYPE (item->decl))))
     669         3157 :     return return_false_with_msg ("different type attributes");
     670              :   /* A METHOD_TYPE promises a nonnull this pointer without carrying an
     671              :      attribute that says so, so it is not interchangeable with a
     672              :      FUNCTION_TYPE that makes no such promise.  */
     673       325845 :   if ((TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
     674       325845 :       != (TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE))
     675          155 :     return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
     676       325690 :   if (!attribute_list_equal (DECL_ATTRIBUTES (decl),
     677       325690 :                              DECL_ATTRIBUTES (item->decl)))
     678         1404 :     return return_false_with_msg ("different decl attributes");
     679              : 
     680              :   /* The type of THIS pointer type memory location for
     681              :      ipa-polymorphic-call-analysis.  */
     682       324286 :   if (opt_for_fn (decl, flag_devirtualize)
     683       324250 :       && (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE
     684       302320 :           || TREE_CODE (TREE_TYPE (item->decl)) == METHOD_TYPE)
     685        21930 :       && param_used_p (0)
     686       340595 :       && compare_polymorphic_p ())
     687              :     {
     688        12619 :       if (TREE_CODE (TREE_TYPE (decl)) != TREE_CODE (TREE_TYPE (item->decl)))
     689            0 :         return return_false_with_msg ("METHOD_TYPE and FUNCTION_TYPE mismatch");
     690        12619 :       if (!func_checker::compatible_polymorphic_types_p
     691        12619 :            (TYPE_METHOD_BASETYPE (TREE_TYPE (decl)),
     692        12619 :             TYPE_METHOD_BASETYPE (TREE_TYPE (item->decl)), false))
     693            0 :         return return_false_with_msg ("THIS pointer ODR type mismatch");
     694              :     }
     695              : 
     696       324286 :   ipa_ref *ref = NULL, *ref2 = NULL;
     697       357219 :   for (unsigned i = 0; node->iterate_reference (i, ref); i++)
     698              :     {
     699        33058 :       item->node->iterate_reference (i, ref2);
     700              : 
     701        33058 :       if (ref->use != ref2->use)
     702            0 :         return return_false_with_msg ("reference use mismatch");
     703              : 
     704        33058 :       if (!compare_symbol_references (ignored_nodes, ref->referred,
     705              :                                       ref2->referred,
     706              :                                       ref->address_matters_p ()))
     707              :         return false;
     708              :     }
     709              : 
     710       324161 :   cgraph_edge *e1 = dyn_cast <cgraph_node *> (node)->callees;
     711       324161 :   cgraph_edge *e2 = dyn_cast <cgraph_node *> (item->node)->callees;
     712              : 
     713       477819 :   while (e1 && e2)
     714              :     {
     715       366752 :       if (!compare_symbol_references (ignored_nodes, e1->callee,
     716       366752 :                                       e2->callee, false))
     717              :         return false;
     718       153658 :       if (!compare_edge_flags (e1, e2))
     719              :         return false;
     720              : 
     721       153658 :       e1 = e1->next_callee;
     722       153658 :       e2 = e2->next_callee;
     723              :     }
     724              : 
     725       111067 :   if (e1 || e2)
     726            0 :     return return_false_with_msg ("different number of calls");
     727              : 
     728       111067 :   e1 = dyn_cast <cgraph_node *> (node)->indirect_calls;
     729       111067 :   e2 = dyn_cast <cgraph_node *> (item->node)->indirect_calls;
     730              : 
     731       111786 :   while (e1 && e2)
     732              :     {
     733          719 :       if (!compare_edge_flags (e1, e2))
     734              :         return false;
     735              : 
     736          719 :       e1 = e1->next_callee;
     737          719 :       e2 = e2->next_callee;
     738              :     }
     739              : 
     740       111067 :   if (e1 || e2)
     741            0 :     return return_false_with_msg ("different number of indirect calls");
     742              : 
     743              :   return true;
     744              : }
     745              : 
     746              : /* Update hash by address sensitive references. We iterate over all
     747              :    sensitive references (address_matters_p) and we hash ultimate alias
     748              :    target of these nodes, which can improve a semantic item hash.
     749              : 
     750              :    Also hash in referenced symbols properties.  This can be done at any time
     751              :    (as the properties should not change), but it is convenient to do it here
     752              :    while we walk the references anyway.  */
     753              : 
     754              : void
     755      2512395 : sem_item::update_hash_by_addr_refs (hash_map <symtab_node *,
     756              :                                     sem_item *> &m_symtab_node_map)
     757              : {
     758      2512395 :   ipa_ref* ref;
     759      2512395 :   inchash::hash hstate (get_hash ());
     760              : 
     761      6985965 :   for (unsigned i = 0; node->iterate_reference (i, ref); i++)
     762              :     {
     763      4473570 :       hstate.add_int (ref->use);
     764      4473570 :       hash_referenced_symbol_properties (ref->referred, hstate,
     765      4473570 :                                          ref->use == IPA_REF_ADDR);
     766      4473570 :       if (ref->address_matters_p () || !m_symtab_node_map.get (ref->referred))
     767      4318116 :         hstate.add_int (ref->referred->ultimate_alias_target ()->order);
     768              :     }
     769              : 
     770      2512395 :   if (is_a <cgraph_node *> (node))
     771              :     {
     772      2606068 :       for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callers; e;
     773      1585980 :            e = e->next_caller)
     774              :         {
     775      1585980 :           sem_item **result = m_symtab_node_map.get (e->callee);
     776      1585980 :           hash_referenced_symbol_properties (e->callee, hstate, false);
     777      1585980 :           if (!result)
     778            0 :             hstate.add_int (e->callee->ultimate_alias_target ()->order);
     779              :         }
     780              :     }
     781              : 
     782      2512395 :   set_hash (hstate.end ());
     783      2512395 : }
     784              : 
     785              : /* Update hash by computed local hash values taken from different
     786              :    semantic items.
     787              :    TODO: stronger SCC based hashing would be desirable here.  */
     788              : 
     789              : void
     790      2512395 : sem_item::update_hash_by_local_refs (hash_map <symtab_node *,
     791              :                                      sem_item *> &m_symtab_node_map)
     792              : {
     793      2512395 :   ipa_ref* ref;
     794      2512395 :   inchash::hash state (get_hash ());
     795              : 
     796      9498360 :   for (unsigned j = 0; node->iterate_reference (j, ref); j++)
     797              :     {
     798      4473570 :       sem_item **result = m_symtab_node_map.get (ref->referring);
     799      4473570 :       if (result)
     800      4473570 :         state.merge_hash ((*result)->get_hash ());
     801              :     }
     802              : 
     803      2512395 :   if (type == FUNC)
     804              :     {
     805      4945630 :       for (cgraph_edge *e = dyn_cast <cgraph_node *> (node)->callees; e;
     806      3925542 :            e = e->next_callee)
     807              :         {
     808      3925542 :           sem_item **result = m_symtab_node_map.get (e->caller);
     809      3925542 :           if (result)
     810      3925542 :             state.merge_hash ((*result)->get_hash ());
     811              :         }
     812              :     }
     813              : 
     814      2512395 :   global_hash = state.end ();
     815      2512395 : }
     816              : 
     817              : /* Returns true if the item equals to ITEM given as argument.  */
     818              : 
     819              : bool
     820       127551 : sem_function::equals (sem_item *item,
     821              :                       hash_map <symtab_node *, sem_item *> &)
     822              : {
     823       127551 :   gcc_assert (item->type == FUNC);
     824       127551 :   bool eq = equals_private (item);
     825              : 
     826       127551 :   if (m_checker != NULL)
     827              :     {
     828       127551 :       delete m_checker;
     829       127551 :       m_checker = NULL;
     830              :     }
     831              : 
     832       127551 :   if (dump_file && (dump_flags & TDF_DETAILS))
     833           46 :     fprintf (dump_file,
     834              :              "Equals called for: %s:%s with result: %s\n\n",
     835           23 :              node->dump_name (),
     836           23 :              item->node->dump_name (),
     837              :              eq ? "true" : "false");
     838              : 
     839       127551 :   return eq;
     840              : }
     841              : 
     842              : /* Processes function equality comparison.  */
     843              : 
     844              : bool
     845       127551 : sem_function::equals_private (sem_item *item)
     846              : {
     847       127551 :   if (item->type != FUNC)
     848              :     return false;
     849              : 
     850       127551 :   basic_block bb1, bb2;
     851       127551 :   edge e1, e2;
     852       127551 :   edge_iterator ei1, ei2;
     853       127551 :   bool result = true;
     854       127551 :   tree arg1, arg2;
     855              : 
     856       127551 :   m_compared_func = static_cast<sem_function *> (item);
     857              : 
     858       127551 :   gcc_assert (decl != item->decl);
     859              : 
     860       255102 :   if (bb_sorted.length () != m_compared_func->bb_sorted.length ()
     861       127551 :       || edge_count != m_compared_func->edge_count
     862       255102 :       || cfg_checksum != m_compared_func->cfg_checksum)
     863            0 :     return return_false ();
     864              : 
     865       255102 :   m_checker = new func_checker (decl, m_compared_func->decl,
     866              :                                 false,
     867       255102 :                                 opt_for_fn (m_compared_func->decl,
     868              :                                             flag_strict_aliasing),
     869              :                                 &refs_set,
     870       127551 :                                 &m_compared_func->refs_set);
     871       127551 :   arg1 = DECL_ARGUMENTS (decl);
     872       127551 :   arg2 = DECL_ARGUMENTS (m_compared_func->decl);
     873       127551 :   for (unsigned i = 0;
     874       327793 :        arg1 && arg2; arg1 = DECL_CHAIN (arg1), arg2 = DECL_CHAIN (arg2), i++)
     875              :     {
     876       200481 :       if (!types_compatible_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
     877          239 :         return return_false_with_msg ("argument types are not compatible");
     878       200242 :       if (!param_used_p (i))
     879        34830 :         continue;
     880              :       /* Perform additional checks for used parameters.  */
     881       165412 :       if (!compatible_parm_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
     882              :         return false;
     883       165412 :       if (!m_checker->compare_decl (arg1, arg2))
     884            0 :         return return_false ();
     885              :     }
     886       127312 :   if (arg1 || arg2)
     887            0 :     return return_false_with_msg ("mismatched number of arguments");
     888              : 
     889       127312 :  if (DECL_STATIC_CHAIN (decl) != DECL_STATIC_CHAIN (m_compared_func->decl))
     890            0 :     return return_false_with_msg ("static chain mismatch");
     891              : 
     892       254624 :   if (!dyn_cast <cgraph_node *> (node)->has_gimple_body_p ())
     893              :     return true;
     894              : 
     895              :   /* Fill-up label dictionary.  */
     896      1449692 :   for (unsigned i = 0; i < bb_sorted.length (); ++i)
     897              :     {
     898       597534 :       m_checker->parse_labels (bb_sorted[i]);
     899       597534 :       m_checker->parse_labels (m_compared_func->bb_sorted[i]);
     900              :     }
     901              : 
     902              :   /* Checking all basic blocks.  */
     903       474691 :   for (unsigned i = 0; i < bb_sorted.length (); ++i)
     904       395228 :     if(!m_checker->compare_bb (bb_sorted[i], m_compared_func->bb_sorted[i]))
     905        47849 :       return return_false ();
     906              : 
     907        79463 :   auto_vec <int> bb_dict;
     908              : 
     909              :   /* Basic block edges check.  */
     910       839608 :   for (unsigned i = 0; i < bb_sorted.length (); ++i)
     911              :     {
     912       340349 :       bb1 = bb_sorted[i]->bb;
     913       340349 :       bb2 = m_compared_func->bb_sorted[i]->bb;
     914              : 
     915       340349 :       ei2 = ei_start (bb2->preds);
     916              : 
     917       770555 :       for (ei1 = ei_start (bb1->preds); ei_cond (ei1, &e1); ei_next (&ei1))
     918              :         {
     919       430214 :           ei_cond (ei2, &e2);
     920              : 
     921       430214 :           if (e1->flags != e2->flags)
     922            0 :             return return_false_with_msg ("flags comparison returns false");
     923              : 
     924       430214 :           if (!bb_dict_test (&bb_dict, e1->src->index, e2->src->index))
     925            8 :             return return_false_with_msg ("edge comparison returns false");
     926              : 
     927       430206 :           if (!bb_dict_test (&bb_dict, e1->dest->index, e2->dest->index))
     928            0 :             return return_false_with_msg ("BB comparison returns false");
     929              : 
     930       430206 :           if (!m_checker->compare_edge (e1, e2))
     931            0 :             return return_false_with_msg ("edge comparison returns false");
     932              : 
     933       430206 :           ei_next (&ei2);
     934              :         }
     935              :     }
     936              : 
     937              :   /* Basic block PHI nodes comparison.  */
     938       419585 :   for (unsigned i = 0; i < bb_sorted.length (); i++)
     939       340122 :     if (!compare_phi_node (bb_sorted[i]->bb, m_compared_func->bb_sorted[i]->bb))
     940           33 :       return return_false_with_msg ("PHI node comparison returns false");
     941              : 
     942              :   return result;
     943        79463 : }
     944              : 
     945              : /* Set LOCAL_P of NODE to true if DATA is non-NULL.
     946              :    Helper for call_for_symbol_thunks_and_aliases.  */
     947              : 
     948              : static bool
     949        59124 : set_local (cgraph_node *node, void *data)
     950              : {
     951        59124 :   node->local = data != NULL;
     952        59124 :   return false;
     953              : }
     954              : 
     955              : /* TREE_ADDRESSABLE of NODE to true.
     956              :    Helper for call_for_symbol_thunks_and_aliases.  */
     957              : 
     958              : static bool
     959          858 : set_addressable (varpool_node *node, void *)
     960              : {
     961          858 :   TREE_ADDRESSABLE (node->decl) = 1;
     962          858 :   return false;
     963              : }
     964              : 
     965              : /* Clear DECL_RTL of NODE.
     966              :    Helper for call_for_symbol_thunks_and_aliases.  */
     967              : 
     968              : static bool
     969        26443 : clear_decl_rtl (symtab_node *node, void *)
     970              : {
     971        26443 :   SET_DECL_RTL (node->decl, NULL);
     972        26443 :   return false;
     973              : }
     974              : 
     975              : /* Redirect all callers of N and its aliases to TO.  Remove aliases if
     976              :    possible.  Return number of redirections made.  */
     977              : 
     978              : static int
     979        16860 : redirect_all_callers (cgraph_node *n, cgraph_node *to)
     980              : {
     981        16860 :   int nredirected = 0;
     982        16860 :   ipa_ref *ref;
     983        16860 :   cgraph_edge *e = n->callers;
     984              : 
     985        17299 :   while (e)
     986              :     {
     987              :       /* Redirecting thunks to interposable symbols or symbols in other sections
     988              :          may not be supported by target output code.  Play safe for now and
     989              :          punt on redirection.  */
     990          439 :       if (!e->caller->thunk)
     991              :         {
     992          439 :           struct cgraph_edge *nexte = e->next_caller;
     993          439 :           e->redirect_callee (to);
     994          439 :           e = nexte;
     995          439 :           nredirected++;
     996              :         }
     997              :       else
     998            0 :         e = e->next_callee;
     999              :     }
    1000        16872 :   for (unsigned i = 0; n->iterate_direct_aliases (i, ref);)
    1001              :     {
    1002           12 :       bool removed = false;
    1003           12 :       cgraph_node *n_alias = dyn_cast <cgraph_node *> (ref->referring);
    1004              : 
    1005           12 :       if ((DECL_COMDAT_GROUP (n->decl)
    1006            0 :            && (DECL_COMDAT_GROUP (n->decl)
    1007            0 :                == DECL_COMDAT_GROUP (n_alias->decl)))
    1008           12 :           || (n_alias->get_availability () > AVAIL_INTERPOSABLE
    1009           12 :               && n->get_availability () > AVAIL_INTERPOSABLE))
    1010              :         {
    1011           12 :           nredirected += redirect_all_callers (n_alias, to);
    1012           12 :           if (n_alias->can_remove_if_no_direct_calls_p ()
    1013            0 :               && !n_alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
    1014              :                                                         NULL, true)
    1015           12 :               && !n_alias->has_aliases_p ())
    1016            0 :             n_alias->remove ();
    1017              :         }
    1018           12 :       if (!removed)
    1019           12 :         i++;
    1020              :     }
    1021        16860 :   return nredirected;
    1022              : }
    1023              : 
    1024              : /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
    1025              :    be applied.  */
    1026              : 
    1027              : bool
    1028        77985 : sem_function::merge (sem_item *alias_item)
    1029              : {
    1030        77985 :   gcc_assert (alias_item->type == FUNC);
    1031              : 
    1032        77985 :   sem_function *alias_func = static_cast<sem_function *> (alias_item);
    1033              : 
    1034        77985 :   cgraph_node *original = get_node ();
    1035        77985 :   cgraph_node *local_original = NULL;
    1036        77985 :   cgraph_node *alias = alias_func->get_node ();
    1037              : 
    1038        77985 :   bool create_wrapper = false;
    1039        77985 :   bool create_alias = false;
    1040        77985 :   bool redirect_callers = false;
    1041        77985 :   bool remove = false;
    1042              : 
    1043        77985 :   bool original_discardable = false;
    1044        77985 :   bool original_discarded = false;
    1045              : 
    1046        77985 :   bool original_address_matters = original->address_matters_p ();
    1047        77985 :   bool alias_address_matters = alias->address_matters_p ();
    1048              : 
    1049        77985 :   AUTO_DUMP_SCOPE ("merge",
    1050              :                    dump_user_location_t::from_function_decl (decl));
    1051              : 
    1052        77985 :   if (DECL_EXTERNAL (alias->decl))
    1053              :     {
    1054          104 :       if (dump_enabled_p ())
    1055            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    1056              :                      "Not unifying; alias is external.\n");
    1057              :       return false;
    1058              :     }
    1059              : 
    1060        77881 :   if (DECL_NO_INLINE_WARNING_P (original->decl)
    1061        77881 :       != DECL_NO_INLINE_WARNING_P (alias->decl))
    1062              :     {
    1063          373 :       if (dump_enabled_p ())
    1064            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    1065              :                      "Not unifying; DECL_NO_INLINE_WARNING mismatch.\n");
    1066              :       return false;
    1067              :     }
    1068              : 
    1069              :   /* Do not attempt to mix functions from different user sections;
    1070              :      we do not know what user intends with those.  */
    1071        77508 :   if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
    1072        77508 :        || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
    1073        77508 :       && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
    1074              :     {
    1075            0 :       if (dump_enabled_p ())
    1076            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    1077              :                      "Not unifying; "
    1078              :                      "original and alias are in different sections.\n");
    1079              :       return false;
    1080              :     }
    1081              : 
    1082        77508 :   if (!original->in_same_comdat_group_p (alias)
    1083        77508 :       || original->comdat_local_p ())
    1084              :     {
    1085         8737 :       if (dump_enabled_p ())
    1086            3 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    1087              :                      "Not unifying; alias nor wrapper cannot be created; "
    1088              :                      "across comdat group boundary\n");
    1089              :       return false;
    1090              :     }
    1091              : 
    1092              :   /* See if original is in a section that can be discarded if the main
    1093              :      symbol is not used.  */
    1094              : 
    1095        68771 :   if (original->can_be_discarded_p ())
    1096              :     original_discardable = true;
    1097              :   /* Also consider case where we have resolution info and we know that
    1098              :      original's definition is not going to be used.  In this case we cannot
    1099              :      create alias to original.  */
    1100        68771 :   if (node->resolution != LDPR_UNKNOWN
    1101        68771 :       && !decl_binds_to_current_def_p (node->decl))
    1102              :     original_discardable = original_discarded = true;
    1103              : 
    1104              :   /* Creating a symtab alias is the optimal way to merge.
    1105              :      It however cannot be used in the following cases:
    1106              : 
    1107              :      1) if ORIGINAL and ALIAS may be possibly compared for address equality.
    1108              :      2) if ORIGINAL is in a section that may be discarded by linker or if
    1109              :         it is an external functions where we cannot create an alias
    1110              :         (ORIGINAL_DISCARDABLE)
    1111              :      3) if target do not support symbol aliases.
    1112              :      4) original and alias lie in different comdat groups.
    1113              : 
    1114              :      If we cannot produce alias, we will turn ALIAS into WRAPPER of ORIGINAL
    1115              :      and/or redirect all callers from ALIAS to ORIGINAL.  */
    1116        68771 :   if ((original_address_matters && alias_address_matters)
    1117        13521 :       || (original_discardable
    1118            0 :           && (!DECL_COMDAT_GROUP (alias->decl)
    1119            0 :               || (DECL_COMDAT_GROUP (alias->decl)
    1120            0 :                   != DECL_COMDAT_GROUP (original->decl))))
    1121        13521 :       || original_discarded
    1122        13521 :       || !sem_item::target_supports_symbol_aliases_p ()
    1123        82292 :       || DECL_COMDAT_GROUP (alias->decl) != DECL_COMDAT_GROUP (original->decl))
    1124              :     {
    1125              :       /* First see if we can produce wrapper.  */
    1126              : 
    1127              :       /* Symbol properties that matter for references must be preserved.
    1128              :          TODO: We can produce wrapper, but we need to produce alias of ORIGINAL
    1129              :          with proper properties.  */
    1130        55250 :       if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
    1131        55250 :                                                            alias->address_taken))
    1132              :         {
    1133            7 :           if (dump_enabled_p ())
    1134            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1135              :                          "Wrapper cannot be created because referenced symbol "
    1136              :                          "properties mismatch\n");
    1137              :         }
    1138              :       /* Do not turn function in one comdat group into wrapper to another
    1139              :          comdat group. Other compiler producing the body of the
    1140              :          another comdat group may make opposite decision and with unfortunate
    1141              :          linker choices this may close a loop.  */
    1142        55243 :       else if (DECL_COMDAT_GROUP (original->decl)
    1143            0 :                && DECL_COMDAT_GROUP (alias->decl)
    1144        55243 :                && (DECL_COMDAT_GROUP (alias->decl)
    1145            0 :                    != DECL_COMDAT_GROUP (original->decl)))
    1146              :         {
    1147            0 :           if (dump_enabled_p ())
    1148            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1149              :                          "Wrapper cannot be created because of COMDAT\n");
    1150              :         }
    1151        55243 :       else if (DECL_STATIC_CHAIN (alias->decl)
    1152        55243 :                || DECL_STATIC_CHAIN (original->decl))
    1153              :         {
    1154            4 :           if (dump_enabled_p ())
    1155            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1156              :                          "Cannot create wrapper of nested function.\n");
    1157              :         }
    1158              :       /* TODO: We can also deal with variadic functions never calling
    1159              :          VA_START.  */
    1160        55239 :       else if (stdarg_p (TREE_TYPE (alias->decl)))
    1161              :         {
    1162            2 :           if (dump_enabled_p ())
    1163            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1164              :                          "cannot create wrapper of stdarg function.\n");
    1165              :         }
    1166        55237 :       else if (ipa_fn_summaries
    1167        55237 :                && ipa_size_summaries->get (alias) != NULL
    1168        55227 :                && ipa_size_summaries->get (alias)->self_size <= 2)
    1169              :         {
    1170           16 :           if (dump_enabled_p ())
    1171            0 :             dump_printf (MSG_MISSED_OPTIMIZATION, "Wrapper creation is not "
    1172              :                          "profitable (function is too small).\n");
    1173              :         }
    1174              :       /* If user paid attention to mark function noinline, assume it is
    1175              :          somewhat special and do not try to turn it into a wrapper that
    1176              :          cannot be undone by inliner.  */
    1177        55221 :       else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl)))
    1178              :         {
    1179        36477 :           if (dump_enabled_p ())
    1180           24 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1181              :                          "Wrappers are not created for noinline.\n");
    1182              :         }
    1183              :       else
    1184              :         create_wrapper = true;
    1185              : 
    1186              :       /* We can redirect local calls in the case both alias and original
    1187              :          are not interposable.  */
    1188        55250 :       redirect_callers
    1189        55250 :         = alias->get_availability () > AVAIL_INTERPOSABLE
    1190        55250 :           && original->get_availability () > AVAIL_INTERPOSABLE;
    1191              :       /* TODO: We can redirect, but we need to produce alias of ORIGINAL
    1192              :          with proper properties.  */
    1193        55250 :       if (!sem_item::compare_referenced_symbol_properties (NULL, original, alias,
    1194        55250 :                                                            alias->address_taken))
    1195            7 :         redirect_callers = false;
    1196              : 
    1197        55250 :       if (!redirect_callers && !create_wrapper)
    1198              :         {
    1199           22 :           if (dump_enabled_p ())
    1200            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1201              :                          "Not unifying; cannot redirect callers nor "
    1202              :                          "produce wrapper\n");
    1203              :           return false;
    1204              :         }
    1205              : 
    1206              :       /* Work out the symbol the wrapper should call.
    1207              :          If ORIGINAL is interposable, we need to call a local alias.
    1208              :          Also produce local alias (if possible) as an optimization.
    1209              : 
    1210              :          Local aliases cannot be created inside comdat groups because that
    1211              :          prevents inlining.  */
    1212        55228 :       if (!original_discardable && !original->get_comdat_group ())
    1213              :         {
    1214        55228 :           local_original
    1215        55228 :             = dyn_cast <cgraph_node *> (original->noninterposable_alias ());
    1216            0 :           if (!local_original
    1217            0 :               && original->get_availability () > AVAIL_INTERPOSABLE)
    1218              :             local_original = original;
    1219              :         }
    1220              :       /* If we cannot use local alias, fallback to the original
    1221              :          when possible.  */
    1222            0 :       else if (original->get_availability () > AVAIL_INTERPOSABLE)
    1223            0 :         local_original = original;
    1224              : 
    1225              :       /* If original is COMDAT local, we cannot really redirect calls outside
    1226              :          of its comdat group to it.  */
    1227        55228 :       if (original->comdat_local_p ())
    1228        55228 :         redirect_callers = false;
    1229        55228 :       if (!local_original)
    1230              :         {
    1231            0 :           if (dump_enabled_p ())
    1232            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1233              :                          "Not unifying; cannot produce local alias.\n");
    1234              :           return false;
    1235              :         }
    1236              : 
    1237        55228 :       if (!redirect_callers && !create_wrapper)
    1238              :         {
    1239            0 :           if (dump_enabled_p ())
    1240            0 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1241              :                          "Not unifying; "
    1242              :                          "cannot redirect callers nor produce a wrapper\n");
    1243              :           return false;
    1244              :         }
    1245        55228 :       if (!create_wrapper
    1246        36484 :           && !alias->call_for_symbol_and_aliases (cgraph_node::has_thunk_p,
    1247              :                                                   NULL, true)
    1248        91712 :           && !alias->can_remove_if_no_direct_calls_p ())
    1249              :         {
    1250        36484 :           if (dump_enabled_p ())
    1251           24 :             dump_printf (MSG_MISSED_OPTIMIZATION,
    1252              :                          "Not unifying; cannot make wrapper and "
    1253              :                          "function has other uses than direct calls\n");
    1254              :           return false;
    1255              :         }
    1256              :     }
    1257              :   else
    1258              :     create_alias = true;
    1259              : 
    1260        18744 :   if (redirect_callers)
    1261              :     {
    1262        16848 :       int nredirected = redirect_all_callers (alias, local_original);
    1263              : 
    1264        16848 :       if (nredirected)
    1265              :         {
    1266          343 :           alias->icf_merged = true;
    1267          343 :           local_original->icf_merged = true;
    1268              : 
    1269          343 :           if (dump_enabled_p ())
    1270            3 :             dump_printf (MSG_NOTE,
    1271              :                          "%i local calls have been "
    1272              :                          "redirected.\n", nredirected);
    1273              :         }
    1274              : 
    1275              :       /* If all callers was redirected, do not produce wrapper.  */
    1276        16848 :       if (alias->can_remove_if_no_direct_calls_p ()
    1277          139 :           && !DECL_VIRTUAL_P (alias->decl)
    1278        16987 :           && !alias->has_aliases_p ())
    1279              :         {
    1280              :           create_wrapper = false;
    1281              :           remove = true;
    1282              :         }
    1283              :       gcc_assert (!create_alias);
    1284              :     }
    1285        15417 :   else if (create_alias)
    1286              :     {
    1287        13521 :       alias->icf_merged = true;
    1288              : 
    1289              :       /* Remove the function's body.  */
    1290        13521 :       ipa_merge_profiles (original, alias);
    1291        13521 :       symtab->call_cgraph_removal_hooks (alias);
    1292        13521 :       alias->release_body (true);
    1293        13521 :       alias->reset ();
    1294              :       /* Notice global symbol possibly produced RTL.  */
    1295        13521 :       ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
    1296              :                                                            NULL, true);
    1297              : 
    1298              :       /* Create the alias.  */
    1299        13521 :       cgraph_node::create_alias (alias_func->decl, decl);
    1300        13521 :       alias->resolve_alias (original);
    1301              : 
    1302        13521 :       original->call_for_symbol_thunks_and_aliases
    1303        13521 :          (set_local, (void *)(size_t) original->local_p (), true);
    1304              : 
    1305        13521 :       if (dump_enabled_p ())
    1306           20 :         dump_printf (MSG_OPTIMIZED_LOCATIONS,
    1307              :                      "Unified; Function alias has been created.\n");
    1308              :     }
    1309        32265 :   if (create_wrapper)
    1310              :     {
    1311        18605 :       gcc_assert (!create_alias);
    1312        18605 :       alias->icf_merged = true;
    1313        18605 :       symtab->call_cgraph_removal_hooks (alias);
    1314        18605 :       local_original->icf_merged = true;
    1315              : 
    1316              :       /* FIXME update local_original counts.  */
    1317        18605 :       ipa_merge_profiles (original, alias, true);
    1318        18605 :       alias->create_wrapper (local_original);
    1319        18605 :       symtab->call_cgraph_insertion_hooks (alias);
    1320              : 
    1321        18605 :       if (dump_enabled_p ())
    1322           19 :         dump_printf (MSG_OPTIMIZED_LOCATIONS,
    1323              :                      "Unified; Wrapper has been created.\n");
    1324              :     }
    1325              : 
    1326              :   /* It's possible that redirection can hit thunks that block
    1327              :      redirection opportunities.  */
    1328        32265 :   gcc_assert (alias->icf_merged || remove || redirect_callers);
    1329        32265 :   original->icf_merged = true;
    1330              : 
    1331              :   /* We use merged flag to track cases where COMDAT function is known to be
    1332              :      compatible its callers.  If we merged in non-COMDAT, we need to give up
    1333              :      on this optimization.  */
    1334        32265 :   if (original->merged_comdat && !alias->merged_comdat)
    1335              :     {
    1336            0 :       if (dump_enabled_p ())
    1337            0 :         dump_printf (MSG_NOTE, "Dropping merged_comdat flag.\n");
    1338            0 :       if (local_original)
    1339            0 :         local_original->merged_comdat = false;
    1340            0 :       original->merged_comdat = false;
    1341              :     }
    1342              : 
    1343        32265 :   if (remove)
    1344              :     {
    1345          139 :       ipa_merge_profiles (original, alias);
    1346          139 :       alias->release_body ();
    1347          139 :       alias->reset ();
    1348          139 :       alias->body_removed = true;
    1349          139 :       alias->icf_merged = true;
    1350          139 :       if (dump_enabled_p ())
    1351            0 :         dump_printf (MSG_OPTIMIZED_LOCATIONS,
    1352              :                      "Unified; Function body was removed.\n");
    1353              :     }
    1354              : 
    1355              :   return true;
    1356              : }
    1357              : 
    1358              : /* Semantic item initialization function.  */
    1359              : 
    1360              : void
    1361      1127398 : sem_function::init (ipa_icf_gimple::func_checker *checker)
    1362              : {
    1363      1127398 :   m_checker = checker;
    1364      1127398 :   if (in_lto_p)
    1365        65524 :     get_node ()->get_untransformed_body ();
    1366              : 
    1367      1127398 :   tree fndecl = node->decl;
    1368      1127398 :   function *func = DECL_STRUCT_FUNCTION (fndecl);
    1369              : 
    1370      1127398 :   gcc_assert (func);
    1371      1127398 :   gcc_assert (SSANAMES (func));
    1372              : 
    1373      1127398 :   ssa_names_size = SSANAMES (func)->length ();
    1374              : 
    1375      1127398 :   decl = fndecl;
    1376      1127398 :   region_tree = func->eh->region_tree;
    1377              : 
    1378              :   /* iterating all function arguments.  */
    1379      1127398 :   arg_count = count_formal_params (fndecl);
    1380              : 
    1381      1127398 :   edge_count = n_edges_for_fn (func);
    1382      1127398 :   cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
    1383      1127398 :   if (!cnode->thunk)
    1384              :     {
    1385      1127398 :       cfg_checksum = coverage_compute_cfg_checksum (func);
    1386              : 
    1387      1127398 :       inchash::hash hstate;
    1388              : 
    1389      1127398 :       basic_block bb;
    1390      7975522 :       FOR_EACH_BB_FN (bb, func)
    1391              :       {
    1392      6848124 :         unsigned nondbg_stmt_count = 0;
    1393              : 
    1394      6848124 :         edge e;
    1395     15961901 :         for (edge_iterator ei = ei_start (bb->preds); ei_cond (ei, &e);
    1396      9113777 :              ei_next (&ei))
    1397      9113777 :           cfg_checksum = iterative_hash_host_wide_int (e->flags,
    1398              :                          cfg_checksum);
    1399              : 
    1400              :         /* TODO: We should be able to match PHIs with different order of
    1401              :            parameters.  This needs to be also updated in
    1402              :            sem_function::compare_phi_node.  */
    1403      6848124 :         gphi_iterator si;
    1404      7967951 :         for (si = gsi_start_nonvirtual_phis (bb); !gsi_end_p (si);
    1405      1119827 :              gsi_next_nonvirtual_phi (&si))
    1406              :           {
    1407      1119827 :             hstate.add_int (GIMPLE_PHI);
    1408      1119827 :             gphi *phi = si.phi ();
    1409      1119827 :             m_checker->hash_operand (gimple_phi_result (phi), hstate, 0,
    1410              :                                      func_checker::OP_NORMAL);
    1411      1119827 :             hstate.add_int (gimple_phi_num_args (phi));
    1412      3777603 :             for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
    1413      2657776 :               m_checker->hash_operand (gimple_phi_arg_def (phi, i),
    1414              :                                        hstate, 0, func_checker::OP_NORMAL);
    1415              :           }
    1416              : 
    1417     59076854 :         for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
    1418     45380606 :              gsi_next (&gsi))
    1419              :           {
    1420     45380606 :             gimple *stmt = gsi_stmt (gsi);
    1421              : 
    1422     45380606 :             if (gimple_code (stmt) != GIMPLE_DEBUG
    1423     45380606 :                 && gimple_code (stmt) != GIMPLE_PREDICT)
    1424              :               {
    1425     21718742 :                 hash_stmt (stmt, hstate);
    1426     21718742 :                 nondbg_stmt_count++;
    1427              :               }
    1428              :           }
    1429              : 
    1430      6848124 :         hstate.commit_flag ();
    1431      6848124 :         gcode_hash = hstate.end ();
    1432      6848124 :         bb_sizes.safe_push (nondbg_stmt_count);
    1433              : 
    1434              :         /* Inserting basic block to hash table.  */
    1435      6848124 :         sem_bb *semantic_bb = new sem_bb (bb, nondbg_stmt_count,
    1436     13696248 :                                           EDGE_COUNT (bb->preds)
    1437     20533588 :                                           + EDGE_COUNT (bb->succs));
    1438              : 
    1439      6848124 :         bb_sorted.safe_push (semantic_bb);
    1440              :       }
    1441              :     }
    1442              :   else
    1443              :     {
    1444            0 :       cfg_checksum = 0;
    1445            0 :       gcode_hash = thunk_info::get (cnode)->hash ();
    1446              :     }
    1447              : 
    1448      1127398 :   m_checker = NULL;
    1449      1127398 : }
    1450              : 
    1451              : /* Improve accumulated hash for HSTATE based on a gimple statement STMT.  */
    1452              : 
    1453              : void
    1454     21718742 : sem_function::hash_stmt (gimple *stmt, inchash::hash &hstate)
    1455              : {
    1456     21718742 :   enum gimple_code code = gimple_code (stmt);
    1457              : 
    1458     21718742 :   hstate.add_int (code);
    1459              : 
    1460     21718742 :   switch (code)
    1461              :     {
    1462        19821 :     case GIMPLE_SWITCH:
    1463        19821 :       m_checker->hash_operand (gimple_switch_index (as_a <gswitch *> (stmt)),
    1464              :                                hstate, 0, func_checker::OP_NORMAL);
    1465        19821 :       break;
    1466     13420789 :     case GIMPLE_ASSIGN:
    1467     13420789 :       hstate.add_int (gimple_assign_rhs_code (stmt));
    1468              :       /* fall through */
    1469     21218688 :     case GIMPLE_CALL:
    1470     21218688 :     case GIMPLE_ASM:
    1471     21218688 :     case GIMPLE_COND:
    1472     21218688 :     case GIMPLE_GOTO:
    1473     21218688 :     case GIMPLE_RETURN:
    1474     21218688 :       {
    1475     21218688 :         func_checker::operand_access_type_map map (5);
    1476     21218688 :         func_checker::classify_operands (stmt, &map);
    1477              : 
    1478              :         /* All these statements are equivalent if their operands are.  */
    1479    105952501 :         for (unsigned i = 0; i < gimple_num_ops (stmt); ++i)
    1480              :           {
    1481     63515125 :             func_checker::operand_access_type
    1482              :                 access_type = func_checker::get_operand_access_type
    1483     63515125 :                                           (&map, gimple_op (stmt, i));
    1484     63515125 :             m_checker->hash_operand (gimple_op (stmt, i), hstate, 0,
    1485              :                                      access_type);
    1486              :             /* For memory accesses when hashing for LTO streaming record
    1487              :                base and ref alias ptr types so we can compare them at WPA
    1488              :                time without having to read actual function body.  */
    1489     63515125 :             if (access_type == func_checker::OP_MEMORY
    1490      8447130 :                 && lto_streaming_expected_p ()
    1491     63839019 :                 && flag_strict_aliasing)
    1492              :               {
    1493       323376 :                 ao_ref ref;
    1494              : 
    1495       323376 :                 ao_ref_init (&ref, gimple_op (stmt, i));
    1496       323376 :                 tree t = ao_ref_alias_ptr_type (&ref);
    1497       323376 :                 if (!variably_modified_type_p (t, NULL_TREE))
    1498       323348 :                   memory_access_types.safe_push (t);
    1499       323376 :                 t = ao_ref_base_alias_ptr_type (&ref);
    1500       323376 :                 if (!variably_modified_type_p (t, NULL_TREE))
    1501       322965 :                   memory_access_types.safe_push (t);
    1502              :               }
    1503              :           }
    1504              :         /* Consider nocf_check attribute in hash as it affects code
    1505              :            generation.  */
    1506     21218688 :         if (code == GIMPLE_CALL
    1507      4101489 :             && flag_cf_protection & CF_BRANCH)
    1508      1886520 :           hstate.add_flag (gimple_call_nocf_check_p (as_a <gcall *> (stmt)));
    1509     21218688 :       }
    1510     21218688 :       break;
    1511              :     default:
    1512              :       break;
    1513              :     }
    1514     21718742 : }
    1515              : 
    1516              : 
    1517              : /* Return true if polymorphic comparison must be processed.  */
    1518              : 
    1519              : bool
    1520        68436 : sem_function::compare_polymorphic_p (void)
    1521              : {
    1522        68436 :   struct cgraph_edge *e;
    1523              : 
    1524       136872 :   if (!opt_for_fn (get_node ()->decl, flag_devirtualize))
    1525              :     return false;
    1526       136872 :   if (get_node ()->indirect_calls != NULL)
    1527              :     return true;
    1528              :   /* TODO: We can do simple propagation determining what calls may lead to
    1529              :      a polymorphic call.  */
    1530       152295 :   for (e = get_node ()->callees; e; e = e->next_callee)
    1531        71658 :     if (e->callee->definition
    1532        71658 :         && opt_for_fn (e->callee->decl, flag_devirtualize))
    1533              :       return true;
    1534              :   return false;
    1535              : }
    1536              : 
    1537              : /* For a given call graph NODE, the function constructs new
    1538              :    semantic function item.  */
    1539              : 
    1540              : sem_function *
    1541      1083405 : sem_function::parse (cgraph_node *node, bitmap_obstack *stack,
    1542              :                      func_checker *checker)
    1543              : {
    1544      1083405 :   tree fndecl = node->decl;
    1545      1083405 :   function *func = DECL_STRUCT_FUNCTION (fndecl);
    1546              : 
    1547      1083405 :   if (!func || (!node->has_gimple_body_p () && !node->thunk))
    1548              :     return NULL;
    1549              : 
    1550      1020015 :   if (lookup_attribute_by_prefix ("omp ", DECL_ATTRIBUTES (node->decl)) != NULL)
    1551              :     return NULL;
    1552              : 
    1553       998524 :   if (lookup_attribute_by_prefix ("oacc ",
    1554       998524 :                                   DECL_ATTRIBUTES (node->decl)) != NULL)
    1555              :     return NULL;
    1556              : 
    1557              :   /* PR ipa/70306.  */
    1558       998524 :   if (DECL_STATIC_CONSTRUCTOR (node->decl)
    1559       998524 :       || DECL_STATIC_DESTRUCTOR (node->decl))
    1560              :     return NULL;
    1561              : 
    1562       991071 :   sem_function *f = new sem_function (node, stack);
    1563       991071 :   f->init (checker);
    1564              : 
    1565       991071 :   return f;
    1566              : }
    1567              : 
    1568              : /* For given basic blocks BB1 and BB2 (from functions FUNC1 and FUNC),
    1569              :    return true if phi nodes are semantically equivalent in these blocks .  */
    1570              : 
    1571              : bool
    1572       340122 : sem_function::compare_phi_node (basic_block bb1, basic_block bb2)
    1573              : {
    1574       340122 :   gphi_iterator si1, si2;
    1575       340122 :   gphi *phi1, *phi2;
    1576       340122 :   unsigned size1, size2, i;
    1577       340122 :   tree t1, t2;
    1578       340122 :   edge e1, e2;
    1579              : 
    1580       340122 :   gcc_assert (bb1 != NULL);
    1581       340122 :   gcc_assert (bb2 != NULL);
    1582              : 
    1583       340122 :   si2 = gsi_start_nonvirtual_phis (bb2);
    1584       355291 :   for (si1 = gsi_start_nonvirtual_phis (bb1); !gsi_end_p (si1);
    1585        15169 :        gsi_next_nonvirtual_phi (&si1))
    1586              :     {
    1587        15202 :       if (gsi_end_p (si1) && gsi_end_p (si2))
    1588              :         break;
    1589              : 
    1590        15202 :       if (gsi_end_p (si1) || gsi_end_p (si2))
    1591            0 :         return return_false();
    1592              : 
    1593        15202 :       phi1 = si1.phi ();
    1594        15202 :       phi2 = si2.phi ();
    1595              : 
    1596        15202 :       tree phi_result1 = gimple_phi_result (phi1);
    1597        15202 :       tree phi_result2 = gimple_phi_result (phi2);
    1598              : 
    1599        15202 :       if (!m_checker->compare_operand (phi_result1, phi_result2,
    1600              :                                        func_checker::OP_NORMAL))
    1601            1 :         return return_false_with_msg ("PHI results are different");
    1602              : 
    1603        15201 :       size1 = gimple_phi_num_args (phi1);
    1604        15201 :       size2 = gimple_phi_num_args (phi2);
    1605              : 
    1606        15201 :       if (size1 != size2)
    1607            0 :         return return_false ();
    1608              : 
    1609              :       /* TODO: We should be able to match PHIs with different order of
    1610              :          parameters.  This needs to be also updated in sem_function::init.  */
    1611        49590 :       for (i = 0; i < size1; ++i)
    1612              :         {
    1613        34421 :           t1 = gimple_phi_arg (phi1, i)->def;
    1614        34421 :           t2 = gimple_phi_arg (phi2, i)->def;
    1615              : 
    1616        34421 :           if (!m_checker->compare_operand (t1, t2, func_checker::OP_NORMAL))
    1617           32 :             return return_false ();
    1618              : 
    1619        34389 :           e1 = gimple_phi_arg_edge (phi1, i);
    1620        34389 :           e2 = gimple_phi_arg_edge (phi2, i);
    1621              : 
    1622        34389 :           if (!m_checker->compare_edge (e1, e2))
    1623            0 :             return return_false ();
    1624              :         }
    1625              : 
    1626        15169 :       gsi_next_nonvirtual_phi (&si2);
    1627              :     }
    1628              : 
    1629              :   return true;
    1630              : }
    1631              : 
    1632              : /* Basic blocks dictionary BB_DICT returns true if SOURCE index BB
    1633              :    corresponds to TARGET.  */
    1634              : 
    1635              : bool
    1636       860420 : sem_function::bb_dict_test (vec<int> *bb_dict, int source, int target)
    1637              : {
    1638       860420 :   source++;
    1639       860420 :   target++;
    1640              : 
    1641       860420 :   if (bb_dict->length () <= (unsigned)source)
    1642       268900 :     bb_dict->safe_grow_cleared (source + 1, true);
    1643              : 
    1644       860420 :   if ((*bb_dict)[source] == 0)
    1645              :     {
    1646       282316 :       (*bb_dict)[source] = target;
    1647       282316 :       return true;
    1648              :     }
    1649              :   else
    1650       578104 :     return (*bb_dict)[source] == target;
    1651              : }
    1652              : 
    1653      2308308 : sem_variable::sem_variable (varpool_node *node, bitmap_obstack *stack)
    1654      2308308 : : sem_item (VAR, node, stack)
    1655              : {
    1656      2308308 :   gcc_checking_assert (node);
    1657      2308308 :   gcc_checking_assert (get_node ());
    1658      2308308 : }
    1659              : 
    1660              : /* Fast equality function based on knowledge known in WPA.  */
    1661              : 
    1662              : bool
    1663       442021 : sem_variable::equals_wpa (sem_item *item,
    1664              :                           hash_map <symtab_node *, sem_item *> &ignored_nodes)
    1665              : {
    1666       442021 :   gcc_assert (item->type == VAR);
    1667              : 
    1668       442021 :   if (node->must_remain_in_tu_name || item->node->must_remain_in_tu_name
    1669       442021 :       || node->must_remain_in_tu_body || item->node->must_remain_in_tu_body)
    1670            0 :     return return_false_with_msg ("must remain in TU");
    1671              : 
    1672       626025 :   if (node->num_references () != item->node->num_references ())
    1673            0 :     return return_false_with_msg ("different number of references");
    1674              : 
    1675       442021 :   if (DECL_TLS_MODEL (decl) || DECL_TLS_MODEL (item->decl))
    1676            0 :     return return_false_with_msg ("TLS model");
    1677              : 
    1678              :   /* DECL_ALIGN is safe to merge, because we will always chose the largest
    1679              :      alignment out of all aliases.  */
    1680              : 
    1681       442021 :   if (DECL_VIRTUAL_P (decl) != DECL_VIRTUAL_P (item->decl))
    1682            0 :     return return_false_with_msg ("Virtual flag mismatch");
    1683              : 
    1684       442021 :   if (DECL_SIZE (decl) != DECL_SIZE (item->decl)
    1685       442021 :       && ((!DECL_SIZE (decl) || !DECL_SIZE (item->decl))
    1686        14373 :           || !operand_equal_p (DECL_SIZE (decl),
    1687        14373 :                                DECL_SIZE (item->decl), OEP_ONLY_CONST)))
    1688        14373 :     return return_false_with_msg ("size mismatch");
    1689              : 
    1690              :   /* Do not attempt to mix data from different user sections;
    1691              :      we do not know what user intends with those.  */
    1692       835865 :   if (((DECL_SECTION_NAME (decl) && !node->implicit_section)
    1693       427647 :        || (DECL_SECTION_NAME (item->decl) && !item->node->implicit_section))
    1694       427649 :       && DECL_SECTION_NAME (decl) != DECL_SECTION_NAME (item->decl))
    1695            1 :     return return_false_with_msg ("user section mismatch");
    1696              : 
    1697       427647 :   if (DECL_IN_TEXT_SECTION (decl) != DECL_IN_TEXT_SECTION (item->decl))
    1698            0 :     return return_false_with_msg ("text section");
    1699              : 
    1700       427647 :   if (TYPE_ADDR_SPACE (TREE_TYPE (decl))
    1701       427647 :       != TYPE_ADDR_SPACE (TREE_TYPE (item->decl)))
    1702            0 :     return return_false_with_msg ("address-space");
    1703              : 
    1704       548957 :   ipa_ref *ref = NULL, *ref2 = NULL;
    1705       548957 :   for (unsigned i = 0; node->iterate_reference (i, ref); i++)
    1706              :     {
    1707       121527 :       item->node->iterate_reference (i, ref2);
    1708              : 
    1709       121527 :       if (ref->use != ref2->use)
    1710            0 :         return return_false_with_msg ("reference use mismatch");
    1711              : 
    1712       121527 :       if (!compare_symbol_references (ignored_nodes,
    1713              :                                       ref->referred, ref2->referred,
    1714              :                                       ref->address_matters_p ()))
    1715              :         return false;
    1716              :     }
    1717              : 
    1718              :   return true;
    1719              : }
    1720              : 
    1721              : /* Returns true if the item equals to ITEM given as argument.  */
    1722              : 
    1723              : bool
    1724       470080 : sem_variable::equals (sem_item *item,
    1725              :                       hash_map <symtab_node *, sem_item *> &)
    1726              : {
    1727       470080 :   gcc_assert (item->type == VAR);
    1728       470080 :   bool ret;
    1729              : 
    1730       470080 :   if (DECL_INITIAL (decl) == error_mark_node && in_lto_p)
    1731          144 :     dyn_cast <varpool_node *>(node)->get_constructor ();
    1732       470080 :   if (DECL_INITIAL (item->decl) == error_mark_node && in_lto_p)
    1733          304 :     dyn_cast <varpool_node *>(item->node)->get_constructor ();
    1734              : 
    1735              :   /* As seen in PR ipa/65303 we have to compare variables types.  */
    1736       470080 :   if (!func_checker::compatible_types_p (TREE_TYPE (decl),
    1737       470080 :                                          TREE_TYPE (item->decl)))
    1738        46673 :     return return_false_with_msg ("variables types are different");
    1739              : 
    1740       423407 :   ret = sem_variable::equals (DECL_INITIAL (decl),
    1741       423407 :                               DECL_INITIAL (item->node->decl));
    1742       423407 :   if (dump_file && (dump_flags & TDF_DETAILS))
    1743            6 :     fprintf (dump_file,
    1744              :              "Equals called for vars: %s:%s with result: %s\n\n",
    1745            3 :              node->dump_name (), item->node->dump_name (),
    1746              :              ret ? "true" : "false");
    1747              : 
    1748              :   return ret;
    1749              : }
    1750              : 
    1751              : /* Compares trees T1 and T2 for semantic equality.  */
    1752              : 
    1753              : bool
    1754      2023618 : sem_variable::equals (tree t1, tree t2)
    1755              : {
    1756      2407500 :   if (!t1 || !t2)
    1757         1735 :     return return_with_debug (t1 == t2);
    1758      2405765 :   if (t1 == t2)
    1759              :     return true;
    1760      1119983 :   tree_code tc1 = TREE_CODE (t1);
    1761      1119983 :   tree_code tc2 = TREE_CODE (t2);
    1762              : 
    1763      1119983 :   if (tc1 != tc2)
    1764            0 :     return return_false_with_msg ("TREE_CODE mismatch");
    1765              : 
    1766      1119983 :   switch (tc1)
    1767              :     {
    1768       418103 :     case CONSTRUCTOR:
    1769       418103 :       {
    1770       418103 :         vec<constructor_elt, va_gc> *v1, *v2;
    1771       418103 :         unsigned HOST_WIDE_INT idx;
    1772              : 
    1773       418103 :         enum tree_code typecode = TREE_CODE (TREE_TYPE (t1));
    1774       418103 :         if (typecode != TREE_CODE (TREE_TYPE (t2)))
    1775            0 :           return return_false_with_msg ("constructor type mismatch");
    1776              : 
    1777       418103 :         if (typecode == ARRAY_TYPE)
    1778              :           {
    1779       167492 :             HOST_WIDE_INT size_1 = int_size_in_bytes (TREE_TYPE (t1));
    1780              :             /* For arrays, check that the sizes all match.  */
    1781       167492 :             if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))
    1782       167492 :                 || size_1 == -1
    1783       334984 :                 || size_1 != int_size_in_bytes (TREE_TYPE (t2)))
    1784            0 :               return return_false_with_msg ("constructor array size mismatch");
    1785              :           }
    1786       250611 :         else if (!func_checker::compatible_types_p (TREE_TYPE (t1),
    1787       250611 :                                                     TREE_TYPE (t2)))
    1788            0 :           return return_false_with_msg ("constructor type incompatible");
    1789              : 
    1790       418103 :         v1 = CONSTRUCTOR_ELTS (t1);
    1791       418103 :         v2 = CONSTRUCTOR_ELTS (t2);
    1792      1131565 :         if (vec_safe_length (v1) != vec_safe_length (v2))
    1793            0 :           return return_false_with_msg ("constructor number of elts mismatch");
    1794              : 
    1795      1176213 :         for (idx = 0; idx < vec_safe_length (v1); ++idx)
    1796              :           {
    1797       760410 :             constructor_elt *c1 = &(*v1)[idx];
    1798       760410 :             constructor_elt *c2 = &(*v2)[idx];
    1799              : 
    1800              :             /* Check that each value is the same...  */
    1801       760410 :             if (!sem_variable::equals (c1->value, c2->value))
    1802              :               return false;
    1803              :             /* ... and that they apply to the same fields!  */
    1804       760407 :             if (!sem_variable::equals (c1->index, c2->index))
    1805              :               return false;
    1806              :           }
    1807              :         return true;
    1808              :       }
    1809            0 :     case MEM_REF:
    1810            0 :       {
    1811            0 :         tree x1 = TREE_OPERAND (t1, 0);
    1812            0 :         tree x2 = TREE_OPERAND (t2, 0);
    1813            0 :         tree y1 = TREE_OPERAND (t1, 1);
    1814            0 :         tree y2 = TREE_OPERAND (t2, 1);
    1815              : 
    1816            0 :         if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
    1817            0 :           return return_false ();
    1818              : 
    1819              :         /* Type of the offset on MEM_REF does not matter.  */
    1820            0 :         return return_with_debug (sem_variable::equals (x1, x2)
    1821              :                                   && known_eq (wi::to_poly_offset (y1),
    1822              :                                                wi::to_poly_offset (y2)));
    1823              :       }
    1824       383126 :     case ADDR_EXPR:
    1825       383126 :     case FDESC_EXPR:
    1826       383126 :       {
    1827       383126 :         tree op1 = TREE_OPERAND (t1, 0);
    1828       383126 :         tree op2 = TREE_OPERAND (t2, 0);
    1829       383126 :         return sem_variable::equals (op1, op2);
    1830              :       }
    1831              :     /* References to other vars/decls are compared using ipa-ref.  */
    1832            4 :     case FUNCTION_DECL:
    1833            4 :     case VAR_DECL:
    1834            4 :       if (decl_in_symtab_p (t1) && decl_in_symtab_p (t2))
    1835              :         return true;
    1836            0 :       return return_false_with_msg ("Declaration mismatch");
    1837         2268 :     case CONST_DECL:
    1838              :       /* TODO: We can check CONST_DECL by its DECL_INITIAL, but for that we
    1839              :          need to process its VAR/FUNCTION references without relying on ipa-ref
    1840              :          compare.  */
    1841         2268 :     case FIELD_DECL:
    1842         2268 :     case LABEL_DECL:
    1843         2268 :       return return_false_with_msg ("Declaration mismatch");
    1844          654 :     case INTEGER_CST:
    1845              :       /* Integer constants are the same only if the same width of type.  */
    1846          654 :       if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
    1847           29 :         return return_false_with_msg ("INTEGER_CST precision mismatch");
    1848          625 :       if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
    1849            0 :         return return_false_with_msg ("INTEGER_CST mode mismatch");
    1850          625 :       return return_with_debug (tree_int_cst_equal (t1, t2));
    1851       265869 :     case STRING_CST:
    1852       265869 :       if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2)))
    1853            0 :         return return_false_with_msg ("STRING_CST mode mismatch");
    1854       265869 :       if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2))
    1855            0 :         return return_false_with_msg ("STRING_CST length mismatch");
    1856       265869 :       if (memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
    1857       265869 :                     TREE_STRING_LENGTH (t1)))
    1858            0 :         return return_false_with_msg ("STRING_CST mismatch");
    1859              :       return true;
    1860            0 :     case FIXED_CST:
    1861              :       /* Fixed constants are the same only if the same width of type.  */
    1862            0 :       if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
    1863            0 :         return return_false_with_msg ("FIXED_CST precision mismatch");
    1864              : 
    1865            0 :       return return_with_debug (FIXED_VALUES_IDENTICAL (TREE_FIXED_CST (t1),
    1866              :                                                         TREE_FIXED_CST (t2)));
    1867         2528 :     case COMPLEX_CST:
    1868         2528 :       return (sem_variable::equals (TREE_REALPART (t1), TREE_REALPART (t2))
    1869         5056 :               && sem_variable::equals (TREE_IMAGPART (t1), TREE_IMAGPART (t2)));
    1870        28060 :     case REAL_CST:
    1871              :       /* Real constants are the same only if the same width of type.  */
    1872        28060 :       if (TYPE_PRECISION (TREE_TYPE (t1)) != TYPE_PRECISION (TREE_TYPE (t2)))
    1873            0 :         return return_false_with_msg ("REAL_CST precision mismatch");
    1874        28060 :       return return_with_debug (real_identical (&TREE_REAL_CST (t1),
    1875              :                                                 &TREE_REAL_CST (t2)));
    1876           30 :     case VECTOR_CST:
    1877           30 :       {
    1878           30 :         if (maybe_ne (VECTOR_CST_NELTS (t1), VECTOR_CST_NELTS (t2)))
    1879            0 :           return return_false_with_msg ("VECTOR_CST nelts mismatch");
    1880              : 
    1881           30 :         unsigned int count
    1882           30 :           = tree_vector_builder::binary_encoded_nelts (t1, t2);
    1883          132 :         for (unsigned int i = 0; i < count; ++i)
    1884          144 :           if (!sem_variable::equals (VECTOR_CST_ENCODED_ELT (t1, i),
    1885           72 :                                      VECTOR_CST_ENCODED_ELT (t2, i)))
    1886              :             return false;
    1887              : 
    1888              :         return true;
    1889              :       }
    1890        18551 :     case ARRAY_REF:
    1891        18551 :     case ARRAY_RANGE_REF:
    1892        18551 :       {
    1893        18551 :         tree x1 = TREE_OPERAND (t1, 0);
    1894        18551 :         tree x2 = TREE_OPERAND (t2, 0);
    1895        18551 :         tree y1 = TREE_OPERAND (t1, 1);
    1896        18551 :         tree y2 = TREE_OPERAND (t2, 1);
    1897              : 
    1898        18551 :         if (!sem_variable::equals (x1, x2) || !sem_variable::equals (y1, y2))
    1899              :           return false;
    1900        18551 :         if (!sem_variable::equals (array_ref_low_bound (t1),
    1901              :                                    array_ref_low_bound (t2)))
    1902              :           return false;
    1903        18551 :         if (!sem_variable::equals (array_ref_element_size (t1),
    1904              :                                    array_ref_element_size (t2)))
    1905              :           return false;
    1906              :         return true;
    1907              :       }
    1908              : 
    1909           31 :     case COMPONENT_REF:
    1910           31 :     case POINTER_PLUS_EXPR:
    1911           31 :     case PLUS_EXPR:
    1912           31 :     case MINUS_EXPR:
    1913           31 :     case RANGE_EXPR:
    1914           31 :       {
    1915           31 :         tree x1 = TREE_OPERAND (t1, 0);
    1916           31 :         tree x2 = TREE_OPERAND (t2, 0);
    1917           31 :         tree y1 = TREE_OPERAND (t1, 1);
    1918           31 :         tree y2 = TREE_OPERAND (t2, 1);
    1919              : 
    1920           31 :         return sem_variable::equals (x1, x2) && sem_variable::equals (y1, y2);
    1921              :       }
    1922              : 
    1923          756 :     CASE_CONVERT:
    1924          756 :     case VIEW_CONVERT_EXPR:
    1925          756 :       if (!func_checker::compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
    1926            0 :           return return_false ();
    1927          756 :       return sem_variable::equals (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
    1928            0 :     case ERROR_MARK:
    1929            0 :       return return_false_with_msg ("ERROR_MARK");
    1930            3 :     default:
    1931            3 :       return return_false_with_msg ("Unknown TREE code reached");
    1932              :     }
    1933              : }
    1934              : 
    1935              : /* Parser function that visits a varpool NODE.  */
    1936              : 
    1937              : sem_variable *
    1938      2352572 : sem_variable::parse (varpool_node *node, bitmap_obstack *stack,
    1939              :                      func_checker *checker)
    1940              : {
    1941      2288161 :   if (TREE_THIS_VOLATILE (node->decl) || DECL_HARD_REGISTER (node->decl)
    1942      4640681 :       || node->alias)
    1943              :     return NULL;
    1944              : 
    1945      2288024 :   sem_variable *v = new sem_variable (node, stack);
    1946      2288024 :   v->init (checker);
    1947              : 
    1948      2288024 :   return v;
    1949              : }
    1950              : 
    1951              : /* Semantic variable initialization function.  */
    1952              : 
    1953              : void
    1954      2796550 : sem_variable::init (ipa_icf_gimple::func_checker *checker)
    1955              : {
    1956      2796550 :   decl = get_node ()->decl;
    1957              : 
    1958              :   /* All WPA streamed in symbols should have their hashes computed at compile
    1959              :      time.  At this point, the constructor may not be in memory at all.
    1960              :      DECL_INITIAL (decl) would be error_mark_node in that case.  */
    1961      2796550 :   if (!m_hash_set)
    1962              :     {
    1963      2288024 :       gcc_assert (!node->lto_file_data);
    1964      2288024 :       inchash::hash hstate;
    1965      2288024 :       hstate.add_int (456346417);
    1966      2288024 :       checker->hash_operand (DECL_INITIAL (decl), hstate, 0);
    1967      2288024 :       set_hash (hstate.end ());
    1968              :     }
    1969      2796550 : }
    1970              : 
    1971              : /* References independent hash function.  */
    1972              : 
    1973              : hashval_t
    1974      8799481 : sem_variable::get_hash (void)
    1975              : {
    1976      8799481 :   gcc_checking_assert (m_hash_set);
    1977      8799481 :   return m_hash;
    1978              : }
    1979              : 
    1980              : /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can
    1981              :    be applied.  */
    1982              : 
    1983              : bool
    1984       421084 : sem_variable::merge (sem_item *alias_item)
    1985              : {
    1986       421084 :   gcc_assert (alias_item->type == VAR);
    1987              : 
    1988       421084 :   AUTO_DUMP_SCOPE ("merge",
    1989              :                    dump_user_location_t::from_function_decl (decl));
    1990       421084 :   if (!sem_item::target_supports_symbol_aliases_p ())
    1991              :     {
    1992            0 :       if (dump_enabled_p ())
    1993            0 :         dump_printf (MSG_MISSED_OPTIMIZATION, "Not unifying; "
    1994              :                      "Symbol aliases are not supported by target\n");
    1995              :       return false;
    1996              :     }
    1997              : 
    1998       421084 :   if (DECL_EXTERNAL (alias_item->decl))
    1999              :     {
    2000            0 :       if (dump_enabled_p ())
    2001            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2002              :                      "Not unifying; alias is external.\n");
    2003              :       return false;
    2004              :     }
    2005              : 
    2006       421084 :   sem_variable *alias_var = static_cast<sem_variable *> (alias_item);
    2007              : 
    2008       421084 :   varpool_node *original = get_node ();
    2009       421084 :   varpool_node *alias = alias_var->get_node ();
    2010       421084 :   bool original_discardable = false;
    2011              : 
    2012       421084 :   bool alias_address_matters = alias->address_matters_p ();
    2013              : 
    2014              :   /* See if original is in a section that can be discarded if the main
    2015              :      symbol is not used.
    2016              :      Also consider case where we have resolution info and we know that
    2017              :      original's definition is not going to be used.  In this case we cannot
    2018              :      create alias to original.  */
    2019       421084 :   if (original->can_be_discarded_p ()
    2020       421084 :       || (node->resolution != LDPR_UNKNOWN
    2021       419269 :           && !decl_binds_to_current_def_p (node->decl)))
    2022              :     original_discardable = true;
    2023              : 
    2024       421084 :   gcc_assert (!TREE_ASM_WRITTEN (alias->decl));
    2025              : 
    2026              :   /* Constant pool machinery is not quite ready for aliases.
    2027              :      TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL.
    2028              :      For LTO merging does not happen that is an important missing feature.
    2029              :      We can enable merging with LTO if the DECL_IN_CONSTANT_POOL
    2030              :      flag is dropped and non-local symbol name is assigned.  */
    2031       421084 :   if (DECL_IN_CONSTANT_POOL (alias->decl)
    2032       421084 :       || DECL_IN_CONSTANT_POOL (original->decl))
    2033              :     {
    2034            3 :       if (dump_enabled_p ())
    2035            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2036              :                      "Not unifying; constant pool variables.\n");
    2037              :       return false;
    2038              :     }
    2039              : 
    2040              :   /* Do not attempt to mix functions from different user sections;
    2041              :      we do not know what user intends with those.  */
    2042       825753 :   if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section)
    2043       421081 :        || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section))
    2044       421081 :       && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl))
    2045              :     {
    2046            0 :       if (dump_enabled_p ())
    2047            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2048              :                      "Not unifying; "
    2049              :                      "original and alias are in different sections.\n");
    2050              :       return false;
    2051              :     }
    2052              : 
    2053              :   /* We cannot merge if address comparison matters.  */
    2054       421081 :   if (alias_address_matters && flag_merge_constants < 2)
    2055              :     {
    2056       408093 :       if (dump_enabled_p ())
    2057            1 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2058              :                      "Not unifying; address of original may be compared.\n");
    2059              :       return false;
    2060              :     }
    2061              : 
    2062        12988 :   if (DECL_ALIGN (original->decl) != DECL_ALIGN (alias->decl)
    2063        12988 :       && (sanitize_flags_p (SANITIZE_ADDRESS, original->decl)
    2064            0 :           || sanitize_flags_p (SANITIZE_ADDRESS, alias->decl)))
    2065              :     {
    2066           14 :       if (dump_enabled_p ())
    2067            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2068              :                      "Not unifying; "
    2069              :                      "ASAN requires equal alignments for original and alias\n");
    2070              : 
    2071              :       return false;
    2072              :     }
    2073              : 
    2074        12974 :   if (DECL_ALIGN (original->decl) < DECL_ALIGN (alias->decl))
    2075              :     {
    2076            0 :       if (dump_enabled_p ())
    2077            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2078              :                      "Not unifying; "
    2079              :                      "original and alias have incompatible alignments\n");
    2080              : 
    2081              :       return false;
    2082              :     }
    2083              : 
    2084        12974 :   if (DECL_COMDAT_GROUP (original->decl) != DECL_COMDAT_GROUP (alias->decl))
    2085              :     {
    2086           84 :       if (dump_enabled_p ())
    2087            0 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2088              :                      "Not unifying; alias cannot be created; "
    2089              :                      "across comdat group boundary\n");
    2090              : 
    2091              :       return false;
    2092              :     }
    2093              : 
    2094        12890 :   if (original_discardable)
    2095              :     {
    2096            4 :       if (dump_enabled_p ())
    2097            1 :         dump_printf (MSG_MISSED_OPTIMIZATION,
    2098              :                      "Not unifying; alias cannot be created; "
    2099              :                      "target is discardable\n");
    2100              : 
    2101              :       return false;
    2102              :     }
    2103              :   else
    2104              :     {
    2105        12886 :       gcc_assert (!original->alias);
    2106        12886 :       gcc_assert (!alias->alias);
    2107              : 
    2108        12886 :       alias->analyzed = false;
    2109              : 
    2110        12886 :       DECL_INITIAL (alias->decl) = NULL;
    2111        12886 :       ((symtab_node *)alias)->call_for_symbol_and_aliases (clear_decl_rtl,
    2112              :                                                            NULL, true);
    2113        12886 :       alias->remove_all_references ();
    2114        12886 :       if (TREE_ADDRESSABLE (alias->decl))
    2115          480 :         original->call_for_symbol_and_aliases (set_addressable, NULL, true);
    2116              : 
    2117        12886 :       varpool_node::create_alias (alias_var->decl, decl);
    2118        12886 :       alias->resolve_alias (original);
    2119              : 
    2120        12886 :       if (dump_enabled_p ())
    2121           17 :         dump_printf (MSG_OPTIMIZED_LOCATIONS,
    2122              :                      "Unified; Variable alias has been created.\n");
    2123              : 
    2124              :       return true;
    2125              :     }
    2126              : }
    2127              : 
    2128              : /* Dump symbol to FILE.  */
    2129              : 
    2130              : void
    2131            6 : sem_variable::dump_to_file (FILE *file)
    2132              : {
    2133            6 :   gcc_assert (file);
    2134              : 
    2135            6 :   print_node (file, "", decl, 0);
    2136            6 :   fprintf (file, "\n\n");
    2137            6 : }
    2138              : 
    2139              : unsigned int sem_item_optimizer::class_id = 0;
    2140              : 
    2141       140617 : sem_item_optimizer::sem_item_optimizer ()
    2142       140617 : : worklist (0), m_classes (0), m_classes_count (0), m_cgraph_node_hooks (NULL),
    2143       140617 :   m_varpool_node_hooks (NULL), m_merged_variables (), m_references ()
    2144              : {
    2145       140617 :   m_items.create (0);
    2146       140617 :   bitmap_obstack_initialize (&m_bmstack);
    2147       140617 : }
    2148              : 
    2149       131334 : sem_item_optimizer::~sem_item_optimizer ()
    2150              : {
    2151      2643729 :   for (unsigned int i = 0; i < m_items.length (); i++)
    2152      2512395 :     delete m_items[i];
    2153              : 
    2154              : 
    2155      2036300 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    2156      2036300 :        it != m_classes.end (); ++it)
    2157              :     {
    2158      3917508 :       for (unsigned int i = 0; i < (*it)->classes.length (); i++)
    2159      4025084 :         delete (*it)->classes[i];
    2160              : 
    2161      1904966 :       (*it)->classes.release ();
    2162      1904966 :       free (*it);
    2163              :     }
    2164              : 
    2165       131334 :   m_items.release ();
    2166              : 
    2167       131334 :   bitmap_obstack_release (&m_bmstack);
    2168       131334 :   m_merged_variables.release ();
    2169       131334 : }
    2170              : 
    2171              : /* Write IPA ICF summary for symbols.  */
    2172              : 
    2173              : void
    2174        20319 : sem_item_optimizer::write_summary (void)
    2175              : {
    2176        20319 :   unsigned int count = 0;
    2177              : 
    2178        20319 :   output_block *ob = create_output_block (LTO_section_ipa_icf);
    2179        20319 :   lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
    2180        20319 :   ob->symbol = NULL;
    2181              : 
    2182              :   /* Calculate number of symbols to be serialized.  */
    2183        20319 :   for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
    2184       370301 :        !lsei_end_p (lsei);
    2185       349982 :        lsei_next_in_partition (&lsei))
    2186              :     {
    2187       349982 :       symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
    2188       349982 :       if (!node)
    2189           56 :         continue;
    2190              : 
    2191       349926 :       if (m_symtab_node_map.get (node))
    2192       326074 :         count++;
    2193              :     }
    2194              : 
    2195        20319 :   streamer_write_uhwi (ob, count);
    2196              : 
    2197              :   /* Process all of the symbols.  */
    2198        20319 :   for (lto_symtab_encoder_iterator lsei = lsei_start_in_partition (encoder);
    2199       370301 :        !lsei_end_p (lsei);
    2200       349982 :        lsei_next_in_partition (&lsei))
    2201              :     {
    2202       349982 :       symtab_node *node = dyn_cast <symtab_node *> (lsei_node (lsei));
    2203       349982 :       if (!node)
    2204           56 :         continue;
    2205              : 
    2206       349926 :       sem_item **item = m_symtab_node_map.get (node);
    2207              : 
    2208       349926 :       if (item && *item)
    2209              :         {
    2210       326074 :           int node_ref = lto_symtab_encoder_encode (encoder, node);
    2211       326074 :           streamer_write_uhwi_stream (ob->main_stream, node_ref);
    2212              : 
    2213       326074 :           streamer_write_uhwi (ob, (*item)->get_hash ());
    2214              : 
    2215       326074 :           if ((*item)->type == FUNC)
    2216              :             {
    2217        93294 :               sem_function *fn = static_cast<sem_function *> (*item);
    2218        93294 :               streamer_write_uhwi (ob, fn->memory_access_types.length ());
    2219      1079459 :               for (unsigned i = 0; i < fn->memory_access_types.length (); i++)
    2220       636239 :                 stream_write_tree (ob, fn->memory_access_types[i], true);
    2221              :             }
    2222              :         }
    2223              :     }
    2224              : 
    2225        20319 :   streamer_write_char_stream (ob->main_stream, 0);
    2226        20319 :   produce_asm (ob);
    2227        20319 :   destroy_output_block (ob);
    2228        20319 : }
    2229              : 
    2230              : /* Reads a section from LTO stream file FILE_DATA. Input block for DATA
    2231              :    contains LEN bytes.  */
    2232              : 
    2233              : void
    2234        11131 : sem_item_optimizer::read_section (lto_file_decl_data *file_data,
    2235              :                                   const char *data, size_t len)
    2236              : {
    2237        11131 :   const lto_function_header *header
    2238              :     = (const lto_function_header *) data;
    2239        11131 :   const int cfg_offset = sizeof (lto_function_header);
    2240        11131 :   const int main_offset = cfg_offset + header->cfg_size;
    2241        11131 :   const int string_offset = main_offset + header->main_size;
    2242        11131 :   data_in *data_in;
    2243        11131 :   unsigned int i;
    2244        11131 :   unsigned int count;
    2245              : 
    2246        11131 :   lto_input_block ib_main ((const char *) data + main_offset, 0,
    2247        11131 :                            header->main_size, file_data);
    2248              : 
    2249        11131 :   data_in
    2250        22262 :     = lto_data_in_create (file_data, (const char *) data + string_offset,
    2251        11131 :                           header->string_size, vNULL);
    2252              : 
    2253        11131 :   count = streamer_read_uhwi (&ib_main);
    2254              : 
    2255       109426 :   for (i = 0; i < count; i++)
    2256              :     {
    2257        98295 :       unsigned int index;
    2258        98295 :       toplevel_node *node;
    2259        98295 :       lto_symtab_encoder_t encoder;
    2260              : 
    2261        98295 :       index = streamer_read_uhwi (&ib_main);
    2262        98295 :       encoder = file_data->symtab_node_encoder;
    2263        98295 :       node = lto_symtab_encoder_deref (encoder, index);
    2264              : 
    2265        98295 :       hashval_t hash = streamer_read_uhwi (&ib_main);
    2266        98295 :       if (symtab_node *snode = dyn_cast <symtab_node *> (node))
    2267        98295 :         gcc_assert (snode->definition);
    2268              : 
    2269        98295 :       if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
    2270              :         {
    2271        78011 :           sem_function *fn = new sem_function (cnode, &m_bmstack);
    2272        78011 :           unsigned count = streamer_read_uhwi (&ib_main);
    2273        78011 :           inchash::hash hstate (0);
    2274        78011 :           if (flag_incremental_link == INCREMENTAL_LINK_LTO)
    2275           49 :             fn->memory_access_types.reserve_exact (count);
    2276       618060 :           for (unsigned i = 0; i < count; i++)
    2277              :             {
    2278       540049 :               tree type = stream_read_tree (&ib_main, data_in);
    2279       540049 :               hstate.add_int (get_deref_alias_set (type));
    2280       540049 :               if (flag_incremental_link == INCREMENTAL_LINK_LTO)
    2281          138 :                 fn->memory_access_types.quick_push (type);
    2282              :             }
    2283        78011 :           fn->m_alias_sets_hash = hstate.end ();
    2284        78011 :           fn->set_hash (hash);
    2285        78011 :           m_items.safe_push (fn);
    2286              :         }
    2287       118579 :       else if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
    2288              :         {
    2289        20284 :           sem_variable *var = new sem_variable (vnode, &m_bmstack);
    2290        20284 :           var->set_hash (hash);
    2291        20284 :           m_items.safe_push (var);
    2292              :         }
    2293              :     }
    2294              : 
    2295        11131 :   lto_free_section_data (file_data, LTO_section_ipa_icf, NULL, data,
    2296              :                          len);
    2297        11131 :   lto_data_in_delete (data_in);
    2298        11131 : }
    2299              : 
    2300              : /* Read IPA ICF summary for symbols.  */
    2301              : 
    2302              : void
    2303        12468 : sem_item_optimizer::read_summary (void)
    2304              : {
    2305        12468 :   lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
    2306        12468 :   lto_file_decl_data *file_data;
    2307        12468 :   unsigned int j = 0;
    2308              : 
    2309        38496 :   while ((file_data = file_data_vec[j++]))
    2310              :     {
    2311        13560 :       size_t len;
    2312        13560 :       const char *data
    2313        13560 :         = lto_get_summary_section_data (file_data, LTO_section_ipa_icf, &len);
    2314        13560 :       if (data)
    2315        11131 :         read_section (file_data, data, len);
    2316              :     }
    2317        12468 : }
    2318              : 
    2319              : /* Register callgraph and varpool hooks.  */
    2320              : 
    2321              : void
    2322       140617 : sem_item_optimizer::register_hooks (void)
    2323              : {
    2324       140617 :   if (!m_cgraph_node_hooks)
    2325       140617 :     m_cgraph_node_hooks = symtab->add_cgraph_removal_hook
    2326       140617 :                           (&sem_item_optimizer::cgraph_removal_hook, this);
    2327              : 
    2328       140617 :   if (!m_varpool_node_hooks)
    2329       140617 :     m_varpool_node_hooks = symtab->add_varpool_removal_hook
    2330       140617 :                            (&sem_item_optimizer::varpool_removal_hook, this);
    2331       140617 : }
    2332              : 
    2333              : /* Unregister callgraph and varpool hooks.  */
    2334              : 
    2335              : void
    2336       131334 : sem_item_optimizer::unregister_hooks (void)
    2337              : {
    2338       131334 :   if (m_cgraph_node_hooks)
    2339       131334 :     symtab->remove_cgraph_removal_hook (m_cgraph_node_hooks);
    2340              : 
    2341       131334 :   if (m_varpool_node_hooks)
    2342       131334 :     symtab->remove_varpool_removal_hook (m_varpool_node_hooks);
    2343       131334 : }
    2344              : 
    2345              : /* Adds a CLS to hashtable associated by hash value.  */
    2346              : 
    2347              : void
    2348        35880 : sem_item_optimizer::add_class (congruence_class *cls)
    2349              : {
    2350        35880 :   gcc_assert (cls->members.length ());
    2351              : 
    2352        35880 :   congruence_class_group *group
    2353        35880 :     = get_group_by_hash (cls->members[0]->get_hash (),
    2354        35880 :                          cls->members[0]->type);
    2355        35880 :   group->classes.safe_push (cls);
    2356        35880 : }
    2357              : 
    2358              : /* Gets a congruence class group based on given HASH value and TYPE.  */
    2359              : 
    2360              : congruence_class_group *
    2361      2548275 : sem_item_optimizer::get_group_by_hash (hashval_t hash, sem_item_type type)
    2362              : {
    2363      2548275 :   congruence_class_group *item = XNEW (congruence_class_group);
    2364      2548275 :   item->hash = hash;
    2365      2548275 :   item->type = type;
    2366              : 
    2367      2548275 :   congruence_class_group **slot = m_classes.find_slot (item, INSERT);
    2368              : 
    2369      2548275 :   if (*slot)
    2370       643309 :     free (item);
    2371              :   else
    2372              :     {
    2373      1904966 :       item->classes.create (1);
    2374      1904966 :       *slot = item;
    2375              :     }
    2376              : 
    2377      2548275 :   return *slot;
    2378              : }
    2379              : 
    2380              : /* Callgraph removal hook called for a NODE with a custom DATA.  */
    2381              : 
    2382              : void
    2383        11339 : sem_item_optimizer::cgraph_removal_hook (cgraph_node *node, void *data)
    2384              : {
    2385        11339 :   sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
    2386        11339 :   optimizer->remove_symtab_node (node);
    2387        11339 : }
    2388              : 
    2389              : /* Varpool removal hook called for a NODE with a custom DATA.  */
    2390              : 
    2391              : void
    2392         3415 : sem_item_optimizer::varpool_removal_hook (varpool_node *node, void *data)
    2393              : {
    2394         3415 :   sem_item_optimizer *optimizer = (sem_item_optimizer *) data;
    2395         3415 :   optimizer->remove_symtab_node (node);
    2396         3415 : }
    2397              : 
    2398              : /* Remove symtab NODE triggered by symtab removal hooks.  */
    2399              : 
    2400              : void
    2401        14754 : sem_item_optimizer::remove_symtab_node (symtab_node *node)
    2402              : {
    2403        14754 :   gcc_assert (m_classes.is_empty ());
    2404              : 
    2405        14754 :   m_removed_items_set.add (node);
    2406        14754 : }
    2407              : 
    2408              : void
    2409       709523 : sem_item_optimizer::remove_item (sem_item *item)
    2410              : {
    2411       709523 :   if (m_symtab_node_map.get (item->node))
    2412       685801 :     m_symtab_node_map.remove (item->node);
    2413       709523 :   delete item;
    2414       709523 : }
    2415              : 
    2416              : /* Removes all callgraph and varpool nodes that are marked by symtab
    2417              :    as deleted.  */
    2418              : 
    2419              : void
    2420       131334 : sem_item_optimizer::filter_removed_items (void)
    2421              : {
    2422       131334 :   auto_vec <sem_item *> filtered;
    2423              : 
    2424      3353252 :   for (unsigned int i = 0; i < m_items.length(); i++)
    2425              :     {
    2426      3221918 :       sem_item *item = m_items[i];
    2427              : 
    2428      3221918 :       if (m_removed_items_set.contains (item->node))
    2429              :         {
    2430         8958 :           remove_item (item);
    2431         8958 :           continue;
    2432              :         }
    2433              : 
    2434      3212960 :       if (item->type == FUNC)
    2435              :         {
    2436      1020099 :           cgraph_node *cnode = static_cast <sem_function *>(item)->get_node ();
    2437              : 
    2438      1020099 :           if (in_lto_p && (cnode->alias || cnode->body_removed))
    2439           11 :             remove_item (item);
    2440              :           else
    2441      1020088 :             filtered.safe_push (item);
    2442              :         }
    2443              :       else /* VAR.  */
    2444              :         {
    2445      2192861 :           if (!flag_ipa_icf_variables)
    2446            1 :             remove_item (item);
    2447              :           else
    2448              :             {
    2449              :               /* Filter out non-readonly variables.  */
    2450      2192860 :               tree decl = item->decl;
    2451      2192860 :               varpool_node *vnode = static_cast <sem_variable *>(item)->get_node ();
    2452      2192860 :               if (!TREE_READONLY (decl) || vnode->body_removed)
    2453       700553 :                 remove_item (item);
    2454              :               else
    2455      1492307 :                 filtered.safe_push (item);
    2456              :             }
    2457              :         }
    2458              :     }
    2459              : 
    2460              :   /* Clean-up of released semantic items.  */
    2461              : 
    2462       131334 :   m_items.release ();
    2463      2775063 :   for (unsigned int i = 0; i < filtered.length(); i++)
    2464      2512395 :     m_items.safe_push (filtered[i]);
    2465       131334 : }
    2466              : 
    2467              : /* Optimizer entry point which returns true in case it processes
    2468              :    a merge operation. True is returned if there's a merge operation
    2469              :    processed.  */
    2470              : 
    2471              : bool
    2472       131334 : sem_item_optimizer::execute (void)
    2473              : {
    2474       131334 :   filter_removed_items ();
    2475       131334 :   unregister_hooks ();
    2476              : 
    2477       131334 :   build_graph ();
    2478       131334 :   update_hash_by_addr_refs ();
    2479       131334 :   update_hash_by_memory_access_type ();
    2480       131334 :   build_hash_based_classes ();
    2481              : 
    2482       131334 :   if (dump_file)
    2483          192 :     fprintf (dump_file, "Dump after hash based groups\n");
    2484       131334 :   dump_cong_classes ();
    2485              : 
    2486       131334 :   subdivide_classes_by_equality (true);
    2487              : 
    2488       131334 :   if (dump_file)
    2489          192 :     fprintf (dump_file, "Dump after WPA based types groups\n");
    2490              : 
    2491       131334 :   dump_cong_classes ();
    2492              : 
    2493       131334 :   process_cong_reduction ();
    2494       131334 :   checking_verify_classes ();
    2495              : 
    2496       131334 :   if (dump_file)
    2497          192 :     fprintf (dump_file, "Dump after callgraph-based congruence reduction\n");
    2498              : 
    2499       131334 :   dump_cong_classes ();
    2500              : 
    2501       131334 :   unsigned int loaded_symbols = parse_nonsingleton_classes ();
    2502       131334 :   subdivide_classes_by_equality ();
    2503              : 
    2504       131334 :   if (dump_file)
    2505          192 :     fprintf (dump_file, "Dump after full equality comparison of groups\n");
    2506              : 
    2507       131334 :   dump_cong_classes ();
    2508              : 
    2509       131334 :   unsigned int prev_class_count = m_classes_count;
    2510              : 
    2511       131334 :   process_cong_reduction ();
    2512       131334 :   dump_cong_classes ();
    2513       131334 :   checking_verify_classes ();
    2514       131334 :   bool merged_p = merge_classes (prev_class_count, loaded_symbols);
    2515              : 
    2516       131334 :   if (dump_file && (dump_flags & TDF_DETAILS))
    2517           30 :     symtab->dump (dump_file);
    2518              : 
    2519       131334 :   return merged_p;
    2520              : }
    2521              : 
    2522              : /* Function responsible for visiting all potential functions and
    2523              :    read-only variables that can be merged.  */
    2524              : 
    2525              : void
    2526       128149 : sem_item_optimizer::parse_funcs_and_vars (void)
    2527              : {
    2528       128149 :   cgraph_node *cnode;
    2529              : 
    2530              :   /* Create dummy func_checker for hashing purpose.  */
    2531       128149 :   func_checker checker;
    2532              : 
    2533       128149 :   if (flag_ipa_icf_functions)
    2534      1208045 :     FOR_EACH_DEFINED_FUNCTION (cnode)
    2535              :     {
    2536      1083405 :       sem_function *f = sem_function::parse (cnode, &m_bmstack, &checker);
    2537      1083405 :       if (f)
    2538              :         {
    2539       991071 :           m_items.safe_push (f);
    2540       991071 :           m_symtab_node_map.put (cnode, f);
    2541              :         }
    2542              :     }
    2543              : 
    2544       128149 :   varpool_node *vnode;
    2545              : 
    2546       128149 :   if (flag_ipa_icf_variables)
    2547      2480718 :     FOR_EACH_DEFINED_VARIABLE (vnode)
    2548              :     {
    2549      2352572 :       sem_variable *v = sem_variable::parse (vnode, &m_bmstack, &checker);
    2550              : 
    2551      2352572 :       if (v)
    2552              :         {
    2553      2288024 :           m_items.safe_push (v);
    2554      2288024 :           m_symtab_node_map.put (vnode, v);
    2555              :         }
    2556              :     }
    2557       128149 : }
    2558              : 
    2559              : /* Makes pairing between a congruence class CLS and semantic ITEM.  */
    2560              : 
    2561              : void
    2562      4084086 : sem_item_optimizer::add_item_to_class (congruence_class *cls, sem_item *item)
    2563              : {
    2564      4084086 :   item->index_in_class = cls->members.length ();
    2565      4084086 :   cls->members.safe_push (item);
    2566      4084086 :   cls->referenced_by_count += item->referenced_by_count;
    2567      4084086 :   item->cls = cls;
    2568      4084086 : }
    2569              : 
    2570              : /* For each semantic item, append hash values of references.  */
    2571              : 
    2572              : void
    2573       131334 : sem_item_optimizer::update_hash_by_addr_refs ()
    2574              : {
    2575              :   /* First, append to hash sensitive references and class type if it need to
    2576              :      be matched for ODR.  */
    2577      5280489 :   for (unsigned i = 0; i < m_items.length (); i++)
    2578              :     {
    2579      2512395 :       m_items[i]->update_hash_by_addr_refs (m_symtab_node_map);
    2580      2512395 :       if (m_items[i]->type == FUNC)
    2581              :         {
    2582      1020088 :           if (TREE_CODE (TREE_TYPE (m_items[i]->decl)) == METHOD_TYPE
    2583       304422 :               && contains_polymorphic_type_p
    2584       304422 :                    (TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl)))
    2585      1093493 :               && (DECL_CXX_CONSTRUCTOR_P (m_items[i]->decl)
    2586        62735 :                   || (static_cast<sem_function *> (m_items[i])->param_used_p (0)
    2587       104254 :                       && static_cast<sem_function *> (m_items[i])
    2588        52127 :                            ->compare_polymorphic_p ())))
    2589              :              {
    2590        44833 :                 tree class_type
    2591        44833 :                   = TYPE_METHOD_BASETYPE (TREE_TYPE (m_items[i]->decl));
    2592        44833 :                 inchash::hash hstate (m_items[i]->get_hash ());
    2593              : 
    2594              :                 /* Hash ODR types by mangled name if it is defined.
    2595              :                    If not we know that type is anonymous of free_lang_data
    2596              :                    was not run and in that case type main variants are
    2597              :                    unique.  */
    2598        44833 :                 if (TYPE_NAME (class_type)
    2599        44833 :                      && DECL_ASSEMBLER_NAME_SET_P (TYPE_NAME (class_type))
    2600        45150 :                      && !type_in_anonymous_namespace_p
    2601          317 :                                  (class_type))
    2602          310 :                   hstate.add_hwi
    2603          310 :                     (IDENTIFIER_HASH_VALUE
    2604              :                        (DECL_ASSEMBLER_NAME (TYPE_NAME (class_type))));
    2605              :                 else
    2606              :                   {
    2607        44523 :                     gcc_checking_assert
    2608              :                          (!in_lto_p
    2609              :                           || type_in_anonymous_namespace_p (class_type));
    2610        44523 :                     hstate.add_hwi (TYPE_UID (TYPE_MAIN_VARIANT (class_type)));
    2611              :                   }
    2612              : 
    2613        44833 :                 m_items[i]->set_hash (hstate.end ());
    2614              :              }
    2615              :         }
    2616              :     }
    2617              : 
    2618              :   /* Once all symbols have enhanced hash value, we can append
    2619              :      hash values of symbols that are seen by IPA ICF and are
    2620              :      references by a semantic item. Newly computed values
    2621              :      are saved to global_hash member variable.  */
    2622      5280489 :   for (unsigned i = 0; i < m_items.length (); i++)
    2623      2512395 :     m_items[i]->update_hash_by_local_refs (m_symtab_node_map);
    2624              : 
    2625              :   /* Global hash value replace current hash values.  */
    2626      2643729 :   for (unsigned i = 0; i < m_items.length (); i++)
    2627      2512395 :     m_items[i]->set_hash (m_items[i]->global_hash);
    2628       131334 : }
    2629              : 
    2630              : void
    2631       131334 : sem_item_optimizer::update_hash_by_memory_access_type ()
    2632              : {
    2633      2643729 :   for (unsigned i = 0; i < m_items.length (); i++)
    2634              :     {
    2635      2512395 :       if (m_items[i]->type == FUNC)
    2636              :         {
    2637      1020088 :           sem_function *fn = static_cast<sem_function *> (m_items[i]);
    2638      1020088 :           inchash::hash hstate (fn->get_hash ());
    2639      1020088 :           hstate.add_int (fn->m_alias_sets_hash);
    2640      1020088 :           fn->set_hash (hstate.end ());
    2641              :         }
    2642              :     }
    2643       131334 : }
    2644              : 
    2645              : /* Congruence classes are built by hash value.  */
    2646              : 
    2647              : void
    2648       131334 : sem_item_optimizer::build_hash_based_classes (void)
    2649              : {
    2650      2643729 :   for (unsigned i = 0; i < m_items.length (); i++)
    2651              :     {
    2652      2512395 :       sem_item *item = m_items[i];
    2653              : 
    2654      2512395 :       congruence_class_group *group
    2655      2512395 :         = get_group_by_hash (item->get_hash (), item->type);
    2656              : 
    2657      2512395 :       if (!group->classes.length ())
    2658              :         {
    2659      1904966 :           m_classes_count++;
    2660      1904966 :           group->classes.safe_push (new congruence_class (class_id++));
    2661              :         }
    2662              : 
    2663      2512395 :       add_item_to_class (group->classes[0], item);
    2664              :     }
    2665       131334 : }
    2666              : 
    2667              : /* Build references according to call graph.  */
    2668              : 
    2669              : void
    2670       131334 : sem_item_optimizer::build_graph (void)
    2671              : {
    2672      5280489 :   for (unsigned i = 0; i < m_items.length (); i++)
    2673              :     {
    2674      2512395 :       sem_item *item = m_items[i];
    2675      2512395 :       m_symtab_node_map.put (item->node, item);
    2676              : 
    2677              :       /* Initialize hash values if we are not in LTO mode.  */
    2678      2512395 :       if (!in_lto_p)
    2679      2437953 :         item->get_hash ();
    2680              :     }
    2681              : 
    2682      2643729 :   for (unsigned i = 0; i < m_items.length (); i++)
    2683              :     {
    2684      2512395 :       sem_item *item = m_items[i];
    2685              : 
    2686      2512395 :       if (item->type == FUNC)
    2687              :         {
    2688      1020088 :           cgraph_node *cnode = dyn_cast <cgraph_node *> (item->node);
    2689              : 
    2690      1020088 :           cgraph_edge *e = cnode->callees;
    2691      4945630 :           while (e)
    2692              :             {
    2693      3925542 :               sem_item **slot = m_symtab_node_map.get
    2694      3925542 :                 (e->callee->ultimate_alias_target ());
    2695      3925542 :               if (slot)
    2696      1712487 :                 item->add_reference (&m_references, *slot);
    2697              : 
    2698      3925542 :               e = e->next_callee;
    2699              :             }
    2700              :         }
    2701              : 
    2702      2512395 :       ipa_ref *ref = NULL;
    2703      7970866 :       for (unsigned i = 0; item->node->iterate_reference (i, ref); i++)
    2704              :         {
    2705      4473570 :           sem_item **slot = m_symtab_node_map.get
    2706      4473570 :             (ref->referred->ultimate_alias_target ());
    2707      4473570 :           if (slot)
    2708      2341371 :             item->add_reference (&m_references, *slot);
    2709              :         }
    2710              :     }
    2711       131334 : }
    2712              : 
    2713              : /* Semantic items in classes having more than one element and initialized.
    2714              :    In case of WPA, we load function body.  */
    2715              : 
    2716              : unsigned int
    2717       131334 : sem_item_optimizer::parse_nonsingleton_classes (void)
    2718              : {
    2719       131334 :   unsigned int counter = 0;
    2720              : 
    2721              :   /* Create dummy func_checker for hashing purpose.  */
    2722       131334 :   func_checker checker;
    2723              : 
    2724      2775063 :   for (unsigned i = 0; i < m_items.length (); i++)
    2725      3157248 :     if (m_items[i]->cls->members.length () > 1)
    2726              :       {
    2727       644853 :         m_items[i]->init (&checker);
    2728       644853 :         ++counter;
    2729              :       }
    2730              : 
    2731       131334 :   if (dump_file)
    2732              :     {
    2733          192 :       float f = m_items.length () ? 100.0f * counter / m_items.length () : 0.0f;
    2734          192 :       fprintf (dump_file, "Init called for %u items (%.2f%%).\n", counter, f);
    2735              :     }
    2736              : 
    2737       262668 :   return counter;
    2738       131334 : }
    2739              : 
    2740              : /* Equality function for semantic items is used to subdivide existing
    2741              :    classes. If IN_WPA, fast equality function is invoked.  */
    2742              : 
    2743              : void
    2744       262668 : sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa)
    2745              : {
    2746      4072600 :   for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
    2747      4072600 :        it != m_classes.end (); ++it)
    2748              :     {
    2749      3809932 :       unsigned int class_count = (*it)->classes.length ();
    2750              : 
    2751      7706079 :       for (unsigned i = 0; i < class_count; i++)
    2752              :         {
    2753      3896147 :           congruence_class *c = (*it)->classes[i];
    2754              : 
    2755      4160985 :           if (c->members.length() > 1)
    2756              :             {
    2757       264838 :               auto_vec <sem_item *> new_vector;
    2758              : 
    2759       264838 :               sem_item *first = c->members[0];
    2760       264838 :               new_vector.safe_push (first);
    2761              : 
    2762       264838 :               unsigned class_split_first = (*it)->classes.length ();
    2763              : 
    2764      1393481 :               for (unsigned j = 1; j < c->members.length (); j++)
    2765              :                 {
    2766      1128643 :                   sem_item *item = c->members[j];
    2767              : 
    2768      1128643 :                   bool equals
    2769      1128643 :                     = in_wpa ? first->equals_wpa (item, m_symtab_node_map)
    2770      1128643 :                              : first->equals (item, m_symtab_node_map);
    2771              : 
    2772      1128643 :                   if (equals)
    2773       961130 :                     new_vector.safe_push (item);
    2774              :                   else
    2775              :                     {
    2776      1722752 :                       bool integrated = false;
    2777              : 
    2778      1555239 :                       for (unsigned k = class_split_first;
    2779      1722752 :                            k < (*it)->classes.length (); k++)
    2780              :                         {
    2781      1633116 :                           sem_item *x = (*it)->classes[k]->members[0];
    2782      1633116 :                           bool equals
    2783      1633116 :                             = in_wpa ? x->equals_wpa (item, m_symtab_node_map)
    2784      1633116 :                                      : x->equals (item, m_symtab_node_map);
    2785              : 
    2786      1633116 :                           if (equals)
    2787              :                             {
    2788        77877 :                               integrated = true;
    2789        77877 :                               add_item_to_class ((*it)->classes[k], item);
    2790              : 
    2791        77877 :                               break;
    2792              :                             }
    2793              :                         }
    2794              : 
    2795        77877 :                       if (!integrated)
    2796              :                         {
    2797        89636 :                           congruence_class *c
    2798        89636 :                             = new congruence_class (class_id++);
    2799        89636 :                           m_classes_count++;
    2800        89636 :                           add_item_to_class (c, item);
    2801              : 
    2802        89636 :                           (*it)->classes.safe_push (c);
    2803              :                         }
    2804              :                     }
    2805              :                 }
    2806              : 
    2807              :               // We replace newly created new_vector for the class we've just
    2808              :               // split.
    2809       264838 :               c->members.release ();
    2810       264838 :               c->members.create (new_vector.length ());
    2811              : 
    2812      1755644 :               for (unsigned int j = 0; j < new_vector.length (); j++)
    2813      1225968 :                 add_item_to_class (c, new_vector[j]);
    2814       264838 :             }
    2815              :         }
    2816              :     }
    2817              : 
    2818       262668 :   checking_verify_classes ();
    2819       262668 : }
    2820              : 
    2821              : /* Subdivide classes by address references that members of the class
    2822              :    reference. Example can be a pair of functions that have an address
    2823              :    taken from a function. If these addresses are different the class
    2824              :    is split.  */
    2825              : 
    2826              : unsigned
    2827       262668 : sem_item_optimizer::subdivide_classes_by_sensitive_refs ()
    2828              : {
    2829       262668 :   typedef hash_map <symbol_compare_hash, vec <sem_item *> > subdivide_hash_map;
    2830              : 
    2831       262668 :   unsigned newly_created_classes = 0;
    2832              : 
    2833       262668 :   for (hash_table <congruence_class_hash>::iterator it = m_classes.begin ();
    2834      4072600 :        it != m_classes.end (); ++it)
    2835              :     {
    2836      3809932 :       unsigned int class_count = (*it)->classes.length ();
    2837      3809932 :       auto_vec<congruence_class *> new_classes;
    2838              : 
    2839      7813655 :       for (unsigned i = 0; i < class_count; i++)
    2840              :         {
    2841      4003723 :           congruence_class *c = (*it)->classes[i];
    2842              : 
    2843      4249392 :           if (c->members.length() > 1)
    2844              :             {
    2845       245669 :               subdivide_hash_map split_map;
    2846              : 
    2847      1758074 :               for (unsigned j = 0; j < c->members.length (); j++)
    2848              :                 {
    2849      1266736 :                   sem_item *source_node = c->members[j];
    2850              : 
    2851      1266736 :                   symbol_compare_collection *collection
    2852      1266736 :                     = new symbol_compare_collection (source_node->node);
    2853              : 
    2854      1266736 :                   bool existed;
    2855      1266736 :                   vec <sem_item *> *slot
    2856      1266736 :                     = &split_map.get_or_insert (collection, &existed);
    2857      1266736 :                   gcc_checking_assert (slot);
    2858              : 
    2859      1266736 :                   slot->safe_push (source_node);
    2860              : 
    2861      1266736 :                   if (existed)
    2862      2042134 :                     delete collection;
    2863              :                 }
    2864              : 
    2865              :                /* If the map contains more than one key, we have to split
    2866              :                   the map appropriately.  */
    2867       245669 :               if (split_map.elements () != 1)
    2868              :                 {
    2869            0 :                   bool first_class = true;
    2870              : 
    2871            0 :                   for (subdivide_hash_map::iterator it2 = split_map.begin ();
    2872            0 :                        it2 != split_map.end (); ++it2)
    2873              :                     {
    2874            0 :                       congruence_class *new_cls;
    2875            0 :                       new_cls = new congruence_class (class_id++);
    2876              : 
    2877            0 :                       for (unsigned k = 0; k < (*it2).second.length (); k++)
    2878            0 :                         add_item_to_class (new_cls, (*it2).second[k]);
    2879              : 
    2880            0 :                       worklist_push (new_cls);
    2881            0 :                       newly_created_classes++;
    2882              : 
    2883            0 :                       if (first_class)
    2884              :                         {
    2885            0 :                           (*it)->classes[i] = new_cls;
    2886            0 :                           first_class = false;
    2887              :                         }
    2888              :                       else
    2889              :                         {
    2890            0 :                           new_classes.safe_push (new_cls);
    2891            0 :                           m_classes_count++;
    2892              :                         }
    2893              :                     }
    2894              :                 }
    2895              : 
    2896              :               /* Release memory.  */
    2897       491338 :               for (subdivide_hash_map::iterator it2 = split_map.begin ();
    2898       737007 :                    it2 != split_map.end (); ++it2)
    2899              :                 {
    2900       491338 :                   delete (*it2).first;
    2901       245669 :                   (*it2).second.release ();
    2902              :                 }
    2903       245669 :             }
    2904              :           }
    2905              : 
    2906      3809932 :         for (unsigned i = 0; i < new_classes.length (); i++)
    2907            0 :           (*it)->classes.safe_push (new_classes[i]);
    2908      3809932 :     }
    2909              : 
    2910       262668 :   return newly_created_classes;
    2911              : }
    2912              : 
    2913              : /* Verify congruence classes, if checking is enabled.  */
    2914              : 
    2915              : void
    2916       525336 : sem_item_optimizer::checking_verify_classes (void)
    2917              : {
    2918       525336 :   if (flag_checking)
    2919       525304 :     verify_classes ();
    2920       525336 : }
    2921              : 
    2922              : /* Verify congruence classes.  */
    2923              : 
    2924              : void
    2925       525304 : sem_item_optimizer::verify_classes (void)
    2926              : {
    2927       525304 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    2928      8145016 :        it != m_classes.end (); ++it)
    2929              :     {
    2930     15609066 :       for (unsigned int i = 0; i < (*it)->classes.length (); i++)
    2931              :         {
    2932      7989354 :           congruence_class *cls = (*it)->classes[i];
    2933              : 
    2934      7989354 :           gcc_assert (cls);
    2935      7989354 :           gcc_assert (cls->members.length () > 0);
    2936              : 
    2937     18038782 :           for (unsigned int j = 0; j < cls->members.length (); j++)
    2938              :             {
    2939     10049428 :               sem_item *item = cls->members[j];
    2940              : 
    2941     10049428 :               gcc_assert (item);
    2942     10049428 :               gcc_assert (item->cls == cls);
    2943              :             }
    2944              :         }
    2945              :     }
    2946       525304 : }
    2947              : 
    2948              : /* Disposes split map traverse function. CLS_PTR is pointer to congruence
    2949              :    class, BSLOT is bitmap slot we want to release. DATA is mandatory,
    2950              :    but unused argument.  */
    2951              : 
    2952              : bool
    2953       146907 : sem_item_optimizer::release_split_map (congruence_class * const &,
    2954              :                                        bitmap const &b, traverse_split_pair *)
    2955              : {
    2956       146907 :   bitmap bmp = b;
    2957              : 
    2958       146907 :   BITMAP_FREE (bmp);
    2959              : 
    2960       146907 :   return true;
    2961              : }
    2962              : 
    2963              : /* Process split operation for a class given as pointer CLS_PTR,
    2964              :    where bitmap B splits congruence class members. DATA is used
    2965              :    as argument of split pair.  */
    2966              : 
    2967              : bool
    2968       146907 : sem_item_optimizer::traverse_congruence_split (congruence_class * const &cls,
    2969              :                                                bitmap const &b,
    2970              :                                                traverse_split_pair *pair)
    2971              : {
    2972       146907 :   sem_item_optimizer *optimizer = pair->optimizer;
    2973       146907 :   const congruence_class *splitter_cls = pair->cls;
    2974              : 
    2975              :   /* If counted bits are greater than zero and less than the number of members
    2976              :      a group will be split.  */
    2977       146907 :   unsigned popcount = bitmap_count_bits (b);
    2978              : 
    2979       146907 :   if (popcount > 0 && popcount < cls->members.length ())
    2980              :     {
    2981        17940 :       auto_vec <congruence_class *, 2> newclasses;
    2982        17940 :       newclasses.quick_push (new congruence_class (class_id++));
    2983        17940 :       newclasses.quick_push (new congruence_class (class_id++));
    2984              : 
    2985       196150 :       for (unsigned int i = 0; i < cls->members.length (); i++)
    2986              :         {
    2987       178210 :           int target = bitmap_bit_p (b, i);
    2988       178210 :           congruence_class *tc = newclasses[target];
    2989              : 
    2990       178210 :           add_item_to_class (tc, cls->members[i]);
    2991              :         }
    2992              : 
    2993        17940 :       if (flag_checking)
    2994              :         {
    2995        53820 :           for (unsigned int i = 0; i < 2; i++)
    2996        35880 :             gcc_assert (newclasses[i]->members.length ());
    2997              :         }
    2998              : 
    2999        17940 :       if (splitter_cls == cls)
    3000            6 :         optimizer->splitter_class_removed = true;
    3001              : 
    3002              :       /* Remove old class from worklist if presented.  */
    3003        17940 :       bool in_worklist = cls->in_worklist;
    3004              : 
    3005        17940 :       if (in_worklist)
    3006        13409 :         cls->in_worklist = false;
    3007              : 
    3008        17940 :       congruence_class_group g;
    3009        17940 :       g.hash = cls->members[0]->get_hash ();
    3010        17940 :       g.type = cls->members[0]->type;
    3011              : 
    3012        17940 :       congruence_class_group *slot = optimizer->m_classes.find (&g);
    3013              : 
    3014       151435 :       for (unsigned int i = 0; i < slot->classes.length (); i++)
    3015       151435 :         if (slot->classes[i] == cls)
    3016              :           {
    3017        17940 :             slot->classes.ordered_remove (i);
    3018        17940 :             break;
    3019              :           }
    3020              : 
    3021              :       /* New class will be inserted and integrated to work list.  */
    3022        53820 :       for (unsigned int i = 0; i < 2; i++)
    3023        35880 :         optimizer->add_class (newclasses[i]);
    3024              : 
    3025              :       /* Two classes replace one, so that increment just by one.  */
    3026        17940 :       optimizer->m_classes_count++;
    3027              : 
    3028              :       /* If OLD class was presented in the worklist, we remove the class
    3029              :          and replace it will both newly created classes.  */
    3030        17940 :       if (in_worklist)
    3031        40227 :         for (unsigned int i = 0; i < 2; i++)
    3032        26818 :           optimizer->worklist_push (newclasses[i]);
    3033              :       else /* Just smaller class is inserted.  */
    3034              :         {
    3035         4531 :           unsigned int smaller_index
    3036         9062 :             = (newclasses[0]->members.length ()
    3037         4531 :                < newclasses[1]->members.length ()
    3038         4531 :                ? 0 : 1);
    3039         4531 :           optimizer->worklist_push (newclasses[smaller_index]);
    3040              :         }
    3041              : 
    3042        17940 :       if (dump_file && (dump_flags & TDF_DETAILS))
    3043              :         {
    3044            1 :           fprintf (dump_file, "  congruence class split:\n");
    3045            1 :           cls->dump (dump_file, 4);
    3046              : 
    3047            1 :           fprintf (dump_file, "  newly created groups:\n");
    3048            4 :           for (unsigned int i = 0; i < 2; i++)
    3049            2 :             newclasses[i]->dump (dump_file, 4);
    3050              :         }
    3051              : 
    3052              :       /* Release class if not presented in work list.  */
    3053        17940 :       if (!in_worklist)
    3054         9062 :         delete cls;
    3055              : 
    3056        17940 :       return true;
    3057        17940 :     }
    3058              : 
    3059              :   return false;
    3060              : }
    3061              : 
    3062              : /* Compare function for sorting pairs in do_congruence_step_f.  */
    3063              : 
    3064              : int
    3065      1461498 : sem_item_optimizer::sort_congruence_split (const void *a_, const void *b_)
    3066              : {
    3067      1461498 :   const std::pair<congruence_class *, bitmap> *a
    3068              :     = (const std::pair<congruence_class *, bitmap> *)a_;
    3069      1461498 :   const std::pair<congruence_class *, bitmap> *b
    3070              :     = (const std::pair<congruence_class *, bitmap> *)b_;
    3071      1461498 :   if (a->first->id < b->first->id)
    3072              :     return -1;
    3073       690148 :   else if (a->first->id > b->first->id)
    3074       690148 :     return 1;
    3075              :   return 0;
    3076              : }
    3077              : 
    3078              : /* Tests if a class CLS used as INDEXth splits any congruence classes.
    3079              :    Bitmap stack BMSTACK is used for bitmap allocation.  */
    3080              : 
    3081              : bool
    3082      5193532 : sem_item_optimizer::do_congruence_step_for_index (congruence_class *cls,
    3083              :                                                   unsigned int index)
    3084              : {
    3085      5193532 :   hash_map <congruence_class *, bitmap> split_map;
    3086              : 
    3087     39490094 :   for (unsigned int i = 0; i < cls->members.length (); i++)
    3088              :     {
    3089     29103030 :       sem_item *item = cls->members[i];
    3090     29103030 :       sem_usage_pair needle (item, index);
    3091     29103030 :       vec<sem_item *> *callers = m_references.get (&needle);
    3092     29103030 :       if (callers == NULL)
    3093     23160960 :         continue;
    3094              : 
    3095     14052737 :       for (unsigned int j = 0; j < callers->length (); j++)
    3096              :         {
    3097      8110667 :           sem_item *caller = (*callers)[j];
    3098      8110667 :           if (caller->cls->members.length () < 2)
    3099      7622431 :             continue;
    3100       488236 :           bitmap *slot = split_map.get (caller->cls);
    3101       488236 :           bitmap b;
    3102              : 
    3103       488236 :           if(!slot)
    3104              :             {
    3105       146907 :               b = BITMAP_ALLOC (&m_bmstack);
    3106       146907 :               split_map.put (caller->cls, b);
    3107              :             }
    3108              :           else
    3109       341329 :             b = *slot;
    3110              : 
    3111       488236 :           gcc_checking_assert (caller->cls);
    3112       488236 :           gcc_checking_assert (caller->index_in_class
    3113              :                                < caller->cls->members.length ());
    3114              : 
    3115       488236 :           bitmap_set_bit (b, caller->index_in_class);
    3116              :         }
    3117              :     }
    3118              : 
    3119      5193532 :   auto_vec<std::pair<congruence_class *, bitmap> > to_split;
    3120      5193532 :   to_split.reserve_exact (split_map.elements ());
    3121      5193532 :   for (hash_map <congruence_class *, bitmap>::iterator i = split_map.begin ();
    3122      5340439 :        i != split_map.end (); ++i)
    3123       146907 :     to_split.safe_push (*i);
    3124      5193532 :   to_split.qsort (sort_congruence_split);
    3125              : 
    3126      5193532 :   traverse_split_pair pair;
    3127      5193532 :   pair.optimizer = this;
    3128      5193532 :   pair.cls = cls;
    3129              : 
    3130      5193532 :   splitter_class_removed = false;
    3131      5193532 :   bool r = false;
    3132      5340439 :   for (unsigned i = 0; i < to_split.length (); ++i)
    3133       146907 :     r |= traverse_congruence_split (to_split[i].first, to_split[i].second,
    3134              :                                     &pair);
    3135              : 
    3136              :   /* Bitmap clean-up.  */
    3137      5193532 :   split_map.traverse <traverse_split_pair *,
    3138      5340439 :                       sem_item_optimizer::release_split_map> (NULL);
    3139              : 
    3140      5193532 :   return r;
    3141      5193532 : }
    3142              : 
    3143              : /* Every usage of a congruence class CLS is a candidate that can split the
    3144              :    collection of classes. Bitmap stack BMSTACK is used for bitmap
    3145              :    allocation.  */
    3146              : 
    3147              : void
    3148      3022099 : sem_item_optimizer::do_congruence_step (congruence_class *cls)
    3149              : {
    3150      3022099 :   bitmap_iterator bi;
    3151      3022099 :   unsigned int i;
    3152              : 
    3153      3022099 :   bitmap usage = BITMAP_ALLOC (&m_bmstack);
    3154              : 
    3155     10015268 :   for (unsigned int i = 0; i < cls->members.length (); i++)
    3156      3971070 :     bitmap_ior_into (usage, cls->members[i]->usage_index_bitmap);
    3157              : 
    3158      8215625 :   EXECUTE_IF_SET_IN_BITMAP (usage, 0, i, bi)
    3159              :   {
    3160      5193532 :     if (dump_file && (dump_flags & TDF_DETAILS))
    3161          246 :       fprintf (dump_file, "  processing congruence step for class: %u "
    3162              :                "(%u items, %u references), index: %u\n", cls->id,
    3163              :                cls->referenced_by_count, cls->members.length (), i);
    3164      5193532 :     do_congruence_step_for_index (cls, i);
    3165              : 
    3166      5193532 :     if (splitter_class_removed)
    3167              :       break;
    3168              :   }
    3169              : 
    3170      3022099 :   BITMAP_FREE (usage);
    3171      3022099 : }
    3172              : 
    3173              : /* Adds a newly created congruence class CLS to worklist.  */
    3174              : 
    3175              : void
    3176      3035508 : sem_item_optimizer::worklist_push (congruence_class *cls)
    3177              : {
    3178              :   /* Return if the class CLS is already presented in work list.  */
    3179      3035508 :   if (cls->in_worklist)
    3180              :     return;
    3181              : 
    3182      3035508 :   cls->in_worklist = true;
    3183      3035508 :   worklist.insert (cls->referenced_by_count, cls);
    3184              : }
    3185              : 
    3186              : /* Pops a class from worklist. */
    3187              : 
    3188              : congruence_class *
    3189      3284767 : sem_item_optimizer::worklist_pop (void)
    3190              : {
    3191      3284767 :   congruence_class *cls;
    3192              : 
    3193      3298176 :   while (!worklist.empty ())
    3194              :     {
    3195      3035508 :       cls = worklist.extract_min ();
    3196      3035508 :       if (cls->in_worklist)
    3197              :         {
    3198      3022099 :           cls->in_worklist = false;
    3199              : 
    3200      3022099 :           return cls;
    3201              :         }
    3202              :       else
    3203              :         {
    3204              :           /* Work list item was already intended to be removed.
    3205              :              The only reason for doing it is to split a class.
    3206              :              Thus, the class CLS is deleted.  */
    3207        13409 :           delete cls;
    3208              :         }
    3209              :     }
    3210              : 
    3211              :   return NULL;
    3212              : }
    3213              : 
    3214              : /* Iterative congruence reduction function.  */
    3215              : 
    3216              : void
    3217       262668 : sem_item_optimizer::process_cong_reduction (void)
    3218              : {
    3219       262668 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3220      4072600 :        it != m_classes.end (); ++it)
    3221      7795715 :     for (unsigned i = 0; i < (*it)->classes.length (); i++)
    3222      3985783 :       if ((*it)->classes[i]->is_class_used ())
    3223      3004159 :         worklist_push ((*it)->classes[i]);
    3224              : 
    3225       262668 :   if (dump_file)
    3226          384 :     fprintf (dump_file, "Worklist has been filled with: "
    3227              :                         HOST_SIZE_T_PRINT_UNSIGNED "\n",
    3228          384 :              (fmt_size_t) worklist.nodes ());
    3229              : 
    3230       262668 :   if (dump_file && (dump_flags & TDF_DETAILS))
    3231           60 :     fprintf (dump_file, "Congruence class reduction\n");
    3232              : 
    3233              :   congruence_class *cls;
    3234              : 
    3235              :   /* Process complete congruence reduction.  */
    3236      3284767 :   while ((cls = worklist_pop ()) != NULL)
    3237      3022099 :     do_congruence_step (cls);
    3238              : 
    3239              :   /* Subdivide newly created classes according to references.  */
    3240       262668 :   unsigned new_classes = subdivide_classes_by_sensitive_refs ();
    3241              : 
    3242       262668 :   if (dump_file)
    3243          384 :     fprintf (dump_file, "Address reference subdivision created: %u "
    3244              :              "new classes.\n", new_classes);
    3245       262668 : }
    3246              : 
    3247              : /* Debug function prints all information about congruence classes.  */
    3248              : 
    3249              : void
    3250       656670 : sem_item_optimizer::dump_cong_classes (void)
    3251              : {
    3252       656670 :   if (!dump_file)
    3253              :     return;
    3254              : 
    3255              :   /* Histogram calculation.  */
    3256          960 :   unsigned int max_index = 0;
    3257          960 :   unsigned int single_element_classes = 0;
    3258         1915 :   unsigned int* histogram = XCNEWVEC (unsigned int, m_items.length () + 1);
    3259              : 
    3260          960 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3261         3530 :        it != m_classes.end (); ++it)
    3262         5240 :     for (unsigned i = 0; i < (*it)->classes.length (); i++)
    3263              :       {
    3264         2670 :         unsigned int c = (*it)->classes[i]->members.length ();
    3265         2670 :         histogram[c]++;
    3266              : 
    3267         2670 :         if (c > max_index)
    3268              :           max_index = c;
    3269              : 
    3270         2670 :         if (c == 1)
    3271         2244 :           ++single_element_classes;
    3272              :       }
    3273              : 
    3274         1920 :   fprintf (dump_file,
    3275              :            "Congruence classes: " HOST_SIZE_T_PRINT_UNSIGNED " with total: "
    3276              :            "%u items (in a non-singular class: %u)\n",
    3277          960 :            (fmt_size_t) m_classes.elements (),
    3278         1915 :            m_items.length (), m_items.length () - single_element_classes);
    3279          960 :   fprintf (dump_file,
    3280              :            "Class size histogram [number of members]: number of classes\n");
    3281         4218 :   for (unsigned int i = 0; i <= max_index; i++)
    3282         2298 :     if (histogram[i])
    3283         1253 :       fprintf (dump_file, "%6u: %6u\n", i, histogram[i]);
    3284              : 
    3285          960 :   if (dump_flags & TDF_DETAILS)
    3286          150 :     for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3287          700 :          it != m_classes.end (); ++it)
    3288              :       {
    3289          800 :         fprintf (dump_file, "  group: with %u classes:\n",
    3290          400 :                  (*it)->classes.length ());
    3291              : 
    3292         1277 :         for (unsigned i = 0; i < (*it)->classes.length (); i++)
    3293              :           {
    3294          477 :             (*it)->classes[i]->dump (dump_file, 4);
    3295              : 
    3296          954 :             if (i < (*it)->classes.length () - 1)
    3297           77 :               fprintf (dump_file, " ");
    3298              :           }
    3299              :       }
    3300              : 
    3301          960 :   free (histogram);
    3302              : }
    3303              : 
    3304              : /* Sort pair of sem_items A and B by DECL_UID.  */
    3305              : 
    3306              : static int
    3307     11176170 : sort_sem_items_by_decl_uid (const void *a, const void *b)
    3308              : {
    3309     11176170 :   const sem_item *i1 = *(const sem_item * const *)a;
    3310     11176170 :   const sem_item *i2 = *(const sem_item * const *)b;
    3311              : 
    3312     11176170 :   int uid1 = DECL_UID (i1->decl);
    3313     11176170 :   int uid2 = DECL_UID (i2->decl);
    3314     11176170 :   return uid1 - uid2;
    3315              : }
    3316              : 
    3317              : /* Sort pair of congruence_classes A and B by DECL_UID of the first member.  */
    3318              : 
    3319              : static int
    3320      1631189 : sort_congruence_classes_by_decl_uid (const void *a, const void *b)
    3321              : {
    3322      1631189 :   const congruence_class *c1 = *(const congruence_class * const *)a;
    3323      1631189 :   const congruence_class *c2 = *(const congruence_class * const *)b;
    3324              : 
    3325      1631189 :   int uid1 = DECL_UID (c1->members[0]->decl);
    3326      1631189 :   int uid2 = DECL_UID (c2->members[0]->decl);
    3327      1631189 :   return uid1 - uid2;
    3328              : }
    3329              : 
    3330              : /* Sort pair of congruence_class_groups A and B by
    3331              :    DECL_UID of the first member of a first group.  */
    3332              : 
    3333              : static int
    3334     73026104 : sort_congruence_class_groups_by_decl_uid (const void *a, const void *b)
    3335              : {
    3336     73026104 :   const std::pair<congruence_class_group *, int> *g1
    3337              :     = (const std::pair<congruence_class_group *, int> *) a;
    3338     73026104 :   const std::pair<congruence_class_group *, int> *g2
    3339              :     = (const std::pair<congruence_class_group *, int> *) b;
    3340     73026104 :   return g1->second - g2->second;
    3341              : }
    3342              : 
    3343              : /* After reduction is done, we can declare all items in a group
    3344              :    to be equal. PREV_CLASS_COUNT is start number of classes
    3345              :    before reduction. True is returned if there's a merge operation
    3346              :    processed.  LOADED_SYMBOLS is number of symbols that were loaded
    3347              :    in WPA.  */
    3348              : 
    3349              : bool
    3350       131334 : sem_item_optimizer::merge_classes (unsigned int prev_class_count,
    3351              :                                    unsigned int loaded_symbols)
    3352              : {
    3353       131334 :   unsigned int item_count = m_items.length ();
    3354       131334 :   unsigned int class_count = m_classes_count;
    3355       131334 :   unsigned int equal_items = item_count - class_count;
    3356              : 
    3357       131334 :   unsigned int non_singular_classes_count = 0;
    3358       131334 :   unsigned int non_singular_classes_sum = 0;
    3359              : 
    3360       131334 :   bool merged_p = false;
    3361              : 
    3362              :   /* PR lto/78211
    3363              :      Sort functions in congruence classes by DECL_UID and do the same
    3364              :      for the classes to not to break -fcompare-debug.  */
    3365              : 
    3366       131334 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3367      2036300 :        it != m_classes.end (); ++it)
    3368              :     {
    3369      3917508 :       for (unsigned int i = 0; i < (*it)->classes.length (); i++)
    3370              :         {
    3371      2012542 :           congruence_class *c = (*it)->classes[i];
    3372      4025084 :           c->members.qsort (sort_sem_items_by_decl_uid);
    3373              :         }
    3374              : 
    3375      3809932 :       (*it)->classes.qsort (sort_congruence_classes_by_decl_uid);
    3376              :     }
    3377              : 
    3378       131334 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3379      2036300 :        it != m_classes.end (); ++it)
    3380      3917508 :     for (unsigned int i = 0; i < (*it)->classes.length (); i++)
    3381              :       {
    3382      2012542 :         congruence_class *c = (*it)->classes[i];
    3383      2134572 :         if (c->members.length () > 1)
    3384              :           {
    3385       122030 :             non_singular_classes_count++;
    3386       122030 :             non_singular_classes_sum += c->members.length ();
    3387              :           }
    3388              :       }
    3389              : 
    3390       131334 :   auto_vec<std::pair<congruence_class_group *, int> > classes (
    3391       131334 :     m_classes.elements ());
    3392       131334 :   for (hash_table<congruence_class_hash>::iterator it = m_classes.begin ();
    3393      2036300 :        it != m_classes.end (); ++it)
    3394              :     {
    3395      1904966 :       int uid = DECL_UID ((*it)->classes[0]->members[0]->decl);
    3396      1904966 :       classes.quick_push (std::pair<congruence_class_group *, int> (*it, uid));
    3397              :     }
    3398              : 
    3399       131334 :   classes.qsort (sort_congruence_class_groups_by_decl_uid);
    3400              : 
    3401       131334 :   if (dump_file)
    3402              :     {
    3403          192 :       fprintf (dump_file, "\nItem count: %u\n", item_count);
    3404          192 :       fprintf (dump_file, "Congruent classes before: %u, after: %u\n",
    3405              :                prev_class_count, class_count);
    3406          574 :       fprintf (dump_file, "Average class size before: %.2f, after: %.2f\n",
    3407          191 :                prev_class_count ? 1.0f * item_count / prev_class_count : 0.0f,
    3408          191 :                class_count ? 1.0f * item_count / class_count : 0.0f);
    3409          245 :       fprintf (dump_file, "Average non-singular class size: %.2f, count: %u\n",
    3410           53 :                non_singular_classes_count ? 1.0f * non_singular_classes_sum /
    3411              :                non_singular_classes_count : 0.0f,
    3412              :                non_singular_classes_count);
    3413          192 :       fprintf (dump_file, "Equal symbols: %u\n", equal_items);
    3414          192 :       unsigned total = equal_items + non_singular_classes_count;
    3415          252 :       fprintf (dump_file, "Totally needed symbols: %u"
    3416              :                ", fraction of loaded symbols: %.2f%%\n\n", total,
    3417           60 :                loaded_symbols ? 100.0f * total / loaded_symbols : 0.0f);
    3418              :     }
    3419              : 
    3420       131334 :   unsigned int l;
    3421       131334 :   std::pair<congruence_class_group *, int> *it;
    3422      3941266 :   FOR_EACH_VEC_ELT (classes, l, it)
    3423      3917508 :     for (unsigned int i = 0; i < it->first->classes.length (); i++)
    3424              :       {
    3425      2012542 :         congruence_class *c = it->first->classes[i];
    3426              : 
    3427      2012542 :         if (c->members.length () == 1)
    3428      1890512 :           continue;
    3429              : 
    3430       122030 :         sem_item *source = c->members[0];
    3431       122030 :         bool this_merged_p = false;
    3432              : 
    3433       122030 :         if (DECL_NAME (source->decl)
    3434       122030 :             && MAIN_NAME_P (DECL_NAME (source->decl)))
    3435              :           /* If merge via wrappers, picking main as the target can be
    3436              :              problematic.  */
    3437            0 :           source = c->members[1];
    3438              : 
    3439       743913 :         for (unsigned int j = 0; j < c->members.length (); j++)
    3440              :           {
    3441       621883 :             sem_item *alias = c->members[j];
    3442              : 
    3443       621883 :             if (alias == source)
    3444       122810 :               continue;
    3445              : 
    3446       499853 :             dump_user_location_t loc
    3447       499853 :               = dump_user_location_t::from_function_decl (source->decl);
    3448       499853 :             if (dump_enabled_p ())
    3449              :               {
    3450           90 :                 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
    3451              :                                  "Semantic equality hit:%s->%s\n",
    3452           90 :                                  source->node->dump_name (),
    3453           90 :                                  alias->node->dump_name ());
    3454           90 :                 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
    3455              :                                  "Assembler symbol names:%s->%s\n",
    3456           90 :                                  source->node->dump_asm_name (),
    3457           90 :                                  alias->node->dump_asm_name ());
    3458              :               }
    3459              : 
    3460       499853 :             if (lookup_attribute ("no_icf", DECL_ATTRIBUTES (alias->decl))
    3461       499853 :                 || lookup_attribute ("no_icf", DECL_ATTRIBUTES (source->decl)))
    3462              :               {
    3463          780 :                 if (dump_enabled_p ())
    3464            1 :                   dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,
    3465              :                                    "Merge operation is skipped due to no_icf "
    3466              :                                    "attribute.\n");
    3467          780 :                 continue;
    3468              :               }
    3469              : 
    3470       499073 :             if (dump_file && (dump_flags & TDF_DETAILS))
    3471              :               {
    3472           16 :                 source->dump_to_file (dump_file);
    3473           16 :                 alias->dump_to_file (dump_file);
    3474              :               }
    3475              : 
    3476       499073 :             if (dbg_cnt (merged_ipa_icf))
    3477              :               {
    3478       499069 :                 bool merged = source->merge (alias);
    3479       499069 :                 this_merged_p |= merged;
    3480              : 
    3481       499069 :                 if (merged && alias->type == VAR)
    3482              :                   {
    3483        12886 :                     symtab_pair p = symtab_pair (source->node, alias->node);
    3484        12886 :                     m_merged_variables.safe_push (p);
    3485              :                   }
    3486              :               }
    3487              :           }
    3488              : 
    3489       122030 :         merged_p |= this_merged_p;
    3490       122030 :         if (this_merged_p
    3491        19514 :             && source->type == FUNC
    3492        15388 :             && (!flag_wpa || flag_checking))
    3493              :           {
    3494              :             unsigned i;
    3495              :             tree name;
    3496      2083953 :             FOR_EACH_SSA_NAME (i, name, DECL_STRUCT_FUNCTION (source->decl))
    3497              :               {
    3498              :                 /* We need to either merge or reset SSA_NAME_*_INFO.
    3499              :                    For merging we don't preserve the mapping between
    3500              :                    original and alias SSA_NAMEs from successful equals
    3501              :                    calls.  */
    3502        66431 :                 if (POINTER_TYPE_P (TREE_TYPE (name)))
    3503              :                   {
    3504         6096 :                     if (SSA_NAME_PTR_INFO (name))
    3505              :                       {
    3506         3897 :                         gcc_checking_assert (!flag_wpa);
    3507         3897 :                         SSA_NAME_PTR_INFO (name) = NULL;
    3508              :                       }
    3509              :                   }
    3510        60335 :                 else if (SSA_NAME_RANGE_INFO (name))
    3511              :                   {
    3512         4607 :                     gcc_checking_assert (!flag_wpa);
    3513         4607 :                     SSA_NAME_RANGE_INFO (name) = NULL;
    3514              :                   }
    3515              :               }
    3516              :           }
    3517              :       }
    3518              : 
    3519       131334 :   if (!m_merged_variables.is_empty ())
    3520         2058 :     fixup_points_to_sets ();
    3521              : 
    3522       131334 :   return merged_p;
    3523       131334 : }
    3524              : 
    3525              : /* Fixup points to set PT.  */
    3526              : 
    3527              : void
    3528      1257368 : sem_item_optimizer::fixup_pt_set (struct pt_solution *pt)
    3529              : {
    3530      1257368 :   if (pt->vars == NULL)
    3531      1257368 :     return;
    3532              : 
    3533              :   unsigned i;
    3534              :   symtab_pair *item;
    3535     12428617 :   FOR_EACH_VEC_ELT (m_merged_variables, i, item)
    3536     11328906 :     if (bitmap_bit_p (pt->vars, DECL_UID (item->second->decl)))
    3537        13687 :       bitmap_set_bit (pt->vars, DECL_UID (item->first->decl));
    3538              : }
    3539              : 
    3540              : /* Set all points-to UIDs of aliases pointing to node N as UID.  */
    3541              : 
    3542              : static void
    3543       190512 : set_alias_uids (symtab_node *n, int uid)
    3544              : {
    3545       190512 :   ipa_ref *ref;
    3546       368138 :   FOR_EACH_ALIAS (n, ref)
    3547              :     {
    3548       177626 :       if (dump_file)
    3549           19 :         fprintf (dump_file, "  Setting points-to UID of [%s] as %d\n",
    3550           19 :                  ref->referring->dump_asm_name (), uid);
    3551              : 
    3552       177626 :       SET_DECL_PT_UID (ref->referring->decl, uid);
    3553       177626 :       set_alias_uids (ref->referring, uid);
    3554              :     }
    3555       190512 : }
    3556              : 
    3557              : /* Fixup points to analysis info.  */
    3558              : 
    3559              : void
    3560         2058 : sem_item_optimizer::fixup_points_to_sets (void)
    3561              : {
    3562              :   /* TODO: remove in GCC 9 and trigger PTA re-creation after IPA passes.  */
    3563         2058 :   cgraph_node *cnode;
    3564              : 
    3565        68521 :   FOR_EACH_DEFINED_FUNCTION (cnode)
    3566              :     {
    3567        66463 :       tree name;
    3568        66463 :       unsigned i;
    3569        66463 :       function *fn = DECL_STRUCT_FUNCTION (cnode->decl);
    3570        66463 :       if (!gimple_in_ssa_p (fn))
    3571         3896 :         continue;
    3572              : 
    3573      2538128 :       FOR_EACH_SSA_NAME (i, name, fn)
    3574      4580716 :         if (POINTER_TYPE_P (TREE_TYPE (name))
    3575      2512679 :             && SSA_NAME_PTR_INFO (name))
    3576       387374 :           fixup_pt_set (&SSA_NAME_PTR_INFO (name)->pt);
    3577        62567 :       fixup_pt_set (&fn->gimple_df->escaped);
    3578        62567 :       fixup_pt_set (&fn->gimple_df->escaped_return);
    3579              : 
    3580              :        /* The above gets us to 99% I guess, at least catching the
    3581              :           address compares.  Below also gets us aliasing correct
    3582              :           but as said we're giving leeway to the situation with
    3583              :           readonly vars anyway, so ... */
    3584        62567 :        basic_block bb;
    3585       747716 :        FOR_EACH_BB_FN (bb, fn)
    3586      6123875 :         for (gimple_stmt_iterator gsi = gsi_start_bb (bb); !gsi_end_p (gsi);
    3587      4753577 :              gsi_next (&gsi))
    3588              :           {
    3589      5126007 :             gcall *call = dyn_cast<gcall *> (gsi_stmt (gsi));
    3590       372430 :             if (call)
    3591              :               {
    3592       372430 :                 fixup_pt_set (gimple_call_use_set (call));
    3593       372430 :                 fixup_pt_set (gimple_call_clobber_set (call));
    3594              :               }
    3595              :           }
    3596              :     }
    3597              : 
    3598              :   unsigned i;
    3599              :   symtab_pair *item;
    3600        14944 :   FOR_EACH_VEC_ELT (m_merged_variables, i, item)
    3601        12886 :     set_alias_uids (item->first, DECL_UID (item->first->decl));
    3602         2058 : }
    3603              : 
    3604              : /* Dump function prints all class members to a FILE with an INDENT.  */
    3605              : 
    3606              : void
    3607          480 : congruence_class::dump (FILE *file, unsigned int indent) const
    3608              : {
    3609          960 :   FPRINTF_SPACES (file, indent, "class with id: %u, hash: %u, items: %u\n",
    3610          480 :                   id, members[0]->get_hash (), members.length ());
    3611              : 
    3612          480 :   FPUTS_SPACES (file, indent + 2, "");
    3613         1561 :   for (unsigned i = 0; i < members.length (); i++)
    3614          601 :     fprintf (file, "%s ", members[i]->node->dump_asm_name ());
    3615              : 
    3616          480 :   fprintf (file, "\n");
    3617          480 : }
    3618              : 
    3619              : /* Returns true if there's a member that is used from another group.  */
    3620              : 
    3621              : bool
    3622      3985783 : congruence_class::is_class_used (void)
    3623              : {
    3624      5044625 :   for (unsigned int i = 0; i < members.length (); i++)
    3625      4063001 :     if (members[i]->referenced_by_count)
    3626              :       return true;
    3627              : 
    3628              :   return false;
    3629              : }
    3630              : 
    3631              : /* Generate pass summary for IPA ICF pass.  */
    3632              : 
    3633              : static void
    3634       128149 : ipa_icf_generate_summary (void)
    3635              : {
    3636       128149 :   if (!optimizer)
    3637       128149 :     optimizer = new sem_item_optimizer ();
    3638              : 
    3639       128149 :   optimizer->register_hooks ();
    3640       128149 :   optimizer->parse_funcs_and_vars ();
    3641       128149 : }
    3642              : 
    3643              : /* Write pass summary for IPA ICF pass.  */
    3644              : 
    3645              : static void
    3646        20319 : ipa_icf_write_summary (void)
    3647              : {
    3648        20319 :   gcc_assert (optimizer);
    3649              : 
    3650        20319 :   optimizer->write_summary ();
    3651        20319 : }
    3652              : 
    3653              : /* Read pass summary for IPA ICF pass.  */
    3654              : 
    3655              : static void
    3656        12468 : ipa_icf_read_summary (void)
    3657              : {
    3658        12468 :   if (!optimizer)
    3659        12468 :     optimizer = new sem_item_optimizer ();
    3660              : 
    3661        12468 :   optimizer->read_summary ();
    3662        12468 :   optimizer->register_hooks ();
    3663        12468 : }
    3664              : 
    3665              : /* Semantic equality execution function.  */
    3666              : 
    3667              : static unsigned int
    3668       131334 : ipa_icf_driver (void)
    3669              : {
    3670       131334 :   gcc_assert (optimizer);
    3671              : 
    3672       131334 :   bool merged_p = optimizer->execute ();
    3673              : 
    3674       131334 :   delete optimizer;
    3675       131334 :   optimizer = NULL;
    3676              : 
    3677       131334 :   return merged_p ? TODO_remove_functions : 0;
    3678              : }
    3679              : 
    3680              : const pass_data pass_data_ipa_icf =
    3681              : {
    3682              :   IPA_PASS,                 /* type */
    3683              :   "icf",                  /* name */
    3684              :   OPTGROUP_IPA,             /* optinfo_flags */
    3685              :   TV_IPA_ICF,               /* tv_id */
    3686              :   0,                        /* properties_required */
    3687              :   0,                        /* properties_provided */
    3688              :   0,                        /* properties_destroyed */
    3689              :   0,                        /* todo_flags_start */
    3690              :   0,                        /* todo_flags_finish */
    3691              : };
    3692              : 
    3693              : class pass_ipa_icf : public ipa_opt_pass_d
    3694              : {
    3695              : public:
    3696       294587 :   pass_ipa_icf (gcc::context *ctxt)
    3697              :     : ipa_opt_pass_d (pass_data_ipa_icf, ctxt,
    3698              :                       ipa_icf_generate_summary, /* generate_summary */
    3699              :                       ipa_icf_write_summary, /* write_summary */
    3700              :                       ipa_icf_read_summary, /* read_summary */
    3701              :                       NULL, /*
    3702              :                       write_optimization_summary */
    3703              :                       NULL, /*
    3704              :                       read_optimization_summary */
    3705              :                       NULL, /* stmt_fixup */
    3706              :                       0, /* function_transform_todo_flags_start */
    3707              :                       NULL, /* function_transform */
    3708       294587 :                       NULL) /* variable_transform */
    3709       294587 :   {}
    3710              : 
    3711              :   /* opt_pass methods: */
    3712       603188 :   bool gate (function *) final override
    3713              :   {
    3714       603188 :     return in_lto_p || flag_ipa_icf_variables || flag_ipa_icf_functions;
    3715              :   }
    3716              : 
    3717       131334 :   unsigned int execute (function *) final override
    3718              :   {
    3719       131334 :     return ipa_icf_driver();
    3720              :   }
    3721              : }; // class pass_ipa_icf
    3722              : 
    3723              : } // ipa_icf namespace
    3724              : 
    3725              : ipa_opt_pass_d *
    3726       294587 : make_pass_ipa_icf (gcc::context *ctxt)
    3727              : {
    3728       294587 :   return new ipa_icf::pass_ipa_icf (ctxt);
    3729              : }
    3730              : 
    3731              : /* Reset all state within ipa-icf.cc so that we can rerun the compiler
    3732              :    within the same process.  For use by toplev::finalize.  */
    3733              : 
    3734              : void
    3735       264541 : ipa_icf_cc_finalize (void)
    3736              : {
    3737       264541 :   ipa_icf::optimizer = NULL;
    3738       264541 : }
        

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.