LCOV - code coverage report
Current view: top level - gcc - varpool.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 316 371 85.2 %
Date: 2020-04-04 11:58:09 Functions: 23 30 76.7 %
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-2020 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                 :            : 
      39                 :            : const char * const tls_model_names[]={"none", "emulated",
      40                 :            :                                       "global-dynamic", "local-dynamic",
      41                 :            :                                       "initial-exec", "local-exec"};
      42                 :            : 
      43                 :            : /* List of hooks triggered on varpool_node events.  */
      44                 :            : struct varpool_node_hook_list {
      45                 :            :   varpool_node_hook hook;
      46                 :            :   void *data;
      47                 :            :   struct varpool_node_hook_list *next;
      48                 :            : };
      49                 :            : 
      50                 :            : /* Register HOOK to be called with DATA on each removed node.  */
      51                 :            : varpool_node_hook_list *
      52                 :     220820 : symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
      53                 :            : {
      54                 :     220820 :   varpool_node_hook_list *entry;
      55                 :     220820 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      56                 :            : 
      57                 :     220820 :   entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
      58                 :     220820 :   entry->hook = hook;
      59                 :     220820 :   entry->data = data;
      60                 :     220820 :   entry->next = NULL;
      61                 :     227388 :   while (*ptr)
      62                 :       6568 :     ptr = &(*ptr)->next;
      63                 :     220820 :   *ptr = entry;
      64                 :     220820 :   return entry;
      65                 :            : }
      66                 :            : 
      67                 :            : /* Remove ENTRY from the list of hooks called on removing nodes.  */
      68                 :            : void
      69                 :      94729 : symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
      70                 :            : {
      71                 :      94729 :   varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
      72                 :            : 
      73                 :      97872 :   while (*ptr != entry)
      74                 :       3143 :     ptr = &(*ptr)->next;
      75                 :      94729 :   *ptr = entry->next;
      76                 :      94729 :   free (entry);
      77                 :      94729 : }
      78                 :            : 
      79                 :            : /* Call all node removal hooks.  */
      80                 :            : void
      81                 :    7709080 : symbol_table::call_varpool_removal_hooks (varpool_node *node)
      82                 :            : {
      83                 :    7709080 :   varpool_node_hook_list *entry = m_first_varpool_removal_hook;
      84                 :    9550660 :   while (entry)
      85                 :            :   {
      86                 :    1841580 :     entry->hook (node, entry->data);
      87                 :    1841580 :     entry = entry->next;
      88                 :            :   }
      89                 :    7709080 : }
      90                 :            : 
      91                 :            : /* Register HOOK to be called with DATA on each inserted node.  */
      92                 :            : varpool_node_hook_list *
      93                 :          0 : symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
      94                 :            : {
      95                 :          0 :   varpool_node_hook_list *entry;
      96                 :          0 :   varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
      97                 :            : 
      98                 :          0 :   entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
      99                 :          0 :   entry->hook = hook;
     100                 :          0 :   entry->data = data;
     101                 :          0 :   entry->next = NULL;
     102                 :          0 :   while (*ptr)
     103                 :          0 :     ptr = &(*ptr)->next;
     104                 :          0 :   *ptr = entry;
     105                 :          0 :   return entry;
     106                 :            : }
     107                 :            : 
     108                 :            : /* Remove ENTRY from the list of hooks called on inserted nodes.  */
     109                 :            : void
     110                 :          0 : symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
     111                 :            : {
     112                 :          0 :   varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
     113                 :            : 
     114                 :          0 :   while (*ptr != entry)
     115                 :          0 :     ptr = &(*ptr)->next;
     116                 :          0 :   *ptr = entry->next;
     117                 :          0 :   free (entry);
     118                 :          0 : }
     119                 :            : 
     120                 :            : /* Call all node insertion hooks.  */
     121                 :            : void
     122                 :       6143 : symbol_table::call_varpool_insertion_hooks (varpool_node *node)
     123                 :            : {
     124                 :       6143 :   varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
     125                 :       6143 :   while (entry)
     126                 :            :   {
     127                 :          0 :     entry->hook (node, entry->data);
     128                 :          0 :     entry = entry->next;
     129                 :            :   }
     130                 :       6143 : }
     131                 :            : 
     132                 :            : /* Allocate new callgraph node and insert it into basic data structures.  */
     133                 :            : 
     134                 :            : varpool_node *
     135                 :   10125000 : varpool_node::create_empty (void)
     136                 :            : {
     137                 :   10125000 :   return new (ggc_alloc<varpool_node> ()) varpool_node ();
     138                 :            : }   
     139                 :            : 
     140                 :            : /* Return varpool node assigned to DECL.  Create new one when needed.  */
     141                 :            : varpool_node *
     142                 :   67786700 : varpool_node::get_create (tree decl)
     143                 :            : {
     144                 :   67786700 :   varpool_node *node = varpool_node::get (decl);
     145                 :   67786700 :   gcc_checking_assert (VAR_P (decl));
     146                 :   67786700 :   if (node)
     147                 :            :     return node;
     148                 :            : 
     149                 :   10064200 :   node = varpool_node::create_empty ();
     150                 :   10064200 :   node->decl = decl;
     151                 :            : 
     152                 :   10044600 :   if ((flag_openacc || flag_openmp)
     153                 :   10097000 :       && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
     154                 :            :     {
     155                 :        386 :       node->offloadable = 1;
     156                 :        386 :       if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl))
     157                 :            :         {
     158                 :            :           g->have_offload = true;
     159                 :            :           if (!in_lto_p)
     160                 :            :             vec_safe_push (offload_vars, decl);
     161                 :            :         }
     162                 :            :     }
     163                 :            : 
     164                 :   10064200 :   node->register_symbol ();
     165                 :   10064200 :   return node;
     166                 :            : }
     167                 :            : 
     168                 :            : /* Remove variable from symbol table.  */
     169                 :            : 
     170                 :            : void
     171                 :    7709080 : varpool_node::remove (void)
     172                 :            : {
     173                 :    7709080 :   symtab->call_varpool_removal_hooks (this);
     174                 :    7709080 :   if (lto_file_data)
     175                 :            :     {
     176                 :       3584 :       lto_free_function_in_decl_state_for_node (this);
     177                 :       3584 :       lto_file_data = NULL;
     178                 :            :     }
     179                 :            : 
     180                 :            :   /* When streaming we can have multiple nodes associated with decl.  */
     181                 :    7709080 :   if (symtab->state == LTO_STREAMING)
     182                 :            :     ;
     183                 :            :   /* Keep constructor when it may be used for folding. We remove
     184                 :            :      references to external variables before final compilation.  */
     185                 :   14233900 :   else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
     186                 :   14232900 :            && !ctor_useable_for_folding_p ())
     187                 :       2474 :     remove_initializer ();
     188                 :            : 
     189                 :    7709080 :   unregister ();
     190                 :    7709080 :   ggc_free (this);
     191                 :    7709080 : }
     192                 :            : 
     193                 :            : /* Remove node initializer when it is no longer needed.  */
     194                 :            : void
     195                 :    1917990 : varpool_node::remove_initializer (void)
     196                 :            : {
     197                 :    1917990 :   if (DECL_INITIAL (decl)
     198                 :       3070 :       && !DECL_IN_CONSTANT_POOL (decl)
     199                 :            :       /* Keep vtables for BINFO folding.  */
     200                 :       3070 :       && !DECL_VIRTUAL_P (decl)
     201                 :            :       /* FIXME: http://gcc.gnu.org/PR55395 */
     202                 :       2864 :       && debug_info_level == DINFO_LEVEL_NONE
     203                 :            :       /* When doing declaration merging we have duplicate
     204                 :            :          entries for given decl.  Do not attempt to remove
     205                 :            :          the bodies, or we will end up removing
     206                 :            :          wrong one.  */
     207                 :    1920220 :       && symtab->state != LTO_STREAMING)
     208                 :       2226 :     DECL_INITIAL (decl) = error_mark_node;
     209                 :    1917990 : }
     210                 :            : 
     211                 :            : /* Dump given varpool node to F.  */
     212                 :            : void
     213                 :       2680 : varpool_node::dump (FILE *f)
     214                 :            : {
     215                 :       2680 :   dump_base (f);
     216                 :       2680 :   fprintf (f, "  Availability: %s\n",
     217                 :       2680 :            symtab->function_flags_ready
     218                 :       2568 :            ? cgraph_availability_names[get_availability ()]
     219                 :            :            : "not-ready");
     220                 :       2680 :   fprintf (f, "  Varpool flags:");
     221                 :       2680 :   if (DECL_INITIAL (decl))
     222                 :       1770 :     fprintf (f, " initialized");
     223                 :       2680 :   if (output)
     224                 :          0 :     fprintf (f, " output");
     225                 :       2680 :   if (used_by_single_function)
     226                 :         43 :     fprintf (f, " used-by-single-function");
     227                 :       2680 :   if (TREE_READONLY (decl))
     228                 :       1829 :     fprintf (f, " read-only");
     229                 :       2680 :   if (ctor_useable_for_folding_p ())
     230                 :       1461 :     fprintf (f, " const-value-known");
     231                 :       2680 :   if (writeonly)
     232                 :          0 :     fprintf (f, " write-only");
     233                 :       2680 :   if (tls_model)
     234                 :         28 :     fprintf (f, " tls-%s", tls_model_names [tls_model]);
     235                 :       2680 :   fprintf (f, "\n");
     236                 :       2680 : }
     237                 :            : 
     238                 :            : 
     239                 :            : /* Dump given varpool node to stderr.  */
     240                 :          0 : void varpool_node::debug (void)
     241                 :            : {
     242                 :          0 :   varpool_node::dump (stderr);
     243                 :          0 : }
     244                 :            : 
     245                 :            : /* Dump the variable pool to F.  */
     246                 :            : void
     247                 :          0 : varpool_node::dump_varpool (FILE *f)
     248                 :            : {
     249                 :          0 :   varpool_node *node;
     250                 :            : 
     251                 :          0 :   fprintf (f, "variable pool:\n\n");
     252                 :          0 :   FOR_EACH_VARIABLE (node)
     253                 :          0 :     node->dump (f);
     254                 :          0 : }
     255                 :            : 
     256                 :            : /* Dump the variable pool to stderr.  */
     257                 :            : 
     258                 :            : DEBUG_FUNCTION void
     259                 :          0 : varpool_node::debug_varpool (void)
     260                 :            : {
     261                 :          0 :   dump_varpool (stderr);
     262                 :          0 : }
     263                 :            : 
     264                 :            : /* Given an assembler name, lookup node.  */
     265                 :            : varpool_node *
     266                 :          0 : varpool_node::get_for_asmname (tree asmname)
     267                 :            : {
     268                 :          0 :   if (symtab_node *node = symtab_node::get_for_asmname (asmname))
     269                 :          0 :     return dyn_cast <varpool_node *> (node);
     270                 :            :   else
     271                 :            :     return NULL;
     272                 :            : }
     273                 :            : 
     274                 :            : /* When doing LTO, read variable's constructor from disk if
     275                 :            :    it is not already present.  */
     276                 :            : 
     277                 :            : tree
     278                 :    6010190 : varpool_node::get_constructor (void)
     279                 :            : {
     280                 :    6010190 :   lto_file_decl_data *file_data;
     281                 :    6010190 :   const char *data, *name;
     282                 :    6010190 :   size_t len;
     283                 :            : 
     284                 :    6010190 :   if (DECL_INITIAL (decl) != error_mark_node
     285                 :       9452 :       || !in_lto_p
     286                 :    6019630 :       || !lto_file_data)
     287                 :    6010190 :     return DECL_INITIAL (decl);
     288                 :            : 
     289                 :       9448 :   timevar_push (TV_IPA_LTO_CTORS_IN);
     290                 :            : 
     291                 :       9448 :   file_data = lto_file_data;
     292                 :       9448 :   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
     293                 :            : 
     294                 :            :   /* We may have renamed the declaration, e.g., a static function.  */
     295                 :       9448 :   name = lto_get_decl_name_mapping (file_data, name);
     296                 :       9448 :   struct lto_in_decl_state *decl_state
     297                 :       9448 :          = lto_get_function_in_decl_state (file_data, decl);
     298                 :            : 
     299                 :      18896 :   data = lto_get_section_data (file_data, LTO_section_function_body,
     300                 :       9448 :                                name, order - file_data->order_base,
     301                 :       9448 :                                &len, decl_state->compressed);
     302                 :       9448 :   if (!data)
     303                 :          0 :     fatal_error (input_location, "%s: section %s.%d is missing",
     304                 :            :                  file_data->file_name,
     305                 :          0 :                  name, order - file_data->order_base);
     306                 :            : 
     307                 :       9448 :   if (!quiet_flag)
     308                 :          0 :     fprintf (stderr, " in:%s", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
     309                 :       9448 :   lto_input_variable_constructor (file_data, this, data);
     310                 :       9448 :   gcc_assert (DECL_INITIAL (decl) != error_mark_node);
     311                 :       9448 :   lto_stats.num_function_bodies++;
     312                 :       9448 :   lto_free_section_data (file_data, LTO_section_function_body, name,
     313                 :       9448 :                          data, len, decl_state->compressed);
     314                 :       9448 :   lto_free_function_in_decl_state_for_node (this);
     315                 :       9448 :   timevar_pop (TV_IPA_LTO_CTORS_IN);
     316                 :       9448 :   return DECL_INITIAL (decl);
     317                 :            : }
     318                 :            : 
     319                 :            : /* Return true if variable has constructor that can be used for folding.  */
     320                 :            : 
     321                 :            : bool
     322                 :   30364900 : varpool_node::ctor_useable_for_folding_p (void)
     323                 :            : {
     324                 :   30364900 :   varpool_node *real_node = this;
     325                 :            : 
     326                 :   30364900 :   if (real_node->alias && real_node->definition)
     327                 :      82214 :     real_node = ultimate_alias_target ();
     328                 :            : 
     329                 :   30364900 :   if (TREE_CODE (decl) == CONST_DECL
     330                 :   30364900 :       || DECL_IN_CONSTANT_POOL (decl))
     331                 :            :     return true;
     332                 :   30364900 :   if (TREE_THIS_VOLATILE (decl))
     333                 :            :     return false;
     334                 :            : 
     335                 :            :   /* Avoid attempts to load constructors that was not streamed.  */
     336                 :     571263 :   if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
     337                 :   30393800 :       && real_node->body_removed)
     338                 :            :     return false;
     339                 :            : 
     340                 :            :   /* If we do not have a constructor, we can't use it.  */
     341                 :   30330100 :   if (DECL_INITIAL (real_node->decl) == error_mark_node
     342                 :   30330100 :       && !real_node->lto_file_data)
     343                 :            :     return false;
     344                 :            : 
     345                 :            :   /* Vtables are defined by their types and must match no matter of interposition
     346                 :            :      rules.  */
     347                 :   30330000 :   if (DECL_VIRTUAL_P (decl))
     348                 :            :     {
     349                 :            :       /* The C++ front end creates VAR_DECLs for vtables of typeinfo
     350                 :            :          classes not defined in the current TU so that it can refer
     351                 :            :          to them from typeinfo objects.  Avoid returning NULL_TREE.  */
     352                 :     717748 :       return DECL_INITIAL (real_node->decl) != NULL;
     353                 :            :     }
     354                 :            : 
     355                 :            :   /* An alias of a read-only variable is also read-only, since the variable
     356                 :            :      is stored in read-only memory.  We also accept read-only aliases of
     357                 :            :      non-read-only locations assuming that the user knows what he is asking
     358                 :            :      for.  */
     359                 :   29612300 :   if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
     360                 :            :     return false;
     361                 :            : 
     362                 :            :   /* Variables declared 'const' without an initializer
     363                 :            :      have zero as the initializer if they may not be
     364                 :            :      overridden at link or run time.
     365                 :            : 
     366                 :            :      It is actually requirement for C++ compiler to optimize const variables
     367                 :            :      consistently. As a GNU extension, do not enforce this rule for user defined
     368                 :            :      weak variables, so we support interposition on:
     369                 :            :      static const int dummy = 0;
     370                 :            :      extern const int foo __attribute__((__weak__, __alias__("dummy"))); 
     371                 :            :    */
     372                 :    7964210 :   if ((!DECL_INITIAL (real_node->decl)
     373                 :    6798770 :        || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
     374                 :    8068830 :       && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl)))
     375                 :    1266100 :     return false;
     376                 :            : 
     377                 :            :   /* Variables declared `const' with an initializer are considered
     378                 :            :      to not be overwritable with different initializer by default. 
     379                 :            : 
     380                 :            :      ??? Previously we behaved so for scalar variables but not for array
     381                 :            :      accesses.  */
     382                 :            :   return true;
     383                 :            : }
     384                 :            : 
     385                 :            : /* If DECLARATION is constant variable and its initial value is known
     386                 :            :    (so we can do constant folding), return its constructor (DECL_INITIAL).
     387                 :            :    This may be an expression or NULL when DECL is initialized to 0.
     388                 :            :    Return ERROR_MARK_NODE otherwise.
     389                 :            : 
     390                 :            :    In LTO this may actually trigger reading the constructor from disk.
     391                 :            :    For this reason varpool_ctor_useable_for_folding_p should be used when
     392                 :            :    the actual constructor value is not needed.  */
     393                 :            : 
     394                 :            : tree
     395                 :  108301000 : ctor_for_folding (tree decl)
     396                 :            : {
     397                 :  108301000 :   varpool_node *node, *real_node;
     398                 :  108301000 :   tree real_decl;
     399                 :            : 
     400                 :  108301000 :   if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
     401                 :    2230780 :     return error_mark_node;
     402                 :            : 
     403                 :  106070000 :   if (TREE_CODE (decl) == CONST_DECL
     404                 :  106070000 :       || DECL_IN_CONSTANT_POOL (decl))
     405                 :      35770 :     return DECL_INITIAL (decl);
     406                 :            : 
     407                 :  106035000 :   if (TREE_THIS_VOLATILE (decl))
     408                 :    2064180 :     return error_mark_node;
     409                 :            : 
     410                 :            :   /* Do not care about automatic variables.  Those are never initialized
     411                 :            :      anyway, because gimplifier expands the code.  */
     412                 :  193565000 :   if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
     413                 :            :     {
     414                 :   79436900 :       gcc_assert (!TREE_PUBLIC (decl));
     415                 :   79436900 :       return error_mark_node;
     416                 :            :     }
     417                 :            : 
     418                 :   24533400 :   gcc_assert (VAR_P (decl));
     419                 :            : 
     420                 :   24533400 :   real_node = node = varpool_node::get (decl);
     421                 :   24533400 :   if (node)
     422                 :            :     {
     423                 :   24111500 :       real_node = node->ultimate_alias_target ();
     424                 :   24111500 :       real_decl = real_node->decl;
     425                 :            :     }
     426                 :            :   else
     427                 :            :     real_decl = decl;
     428                 :            : 
     429                 :            :   /* See if we are dealing with alias.
     430                 :            :      In most cases alias is just alternative symbol pointing to a given
     431                 :            :      constructor.  This allows us to use interposition rules of DECL
     432                 :            :      constructor of REAL_NODE.  However weakrefs are special by being just
     433                 :            :      alternative name of their target (if defined).  */
     434                 :   24533400 :   if (decl != real_decl)
     435                 :            :     {
     436                 :      81962 :       gcc_assert (!DECL_INITIAL (decl)
     437                 :            :                   || (node->alias && node->get_alias_target () == real_node)
     438                 :            :                   || DECL_INITIAL (decl) == error_mark_node);
     439                 :      81962 :       while (node->transparent_alias && node->analyzed)
     440                 :            :         {
     441                 :          0 :           node = node->get_alias_target ();
     442                 :          0 :           decl = node->decl;
     443                 :            :         }
     444                 :            :     }
     445                 :            : 
     446                 :   24533400 :   if ((!DECL_VIRTUAL_P (real_decl)
     447                 :     520645 :        || DECL_INITIAL (real_decl) == error_mark_node
     448                 :     520174 :        || !DECL_INITIAL (real_decl))
     449                 :   24610500 :       && (!node || !node->ctor_useable_for_folding_p ()))
     450                 :   23285100 :     return error_mark_node;
     451                 :            : 
     452                 :            :   /* OK, we can return constructor.  See if we need to fetch it from disk
     453                 :            :      in LTO mode.  */
     454                 :    1248270 :   if (DECL_INITIAL (real_decl) != error_mark_node
     455                 :    1248270 :       || !in_lto_p)
     456                 :  108301000 :     return DECL_INITIAL (real_decl);
     457                 :       1157 :   return real_node->get_constructor ();
     458                 :            : }
     459                 :            : 
     460                 :            : /* Add the variable DECL to the varpool.
     461                 :            :    Unlike finalize_decl function is intended to be used
     462                 :            :    by middle end and allows insertion of new variable at arbitrary point
     463                 :            :    of compilation.  */
     464                 :            : void
     465                 :       6143 : varpool_node::add (tree decl)
     466                 :            : {
     467                 :       6143 :   varpool_node *node;
     468                 :       6143 :   varpool_node::finalize_decl (decl);
     469                 :       6143 :   node = varpool_node::get_create (decl);
     470                 :       6143 :   symtab->call_varpool_insertion_hooks (node);
     471                 :       6143 :   if (node->externally_visible_p ())
     472                 :       6143 :     node->externally_visible = true;
     473                 :       6143 :   if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
     474                 :          0 :     node->no_reorder = 1;
     475                 :       6143 : }
     476                 :            : 
     477                 :            : /* Return variable availability.  See cgraph.h for description of individual
     478                 :            :    return values.  */
     479                 :            : enum availability
     480                 :  186552000 : varpool_node::get_availability (symtab_node *ref)
     481                 :            : {
     482                 :  186552000 :   if (!definition)
     483                 :            :     return AVAIL_NOT_AVAILABLE;
     484                 :  159045000 :   if (!TREE_PUBLIC (decl))
     485                 :            :     return AVAIL_AVAILABLE;
     486                 :   79069900 :   if (DECL_IN_CONSTANT_POOL (decl)
     487                 :   79069900 :       || DECL_VIRTUAL_P (decl))
     488                 :            :     return AVAIL_AVAILABLE;
     489                 :   79008900 :   if (transparent_alias && definition)
     490                 :            :     {
     491                 :          0 :       enum availability avail;
     492                 :            : 
     493                 :          0 :       ultimate_alias_target (&avail, ref);
     494                 :          0 :       return avail;
     495                 :            :     }
     496                 :            :   /* If this is a reference from symbol itself and there are no aliases, we
     497                 :            :      may be sure that the symbol was not interposed by something else because
     498                 :            :      the symbol itself would be unreachable otherwise.  */
     499                 :          0 :   if ((this == ref && !has_aliases_p ())
     500                 :   79008900 :       || (ref && get_comdat_group ()
     501                 :          0 :           && get_comdat_group () == ref->get_comdat_group ()))
     502                 :            :     return AVAIL_AVAILABLE;
     503                 :            :   /* If the variable can be overwritten, return OVERWRITABLE.  Takes
     504                 :            :      care of at least one notable extension - the COMDAT variables
     505                 :            :      used to share template instantiations in C++.  */
     506                 :   79008900 :   if (decl_replaceable_p (decl)
     507                 :   79008900 :       || DECL_EXTERNAL (decl))
     508                 :   37079200 :     return AVAIL_INTERPOSABLE;
     509                 :            :   return AVAIL_AVAILABLE;
     510                 :            : }
     511                 :            : 
     512                 :            : void
     513                 :    2469420 : varpool_node::analyze (void)
     514                 :            : {
     515                 :            :   /* When reading back varpool at LTO time, we re-construct the queue in order
     516                 :            :      to have "needed" list right by inserting all needed nodes into varpool.
     517                 :            :      We however don't want to re-analyze already analyzed nodes.  */
     518                 :    2469420 :   if (!analyzed)
     519                 :            :     {
     520                 :    2469420 :       gcc_assert (!in_lto_p || symtab->function_flags_ready);
     521                 :            :       /* Compute the alignment early so function body expanders are
     522                 :            :          already informed about increased alignment.  */
     523                 :    2469420 :       align_variable (decl, 0);
     524                 :            :     }
     525                 :    2469420 :   if (alias)
     526                 :        129 :     resolve_alias (varpool_node::get (alias_target));
     527                 :    2469300 :   else if (DECL_INITIAL (decl))
     528                 :    1541180 :     record_references_in_initializer (decl, analyzed);
     529                 :    2469420 :   analyzed = true;
     530                 :    2469420 : }
     531                 :            : 
     532                 :            : /* Assemble thunks and aliases associated to varpool node.  */
     533                 :            : 
     534                 :            : void
     535                 :    2301850 : varpool_node::assemble_aliases (void)
     536                 :            : {
     537                 :    2301850 :   ipa_ref *ref;
     538                 :            : 
     539                 :    2616310 :   FOR_EACH_ALIAS (this, ref)
     540                 :            :     {
     541                 :       1816 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     542                 :       1816 :       if (alias->symver)
     543                 :          0 :         do_assemble_symver (alias->decl,
     544                 :            :                             DECL_ASSEMBLER_NAME (decl));
     545                 :       1816 :       else if (!alias->transparent_alias)
     546                 :       1816 :         do_assemble_alias (alias->decl,
     547                 :            :                            DECL_ASSEMBLER_NAME (decl));
     548                 :       1816 :       alias->assemble_aliases ();
     549                 :            :     }
     550                 :    2301850 : }
     551                 :            : 
     552                 :            : /* Output one variable, if necessary.  Return whether we output it.  */
     553                 :            : 
     554                 :            : bool
     555                 :    2303270 : varpool_node::assemble_decl (void)
     556                 :            : {
     557                 :            :   /* Aliases are output when their target is produced or by
     558                 :            :      output_weakrefs.  */
     559                 :    2303270 :   if (alias)
     560                 :            :     return false;
     561                 :            : 
     562                 :            :   /* Constant pool is output from RTL land when the reference
     563                 :            :      survive till this level.  */
     564                 :    2301450 :   if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
     565                 :            :     return false;
     566                 :            : 
     567                 :            :   /* Decls with VALUE_EXPR should not be in the varpool at all.  They
     568                 :            :      are not real variables, but just info for debugging and codegen.
     569                 :            :      Unfortunately at the moment emutls is not updating varpool correctly
     570                 :            :      after turning real vars into value_expr vars.  */
     571                 :    2300730 :   if (DECL_HAS_VALUE_EXPR_P (decl)
     572                 :    2300730 :       && !targetm.have_tls)
     573                 :            :     return false;
     574                 :            : 
     575                 :            :   /* Hard register vars do not need to be output.  */
     576                 :    2300730 :   if (DECL_HARD_REGISTER (decl))
     577                 :            :     return false;
     578                 :            : 
     579                 :    2300730 :   gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
     580                 :            :                        && VAR_P (decl)
     581                 :            :                        && !DECL_HAS_VALUE_EXPR_P (decl));
     582                 :            : 
     583                 :    2300730 :   if (!in_other_partition
     584                 :    2300730 :       && !DECL_EXTERNAL (decl))
     585                 :            :     {
     586                 :    2300040 :       get_constructor ();
     587                 :    2300040 :       assemble_variable (decl, 0, 1, 0);
     588                 :    2300040 :       gcc_assert (TREE_ASM_WRITTEN (decl));
     589                 :    2300040 :       gcc_assert (definition);
     590                 :    2300040 :       assemble_aliases ();
     591                 :            :       /* After the parser has generated debugging information, augment
     592                 :            :          this information with any new location/etc information that may
     593                 :            :          have become available after the compilation proper.  */
     594                 :    2300040 :       debug_hooks->late_global_decl (decl);
     595                 :    2300040 :       return true;
     596                 :            :     }
     597                 :            : 
     598                 :            :   return false;
     599                 :            : }
     600                 :            : 
     601                 :            : /* Add NODE to queue starting at FIRST. 
     602                 :            :    The queue is linked via AUX pointers and terminated by pointer to 1.  */
     603                 :            : 
     604                 :            : static void
     605                 :    3984910 : enqueue_node (varpool_node *node, varpool_node **first)
     606                 :            : {
     607                 :          0 :   if (node->aux)
     608                 :            :     return;
     609                 :    2299580 :   gcc_checking_assert (*first);
     610                 :    2299580 :   node->aux = *first;
     611                 :    2299580 :   *first = node;
     612                 :            : }
     613                 :            : 
     614                 :            : /* Optimization of function bodies might've rendered some variables as
     615                 :            :    unnecessary so we want to avoid these from being compiled.  Re-do
     616                 :            :    reachability starting from variables that are either externally visible
     617                 :            :    or was referred from the asm output routines.  */
     618                 :            : 
     619                 :            : void
     620                 :     163841 : symbol_table::remove_unreferenced_decls (void)
     621                 :            : {
     622                 :     163841 :   varpool_node *next, *node;
     623                 :     163841 :   varpool_node *first = (varpool_node *)(void *)1;
     624                 :     163841 :   int i;
     625                 :     163841 :   ipa_ref *ref = NULL;
     626                 :     327682 :   hash_set<varpool_node *> referenced;
     627                 :            : 
     628                 :     163841 :   if (seen_error ())
     629                 :          0 :     return;
     630                 :            : 
     631                 :     163841 :   if (dump_file)
     632                 :         72 :     fprintf (dump_file, "Trivially needed variables:");
     633                 :    4975440 :   FOR_EACH_DEFINED_VARIABLE (node)
     634                 :            :     {
     635                 :    2323880 :       if (node->analyzed
     636                 :    2323880 :           && (!node->can_remove_if_no_refs_p ()
     637                 :            :               /* We just expanded all function bodies.  See if any of
     638                 :            :                  them needed the variable.  */
     639                 :    3446460 :               || DECL_RTL_SET_P (node->decl)))
     640                 :            :         {
     641                 :    1776990 :           enqueue_node (node, &first);
     642                 :    1776990 :           if (dump_file)
     643                 :         57 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     644                 :            :         }
     645                 :            :     }
     646                 :    2463420 :   while (first != (varpool_node *)(void *)1)
     647                 :            :     {
     648                 :    2299580 :       node = first;
     649                 :    2299580 :       first = (varpool_node *)first->aux;
     650                 :            : 
     651                 :    2299580 :       if (node->same_comdat_group)
     652                 :            :         {
     653                 :            :           symtab_node *next;
     654                 :     228814 :           for (next = node->same_comdat_group;
     655                 :     239061 :                next != node;
     656                 :     228814 :                next = next->same_comdat_group)
     657                 :            :             {
     658                 :     228814 :               varpool_node *vnext = dyn_cast <varpool_node *> (next);
     659                 :     228814 :               if (vnext && vnext->analyzed && !next->comdat_local_p ())
     660                 :     230040 :                 enqueue_node (vnext, &first);
     661                 :            :             }
     662                 :            :         }
     663                 :    7842020 :       for (i = 0; node->iterate_reference (i, ref); i++)
     664                 :            :         {
     665                 :    3079020 :           varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
     666                 :    3079020 :           if (vnode
     667                 :    2171670 :               && !vnode->in_other_partition
     668                 :    2171660 :               && (!DECL_EXTERNAL (ref->referred->decl)
     669                 :     192543 :                   || vnode->alias)
     670                 :    5058140 :               && vnode->analyzed)
     671                 :    3600380 :             enqueue_node (vnode, &first);
     672                 :            :           else
     673                 :            :             {
     674                 :    1099910 :               referenced.add (vnode);
     675                 :    1099910 :               while (vnode && vnode->alias && vnode->definition)
     676                 :            :                 {
     677                 :          0 :                   vnode = vnode->get_alias_target ();
     678                 :          0 :                   referenced.add (vnode);
     679                 :            :                 }
     680                 :            :             }
     681                 :            :         }
     682                 :            :     }
     683                 :     163841 :   if (dump_file)
     684                 :         72 :     fprintf (dump_file, "\nRemoving variables:");
     685                 :    2651560 :   for (node = first_defined_variable (); node; node = next)
     686                 :            :     {
     687                 :    2323880 :       next = next_defined_variable (node);
     688                 :    2323880 :       if (!node->aux && !node->no_reorder)
     689                 :            :         {
     690                 :      24305 :           if (dump_file)
     691                 :          0 :             fprintf (dump_file, " %s", node->dump_asm_name ());
     692                 :      24305 :           if (referenced.contains(node))
     693                 :          0 :             node->remove_initializer ();
     694                 :            :           else
     695                 :      24305 :             node->remove ();
     696                 :            :         }
     697                 :            :     }
     698                 :            : 
     699                 :     163841 :   if (dump_file)
     700                 :         72 :     fprintf (dump_file, "\n");
     701                 :            : }
     702                 :            : 
     703                 :            : /* For variables in named sections make sure get_variable_section
     704                 :            :    is called before we switch to those sections.  Then section
     705                 :            :    conflicts between read-only and read-only requiring relocations
     706                 :            :    sections can be resolved.  */
     707                 :            : void
     708                 :    2297200 : varpool_node::finalize_named_section_flags (void)
     709                 :            : {
     710                 :    2297200 :   if (!TREE_ASM_WRITTEN (decl)
     711                 :            :       && !alias
     712                 :    2296790 :       && !in_other_partition
     713                 :    2295000 :       && !DECL_EXTERNAL (decl)
     714                 :    2294480 :       && VAR_P (decl)
     715                 :    2294480 :       && !DECL_HAS_VALUE_EXPR_P (decl)
     716                 :    4591680 :       && get_section ())
     717                 :    1184280 :     get_variable_section (decl, false);
     718                 :    2297200 : }
     719                 :            : 
     720                 :            : /* Output all variables enqueued to be assembled.  */
     721                 :            : bool
     722                 :     164036 : symbol_table::output_variables (void)
     723                 :            : {
     724                 :     164036 :   bool changed = false;
     725                 :     164036 :   varpool_node *node;
     726                 :            : 
     727                 :     164036 :   if (seen_error ())
     728                 :            :     return false;
     729                 :            : 
     730                 :     163841 :   remove_unreferenced_decls ();
     731                 :            : 
     732                 :     163841 :   timevar_push (TV_VAROUT);
     733                 :            : 
     734                 :    4926830 :   FOR_EACH_DEFINED_VARIABLE (node)
     735                 :            :     {
     736                 :            :       /* Handled in output_in_order.  */
     737                 :    2299580 :       if (node->no_reorder)
     738                 :     782182 :         continue;
     739                 :            : 
     740                 :    1517390 :       node->finalize_named_section_flags ();
     741                 :            :     }
     742                 :            : 
     743                 :            :   /* There is a similar loop in output_in_order.  Please keep them in sync.  */
     744                 :    5402550 :   FOR_EACH_VARIABLE (node)
     745                 :            :     {
     746                 :            :       /* Handled in output_in_order.  */
     747                 :    2537440 :       if (node->no_reorder)
     748                 :     782708 :         continue;
     749                 :    1754730 :       if (DECL_HARD_REGISTER (node->decl)
     750                 :    1754730 :           || DECL_HAS_VALUE_EXPR_P (node->decl))
     751                 :         31 :         continue;
     752                 :    1754700 :       if (node->definition)
     753                 :    1517360 :         changed |= node->assemble_decl ();
     754                 :            :       else
     755                 :     237333 :         assemble_undefined_decl (node->decl);
     756                 :            :     }
     757                 :     163841 :   timevar_pop (TV_VAROUT);
     758                 :            :   return changed;
     759                 :            : }
     760                 :            : 
     761                 :            : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     762                 :            :    Extra name aliases are output whenever DECL is output.  */
     763                 :            : 
     764                 :            : varpool_node *
     765                 :       5893 : varpool_node::create_alias (tree alias, tree decl)
     766                 :            : {
     767                 :       5893 :   varpool_node *alias_node;
     768                 :            : 
     769                 :       5893 :   gcc_assert (VAR_P (decl));
     770                 :       5893 :   gcc_assert (VAR_P (alias));
     771                 :       5893 :   alias_node = varpool_node::get_create (alias);
     772                 :       5893 :   alias_node->alias = true;
     773                 :       5893 :   alias_node->definition = true;
     774                 :       5893 :   alias_node->alias_target = decl;
     775                 :       5893 :   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
     776                 :         10 :     alias_node->weakref = alias_node->transparent_alias = true;
     777                 :       5893 :   return alias_node;
     778                 :            : }
     779                 :            : 
     780                 :            : /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
     781                 :            :    Extra name aliases are output whenever DECL is output.  */
     782                 :            : 
     783                 :            : varpool_node *
     784                 :        109 : varpool_node::create_extra_name_alias (tree alias, tree decl)
     785                 :            : {
     786                 :        109 :   varpool_node *alias_node;
     787                 :            : 
     788                 :            :   /* If aliases aren't supported by the assembler, fail.  */
     789                 :        109 :   if (!TARGET_SUPPORTS_ALIASES)
     790                 :            :     return NULL;
     791                 :            : 
     792                 :        109 :   alias_node = varpool_node::create_alias (alias, decl);
     793                 :        109 :   alias_node->cpp_implicit_alias = true;
     794                 :            : 
     795                 :            :   /* Extra name alias mechanism creates aliases really late
     796                 :            :      via DECL_ASSEMBLER_NAME mechanism.
     797                 :            :      This is unfortunate because they are not going through the
     798                 :            :      standard channels.  Ensure they get output.  */
     799                 :        109 :   if (symtab->cpp_implicit_aliases_done)
     800                 :        109 :     alias_node->resolve_alias (varpool_node::get_create (decl));
     801                 :        109 :   return alias_node;
     802                 :            : }
     803                 :            : 
     804                 :            : /* Worker for call_for_symbol_and_aliases.  */
     805                 :            : 
     806                 :            : bool
     807                 :       4639 : varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
     808                 :            :                                                                void *),
     809                 :            :                                              void *data,
     810                 :            :                                              bool include_overwritable)
     811                 :            : {
     812                 :       4639 :   ipa_ref *ref;
     813                 :            : 
     814                 :      26454 :   FOR_EACH_ALIAS (this, ref)
     815                 :            :     {
     816                 :      10907 :       varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
     817                 :      10907 :       if (include_overwritable
     818                 :      10907 :           || alias->get_availability () > AVAIL_INTERPOSABLE)
     819                 :      10907 :         if (alias->call_for_symbol_and_aliases (callback, data,
     820                 :            :                                                 include_overwritable))
     821                 :            :           return true;
     822                 :            :     }
     823                 :            :   return false;
     824                 :            : }

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.