1 /* Callgraph handling code.
2    Copyright (C) 2003-2014 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 "tm.h"
25 #include "tree.h"
26 #include "varasm.h"
27 #include "cgraph.h"
28 #include "langhooks.h"
29 #include "diagnostic-core.h"
30 #include "hashtab.h"
31 #include "timevar.h"
32 #include "debug.h"
33 #include "target.h"
34 #include "output.h"
35 #include "gimple-expr.h"
36 #include "flags.h"
37 #include "pointer-set.h"
38 
39 /* List of hooks triggered on varpool_node events.  */
40 struct varpool_node_hook_list {
41   varpool_node_hook hook;
42   void *data;
43   struct varpool_node_hook_list *next;
44 };
45 
46 /* List of hooks triggered when a node is removed.  */
47 struct varpool_node_hook_list *first_varpool_node_removal_hook;
48 /* List of hooks triggered when an variable is inserted.  */
49 struct varpool_node_hook_list *first_varpool_variable_insertion_hook;
50 
51 /* Register HOOK to be called with DATA on each removed node.  */
52 struct varpool_node_hook_list *
varpool_add_node_removal_hook(varpool_node_hook hook,void * data)53 varpool_add_node_removal_hook (varpool_node_hook hook, void *data)
54 {
55   struct varpool_node_hook_list *entry;
56   struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
57 
58   entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
59   entry->hook = hook;
60   entry->data = data;
61   entry->next = NULL;
62   while (*ptr)
63     ptr = &(*ptr)->next;
64   *ptr = entry;
65   return entry;
66 }
67 
68 /* Remove ENTRY from the list of hooks called on removing nodes.  */
69 void
varpool_remove_node_removal_hook(struct varpool_node_hook_list * entry)70 varpool_remove_node_removal_hook (struct varpool_node_hook_list *entry)
71 {
72   struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
73 
74   while (*ptr != entry)
75     ptr = &(*ptr)->next;
76   *ptr = entry->next;
77   free (entry);
78 }
79 
80 /* Call all node removal hooks.  */
81 static void
varpool_call_node_removal_hooks(varpool_node * node)82 varpool_call_node_removal_hooks (varpool_node *node)
83 {
84   struct varpool_node_hook_list *entry = first_varpool_node_removal_hook;
85   while (entry)
86   {
87     entry->hook (node, entry->data);
88     entry = entry->next;
89   }
90 }
91 
92 /* Register HOOK to be called with DATA on each inserted node.  */
93 struct varpool_node_hook_list *
varpool_add_variable_insertion_hook(varpool_node_hook hook,void * data)94 varpool_add_variable_insertion_hook (varpool_node_hook hook, void *data)
95 {
96   struct varpool_node_hook_list *entry;
97   struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
98 
99   entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
100   entry->hook = hook;
101   entry->data = data;
102   entry->next = NULL;
103   while (*ptr)
104     ptr = &(*ptr)->next;
105   *ptr = entry;
106   return entry;
107 }
108 
109 /* Remove ENTRY from the list of hooks called on inserted nodes.  */
110 void
varpool_remove_variable_insertion_hook(struct varpool_node_hook_list * entry)111 varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *entry)
112 {
113   struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
114 
115   while (*ptr != entry)
116     ptr = &(*ptr)->next;
117   *ptr = entry->next;
118   free (entry);
119 }
120 
121 /* Call all node insertion hooks.  */
122 void
varpool_call_variable_insertion_hooks(varpool_node * node)123 varpool_call_variable_insertion_hooks (varpool_node *node)
124 {
125   struct varpool_node_hook_list *entry = first_varpool_variable_insertion_hook;
126   while (entry)
127   {
128     entry->hook (node, entry->data);
129     entry = entry->next;
130   }
131 }
132 
133 /* Allocate new callgraph node and insert it into basic data structures.  */
134 
135 varpool_node *
varpool_create_empty_node(void)136 varpool_create_empty_node (void)
137 {
138   varpool_node *node = ggc_alloc_cleared_varpool_node ();
139   node->type = SYMTAB_VARIABLE;
140   return node;
141 }
142 
143 /* Return varpool node assigned to DECL.  Create new one when needed.  */
144 varpool_node *
varpool_node_for_decl(tree decl)145 varpool_node_for_decl (tree decl)
146 {
147   varpool_node *node = varpool_get_node (decl);
148   gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
149   if (node)
150     return node;
151 
152   node = varpool_create_empty_node ();
153   node->decl = decl;
154   symtab_register_node (node);
155   return node;
156 }
157 
158 /* Remove node from the varpool.  */
159 void
varpool_remove_node(varpool_node * node)160 varpool_remove_node (varpool_node *node)
161 {
162   tree init;
163   varpool_call_node_removal_hooks (node);
164   symtab_unregister_node (node);
165 
166   /* Because we remove references from external functions before final compilation,
167      we may end up removing useful constructors.
168      FIXME: We probably want to trace boundaries better.  */
169   if (cgraph_state == CGRAPH_LTO_STREAMING)
170     ;
171   else if ((init = ctor_for_folding (node->decl)) == error_mark_node)
172     varpool_remove_initializer (node);
173   else
174     DECL_INITIAL (node->decl) = init;
175   ggc_free (node);
176 }
177 
178 /* Renove node initializer when it is no longer needed.  */
179 void
varpool_remove_initializer(varpool_node * node)180 varpool_remove_initializer (varpool_node *node)
181 {
182   if (DECL_INITIAL (node->decl)
183       && !DECL_IN_CONSTANT_POOL (node->decl)
184       /* Keep vtables for BINFO folding.  */
185       && !DECL_VIRTUAL_P (node->decl)
186       /* FIXME: http://gcc.gnu.org/PR55395 */
187       && debug_info_level == DINFO_LEVEL_NONE
188       /* When doing declaration merging we have duplicate
189 	 entries for given decl.  Do not attempt to remove
190 	 the boides, or we will end up remiving
191 	 wrong one.  */
192       && cgraph_state != CGRAPH_LTO_STREAMING)
193     DECL_INITIAL (node->decl) = error_mark_node;
194 }
195 
196 /* Dump given cgraph node.  */
197 void
dump_varpool_node(FILE * f,varpool_node * node)198 dump_varpool_node (FILE *f, varpool_node *node)
199 {
200   dump_symtab_base (f, node);
201   fprintf (f, "  Availability: %s\n",
202 	   cgraph_function_flags_ready
203 	   ? cgraph_availability_names[cgraph_variable_initializer_availability (node)]
204 	   : "not-ready");
205   fprintf (f, "  Varpool flags:");
206   if (DECL_INITIAL (node->decl))
207     fprintf (f, " initialized");
208   if (node->output)
209     fprintf (f, " output");
210   if (TREE_READONLY (node->decl))
211     fprintf (f, " read-only");
212   if (ctor_for_folding (node->decl) != error_mark_node)
213     fprintf (f, " const-value-known");
214   fprintf (f, "\n");
215 }
216 
217 /* Dump the variable pool.  */
218 void
dump_varpool(FILE * f)219 dump_varpool (FILE *f)
220 {
221   varpool_node *node;
222 
223   fprintf (f, "variable pool:\n\n");
224   FOR_EACH_VARIABLE (node)
225     dump_varpool_node (f, node);
226 }
227 
228 /* Dump the variable pool to stderr.  */
229 
230 DEBUG_FUNCTION void
debug_varpool(void)231 debug_varpool (void)
232 {
233   dump_varpool (stderr);
234 }
235 
236 /* Given an assembler name, lookup node.  */
237 varpool_node *
varpool_node_for_asm(tree asmname)238 varpool_node_for_asm (tree asmname)
239 {
240   if (symtab_node *node = symtab_node_for_asm (asmname))
241     return dyn_cast <varpool_node> (node);
242   else
243     return NULL;
244 }
245 
246 /* Return if DECL is constant and its initial value is known (so we can do
247    constant folding using DECL_INITIAL (decl)).
248    Return ERROR_MARK_NODE when value is unknown.  */
249 
250 tree
ctor_for_folding(tree decl)251 ctor_for_folding (tree decl)
252 {
253   varpool_node *node, *real_node;
254   tree real_decl;
255 
256   if (TREE_CODE (decl) != VAR_DECL
257       && TREE_CODE (decl) != CONST_DECL)
258     return error_mark_node;
259 
260   if (TREE_CODE (decl) == CONST_DECL
261       || DECL_IN_CONSTANT_POOL (decl))
262     return DECL_INITIAL (decl);
263 
264   if (TREE_THIS_VOLATILE (decl))
265     return error_mark_node;
266 
267   /* Do not care about automatic variables.  Those are never initialized
268      anyway, because gimplifier exapnds the code.  */
269   if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
270     {
271       gcc_assert (!TREE_PUBLIC (decl));
272       return error_mark_node;
273     }
274 
275   gcc_assert (TREE_CODE (decl) == VAR_DECL);
276 
277   node = varpool_get_node (decl);
278   if (node)
279     {
280       real_node = varpool_variable_node (node);
281       real_decl = real_node->decl;
282     }
283   else
284     real_decl = decl;
285 
286   /* See if we are dealing with alias.
287      In most cases alias is just alternative symbol pointing to a given
288      constructor.  This allows us to use interposition rules of DECL
289      constructor of REAL_NODE.  However weakrefs are special by being just
290      alternative name of their target (if defined).  */
291   if (decl != real_decl)
292     {
293       gcc_assert (!DECL_INITIAL (decl)
294 		  || DECL_INITIAL (decl) == error_mark_node);
295       if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)))
296 	{
297 	  node = varpool_alias_target (node);
298 	  decl = node->decl;
299 	}
300     }
301 
302   /* Vtables are defined by their types and must match no matter of interposition
303      rules.  */
304   if (DECL_VIRTUAL_P (real_decl))
305     {
306       gcc_checking_assert (TREE_READONLY (real_decl));
307       if (DECL_INITIAL (real_decl))
308 	return DECL_INITIAL (real_decl);
309       else
310 	{
311 	  /* The C++ front end creates VAR_DECLs for vtables of typeinfo
312 	     classes not defined in the current TU so that it can refer
313 	     to them from typeinfo objects.  Avoid returning NULL_TREE.  */
314 	  gcc_checking_assert (!COMPLETE_TYPE_P (DECL_CONTEXT (real_decl)));
315 	  return error_mark_node;
316 	}
317     }
318 
319   /* If there is no constructor, we have nothing to do.  */
320   if (DECL_INITIAL (real_decl) == error_mark_node)
321     return error_mark_node;
322 
323   /* Non-readonly alias of readonly variable is also de-facto readonly,
324      because the variable itself is in readonly section.
325      We also honnor READONLY flag on alias assuming that user knows
326      what he is doing.  */
327   if (!TREE_READONLY (decl) && !TREE_READONLY (real_decl))
328     return error_mark_node;
329 
330   /* Variables declared 'const' without an initializer
331      have zero as the initializer if they may not be
332      overridden at link or run time.
333 
334      It is actually requirement for C++ compiler to optimize const variables
335      consistently. As a GNU extension, do not enfore this rule for user defined
336      weak variables, so we support interposition on:
337      static const int dummy = 0;
338      extern const int foo __attribute__((__weak__, __alias__("dummy")));
339    */
340   if ((!DECL_INITIAL (real_decl)
341        || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
342       && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl)))
343     return error_mark_node;
344 
345   /* Variables declared `const' with an initializer are considered
346      to not be overwritable with different initializer by default.
347 
348      ??? Previously we behaved so for scalar variables but not for array
349      accesses.  */
350   return DECL_INITIAL (real_decl);
351 }
352 
353 /* Add the variable DECL to the varpool.
354    Unlike varpool_finalize_decl function is intended to be used
355    by middle end and allows insertion of new variable at arbitrary point
356    of compilation.  */
357 void
varpool_add_new_variable(tree decl)358 varpool_add_new_variable (tree decl)
359 {
360   varpool_node *node;
361   varpool_finalize_decl (decl);
362   node = varpool_node_for_decl (decl);
363   varpool_call_variable_insertion_hooks (node);
364   if (varpool_externally_visible_p (node))
365     node->externally_visible = true;
366 }
367 
368 /* Return variable availability.  See cgraph.h for description of individual
369    return values.  */
370 enum availability
cgraph_variable_initializer_availability(varpool_node * node)371 cgraph_variable_initializer_availability (varpool_node *node)
372 {
373   gcc_assert (cgraph_function_flags_ready);
374   if (!node->definition)
375     return AVAIL_NOT_AVAILABLE;
376   if (!TREE_PUBLIC (node->decl))
377     return AVAIL_AVAILABLE;
378   if (DECL_IN_CONSTANT_POOL (node->decl)
379       || DECL_VIRTUAL_P (node->decl))
380     return AVAIL_AVAILABLE;
381   if (node->alias && node->weakref)
382     {
383       enum availability avail;
384 
385       cgraph_variable_initializer_availability
386 	      (varpool_variable_node (node, &avail));
387       return avail;
388     }
389   /* If the variable can be overwritten, return OVERWRITABLE.  Takes
390      care of at least one notable extension - the COMDAT variables
391      used to share template instantiations in C++.  */
392   if (decl_replaceable_p (node->decl)
393       || DECL_EXTERNAL (node->decl))
394     return AVAIL_OVERWRITABLE;
395   return AVAIL_AVAILABLE;
396 }
397 
398 void
varpool_analyze_node(varpool_node * node)399 varpool_analyze_node (varpool_node *node)
400 {
401   tree decl = node->decl;
402 
403   /* When reading back varpool at LTO time, we re-construct the queue in order
404      to have "needed" list right by inserting all needed nodes into varpool.
405      We however don't want to re-analyze already analyzed nodes.  */
406   if (!node->analyzed)
407     {
408       gcc_assert (!in_lto_p || cgraph_function_flags_ready);
409       /* Compute the alignment early so function body expanders are
410 	 already informed about increased alignment.  */
411       align_variable (decl, 0);
412     }
413   if (node->alias)
414     symtab_resolve_alias
415        (node, varpool_get_node (node->alias_target));
416   else if (DECL_INITIAL (decl))
417     record_references_in_initializer (decl, node->analyzed);
418   node->analyzed = true;
419 }
420 
421 /* Assemble thunks and aliases associated to NODE.  */
422 
423 static void
assemble_aliases(varpool_node * node)424 assemble_aliases (varpool_node *node)
425 {
426   int i;
427   struct ipa_ref *ref;
428   for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
429     if (ref->use == IPA_REF_ALIAS)
430       {
431 	varpool_node *alias = ipa_ref_referring_varpool_node (ref);
432 	do_assemble_alias (alias->decl,
433 			   DECL_ASSEMBLER_NAME (node->decl));
434 	assemble_aliases (alias);
435       }
436 }
437 
438 /* Output one variable, if necessary.  Return whether we output it.  */
439 
440 bool
varpool_assemble_decl(varpool_node * node)441 varpool_assemble_decl (varpool_node *node)
442 {
443   tree decl = node->decl;
444 
445   /* Aliases are outout when their target is produced or by
446      output_weakrefs.  */
447   if (node->alias)
448     return false;
449 
450   /* Constant pool is output from RTL land when the reference
451      survive till this level.  */
452   if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
453     return false;
454 
455   /* Decls with VALUE_EXPR should not be in the varpool at all.  They
456      are not real variables, but just info for debugging and codegen.
457      Unfortunately at the moment emutls is not updating varpool correctly
458      after turning real vars into value_expr vars.  */
459   if (DECL_HAS_VALUE_EXPR_P (decl)
460       && !targetm.have_tls)
461     return false;
462 
463   /* Hard register vars do not need to be output.  */
464   if (DECL_HARD_REGISTER (decl))
465     return false;
466 
467   gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
468 		       && TREE_CODE (decl) == VAR_DECL
469 		       && !DECL_HAS_VALUE_EXPR_P (decl));
470 
471   if (!node->in_other_partition
472       && !DECL_EXTERNAL (decl))
473     {
474       assemble_variable (decl, 0, 1, 0);
475       gcc_assert (TREE_ASM_WRITTEN (decl));
476       node->definition = true;
477       assemble_aliases (node);
478       return true;
479     }
480 
481   return false;
482 }
483 
484 /* Add NODE to queue starting at FIRST.
485    The queue is linked via AUX pointers and terminated by pointer to 1.  */
486 
487 static void
enqueue_node(varpool_node * node,varpool_node ** first)488 enqueue_node (varpool_node *node, varpool_node **first)
489 {
490   if (node->aux)
491     return;
492   gcc_checking_assert (*first);
493   node->aux = *first;
494   *first = node;
495 }
496 
497 /* Optimization of function bodies might've rendered some variables as
498    unnecessary so we want to avoid these from being compiled.  Re-do
499    reachability starting from variables that are either externally visible
500    or was referred from the asm output routines.  */
501 
502 static void
varpool_remove_unreferenced_decls(void)503 varpool_remove_unreferenced_decls (void)
504 {
505   varpool_node *next, *node;
506   varpool_node *first = (varpool_node *)(void *)1;
507   int i;
508   struct ipa_ref *ref;
509   struct pointer_set_t *referenced = pointer_set_create ();
510 
511   if (seen_error ())
512     return;
513 
514   if (cgraph_dump_file)
515     fprintf (cgraph_dump_file, "Trivially needed variables:");
516   FOR_EACH_DEFINED_VARIABLE (node)
517     {
518       if (node->analyzed
519 	  && (!varpool_can_remove_if_no_refs (node)
520 	      /* We just expanded all function bodies.  See if any of
521 		 them needed the variable.  */
522 	      || DECL_RTL_SET_P (node->decl)))
523 	{
524 	  enqueue_node (node, &first);
525           if (cgraph_dump_file)
526 	    fprintf (cgraph_dump_file, " %s", node->asm_name ());
527 	}
528     }
529   while (first != (varpool_node *)(void *)1)
530     {
531       node = first;
532       first = (varpool_node *)first->aux;
533 
534       if (node->same_comdat_group)
535 	{
536 	  symtab_node *next;
537 	  for (next = node->same_comdat_group;
538 	       next != node;
539 	       next = next->same_comdat_group)
540 	    {
541 	      varpool_node *vnext = dyn_cast <varpool_node> (next);
542 	      if (vnext && vnext->analyzed && !symtab_comdat_local_p (next))
543 		enqueue_node (vnext, &first);
544 	    }
545 	}
546       for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
547 	{
548 	  varpool_node *vnode = dyn_cast <varpool_node> (ref->referred);
549 	  if (vnode
550 	      && !vnode->in_other_partition
551 	      && (!DECL_EXTERNAL (ref->referred->decl)
552 		  || vnode->alias)
553 	      && vnode->analyzed)
554 	    enqueue_node (vnode, &first);
555 	  else
556 	    pointer_set_insert (referenced, node);
557 	}
558     }
559   if (cgraph_dump_file)
560     fprintf (cgraph_dump_file, "\nRemoving variables:");
561   for (node = varpool_first_defined_variable (); node; node = next)
562     {
563       next = varpool_next_defined_variable (node);
564       if (!node->aux)
565 	{
566           if (cgraph_dump_file)
567 	    fprintf (cgraph_dump_file, " %s", node->asm_name ());
568 	  if (pointer_set_contains (referenced, node))
569 	    varpool_remove_initializer (node);
570 	  else
571 	    varpool_remove_node (node);
572 	}
573     }
574   pointer_set_destroy (referenced);
575   if (cgraph_dump_file)
576     fprintf (cgraph_dump_file, "\n");
577 }
578 
579 /* For variables in named sections make sure get_variable_section
580    is called before we switch to those sections.  Then section
581    conflicts between read-only and read-only requiring relocations
582    sections can be resolved.  */
583 void
varpool_finalize_named_section_flags(varpool_node * node)584 varpool_finalize_named_section_flags (varpool_node *node)
585 {
586   if (!TREE_ASM_WRITTEN (node->decl)
587       && !node->alias
588       && !node->in_other_partition
589       && !DECL_EXTERNAL (node->decl)
590       && TREE_CODE (node->decl) == VAR_DECL
591       && !DECL_HAS_VALUE_EXPR_P (node->decl)
592       && DECL_SECTION_NAME (node->decl))
593     get_variable_section (node->decl, false);
594 }
595 
596 /* Output all variables enqueued to be assembled.  */
597 bool
varpool_output_variables(void)598 varpool_output_variables (void)
599 {
600   bool changed = false;
601   varpool_node *node;
602 
603   if (seen_error ())
604     return false;
605 
606   varpool_remove_unreferenced_decls ();
607 
608   timevar_push (TV_VAROUT);
609 
610   FOR_EACH_DEFINED_VARIABLE (node)
611     varpool_finalize_named_section_flags (node);
612 
613   FOR_EACH_DEFINED_VARIABLE (node)
614     if (varpool_assemble_decl (node))
615       changed = true;
616   timevar_pop (TV_VAROUT);
617   return changed;
618 }
619 
620 /* Create a new global variable of type TYPE.  */
621 tree
add_new_static_var(tree type)622 add_new_static_var (tree type)
623 {
624   tree new_decl;
625   varpool_node *new_node;
626 
627   new_decl = create_tmp_var_raw (type, NULL);
628   DECL_NAME (new_decl) = create_tmp_var_name (NULL);
629   TREE_READONLY (new_decl) = 0;
630   TREE_STATIC (new_decl) = 1;
631   TREE_USED (new_decl) = 1;
632   DECL_CONTEXT (new_decl) = NULL_TREE;
633   DECL_ABSTRACT (new_decl) = 0;
634   lang_hooks.dup_lang_specific_decl (new_decl);
635   new_node = varpool_node_for_decl (new_decl);
636   varpool_finalize_decl (new_decl);
637 
638   return new_node->decl;
639 }
640 
641 /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
642    Extra name aliases are output whenever DECL is output.  */
643 
644 varpool_node *
varpool_create_variable_alias(tree alias,tree decl)645 varpool_create_variable_alias (tree alias, tree decl)
646 {
647   varpool_node *alias_node;
648 
649   gcc_assert (TREE_CODE (decl) == VAR_DECL);
650   gcc_assert (TREE_CODE (alias) == VAR_DECL);
651   alias_node = varpool_node_for_decl (alias);
652   alias_node->alias = true;
653   alias_node->definition = true;
654   alias_node->alias_target = decl;
655   if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
656     alias_node->weakref = true;
657   return alias_node;
658 }
659 
660 /* Attempt to mark ALIAS as an alias to DECL.  Return TRUE if successful.
661    Extra name aliases are output whenever DECL is output.  */
662 
663 varpool_node *
varpool_extra_name_alias(tree alias,tree decl)664 varpool_extra_name_alias (tree alias, tree decl)
665 {
666   varpool_node *alias_node;
667 
668 #ifndef ASM_OUTPUT_DEF
669   /* If aliases aren't supported by the assembler, fail.  */
670   return NULL;
671 #endif
672   alias_node = varpool_create_variable_alias (alias, decl);
673   alias_node->cpp_implicit_alias = true;
674 
675   /* Extra name alias mechanizm creates aliases really late
676      via DECL_ASSEMBLER_NAME mechanizm.
677      This is unfortunate because they are not going through the
678      standard channels.  Ensure they get output.  */
679   if (cpp_implicit_aliases_done)
680     symtab_resolve_alias (alias_node,
681 			  varpool_node_for_decl (decl));
682   return alias_node;
683 }
684 
685 /* Call calback on NODE and aliases associated to NODE.
686    When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
687    skipped. */
688 
689 bool
varpool_for_node_and_aliases(varpool_node * node,bool (* callback)(varpool_node *,void *),void * data,bool include_overwritable)690 varpool_for_node_and_aliases (varpool_node *node,
691 			      bool (*callback) (varpool_node *, void *),
692 			      void *data,
693 			      bool include_overwritable)
694 {
695   int i;
696   struct ipa_ref *ref;
697 
698   if (callback (node, data))
699     return true;
700   for (i = 0; ipa_ref_list_referring_iterate (&node->ref_list, i, ref); i++)
701     if (ref->use == IPA_REF_ALIAS)
702       {
703 	varpool_node *alias = ipa_ref_referring_varpool_node (ref);
704 	if (include_overwritable
705 	    || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE)
706           if (varpool_for_node_and_aliases (alias, callback, data,
707 					   include_overwritable))
708 	    return true;
709       }
710   return false;
711 }
712