LCOV - code coverage report
Current view: top level - gcc - varpool.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 85.6 % 382 327
Test Date: 2024-04-20 14:03:02 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-2024 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                 :      288994 : symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
      54                 :             : {
      55                 :      288994 :   varpool_node_hook_list *entry;
      56                 :      288994 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      57                 :             : 
      58                 :      288994 :   entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
      59                 :      288994 :   entry->hook = hook;
      60                 :      288994 :   entry->data = data;
      61                 :      288994 :   entry->next = NULL;
      62                 :      297306 :   while (*ptr)
      63                 :        8312 :     ptr = &(*ptr)->next;
      64                 :      288994 :   *ptr = entry;
      65                 :      288994 :   return entry;
      66                 :             : }
      67                 :             : 
      68                 :             : /* Remove ENTRY from the list of hooks called on removing nodes.  */
      69                 :             : void
      70                 :      275965 : symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
      71                 :             : {
      72                 :      275965 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      73                 :             : 
      74                 :      284081 :   while (*ptr != entry)
      75                 :        8116 :     ptr = &(*ptr)->next;
      76                 :      275965 :   *ptr = entry->next;
      77                 :      275965 :   free (entry);
      78                 :      275965 : }
      79                 :             : 
      80                 :             : /* Call all node removal hooks.  */
      81                 :             : void
      82                 :    16231299 : symbol_table::call_varpool_removal_hooks (varpool_node *node)
      83                 :             : {
      84                 :    16231299 :   varpool_node_hook_list *entry = m_first_varpool_removal_hook;
      85                 :    19628324 :   while (entry)
      86                 :             :   {
      87                 :     3397025 :     entry->hook (node, entry->data);
      88                 :     3397025 :     entry = entry->next;
      89                 :             :   }
      90                 :    16231299 : }
      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                 :         489 : symbol_table::call_varpool_insertion_hooks (varpool_node *node)
     124                 :             : {
     125                 :         489 :   varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
     126                 :         489 :   while (entry)
     127                 :             :   {
     128                 :           0 :     entry->hook (node, entry->data);
     129                 :           0 :     entry = entry->next;
     130                 :             :   }
     131                 :         489 : }
     132                 :             : 
     133                 :             : /* Allocate new callgraph node and insert it into basic data structures.  */
     134                 :             : 
     135                 :             : varpool_node *
     136                 :    19552047 : varpool_node::create_empty (void)
     137                 :             : {
     138                 :    19552047 :   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                 :   137234226 : varpool_node::get_create (tree decl)
     144                 :             : {
     145                 :   137234226 :   varpool_node *node = varpool_node::get (decl);
     146                 :   137234226 :   gcc_checking_assert (VAR_P (decl));
     147                 :   137234226 :   if (node)
     148                 :             :     return node;
     149                 :             : 
     150                 :    19484302 :   node = varpool_node::create_empty ();
     151                 :    19484302 :   node->decl = decl;
     152                 :             : 
     153                 :    19454765 :   if ((flag_openacc || flag_openmp)
     154                 :    19536539 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     155                 :             :     {
     156                 :        4777 :       node->offloadable = 1;
     157                 :        4777 :       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                 :    19484302 :   node->register_symbol ();
     166                 :    19484302 :   return node;
     167                 :             : }
     168                 :             : 
     169                 :             : /* Remove variable from symbol table.  */
     170                 :             : 
     171                 :             : void
     172                 :    16231299 : varpool_node::remove (void)
     173                 :             : {
     174                 :    16231299 :   symtab->call_varpool_removal_hooks (this);
     175                 :    16231299 :   if (lto_file_data)
     176                 :             :     {
     177                 :        5241 :       lto_free_function_in_decl_state_for_node (this);
     178                 :        5241 :       lto_file_data = NULL;
     179                 :             :     }
     180                 :             : 
     181                 :             :   /* When streaming we can have multiple nodes associated with decl.  */
     182                 :    16231299 :   if (symtab->state == LTO_STREAMING)
     183                 :             :     ;
     184                 :             :   /* Keep constructor when it may be used for folding. We remove
     185                 :             :      references to external variables before final compilation.  */
     186                 :    30525758 :   else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
     187                 :    30524285 :            && !ctor_useable_for_folding_p ())
     188                 :        4670 :     remove_initializer ();
     189                 :             : 
     190                 :    16231299 :   unregister (NULL);
     191                 :    16231299 :   ggc_free (this);
     192                 :    16231299 : }
     193                 :             : 
     194                 :             : /* Remove node initializer when it is no longer needed.  */
     195                 :             : void
     196                 :     1987612 : varpool_node::remove_initializer (void)
     197                 :             : {
     198                 :     1987612 :   if (DECL_INITIAL (decl)
     199                 :        5163 :       && !DECL_IN_CONSTANT_POOL (decl)
     200                 :             :       /* Keep vtables for BINFO folding.  */
     201                 :        5163 :       && !DECL_VIRTUAL_P (decl)
     202                 :             :       /* FIXME: http://gcc.gnu.org/PR55395 */
     203                 :        4974 :       && debug_info_level == DINFO_LEVEL_NONE
     204                 :             :       /* When doing declaration merging we have duplicate
     205                 :             :          entries for given decl.  Do not attempt to remove
     206                 :             :          the bodies, or we will end up removing
     207                 :             :          wrong one.  */
     208                 :     1990049 :       && symtab->state != LTO_STREAMING)
     209                 :        2437 :     DECL_INITIAL (decl) = error_mark_node;
     210                 :     1987612 : }
     211                 :             : 
     212                 :             : /* Dump given varpool node to F.  */
     213                 :             : void
     214                 :        2820 : varpool_node::dump (FILE *f)
     215                 :             : {
     216                 :        2820 :   dump_base (f);
     217                 :        2820 :   fprintf (f, "  Availability: %s\n",
     218                 :        2820 :            symtab->function_flags_ready
     219                 :        2688 :            ? cgraph_availability_names[get_availability ()]
     220                 :             :            : "not-ready");
     221                 :        2820 :   fprintf (f, "  Varpool flags:");
     222                 :        2820 :   if (DECL_INITIAL (decl))
     223                 :        1812 :     fprintf (f, " initialized");
     224                 :        2820 :   if (output)
     225                 :           0 :     fprintf (f, " output");
     226                 :        2820 :   if (used_by_single_function)
     227                 :          43 :     fprintf (f, " used-by-single-function");
     228                 :        2820 :   if (TREE_READONLY (decl))
     229                 :        1822 :     fprintf (f, " read-only");
     230                 :        2820 :   if (ctor_useable_for_folding_p ())
     231                 :        1454 :     fprintf (f, " const-value-known");
     232                 :        2820 :   if (writeonly)
     233                 :           0 :     fprintf (f, " write-only");
     234                 :        2820 :   if (tls_model)
     235                 :          35 :     fprintf (f, " tls-%s", tls_model_names [tls_model]);
     236                 :        2820 :   fprintf (f, "\n");
     237                 :        2820 : }
     238                 :             : 
     239                 :             : 
     240                 :             : /* Dump given varpool node to stderr.  */
     241                 :           0 : void varpool_node::debug (void)
     242                 :             : {
     243                 :           0 :   varpool_node::dump (stderr);
     244                 :           0 : }
     245                 :             : 
     246                 :             : /* Dump the variable pool to F.  */
     247                 :             : void
     248                 :           0 : varpool_node::dump_varpool (FILE *f)
     249                 :             : {
     250                 :           0 :   varpool_node *node;
     251                 :             : 
     252                 :           0 :   fprintf (f, "variable pool:\n\n");
     253                 :           0 :   FOR_EACH_VARIABLE (node)
     254                 :           0 :     node->dump (f);
     255                 :           0 : }
     256                 :             : 
     257                 :             : /* Dump the variable pool to stderr.  */
     258                 :             : 
     259                 :             : DEBUG_FUNCTION void
     260                 :           0 : varpool_node::debug_varpool (void)
     261                 :             : {
     262                 :           0 :   dump_varpool (stderr);
     263                 :           0 : }
     264                 :             : 
     265                 :             : /* Given an assembler name, lookup node.  */
     266                 :             : varpool_node *
     267                 :           0 : varpool_node::get_for_asmname (tree asmname)
     268                 :             : {
     269                 :           0 :   if (symtab_node *node = symtab_node::get_for_asmname (asmname))
     270                 :           0 :     return dyn_cast <varpool_node *> (node);
     271                 :             :   else
     272                 :             :     return NULL;
     273                 :             : }
     274                 :             : 
     275                 :             : /* When doing LTO, read variable's constructor from disk if
     276                 :             :    it is not already present.  */
     277                 :             : 
     278                 :             : tree
     279                 :     7292761 : varpool_node::get_constructor (void)
     280                 :             : {
     281                 :     7292761 :   lto_file_decl_data *file_data;
     282                 :     7292761 :   const char *data, *name;
     283                 :     7292761 :   size_t len;
     284                 :             : 
     285                 :     7292761 :   if (DECL_INITIAL (decl) != error_mark_node
     286                 :        7121 :       || !in_lto_p
     287                 :     7299878 :       || !lto_file_data)
     288                 :     7285644 :     return DECL_INITIAL (decl);
     289                 :             : 
     290                 :        7117 :   timevar_push (TV_IPA_LTO_CTORS_IN);
     291                 :             : 
     292                 :        7117 :   file_data = lto_file_data;
     293                 :        7117 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     294                 :             : 
     295                 :             :   /* We may have renamed the declaration, e.g., a static function.  */
     296                 :        7117 :   name = lto_get_decl_name_mapping (file_data, name);
     297                 :        7117 :   struct lto_in_decl_state *decl_state
     298                 :        7117 :          = lto_get_function_in_decl_state (file_data, decl);
     299                 :             : 
     300                 :       14234 :   data = lto_get_section_data (file_data, LTO_section_function_body,
     301                 :        7117 :                                name, order - file_data->order_base,
     302                 :        7117 :                                &len, decl_state->compressed);
     303                 :        7117 :   if (!data)
     304                 :           0 :     fatal_error (input_location, "%s: section %s.%d is missing",
     305                 :             :                  file_data->file_name,
     306                 :           0 :                  name, order - file_data->order_base);
     307                 :             : 
     308                 :        7117 :   if (!quiet_flag)
     309                 :           0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
     310                 :        7117 :   lto_input_variable_constructor (file_data, this, data);
     311                 :        7117 :   gcc_assert (DECL_INITIAL (decl) != error_mark_node);
     312                 :        7117 :   lto_stats.num_function_bodies++;
     313                 :        7117 :   lto_free_section_data (file_data, LTO_section_function_body, name,
     314                 :        7117 :                          data, len, decl_state->compressed);
     315                 :        7117 :   lto_free_function_in_decl_state_for_node (this);
     316                 :        7117 :   timevar_pop (TV_IPA_LTO_CTORS_IN);
     317                 :        7117 :   return DECL_INITIAL (decl);
     318                 :             : }
     319                 :             : 
     320                 :             : /* Return true if variable has constructor that can be used for folding.  */
     321                 :             : 
     322                 :             : bool
     323                 :    48895581 : varpool_node::ctor_useable_for_folding_p (void)
     324                 :             : {
     325                 :    48895581 :   varpool_node *real_node = this;
     326                 :             : 
     327                 :    48895581 :   if (real_node->alias && real_node->definition)
     328                 :      176347 :     real_node = ultimate_alias_target ();
     329                 :             : 
     330                 :    48895581 :   if (TREE_CODE (decl) == CONST_DECL
     331                 :    48895581 :       || DECL_IN_CONSTANT_POOL (decl))
     332                 :             :     return true;
     333                 :    48895124 :   if (TREE_THIS_VOLATILE (decl))
     334                 :             :     return false;
     335                 :             : 
     336                 :             :   /* Avoid attempts to load constructors that was not streamed.  */
     337                 :      781362 :   if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
     338                 :    48916638 :       && real_node->body_removed)
     339                 :             :     return false;
     340                 :             : 
     341                 :             :   /* If we do not have a constructor, we can't use it.  */
     342                 :    48857728 :   if (DECL_INITIAL (real_node->decl) == error_mark_node
     343                 :    48857728 :       && !real_node->lto_file_data)
     344                 :             :     return false;
     345                 :             : 
     346                 :             :   /* Vtables are defined by their types and must match no matter of interposition
     347                 :             :      rules.  */
     348                 :    48857602 :   if (DECL_VIRTUAL_P (decl))
     349                 :             :     {
     350                 :             :       /* The C++ front end creates VAR_DECLs for vtables of typeinfo
     351                 :             :          classes not defined in the current TU so that it can refer
     352                 :             :          to them from typeinfo objects.  Avoid returning NULL_TREE.  */
     353                 :     1141696 :       return DECL_INITIAL (real_node->decl) != NULL;
     354                 :             :     }
     355                 :             : 
     356                 :             :   /* An alias of a read-only variable is also read-only, since the variable
     357                 :             :      is stored in read-only memory.  We also accept read-only aliases of
     358                 :             :      non-read-only locations assuming that the user knows what he is asking
     359                 :             :      for.  */
     360                 :    47715906 :   if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
     361                 :             :     return false;
     362                 :             : 
     363                 :             :   /* Variables declared 'const' without an initializer
     364                 :             :      have zero as the initializer if they may not be
     365                 :             :      overridden at link or run time.
     366                 :             : 
     367                 :             :      It is actually requirement for C++ compiler to optimize const variables
     368                 :             :      consistently. As a GNU extension, do not enforce this rule for user defined
     369                 :             :      weak variables, so we support interposition on:
     370                 :             :      static const int dummy = 0;
     371                 :             :      extern const int foo __attribute__((__weak__, __alias__("dummy"))); 
     372                 :             :    */
     373                 :    15244058 :   if ((!DECL_INITIAL (real_node->decl)
     374                 :    14210961 :        || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
     375                 :    15244657 :       && ((DECL_EXTERNAL (decl) && !in_other_partition)
     376                 :        7072 :           || decl_replaceable_p (decl, semantic_interposition)))
     377                 :     1027342 :     return false;
     378                 :             : 
     379                 :             :   /* Variables declared `const' with an initializer are considered
     380                 :             :      to not be overwritable with different initializer by default. 
     381                 :             : 
     382                 :             :      ??? Previously we behaved so for scalar variables but not for array
     383                 :             :      accesses.  */
     384                 :             :   return true;
     385                 :             : }
     386                 :             : 
     387                 :             : /* If DECLARATION is constant variable and its initial value is known
     388                 :             :    (so we can do constant folding), return its constructor (DECL_INITIAL).
     389                 :             :    This may be an expression or NULL when DECL is initialized to 0.
     390                 :             :    Return ERROR_MARK_NODE otherwise.
     391                 :             : 
     392                 :             :    In LTO this may actually trigger reading the constructor from disk.
     393                 :             :    For this reason varpool_ctor_useable_for_folding_p should be used when
     394                 :             :    the actual constructor value is not needed.  */
     395                 :             : 
     396                 :             : tree
     397                 :   125074896 : ctor_for_folding (tree decl)
     398                 :             : {
     399                 :   125074896 :   varpool_node *node, *real_node;
     400                 :   125074896 :   tree real_decl;
     401                 :             : 
     402                 :   125074896 :   if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
     403                 :     4114654 :     return error_mark_node;
     404                 :             : 
     405                 :   120960242 :   if (TREE_CODE (decl) == CONST_DECL
     406                 :   120960242 :       || DECL_IN_CONSTANT_POOL (decl))
     407                 :       67160 :     return DECL_INITIAL (decl);
     408                 :             : 
     409                 :   120893082 :   if (TREE_THIS_VOLATILE (decl))
     410                 :     2096559 :     return error_mark_node;
     411                 :             : 
     412                 :             :   /* Do not care about automatic variables.  Those are never initialized
     413                 :             :      anyway, because gimplifier expands the code.  */
     414                 :   118796523 :   if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
     415                 :             :     {
     416                 :    83380270 :       gcc_assert (!TREE_PUBLIC (decl));
     417                 :             :       /* Unless this is called during FE folding.  */
     418                 :    83380270 :       if (cfun
     419                 :    83375634 :           && (cfun->curr_properties & (PROP_gimple | PROP_rtl)) == 0
     420                 :     5497249 :           && TREE_READONLY (decl)
     421                 :       14650 :           && !TREE_SIDE_EFFECTS (decl)
     422                 :    83394920 :           && DECL_INITIAL (decl))
     423                 :         369 :         return DECL_INITIAL (decl);
     424                 :    83379901 :       return error_mark_node;
     425                 :             :     }
     426                 :             : 
     427                 :    35416253 :   gcc_assert (VAR_P (decl));
     428                 :             : 
     429                 :    35416253 :   real_node = node = varpool_node::get (decl);
     430                 :    35416253 :   if (node)
     431                 :             :     {
     432                 :    34902078 :       real_node = node->ultimate_alias_target ();
     433                 :    34902078 :       real_decl = real_node->decl;
     434                 :             :     }
     435                 :             :   else
     436                 :             :     real_decl = decl;
     437                 :             : 
     438                 :             :   /* See if we are dealing with alias.
     439                 :             :      In most cases alias is just alternative symbol pointing to a given
     440                 :             :      constructor.  This allows us to use interposition rules of DECL
     441                 :             :      constructor of REAL_NODE.  However weakrefs are special by being just
     442                 :             :      alternative name of their target (if defined).  */
     443                 :    35416253 :   if (decl != real_decl)
     444                 :             :     {
     445                 :      176059 :       gcc_assert (!DECL_INITIAL (decl)
     446                 :             :                   || (node->alias && node->get_alias_target () == real_node)
     447                 :             :                   || DECL_INITIAL (decl) == error_mark_node);
     448                 :      176059 :       while (node->transparent_alias && node->analyzed)
     449                 :             :         {
     450                 :           0 :           node = node->get_alias_target ();
     451                 :           0 :           decl = node->decl;
     452                 :             :         }
     453                 :             :     }
     454                 :             : 
     455                 :    35416253 :   if ((!DECL_VIRTUAL_P (real_decl)
     456                 :      695546 :        || DECL_INITIAL (real_decl) == error_mark_node
     457                 :      695183 :        || !DECL_INITIAL (real_decl))
     458                 :    35494657 :       && (!node || !node->ctor_useable_for_folding_p ()))
     459                 :    33820246 :     return error_mark_node;
     460                 :             : 
     461                 :             :   /* OK, we can return constructor.  See if we need to fetch it from disk
     462                 :             :      in LTO mode.  */
     463                 :     1596007 :   if (DECL_INITIAL (real_decl) != error_mark_node
     464                 :     1596007 :       || !in_lto_p)
     465                 :     1594778 :     return DECL_INITIAL (real_decl);
     466                 :        1229 :   return real_node->get_constructor ();
     467                 :             : }
     468                 :             : 
     469                 :             : /* Add the variable DECL to the varpool.
     470                 :             :    Unlike finalize_decl function is intended to be used
     471                 :             :    by middle end and allows insertion of new variable at arbitrary point
     472                 :             :    of compilation.  */
     473                 :             : void
     474                 :         489 : varpool_node::add (tree decl)
     475                 :             : {
     476                 :         489 :   varpool_node *node;
     477                 :         489 :   varpool_node::finalize_decl (decl);
     478                 :         489 :   node = varpool_node::get_create (decl);
     479                 :         489 :   symtab->call_varpool_insertion_hooks (node);
     480                 :         489 :   if (node->externally_visible_p ())
     481                 :         481 :     node->externally_visible = true;
     482                 :         489 :   if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
     483                 :           0 :     node->no_reorder = 1;
     484                 :         489 : }
     485                 :             : 
     486                 :             : /* Return variable availability.  See cgraph.h for description of individual
     487                 :             :    return values.  */
     488                 :             : enum availability
     489                 :   166400901 : varpool_node::get_availability (symtab_node *ref)
     490                 :             : {
     491                 :   166400901 :   if (!definition && !in_other_partition)
     492                 :             :     return AVAIL_NOT_AVAILABLE;
     493                 :   142916452 :   if (!TREE_PUBLIC (decl))
     494                 :             :     return AVAIL_AVAILABLE;
     495                 :    49840207 :   if (DECL_IN_CONSTANT_POOL (decl)
     496                 :    49840207 :       || DECL_VIRTUAL_P (decl))
     497                 :             :     return AVAIL_AVAILABLE;
     498                 :    49777227 :   if (transparent_alias && definition)
     499                 :             :     {
     500                 :           0 :       enum availability avail;
     501                 :             : 
     502                 :           0 :       ultimate_alias_target (&avail, ref);
     503                 :           0 :       return avail;
     504                 :             :     }
     505                 :             :   /* If this is a reference from symbol itself and there are no aliases, we
     506                 :             :      may be sure that the symbol was not interposed by something else because
     507                 :             :      the symbol itself would be unreachable otherwise.  */
     508                 :           0 :   if ((this == ref && !has_aliases_p ())
     509                 :    49777227 :       || (ref && get_comdat_group ()
     510                 :           0 :           && get_comdat_group () == ref->get_comdat_group ()))
     511                 :             :     return AVAIL_AVAILABLE;
     512                 :             :   /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     513                 :             :      care of at least one notable extension - the COMDAT variables
     514                 :             :      used to share template instantiations in C++.  */
     515                 :    49777227 :   if (decl_replaceable_p (decl, semantic_interposition)
     516                 :    49777227 :       || (DECL_EXTERNAL (decl) && !in_other_partition))
     517                 :             :     return AVAIL_INTERPOSABLE;
     518                 :             :   return AVAIL_AVAILABLE;
     519                 :             : }
     520                 :             : 
     521                 :             : void
     522                 :     3036627 : varpool_node::analyze (void)
     523                 :             : {
     524                 :             :   /* When reading back varpool at LTO time, we re-construct the queue in order
     525                 :             :      to have "needed" list right by inserting all needed nodes into varpool.
     526                 :             :      We however don't want to re-analyze already analyzed nodes.  */
     527                 :     3036627 :   if (!analyzed)
     528                 :             :     {
     529                 :     3036627 :       gcc_assert (!in_lto_p || symtab->function_flags_ready);
     530                 :             :       /* Compute the alignment early so function body expanders are
     531                 :             :          already informed about increased alignment.  */
     532                 :     3036627 :       align_variable (decl, 0);
     533                 :             :     }
     534                 :     3036627 :   if (alias)
     535                 :         138 :     resolve_alias (varpool_node::get (alias_target));
     536                 :     3036489 :   else if (DECL_INITIAL (decl))
     537                 :     1995556 :     record_references_in_initializer (decl, analyzed);
     538                 :     3036627 :   analyzed = true;
     539                 :     3036627 : }
     540                 :             : 
     541                 :             : /* Assemble thunks and aliases associated to varpool node.  */
     542                 :             : 
     543                 :             : void
     544                 :     2818298 : varpool_node::assemble_aliases (void)
     545                 :             : {
     546                 :     2818298 :   ipa_ref *ref;
     547                 :             : 
     548                 :     2821650 :   FOR_EACH_ALIAS (this, ref)
     549                 :             :     {
     550                 :        3352 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     551                 :        3352 :       if (alias->symver)
     552                 :           0 :         do_assemble_symver (alias->decl,
     553                 :             :                             DECL_ASSEMBLER_NAME (decl));
     554                 :        3352 :       else if (!alias->transparent_alias)
     555                 :        3352 :         do_assemble_alias (alias->decl,
     556                 :             :                            DECL_ASSEMBLER_NAME (decl));
     557                 :        3352 :       alias->assemble_aliases ();
     558                 :             :     }
     559                 :     2818298 : }
     560                 :             : 
     561                 :             : /* Output one variable, if necessary.  Return whether we output it.  */
     562                 :             : 
     563                 :             : bool
     564                 :     2820295 : varpool_node::assemble_decl (void)
     565                 :             : {
     566                 :             :   /* Aliases are output when their target is produced or by
     567                 :             :      output_weakrefs.  */
     568                 :     2820295 :   if (alias)
     569                 :             :     return false;
     570                 :             : 
     571                 :             :   /* Constant pool is output from RTL land when the reference
     572                 :             :      survive till this level.  */
     573                 :     2816940 :   if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
     574                 :             :     return false;
     575                 :             : 
     576                 :             :   /* Decls with VALUE_EXPR should not be in the varpool at all.  They
     577                 :             :      are not real variables, but just info for debugging and codegen.
     578                 :             :      Unfortunately at the moment emutls is not updating varpool correctly
     579                 :             :      after turning real vars into value_expr vars.  */
     580                 :     2815134 :   if (DECL_HAS_VALUE_EXPR_P (decl)
     581                 :     2815134 :       && !targetm.have_tls)
     582                 :             :     return false;
     583                 :             : 
     584                 :             :   /* Hard register vars do not need to be output.  */
     585                 :     2815134 :   if (DECL_HARD_REGISTER (decl))
     586                 :             :     return false;
     587                 :             : 
     588                 :     2815134 :   gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
     589                 :             :                        && VAR_P (decl)
     590                 :             :                        && !DECL_HAS_VALUE_EXPR_P (decl));
     591                 :             : 
     592                 :     2815134 :   if (!in_other_partition
     593                 :     2815134 :       && !DECL_EXTERNAL (decl))
     594                 :             :     {
     595                 :     2814946 :       get_constructor ();
     596                 :     2814946 :       assemble_variable (decl, 0, 1, 0);
     597                 :     2814946 :       gcc_assert (TREE_ASM_WRITTEN (decl));
     598                 :     2814946 :       gcc_assert (definition);
     599                 :     2814946 :       assemble_aliases ();
     600                 :             :       /* After the parser has generated debugging information, augment
     601                 :             :          this information with any new location/etc information that may
     602                 :             :          have become available after the compilation proper.  */
     603                 :     2814946 :       debug_hooks->late_global_decl (decl);
     604                 :     2814946 :       return true;
     605                 :             :     }
     606                 :             : 
     607                 :             :   return false;
     608                 :             : }
     609                 :             : 
     610                 :             : /* Add NODE to queue starting at FIRST. 
     611                 :             :    The queue is linked via AUX pointers and terminated by pointer to 1.  */
     612                 :             : 
     613                 :             : static void
     614                 :     4734320 : enqueue_node (varpool_node *node, varpool_node **first)
     615                 :             : {
     616                 :     4734320 :   if (node->aux)
     617                 :             :     return;
     618                 :     2815749 :   gcc_checking_assert (*first);
     619                 :     2815749 :   node->aux = *first;
     620                 :     2815749 :   *first = node;
     621                 :             : }
     622                 :             : 
     623                 :             : /* Optimization of function bodies might've rendered some variables as
     624                 :             :    unnecessary so we want to avoid these from being compiled.  Re-do
     625                 :             :    reachability starting from variables that are either externally visible
     626                 :             :    or was referred from the asm output routines.  */
     627                 :             : 
     628                 :             : void
     629                 :      227753 : symbol_table::remove_unreferenced_decls (void)
     630                 :             : {
     631                 :      227753 :   varpool_node *next, *node;
     632                 :      227753 :   varpool_node *first = (varpool_node *)(void *)1;
     633                 :      227753 :   int i;
     634                 :      227753 :   ipa_ref *ref = NULL;
     635                 :      227753 :   hash_set<varpool_node *> referenced;
     636                 :             : 
     637                 :      227753 :   if (seen_error ())
     638                 :           0 :     return;
     639                 :             : 
     640                 :      227753 :   if (dump_file)
     641                 :          76 :     fprintf (dump_file, "Trivially needed variables:");
     642                 :     3095196 :   FOR_EACH_DEFINED_VARIABLE (node)
     643                 :             :     {
     644                 :     2867443 :       if (node->analyzed
     645                 :     2867443 :           && (!node->can_remove_if_no_refs_p ()
     646                 :             :               /* We just expanded all function bodies.  See if any of
     647                 :             :                  them needed the variable.  */
     648                 :     1370130 :               || DECL_RTL_SET_P (node->decl)))
     649                 :             :         {
     650                 :     2204904 :           enqueue_node (node, &first);
     651                 :     2204904 :           if (dump_file)
     652                 :          62 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     653                 :             :         }
     654                 :             :     }
     655                 :     3043502 :   while (first != (varpool_node *)(void *)1)
     656                 :             :     {
     657                 :     2815749 :       node = first;
     658                 :     2815749 :       first = (varpool_node *)first->aux;
     659                 :             : 
     660                 :     2815749 :       if (node->same_comdat_group)
     661                 :             :         {
     662                 :             :           symtab_node *next;
     663                 :      231044 :           for (next = node->same_comdat_group;
     664                 :      242059 :                next != node;
     665                 :      231044 :                next = next->same_comdat_group)
     666                 :             :             {
     667                 :      462088 :               varpool_node *vnext = dyn_cast <varpool_node *> (next);
     668                 :      462088 :               if (vnext && vnext->analyzed && !next->comdat_local_p ())
     669                 :      231038 :                 enqueue_node (vnext, &first);
     670                 :             :             }
     671                 :             :         }
     672                 :     9334626 :       for (i = 0; node->iterate_reference (i, ref); i++)
     673                 :             :         {
     674                 :     3475375 :           varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
     675                 :     3475375 :           if (vnode
     676                 :     2545083 :               && !vnode->in_other_partition
     677                 :     2545071 :               && (!DECL_EXTERNAL (ref->referred->decl)
     678                 :      246686 :                   || vnode->alias)
     679                 :     5773760 :               && vnode->analyzed)
     680                 :     2298378 :             enqueue_node (vnode, &first);
     681                 :             :           else
     682                 :             :             {
     683                 :     1176997 :               if (vnode)
     684                 :      246705 :                 referenced.add (vnode);
     685                 :     1176997 :               while (vnode && vnode->alias && vnode->definition)
     686                 :             :                 {
     687                 :           0 :                   vnode = vnode->get_alias_target ();
     688                 :           0 :                   gcc_checking_assert (vnode);
     689                 :           0 :                   referenced.add (vnode);
     690                 :             :                 }
     691                 :             :             }
     692                 :             :         }
     693                 :             :     }
     694                 :      227753 :   if (dump_file)
     695                 :          76 :     fprintf (dump_file, "\nRemoving variables:");
     696                 :     3095196 :   for (node = first_defined_variable (); node; node = next)
     697                 :             :     {
     698                 :     2867443 :       next = next_defined_variable (node);
     699                 :     2867443 :       if (!node->aux && !node->no_reorder)
     700                 :             :         {
     701                 :       51693 :           if (dump_file)
     702                 :           0 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     703                 :       51693 :           if (referenced.contains(node))
     704                 :           0 :             node->remove_initializer ();
     705                 :             :           else
     706                 :       51693 :             node->remove ();
     707                 :             :         }
     708                 :             :     }
     709                 :             : 
     710                 :      227753 :   if (dump_file)
     711                 :          76 :     fprintf (dump_file, "\n");
     712                 :      227753 : }
     713                 :             : 
     714                 :             : /* For variables in named sections make sure get_variable_section
     715                 :             :    is called before we switch to those sections.  Then section
     716                 :             :    conflicts between read-only and read-only requiring relocations
     717                 :             :    sections can be resolved.  */
     718                 :             : void
     719                 :     2807615 : varpool_node::finalize_named_section_flags (void)
     720                 :             : {
     721                 :     2807615 :   if (!TREE_ASM_WRITTEN (decl)
     722                 :             :       && !alias
     723                 :     2806038 :       && !in_other_partition
     724                 :     2802720 :       && !DECL_EXTERNAL (decl)
     725                 :     2802681 :       && VAR_P (decl)
     726                 :     2802681 :       && !DECL_HAS_VALUE_EXPR_P (decl)
     727                 :     5610296 :       && get_section ())
     728                 :     1430866 :     get_variable_section (decl, false);
     729                 :     2807615 : }
     730                 :             : 
     731                 :             : /* Output all variables enqueued to be assembled.  */
     732                 :             : bool
     733                 :      228015 : symbol_table::output_variables (void)
     734                 :             : {
     735                 :      228015 :   bool changed = false;
     736                 :      228015 :   varpool_node *node;
     737                 :             : 
     738                 :      228015 :   if (seen_error ())
     739                 :             :     return false;
     740                 :             : 
     741                 :      227753 :   remove_unreferenced_decls ();
     742                 :             : 
     743                 :      227753 :   timevar_push (TV_VAROUT);
     744                 :             : 
     745                 :     3043503 :   FOR_EACH_DEFINED_VARIABLE (node)
     746                 :             :     {
     747                 :             :       /* Handled in output_in_order.  */
     748                 :     2815750 :       if (node->no_reorder)
     749                 :     1007529 :         continue;
     750                 :             : 
     751                 :     1808221 :       node->finalize_named_section_flags ();
     752                 :             :     }
     753                 :             : 
     754                 :             :   /* There is a similar loop in output_in_order.  Please keep them in sync.  */
     755                 :     6674654 :   FOR_EACH_VARIABLE (node)
     756                 :             :     {
     757                 :             :       /* Handled in output_in_order.  */
     758                 :     3109574 :       if (node->no_reorder)
     759                 :     1008046 :         continue;
     760                 :     2101528 :       if (DECL_HARD_REGISTER (node->decl)
     761                 :     2101528 :           || DECL_HAS_VALUE_EXPR_P (node->decl))
     762                 :         250 :         continue;
     763                 :     2101278 :       if (node->definition)
     764                 :     1808155 :         changed |= node->assemble_decl ();
     765                 :             :       else
     766                 :      293123 :         assemble_undefined_decl (node->decl);
     767                 :             :     }
     768                 :      227753 :   timevar_pop (TV_VAROUT);
     769                 :      227753 :   return changed;
     770                 :             : }
     771                 :             : 
     772                 :             : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     773                 :             :    Extra name aliases are output whenever DECL is output.  */
     774                 :             : 
     775                 :             : varpool_node *
     776                 :       14815 : varpool_node::create_alias (tree alias, tree decl)
     777                 :             : {
     778                 :       14815 :   varpool_node *alias_node;
     779                 :             : 
     780                 :       14815 :   gcc_assert (VAR_P (decl));
     781                 :       14815 :   gcc_assert (VAR_P (alias));
     782                 :       14815 :   alias_node = varpool_node::get_create (alias);
     783                 :       14815 :   alias_node->alias = true;
     784                 :       14815 :   alias_node->definition = true;
     785                 :       14815 :   alias_node->semantic_interposition = flag_semantic_interposition;
     786                 :       14815 :   alias_node->alias_target = decl;
     787                 :       14815 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     788                 :          12 :     alias_node->weakref = alias_node->transparent_alias = true;
     789                 :       14815 :   return alias_node;
     790                 :             : }
     791                 :             : 
     792                 :             : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     793                 :             :    Extra name aliases are output whenever DECL is output.  */
     794                 :             : 
     795                 :             : varpool_node *
     796                 :        4636 : varpool_node::create_extra_name_alias (tree alias, tree decl)
     797                 :             : {
     798                 :        4636 :   varpool_node *alias_node;
     799                 :             : 
     800                 :             :   /* If aliases aren't supported by the assembler, fail.  */
     801                 :        4636 :   if (!TARGET_SUPPORTS_ALIASES)
     802                 :             :     return NULL;
     803                 :             : 
     804                 :        4636 :   alias_node = varpool_node::create_alias (alias, decl);
     805                 :        4636 :   alias_node->cpp_implicit_alias = true;
     806                 :             : 
     807                 :             :   /* Extra name alias mechanism creates aliases really late
     808                 :             :      via DECL_ASSEMBLER_NAME mechanism.
     809                 :             :      This is unfortunate because they are not going through the
     810                 :             :      standard channels.  Ensure they get output.  */
     811                 :        4636 :   if (symtab->cpp_implicit_aliases_done)
     812                 :        4636 :     alias_node->resolve_alias (varpool_node::get_create (decl));
     813                 :        4636 :   return alias_node;
     814                 :             : }
     815                 :             : 
     816                 :             : /* Worker for call_for_symbol_and_aliases.  */
     817                 :             : 
     818                 :             : bool
     819                 :        5684 : varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
     820                 :             :                                                                void *),
     821                 :             :                                              void *data,
     822                 :             :                                              bool include_overwritable)
     823                 :             : {
     824                 :        5684 :   ipa_ref *ref;
     825                 :             : 
     826                 :       24812 :   FOR_EACH_ALIAS (this, ref)
     827                 :             :     {
     828                 :       19128 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     829                 :       19128 :       if (include_overwritable
     830                 :       19128 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
     831                 :       19128 :         if (alias->call_for_symbol_and_aliases (callback, data,
     832                 :             :                                                 include_overwritable))
     833                 :             :           return true;
     834                 :             :     }
     835                 :             :   return false;
     836                 :             : }
        

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.