LCOV - code coverage report
Current view: top level - gcc - varpool.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.6 % 381 326
Test Date: 2025-11-22 14:42:49 Functions: 80.0 % 30 24
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Callgraph handling code.
       2                 :             :    Copyright (C) 2003-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by Jan Hubicka
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "backend.h"
      25                 :             : #include "target.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "gimple.h"
      28                 :             : #include "timevar.h"
      29                 :             : #include "cgraph.h"
      30                 :             : #include "lto-streamer.h"
      31                 :             : #include "varasm.h"
      32                 :             : #include "debug.h"
      33                 :             : #include "output.h"
      34                 :             : #include "omp-offload.h"
      35                 :             : #include "context.h"
      36                 :             : #include "stringpool.h"
      37                 :             : #include "attribs.h"
      38                 :             : #include "tree-pass.h"
      39                 :             : 
      40                 :             : const char * const tls_model_names[]={"none", "emulated",
      41                 :             :                                       "global-dynamic", "local-dynamic",
      42                 :             :                                       "initial-exec", "local-exec"};
      43                 :             : 
      44                 :             : /* List of hooks triggered on varpool_node events.  */
      45                 :             : struct varpool_node_hook_list {
      46                 :             :   varpool_node_hook hook;
      47                 :             :   void *data;
      48                 :             :   struct varpool_node_hook_list *next;
      49                 :             : };
      50                 :             : 
      51                 :             : /* Register HOOK to be called with DATA on each removed node.  */
      52                 :             : varpool_node_hook_list *
      53                 :      303042 : symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
      54                 :             : {
      55                 :      303042 :   varpool_node_hook_list *entry;
      56                 :      606084 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      57                 :             : 
      58                 :      303042 :   entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
      59                 :      303042 :   entry->hook = hook;
      60                 :      303042 :   entry->data = data;
      61                 :      303042 :   entry->next = NULL;
      62                 :      310778 :   while (*ptr)
      63                 :        7736 :     ptr = &(*ptr)->next;
      64                 :      303042 :   *ptr = entry;
      65                 :      303042 :   return entry;
      66                 :             : }
      67                 :             : 
      68                 :             : /* Remove ENTRY from the list of hooks called on removing nodes.  */
      69                 :             : void
      70                 :      289877 : symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
      71                 :             : {
      72                 :      289877 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      73                 :             : 
      74                 :      297407 :   while (*ptr != entry)
      75                 :        7530 :     ptr = &(*ptr)->next;
      76                 :      289877 :   *ptr = entry->next;
      77                 :      289877 :   free (entry);
      78                 :      289877 : }
      79                 :             : 
      80                 :             : /* Call all node removal hooks.  */
      81                 :             : void
      82                 :    20634053 : symbol_table::call_varpool_removal_hooks (varpool_node *node)
      83                 :             : {
      84                 :    20634053 :   varpool_node_hook_list *entry = m_first_varpool_removal_hook;
      85                 :    24618590 :   while (entry)
      86                 :             :   {
      87                 :     3984537 :     entry->hook (node, entry->data);
      88                 :     3984537 :     entry = entry->next;
      89                 :             :   }
      90                 :    20634053 : }
      91                 :             : 
      92                 :             : /* Register HOOK to be called with DATA on each inserted node.  */
      93                 :             : varpool_node_hook_list *
      94                 :           0 : symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
      95                 :             : {
      96                 :           0 :   varpool_node_hook_list *entry;
      97                 :           0 :   varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
      98                 :             : 
      99                 :           0 :   entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
     100                 :           0 :   entry->hook = hook;
     101                 :           0 :   entry->data = data;
     102                 :           0 :   entry->next = NULL;
     103                 :           0 :   while (*ptr)
     104                 :           0 :     ptr = &(*ptr)->next;
     105                 :           0 :   *ptr = entry;
     106                 :           0 :   return entry;
     107                 :             : }
     108                 :             : 
     109                 :             : /* Remove ENTRY from the list of hooks called on inserted nodes.  */
     110                 :             : void
     111                 :           0 : symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
     112                 :             : {
     113                 :           0 :   varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
     114                 :             : 
     115                 :           0 :   while (*ptr != entry)
     116                 :           0 :     ptr = &(*ptr)->next;
     117                 :           0 :   *ptr = entry->next;
     118                 :           0 :   free (entry);
     119                 :           0 : }
     120                 :             : 
     121                 :             : /* Call all node insertion hooks.  */
     122                 :             : void
     123                 :        2367 : symbol_table::call_varpool_insertion_hooks (varpool_node *node)
     124                 :             : {
     125                 :        2367 :   varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
     126                 :        2367 :   while (entry)
     127                 :             :   {
     128                 :           0 :     entry->hook (node, entry->data);
     129                 :           0 :     entry = entry->next;
     130                 :             :   }
     131                 :        2367 : }
     132                 :             : 
     133                 :             : /* Allocate new callgraph node and insert it into basic data structures.  */
     134                 :             : 
     135                 :             : varpool_node *
     136                 :    23979784 : varpool_node::create_empty (void)
     137                 :             : {
     138                 :    23979784 :   return new (ggc_alloc<varpool_node> ()) varpool_node ();
     139                 :             : }
     140                 :             : 
     141                 :             : /* Return varpool node assigned to DECL.  Create new one when needed.  */
     142                 :             : varpool_node *
     143                 :   170931581 : varpool_node::get_create (tree decl)
     144                 :             : {
     145                 :   170931581 :   varpool_node *node = varpool_node::get (decl);
     146                 :   170931581 :   gcc_checking_assert (VAR_P (decl));
     147                 :   170931581 :   if (node)
     148                 :             :     return node;
     149                 :             : 
     150                 :    23910001 :   node = varpool_node::create_empty ();
     151                 :    23910001 :   node->decl = decl;
     152                 :             : 
     153                 :    23879829 :   if ((flag_openacc || flag_openmp)
     154                 :    24013616 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     155                 :             :     {
     156                 :        5034 :       node->offloadable = 1;
     157                 :        5034 :       if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl))
     158                 :             :         {
     159                 :             :           g->have_offload = true;
     160                 :             :           if (!in_lto_p)
     161                 :             :             vec_safe_push (offload_vars, decl);
     162                 :             :         }
     163                 :             :     }
     164                 :             : 
     165                 :    23910001 :   node->register_symbol ();
     166                 :    23910001 :   return node;
     167                 :             : }
     168                 :             : 
     169                 :             : /* Remove variable from symbol table.  */
     170                 :             : 
     171                 :             : void
     172                 :    20634053 : varpool_node::remove (void)
     173                 :             : {
     174                 :    20634053 :   symtab->call_varpool_removal_hooks (this);
     175                 :    20634053 :   lto_free_function_in_decl_state_for_node (this);
     176                 :             : 
     177                 :             :   /* When streaming we can have multiple nodes associated with decl.  */
     178                 :    20634053 :   if (symtab->state == LTO_STREAMING)
     179                 :             :     ;
     180                 :             :   /* Keep constructor when it may be used for folding. We remove
     181                 :             :      references to external variables before final compilation.  */
     182                 :    39232775 :   else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
     183                 :    39231221 :            && !ctor_useable_for_folding_p ())
     184                 :        3712 :     remove_initializer ();
     185                 :             : 
     186                 :    20634053 :   unregister (NULL);
     187                 :    20634053 :   ggc_free (this);
     188                 :    20634053 : }
     189                 :             : 
     190                 :             : /* Remove node initializer when it is no longer needed.  */
     191                 :             : void
     192                 :     1991389 : varpool_node::remove_initializer (void)
     193                 :             : {
     194                 :     1991389 :   if (DECL_INITIAL (decl)
     195                 :        4264 :       && !DECL_IN_CONSTANT_POOL (decl)
     196                 :             :       /* Keep vtables for BINFO folding.  */
     197                 :        4264 :       && !DECL_VIRTUAL_P (decl)
     198                 :             :       /* FIXME: http://gcc.gnu.org/PR55395 */
     199                 :        4043 :       && debug_info_level == DINFO_LEVEL_NONE
     200                 :             :       /* When doing declaration merging we have duplicate
     201                 :             :          entries for given decl.  Do not attempt to remove
     202                 :             :          the bodies, or we will end up removing
     203                 :             :          wrong one.  */
     204                 :     1994786 :       && symtab->state != LTO_STREAMING)
     205                 :        3397 :     DECL_INITIAL (decl) = error_mark_node;
     206                 :     1991389 : }
     207                 :             : 
     208                 :             : /* Dump given varpool node to F.  */
     209                 :             : void
     210                 :        2461 : varpool_node::dump (FILE *f)
     211                 :             : {
     212                 :        2461 :   dump_base (f);
     213                 :        2461 :   fprintf (f, "  Availability: %s\n",
     214                 :        2461 :            symtab->function_flags_ready
     215                 :        2335 :            ? cgraph_availability_names[get_availability ()]
     216                 :             :            : "not-ready");
     217                 :        2461 :   fprintf (f, "  Varpool flags:");
     218                 :        2461 :   if (DECL_INITIAL (decl))
     219                 :        1513 :     fprintf (f, " initialized");
     220                 :        2461 :   if (output)
     221                 :           0 :     fprintf (f, " output");
     222                 :        2461 :   if (used_by_single_function)
     223                 :          43 :     fprintf (f, " used-by-single-function");
     224                 :        2461 :   if (TREE_READONLY (decl))
     225                 :        1441 :     fprintf (f, " read-only");
     226                 :        2461 :   if (ctor_useable_for_folding_p ())
     227                 :        1152 :     fprintf (f, " const-value-known");
     228                 :        2461 :   if (writeonly)
     229                 :           0 :     fprintf (f, " write-only");
     230                 :        2461 :   if (tls_model)
     231                 :          59 :     fprintf (f, " tls-%s", tls_model_names [tls_model]);
     232                 :        2461 :   fprintf (f, "\n");
     233                 :        2461 : }
     234                 :             : 
     235                 :             : 
     236                 :             : /* Dump given varpool node to stderr.  */
     237                 :           0 : void varpool_node::debug (void)
     238                 :             : {
     239                 :           0 :   varpool_node::dump (stderr);
     240                 :           0 : }
     241                 :             : 
     242                 :             : /* Dump the variable pool to F.  */
     243                 :             : void
     244                 :           0 : varpool_node::dump_varpool (FILE *f)
     245                 :             : {
     246                 :           0 :   varpool_node *node;
     247                 :             : 
     248                 :           0 :   fprintf (f, "variable pool:\n\n");
     249                 :           0 :   FOR_EACH_VARIABLE (node)
     250                 :           0 :     node->dump (f);
     251                 :           0 : }
     252                 :             : 
     253                 :             : /* Dump the variable pool to stderr.  */
     254                 :             : 
     255                 :             : DEBUG_FUNCTION void
     256                 :           0 : varpool_node::debug_varpool (void)
     257                 :             : {
     258                 :           0 :   dump_varpool (stderr);
     259                 :           0 : }
     260                 :             : 
     261                 :             : /* Given an assembler name, lookup node.  */
     262                 :             : varpool_node *
     263                 :           0 : varpool_node::get_for_asmname (tree asmname)
     264                 :             : {
     265                 :           0 :   if (symtab_node *node = symtab_node::get_for_asmname (asmname))
     266                 :           0 :     return dyn_cast <varpool_node *> (node);
     267                 :             :   else
     268                 :             :     return NULL;
     269                 :             : }
     270                 :             : 
     271                 :             : /* When doing LTO, read variable's constructor from disk if
     272                 :             :    it is not already present.  */
     273                 :             : 
     274                 :             : tree
     275                 :     7309745 : varpool_node::get_constructor (void)
     276                 :             : {
     277                 :     7309745 :   lto_file_decl_data *file_data;
     278                 :     7309745 :   const char *data, *name;
     279                 :     7309745 :   size_t len;
     280                 :             : 
     281                 :     7309745 :   if (DECL_INITIAL (decl) != error_mark_node
     282                 :        7601 :       || !in_lto_p
     283                 :     7317342 :       || !lto_file_data)
     284                 :     7302148 :     return DECL_INITIAL (decl);
     285                 :             : 
     286                 :        7597 :   timevar_push (TV_IPA_LTO_CTORS_IN);
     287                 :             : 
     288                 :        7597 :   file_data = lto_file_data;
     289                 :        7597 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     290                 :             : 
     291                 :             :   /* We may have renamed the declaration, e.g., a static function.  */
     292                 :        7597 :   name = lto_get_decl_name_mapping (file_data, name);
     293                 :        7597 :   struct lto_in_decl_state *decl_state
     294                 :        7597 :          = lto_get_function_in_decl_state (file_data, decl);
     295                 :             : 
     296                 :       15194 :   data = lto_get_section_data (file_data, LTO_section_function_body,
     297                 :        7597 :                                name, order - file_data->order_base,
     298                 :        7597 :                                &len, decl_state->compressed);
     299                 :        7597 :   if (!data)
     300                 :           0 :     fatal_error (input_location, "%s: section %s.%d is missing",
     301                 :             :                  file_data->file_name,
     302                 :           0 :                  name, order - file_data->order_base);
     303                 :             : 
     304                 :        7597 :   if (!quiet_flag)
     305                 :           0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
     306                 :        7597 :   lto_input_variable_constructor (file_data, this, data);
     307                 :        7597 :   gcc_assert (DECL_INITIAL (decl) != error_mark_node);
     308                 :        7597 :   lto_stats.num_function_bodies++;
     309                 :        7597 :   lto_free_section_data (file_data, LTO_section_function_body, name,
     310                 :        7597 :                          data, len, decl_state->compressed);
     311                 :        7597 :   lto_free_function_in_decl_state_for_node (this);
     312                 :        7597 :   timevar_pop (TV_IPA_LTO_CTORS_IN);
     313                 :        7597 :   return DECL_INITIAL (decl);
     314                 :             : }
     315                 :             : 
     316                 :             : /* Return true if variable has constructor that can be used for folding.  */
     317                 :             : 
     318                 :             : bool
     319                 :    55586424 : varpool_node::ctor_useable_for_folding_p (void)
     320                 :             : {
     321                 :    55586424 :   varpool_node *real_node = this;
     322                 :             : 
     323                 :    55586424 :   if (real_node->alias && real_node->definition)
     324                 :      216819 :     real_node = ultimate_alias_target ();
     325                 :             : 
     326                 :    55586424 :   if (TREE_CODE (decl) == CONST_DECL
     327                 :    55586424 :       || DECL_IN_CONSTANT_POOL (decl))
     328                 :             :     return true;
     329                 :    55585935 :   if (TREE_THIS_VOLATILE (decl))
     330                 :             :     return false;
     331                 :             : 
     332                 :             :   /* Avoid attempts to load constructors that was not streamed.  */
     333                 :      825561 :   if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
     334                 :    55615452 :       && real_node->body_removed)
     335                 :             :     return false;
     336                 :             : 
     337                 :             :   /* If we do not have a constructor, we can't use it.  */
     338                 :    55548361 :   if (DECL_INITIAL (real_node->decl) == error_mark_node
     339                 :    55548361 :       && !real_node->lto_file_data)
     340                 :             :     return false;
     341                 :             : 
     342                 :             :   /* Vtables are defined by their types and must match no matter of interposition
     343                 :             :      rules.  */
     344                 :    55548197 :   if (DECL_VIRTUAL_P (decl))
     345                 :             :     {
     346                 :             :       /* The C++ front end creates VAR_DECLs for vtables of typeinfo
     347                 :             :          classes not defined in the current TU so that it can refer
     348                 :             :          to them from typeinfo objects.  Avoid returning NULL_TREE.  */
     349                 :     1210752 :       return DECL_INITIAL (real_node->decl) != NULL;
     350                 :             :     }
     351                 :             : 
     352                 :             :   /* An alias of a read-only variable is also read-only, since the variable
     353                 :             :      is stored in read-only memory.  We also accept read-only aliases of
     354                 :             :      non-read-only locations assuming that the user knows what he is asking
     355                 :             :      for.  */
     356                 :    54337445 :   if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
     357                 :             :     return false;
     358                 :             : 
     359                 :             :   /* Variables declared 'const' without an initializer
     360                 :             :      have zero as the initializer if they may not be
     361                 :             :      overridden at link or run time.
     362                 :             : 
     363                 :             :      It is actually requirement for C++ compiler to optimize const variables
     364                 :             :      consistently. As a GNU extension, do not enforce this rule for user defined
     365                 :             :      weak variables, so we support interposition on:
     366                 :             :      static const int dummy = 0;
     367                 :             :      extern const int foo __attribute__((__weak__, __alias__("dummy")));
     368                 :             :    */
     369                 :    19678507 :   if ((!DECL_INITIAL (real_node->decl)
     370                 :    18645429 :        || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
     371                 :    19679113 :       && ((DECL_EXTERNAL (decl) && !in_other_partition)
     372                 :        7059 :           || decl_replaceable_p (decl, semantic_interposition)))
     373                 :     1027345 :     return false;
     374                 :             : 
     375                 :             :   /* Variables declared `const' with an initializer are considered
     376                 :             :      to not be overwritable with different initializer by default.
     377                 :             : 
     378                 :             :      ??? Previously we behaved so for scalar variables but not for array
     379                 :             :      accesses.  */
     380                 :             :   return true;
     381                 :             : }
     382                 :             : 
     383                 :             : /* If DECLARATION is constant variable and its initial value is known
     384                 :             :    (so we can do constant folding), return its constructor (DECL_INITIAL).
     385                 :             :    This may be an expression or NULL when DECL is initialized to 0.
     386                 :             :    Return ERROR_MARK_NODE otherwise.
     387                 :             : 
     388                 :             :    In LTO this may actually trigger reading the constructor from disk.
     389                 :             :    For this reason varpool_ctor_useable_for_folding_p should be used when
     390                 :             :    the actual constructor value is not needed.  */
     391                 :             : 
     392                 :             : tree
     393                 :   139712965 : ctor_for_folding (tree decl)
     394                 :             : {
     395                 :   139712965 :   varpool_node *node, *real_node;
     396                 :   139712965 :   tree real_decl;
     397                 :             : 
     398                 :   139712965 :   if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
     399                 :     4464580 :     return error_mark_node;
     400                 :             : 
     401                 :   135248385 :   if (TREE_CODE (decl) == CONST_DECL
     402                 :   135248385 :       || DECL_IN_CONSTANT_POOL (decl))
     403                 :       85562 :     return DECL_INITIAL (decl);
     404                 :             : 
     405                 :   135162823 :   if (TREE_THIS_VOLATILE (decl))
     406                 :     2115261 :     return error_mark_node;
     407                 :             : 
     408                 :             :   /* Do not care about automatic variables.  Those are never initialized
     409                 :             :      anyway, because gimplifier expands the code.  */
     410                 :   133047562 :   if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
     411                 :             :     {
     412                 :    95139185 :       gcc_assert (!TREE_PUBLIC (decl));
     413                 :             :       /* Unless this is called during FE folding.  */
     414                 :    95139185 :       if (cfun
     415                 :    95134521 :           && (cfun->curr_properties & (PROP_gimple | PROP_rtl)) == 0
     416                 :     5807291 :           && TREE_READONLY (decl)
     417                 :       18023 :           && !TREE_SIDE_EFFECTS (decl)
     418                 :    95157208 :           && DECL_INITIAL (decl))
     419                 :         401 :         return DECL_INITIAL (decl);
     420                 :    95138784 :       return error_mark_node;
     421                 :             :     }
     422                 :             : 
     423                 :    37908377 :   gcc_assert (VAR_P (decl));
     424                 :             : 
     425                 :    37908377 :   real_node = node = varpool_node::get (decl);
     426                 :    37908377 :   if (node)
     427                 :             :     {
     428                 :    37323559 :       real_node = node->ultimate_alias_target ();
     429                 :    37323559 :       real_decl = real_node->decl;
     430                 :             :     }
     431                 :             :   else
     432                 :             :     real_decl = decl;
     433                 :             : 
     434                 :             :   /* See if we are dealing with alias.
     435                 :             :      In most cases alias is just alternative symbol pointing to a given
     436                 :             :      constructor.  This allows us to use interposition rules of DECL
     437                 :             :      constructor of REAL_NODE.  However weakrefs are special by being just
     438                 :             :      alternative name of their target (if defined).  */
     439                 :    37908377 :   if (decl != real_decl)
     440                 :             :     {
     441                 :      216519 :       gcc_assert (!DECL_INITIAL (decl)
     442                 :             :                   || (node->alias && node->get_alias_target () == real_node)
     443                 :             :                   || DECL_INITIAL (decl) == error_mark_node);
     444                 :      216519 :       while (node->transparent_alias && node->analyzed)
     445                 :             :         {
     446                 :           0 :           node = node->get_alias_target ();
     447                 :           0 :           decl = node->decl;
     448                 :             :         }
     449                 :             :     }
     450                 :             : 
     451                 :    37908377 :   if ((!DECL_VIRTUAL_P (real_decl)
     452                 :      770974 :        || DECL_INITIAL (real_decl) == error_mark_node
     453                 :      770446 :        || !DECL_INITIAL (real_decl))
     454                 :    37980851 :       && (!node || !node->ctor_useable_for_folding_p ()))
     455                 :    36026539 :     return error_mark_node;
     456                 :             : 
     457                 :             :   /* OK, we can return constructor.  See if we need to fetch it from disk
     458                 :             :      in LTO mode.  */
     459                 :     1881838 :   if (DECL_INITIAL (real_decl) != error_mark_node
     460                 :     1881838 :       || !in_lto_p)
     461                 :     1880503 :     return DECL_INITIAL (real_decl);
     462                 :        1335 :   return real_node->get_constructor ();
     463                 :             : }
     464                 :             : 
     465                 :             : /* Add the variable DECL to the varpool.
     466                 :             :    Unlike finalize_decl function is intended to be used
     467                 :             :    by middle end and allows insertion of new variable at arbitrary point
     468                 :             :    of compilation.  */
     469                 :             : void
     470                 :        2367 : varpool_node::add (tree decl)
     471                 :             : {
     472                 :        2367 :   varpool_node *node;
     473                 :        2367 :   varpool_node::finalize_decl (decl);
     474                 :        2367 :   node = varpool_node::get_create (decl);
     475                 :        2367 :   symtab->call_varpool_insertion_hooks (node);
     476                 :        2367 :   if (node->externally_visible_p ())
     477                 :        2356 :     node->externally_visible = true;
     478                 :        2367 :   if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
     479                 :           0 :     node->no_reorder = 1;
     480                 :        2367 : }
     481                 :             : 
     482                 :             : /* Return variable availability.  See cgraph.h for description of individual
     483                 :             :    return values.  */
     484                 :             : enum availability
     485                 :   170391100 : varpool_node::get_availability (symtab_node *ref)
     486                 :             : {
     487                 :   170391100 :   if (!definition && !in_other_partition)
     488                 :             :     return AVAIL_NOT_AVAILABLE;
     489                 :   146831748 :   if (!TREE_PUBLIC (decl))
     490                 :             :     return AVAIL_AVAILABLE;
     491                 :    51267991 :   if (DECL_IN_CONSTANT_POOL (decl)
     492                 :    51267991 :       || DECL_VIRTUAL_P (decl))
     493                 :             :     return AVAIL_AVAILABLE;
     494                 :    51209223 :   if (transparent_alias && definition)
     495                 :             :     {
     496                 :           0 :       enum availability avail;
     497                 :             : 
     498                 :           0 :       ultimate_alias_target (&avail, ref);
     499                 :           0 :       return avail;
     500                 :             :     }
     501                 :             :   /* If this is a reference from symbol itself and there are no aliases, we
     502                 :             :      may be sure that the symbol was not interposed by something else because
     503                 :             :      the symbol itself would be unreachable otherwise.  */
     504                 :           0 :   if ((this == ref && !has_aliases_p ())
     505                 :    51209223 :       || (ref && get_comdat_group ()
     506                 :           0 :           && get_comdat_group () == ref->get_comdat_group ()))
     507                 :             :     return AVAIL_AVAILABLE;
     508                 :             :   /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     509                 :             :      care of at least one notable extension - the COMDAT variables
     510                 :             :      used to share template instantiations in C++.  */
     511                 :    51209223 :   if (decl_replaceable_p (decl, semantic_interposition)
     512                 :    51209223 :       || (DECL_EXTERNAL (decl) && !in_other_partition))
     513                 :             :     return AVAIL_INTERPOSABLE;
     514                 :             :   return AVAIL_AVAILABLE;
     515                 :             : }
     516                 :             : 
     517                 :             : void
     518                 :     3056970 : varpool_node::analyze (void)
     519                 :             : {
     520                 :             :   /* When reading back varpool at LTO time, we re-construct the queue in order
     521                 :             :      to have "needed" list right by inserting all needed nodes into varpool.
     522                 :             :      We however don't want to re-analyze already analyzed nodes.  */
     523                 :     3056970 :   if (!analyzed)
     524                 :             :     {
     525                 :     3056970 :       gcc_assert (!in_lto_p || symtab->function_flags_ready);
     526                 :             :       /* Compute the alignment early so function body expanders are
     527                 :             :          already informed about increased alignment.  */
     528                 :     3056970 :       align_variable (decl, 0);
     529                 :             :     }
     530                 :     3056970 :   if (alias)
     531                 :         135 :     resolve_alias (varpool_node::get (alias_target));
     532                 :     3056835 :   else if (DECL_INITIAL (decl))
     533                 :     2002117 :     record_references_in_initializer (decl, analyzed);
     534                 :     3056970 :   analyzed = true;
     535                 :     3056970 : }
     536                 :             : 
     537                 :             : /* Assemble thunks and aliases associated to varpool node.  */
     538                 :             : 
     539                 :             : void
     540                 :     2826521 : varpool_node::assemble_aliases (void)
     541                 :             : {
     542                 :     2826521 :   ipa_ref *ref;
     543                 :             : 
     544                 :     2831248 :   FOR_EACH_ALIAS (this, ref)
     545                 :             :     {
     546                 :        4727 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     547                 :        4727 :       if (alias->symver)
     548                 :           0 :         do_assemble_symver (alias->decl,
     549                 :             :                             DECL_ASSEMBLER_NAME (decl));
     550                 :        4727 :       else if (!alias->transparent_alias)
     551                 :        4727 :         do_assemble_alias (alias->decl,
     552                 :             :                            DECL_ASSEMBLER_NAME (decl));
     553                 :        4727 :       alias->assemble_aliases ();
     554                 :             :     }
     555                 :     2826521 : }
     556                 :             : 
     557                 :             : /* Output one variable, if necessary.  Return whether we output it.  */
     558                 :             : 
     559                 :             : bool
     560                 :     2828682 : varpool_node::assemble_decl (void)
     561                 :             : {
     562                 :             :   /* Aliases are output when their target is produced or by
     563                 :             :      output_weakrefs.  */
     564                 :     2828682 :   if (alias)
     565                 :             :     return false;
     566                 :             : 
     567                 :             :   /* Constant pool is output from RTL land when the reference
     568                 :             :      survive till this level.  */
     569                 :     2823952 :   if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
     570                 :             :     return false;
     571                 :             : 
     572                 :             :   /* Decls with VALUE_EXPR should not be in the varpool at all.  They
     573                 :             :      are not real variables, but just info for debugging and codegen.
     574                 :             :      Unfortunately at the moment emutls is not updating varpool correctly
     575                 :             :      after turning real vars into value_expr vars.  */
     576                 :     2821974 :   if (DECL_HAS_VALUE_EXPR_P (decl)
     577                 :     2821974 :       && !targetm.have_tls)
     578                 :             :     return false;
     579                 :             : 
     580                 :             :   /* Hard register vars do not need to be output.  */
     581                 :     2821974 :   if (DECL_HARD_REGISTER (decl))
     582                 :             :     return false;
     583                 :             : 
     584                 :     2821974 :   gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
     585                 :             :                        && VAR_P (decl)
     586                 :             :                        && !DECL_HAS_VALUE_EXPR_P (decl));
     587                 :             : 
     588                 :     2821974 :   if (!in_other_partition
     589                 :     2821974 :       && !DECL_EXTERNAL (decl))
     590                 :             :     {
     591                 :     2821794 :       get_constructor ();
     592                 :     2821794 :       assemble_variable (decl, 0, 1, 0);
     593                 :     2821794 :       gcc_assert (TREE_ASM_WRITTEN (decl));
     594                 :     2821794 :       gcc_assert (definition);
     595                 :     2821794 :       assemble_aliases ();
     596                 :             :       /* After the parser has generated debugging information, augment
     597                 :             :          this information with any new location/etc information that may
     598                 :             :          have become available after the compilation proper.  */
     599                 :     2821794 :       debug_hooks->late_global_decl (decl);
     600                 :     2821794 :       return true;
     601                 :             :     }
     602                 :             : 
     603                 :             :   return false;
     604                 :             : }
     605                 :             : 
     606                 :             : /* Add NODE to queue starting at FIRST.
     607                 :             :    The queue is linked via AUX pointers and terminated by pointer to 1.  */
     608                 :             : 
     609                 :             : static void
     610                 :     4716608 : enqueue_node (varpool_node *node, varpool_node **first)
     611                 :             : {
     612                 :     4716608 :   if (node->aux)
     613                 :             :     return;
     614                 :     2823936 :   gcc_checking_assert (*first);
     615                 :     2823936 :   node->aux = *first;
     616                 :     2823936 :   *first = node;
     617                 :             : }
     618                 :             : 
     619                 :             : /* Optimization of function bodies might've rendered some variables as
     620                 :             :    unnecessary so we want to avoid these from being compiled.  Re-do
     621                 :             :    reachability starting from variables that are either externally visible
     622                 :             :    or was referred from the asm output routines.  */
     623                 :             : 
     624                 :             : void
     625                 :      231294 : symbol_table::remove_unreferenced_decls (void)
     626                 :             : {
     627                 :      231294 :   varpool_node *next, *node;
     628                 :      231294 :   varpool_node *first = (varpool_node *)(void *)1;
     629                 :      231294 :   int i;
     630                 :      231294 :   ipa_ref *ref = NULL;
     631                 :      231294 :   hash_set<varpool_node *> referenced;
     632                 :             : 
     633                 :      231294 :   if (seen_error ())
     634                 :           0 :     return;
     635                 :             : 
     636                 :      231294 :   if (dump_file)
     637                 :          72 :     fprintf (dump_file, "Trivially needed variables:");
     638                 :     3111303 :   FOR_EACH_DEFINED_VARIABLE (node)
     639                 :             :     {
     640                 :     2880009 :       if (node->analyzed
     641                 :     2880009 :           && (!node->can_remove_if_no_refs_p ()
     642                 :             :               /* We just expanded all function bodies.  See if any of
     643                 :             :                  them needed the variable.  */
     644                 :     1389816 :               || DECL_RTL_SET_P (node->decl)))
     645                 :             :         {
     646                 :     2210514 :           enqueue_node (node, &first);
     647                 :     2210514 :           if (dump_file)
     648                 :          59 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     649                 :             :         }
     650                 :             :     }
     651                 :     3055230 :   while (first != (varpool_node *)(void *)1)
     652                 :             :     {
     653                 :     2823936 :       node = first;
     654                 :     2823936 :       first = (varpool_node *)first->aux;
     655                 :             : 
     656                 :     2823936 :       if (node->same_comdat_group)
     657                 :             :         {
     658                 :             :           symtab_node *next;
     659                 :      209894 :           for (next = node->same_comdat_group;
     660                 :      219506 :                next != node;
     661                 :      209894 :                next = next->same_comdat_group)
     662                 :             :             {
     663                 :      419788 :               varpool_node *vnext = dyn_cast <varpool_node *> (next);
     664                 :      419788 :               if (vnext && vnext->analyzed && !next->comdat_local_p ())
     665                 :      209888 :                 enqueue_node (vnext, &first);
     666                 :             :             }
     667                 :             :         }
     668                 :     9351305 :       for (i = 0; node->iterate_reference (i, ref); i++)
     669                 :             :         {
     670                 :     3472139 :           varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
     671                 :     3472139 :           if (vnode
     672                 :     2542339 :               && !vnode->in_other_partition
     673                 :     2542332 :               && (!DECL_EXTERNAL (ref->referred->decl)
     674                 :      246119 :                   || vnode->alias)
     675                 :     5768352 :               && vnode->analyzed)
     676                 :     2296206 :             enqueue_node (vnode, &first);
     677                 :             :           else
     678                 :             :             {
     679                 :     1175933 :               if (vnode)
     680                 :      246133 :                 referenced.add (vnode);
     681                 :     1175933 :               while (vnode && vnode->alias && vnode->definition)
     682                 :             :                 {
     683                 :           0 :                   vnode = vnode->get_alias_target ();
     684                 :           0 :                   gcc_checking_assert (vnode);
     685                 :           0 :                   referenced.add (vnode);
     686                 :             :                 }
     687                 :             :             }
     688                 :             :         }
     689                 :             :     }
     690                 :      231294 :   if (dump_file)
     691                 :          72 :     fprintf (dump_file, "\nRemoving variables:");
     692                 :     3111303 :   for (node = first_defined_variable (); node; node = next)
     693                 :             :     {
     694                 :     2880009 :       next = next_defined_variable (node);
     695                 :     2880009 :       if (!node->aux && !node->no_reorder)
     696                 :             :         {
     697                 :       56072 :           if (dump_file)
     698                 :           0 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     699                 :       56072 :           if (referenced.contains(node))
     700                 :           0 :             node->remove_initializer ();
     701                 :             :           else
     702                 :       56072 :             node->remove ();
     703                 :             :         }
     704                 :             :     }
     705                 :             : 
     706                 :      231294 :   if (dump_file)
     707                 :          72 :     fprintf (dump_file, "\n");
     708                 :      231294 : }
     709                 :             : 
     710                 :             : /* For variables in named sections make sure get_variable_section
     711                 :             :    is called before we switch to those sections.  Then section
     712                 :             :    conflicts between read-only and read-only requiring relocations
     713                 :             :    sections can be resolved.  */
     714                 :             : void
     715                 :     2816657 : varpool_node::finalize_named_section_flags (void)
     716                 :             : {
     717                 :     2816657 :   if (!TREE_ASM_WRITTEN (decl)
     718                 :     2814946 :       && !alias
     719                 :     2810249 :       && !in_other_partition
     720                 :     2810249 :       && !DECL_EXTERNAL (decl)
     721                 :     2810213 :       && VAR_P (decl)
     722                 :     2810213 :       && !DECL_HAS_VALUE_EXPR_P (decl)
     723                 :     5626870 :       && get_section ())
     724                 :     1432443 :     get_variable_section (decl, false);
     725                 :     2816657 : }
     726                 :             : 
     727                 :             : /* Output all variables enqueued to be assembled.  */
     728                 :             : bool
     729                 :      231576 : symbol_table::output_variables (void)
     730                 :             : {
     731                 :      231576 :   bool changed = false;
     732                 :      231576 :   varpool_node *node;
     733                 :             : 
     734                 :      231576 :   if (seen_error ())
     735                 :             :     return false;
     736                 :             : 
     737                 :      231294 :   remove_unreferenced_decls ();
     738                 :             : 
     739                 :      231294 :   timevar_push (TV_VAROUT);
     740                 :             : 
     741                 :     3055231 :   FOR_EACH_DEFINED_VARIABLE (node)
     742                 :             :     {
     743                 :             :       /* Handled in output_in_order.  */
     744                 :     2823937 :       if (node->no_reorder)
     745                 :      995425 :         continue;
     746                 :             : 
     747                 :     1828512 :       node->finalize_named_section_flags ();
     748                 :             :     }
     749                 :             : 
     750                 :             :   /* There is a similar loop in output_in_order.  Please keep them in sync.  */
     751                 :     6697608 :   FOR_EACH_VARIABLE (node)
     752                 :             :     {
     753                 :             :       /* Handled in output_in_order.  */
     754                 :     3117510 :       if (node->no_reorder)
     755                 :      995936 :         continue;
     756                 :     2121574 :       if (DECL_HARD_REGISTER (node->decl)
     757                 :     2121574 :           || DECL_HAS_VALUE_EXPR_P (node->decl))
     758                 :          62 :         continue;
     759                 :     2121512 :       if (node->definition)
     760                 :     1828450 :         changed |= node->assemble_decl ();
     761                 :             :       else
     762                 :      293062 :         assemble_undefined_decl (node->decl);
     763                 :             :     }
     764                 :      231294 :   timevar_pop (TV_VAROUT);
     765                 :      231294 :   return changed;
     766                 :             : }
     767                 :             : 
     768                 :             : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     769                 :             :    Extra name aliases are output whenever DECL is output.  */
     770                 :             : 
     771                 :             : varpool_node *
     772                 :       12405 : varpool_node::create_alias (tree alias, tree decl)
     773                 :             : {
     774                 :       12405 :   varpool_node *alias_node;
     775                 :             : 
     776                 :       12405 :   gcc_assert (VAR_P (decl));
     777                 :       12405 :   gcc_assert (VAR_P (alias));
     778                 :       12405 :   alias_node = varpool_node::get_create (alias);
     779                 :       12405 :   alias_node->alias = true;
     780                 :       12405 :   alias_node->definition = true;
     781                 :       12405 :   alias_node->semantic_interposition = flag_semantic_interposition;
     782                 :       12405 :   alias_node->alias_target = decl;
     783                 :       12405 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     784                 :          11 :     alias_node->weakref = alias_node->transparent_alias = true;
     785                 :       12405 :   return alias_node;
     786                 :             : }
     787                 :             : 
     788                 :             : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     789                 :             :    Extra name aliases are output whenever DECL is output.  */
     790                 :             : 
     791                 :             : varpool_node *
     792                 :          43 : varpool_node::create_extra_name_alias (tree alias, tree decl)
     793                 :             : {
     794                 :          43 :   varpool_node *alias_node;
     795                 :             : 
     796                 :             :   /* If aliases aren't supported by the assembler, fail.  */
     797                 :          43 :   if (!TARGET_SUPPORTS_ALIASES)
     798                 :             :     return NULL;
     799                 :             : 
     800                 :          43 :   alias_node = varpool_node::create_alias (alias, decl);
     801                 :          43 :   alias_node->cpp_implicit_alias = true;
     802                 :             : 
     803                 :             :   /* Extra name alias mechanism creates aliases really late
     804                 :             :      via DECL_ASSEMBLER_NAME mechanism.
     805                 :             :      This is unfortunate because they are not going through the
     806                 :             :      standard channels.  Ensure they get output.  */
     807                 :          43 :   if (symtab->cpp_implicit_aliases_done)
     808                 :          43 :     alias_node->resolve_alias (varpool_node::get_create (decl));
     809                 :          43 :   return alias_node;
     810                 :             : }
     811                 :             : 
     812                 :             : /* Worker for call_for_symbol_and_aliases.  */
     813                 :             : 
     814                 :             : bool
     815                 :        6693 : varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
     816                 :             :                                                                void *),
     817                 :             :                                              void *data,
     818                 :             :                                              bool include_overwritable)
     819                 :             : {
     820                 :        6693 :   ipa_ref *ref;
     821                 :             : 
     822                 :       29484 :   FOR_EACH_ALIAS (this, ref)
     823                 :             :     {
     824                 :       22791 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     825                 :       22791 :       if (include_overwritable
     826                 :       22791 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
     827                 :       22791 :         if (alias->call_for_symbol_and_aliases (callback, data,
     828                 :             :                                                 include_overwritable))
     829                 :             :           return true;
     830                 :             :     }
     831                 :             :   return false;
     832                 :             : }
        

Generated by: LCOV version 2.1-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.