138fd1498Szrj /* Callgraph handling code.
238fd1498Szrj Copyright (C) 2003-2018 Free Software Foundation, Inc.
338fd1498Szrj Contributed by Jan Hubicka
438fd1498Szrj
538fd1498Szrj This file is part of GCC.
638fd1498Szrj
738fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
838fd1498Szrj the terms of the GNU General Public License as published by the Free
938fd1498Szrj Software Foundation; either version 3, or (at your option) any later
1038fd1498Szrj version.
1138fd1498Szrj
1238fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1338fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
1438fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1538fd1498Szrj for more details.
1638fd1498Szrj
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3. If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>. */
2038fd1498Szrj
2138fd1498Szrj #include "config.h"
2238fd1498Szrj #include "system.h"
2338fd1498Szrj #include "coretypes.h"
2438fd1498Szrj #include "backend.h"
2538fd1498Szrj #include "target.h"
2638fd1498Szrj #include "tree.h"
2738fd1498Szrj #include "gimple.h"
2838fd1498Szrj #include "timevar.h"
2938fd1498Szrj #include "cgraph.h"
3038fd1498Szrj #include "lto-streamer.h"
3138fd1498Szrj #include "varasm.h"
3238fd1498Szrj #include "debug.h"
3338fd1498Szrj #include "output.h"
3438fd1498Szrj #include "omp-offload.h"
3538fd1498Szrj #include "context.h"
3638fd1498Szrj #include "stringpool.h"
3738fd1498Szrj #include "attribs.h"
3838fd1498Szrj
3938fd1498Szrj const char * const tls_model_names[]={"none", "emulated",
4038fd1498Szrj "global-dynamic", "local-dynamic",
4138fd1498Szrj "initial-exec", "local-exec"};
4238fd1498Szrj
4338fd1498Szrj /* List of hooks triggered on varpool_node events. */
4438fd1498Szrj struct varpool_node_hook_list {
4538fd1498Szrj varpool_node_hook hook;
4638fd1498Szrj void *data;
4738fd1498Szrj struct varpool_node_hook_list *next;
4838fd1498Szrj };
4938fd1498Szrj
5038fd1498Szrj /* Register HOOK to be called with DATA on each removed node. */
5138fd1498Szrj varpool_node_hook_list *
add_varpool_removal_hook(varpool_node_hook hook,void * data)5238fd1498Szrj symbol_table::add_varpool_removal_hook (varpool_node_hook hook, void *data)
5338fd1498Szrj {
5438fd1498Szrj varpool_node_hook_list *entry;
5538fd1498Szrj varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
5638fd1498Szrj
5738fd1498Szrj entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
5838fd1498Szrj entry->hook = hook;
5938fd1498Szrj entry->data = data;
6038fd1498Szrj entry->next = NULL;
6138fd1498Szrj while (*ptr)
6238fd1498Szrj ptr = &(*ptr)->next;
6338fd1498Szrj *ptr = entry;
6438fd1498Szrj return entry;
6538fd1498Szrj }
6638fd1498Szrj
6738fd1498Szrj /* Remove ENTRY from the list of hooks called on removing nodes. */
6838fd1498Szrj void
remove_varpool_removal_hook(varpool_node_hook_list * entry)6938fd1498Szrj symbol_table::remove_varpool_removal_hook (varpool_node_hook_list *entry)
7038fd1498Szrj {
7138fd1498Szrj varpool_node_hook_list **ptr = &m_first_varpool_removal_hook;
7238fd1498Szrj
7338fd1498Szrj while (*ptr != entry)
7438fd1498Szrj ptr = &(*ptr)->next;
7538fd1498Szrj *ptr = entry->next;
7638fd1498Szrj free (entry);
7738fd1498Szrj }
7838fd1498Szrj
7938fd1498Szrj /* Call all node removal hooks. */
8038fd1498Szrj void
call_varpool_removal_hooks(varpool_node * node)8138fd1498Szrj symbol_table::call_varpool_removal_hooks (varpool_node *node)
8238fd1498Szrj {
8338fd1498Szrj varpool_node_hook_list *entry = m_first_varpool_removal_hook;
8438fd1498Szrj while (entry)
8538fd1498Szrj {
8638fd1498Szrj entry->hook (node, entry->data);
8738fd1498Szrj entry = entry->next;
8838fd1498Szrj }
8938fd1498Szrj }
9038fd1498Szrj
9138fd1498Szrj /* Register HOOK to be called with DATA on each inserted node. */
9238fd1498Szrj varpool_node_hook_list *
add_varpool_insertion_hook(varpool_node_hook hook,void * data)9338fd1498Szrj symbol_table::add_varpool_insertion_hook (varpool_node_hook hook, void *data)
9438fd1498Szrj {
9538fd1498Szrj varpool_node_hook_list *entry;
9638fd1498Szrj varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
9738fd1498Szrj
9838fd1498Szrj entry = (varpool_node_hook_list *) xmalloc (sizeof (*entry));
9938fd1498Szrj entry->hook = hook;
10038fd1498Szrj entry->data = data;
10138fd1498Szrj entry->next = NULL;
10238fd1498Szrj while (*ptr)
10338fd1498Szrj ptr = &(*ptr)->next;
10438fd1498Szrj *ptr = entry;
10538fd1498Szrj return entry;
10638fd1498Szrj }
10738fd1498Szrj
10838fd1498Szrj /* Remove ENTRY from the list of hooks called on inserted nodes. */
10938fd1498Szrj void
remove_varpool_insertion_hook(varpool_node_hook_list * entry)11038fd1498Szrj symbol_table::remove_varpool_insertion_hook (varpool_node_hook_list *entry)
11138fd1498Szrj {
11238fd1498Szrj varpool_node_hook_list **ptr = &m_first_varpool_insertion_hook;
11338fd1498Szrj
11438fd1498Szrj while (*ptr != entry)
11538fd1498Szrj ptr = &(*ptr)->next;
11638fd1498Szrj *ptr = entry->next;
11738fd1498Szrj free (entry);
11838fd1498Szrj }
11938fd1498Szrj
12038fd1498Szrj /* Call all node insertion hooks. */
12138fd1498Szrj void
call_varpool_insertion_hooks(varpool_node * node)12238fd1498Szrj symbol_table::call_varpool_insertion_hooks (varpool_node *node)
12338fd1498Szrj {
12438fd1498Szrj varpool_node_hook_list *entry = m_first_varpool_insertion_hook;
12538fd1498Szrj while (entry)
12638fd1498Szrj {
12738fd1498Szrj entry->hook (node, entry->data);
12838fd1498Szrj entry = entry->next;
12938fd1498Szrj }
13038fd1498Szrj }
13138fd1498Szrj
13238fd1498Szrj /* Allocate new callgraph node and insert it into basic data structures. */
13338fd1498Szrj
13438fd1498Szrj varpool_node *
create_empty(void)13538fd1498Szrj varpool_node::create_empty (void)
13638fd1498Szrj {
13738fd1498Szrj varpool_node *node = ggc_cleared_alloc<varpool_node> ();
13838fd1498Szrj node->type = SYMTAB_VARIABLE;
13938fd1498Szrj return node;
14038fd1498Szrj }
14138fd1498Szrj
14238fd1498Szrj /* Return varpool node assigned to DECL. Create new one when needed. */
14338fd1498Szrj varpool_node *
get_create(tree decl)14438fd1498Szrj varpool_node::get_create (tree decl)
14538fd1498Szrj {
14638fd1498Szrj varpool_node *node = varpool_node::get (decl);
14738fd1498Szrj gcc_checking_assert (VAR_P (decl));
14838fd1498Szrj if (node)
14938fd1498Szrj return node;
15038fd1498Szrj
15138fd1498Szrj node = varpool_node::create_empty ();
15238fd1498Szrj node->decl = decl;
15338fd1498Szrj
15438fd1498Szrj if ((flag_openacc || flag_openmp)
15538fd1498Szrj && lookup_attribute ("omp declare target", DECL_ATTRIBUTES (decl)))
15638fd1498Szrj {
15738fd1498Szrj node->offloadable = 1;
15838fd1498Szrj if (ENABLE_OFFLOADING && !DECL_EXTERNAL (decl))
15938fd1498Szrj {
16038fd1498Szrj g->have_offload = true;
16138fd1498Szrj if (!in_lto_p)
16238fd1498Szrj vec_safe_push (offload_vars, decl);
16338fd1498Szrj }
16438fd1498Szrj }
16538fd1498Szrj
16638fd1498Szrj node->register_symbol ();
16738fd1498Szrj return node;
16838fd1498Szrj }
16938fd1498Szrj
17038fd1498Szrj /* Remove variable from symbol table. */
17138fd1498Szrj
17238fd1498Szrj void
remove(void)17338fd1498Szrj varpool_node::remove (void)
17438fd1498Szrj {
17538fd1498Szrj symtab->call_varpool_removal_hooks (this);
17638fd1498Szrj if (lto_file_data)
17738fd1498Szrj {
17838fd1498Szrj lto_free_function_in_decl_state_for_node (this);
17938fd1498Szrj lto_file_data = NULL;
18038fd1498Szrj }
18138fd1498Szrj
18238fd1498Szrj /* When streaming we can have multiple nodes associated with decl. */
18338fd1498Szrj if (symtab->state == LTO_STREAMING)
18438fd1498Szrj ;
18538fd1498Szrj /* Keep constructor when it may be used for folding. We remove
18638fd1498Szrj references to external variables before final compilation. */
18738fd1498Szrj else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node
18838fd1498Szrj && !ctor_useable_for_folding_p ())
18938fd1498Szrj remove_initializer ();
19038fd1498Szrj
19138fd1498Szrj unregister ();
19238fd1498Szrj ggc_free (this);
19338fd1498Szrj }
19438fd1498Szrj
19538fd1498Szrj /* Remove node initializer when it is no longer needed. */
19638fd1498Szrj void
remove_initializer(void)19738fd1498Szrj varpool_node::remove_initializer (void)
19838fd1498Szrj {
19938fd1498Szrj if (DECL_INITIAL (decl)
20038fd1498Szrj && !DECL_IN_CONSTANT_POOL (decl)
20138fd1498Szrj /* Keep vtables for BINFO folding. */
20238fd1498Szrj && !DECL_VIRTUAL_P (decl)
20338fd1498Szrj /* FIXME: http://gcc.gnu.org/PR55395 */
20438fd1498Szrj && debug_info_level == DINFO_LEVEL_NONE
20538fd1498Szrj /* When doing declaration merging we have duplicate
20638fd1498Szrj entries for given decl. Do not attempt to remove
20738fd1498Szrj the boides, or we will end up remiving
20838fd1498Szrj wrong one. */
20938fd1498Szrj && symtab->state != LTO_STREAMING)
21038fd1498Szrj DECL_INITIAL (decl) = error_mark_node;
21138fd1498Szrj }
21238fd1498Szrj
21338fd1498Szrj /* Dump given varpool node to F. */
21438fd1498Szrj void
dump(FILE * f)21538fd1498Szrj varpool_node::dump (FILE *f)
21638fd1498Szrj {
21738fd1498Szrj dump_base (f);
21838fd1498Szrj fprintf (f, " Availability: %s\n",
21938fd1498Szrj symtab->function_flags_ready
22038fd1498Szrj ? cgraph_availability_names[get_availability ()]
22138fd1498Szrj : "not-ready");
22238fd1498Szrj fprintf (f, " Varpool flags:");
22338fd1498Szrj if (DECL_INITIAL (decl))
22438fd1498Szrj fprintf (f, " initialized");
22538fd1498Szrj if (output)
22638fd1498Szrj fprintf (f, " output");
22738fd1498Szrj if (used_by_single_function)
22838fd1498Szrj fprintf (f, " used-by-single-function");
22938fd1498Szrj if (need_bounds_init)
23038fd1498Szrj fprintf (f, " need-bounds-init");
23138fd1498Szrj if (TREE_READONLY (decl))
23238fd1498Szrj fprintf (f, " read-only");
23338fd1498Szrj if (ctor_useable_for_folding_p ())
23438fd1498Szrj fprintf (f, " const-value-known");
23538fd1498Szrj if (writeonly)
23638fd1498Szrj fprintf (f, " write-only");
23738fd1498Szrj if (tls_model)
23838fd1498Szrj fprintf (f, " tls-%s", tls_model_names [tls_model]);
23938fd1498Szrj fprintf (f, "\n");
24038fd1498Szrj }
24138fd1498Szrj
24238fd1498Szrj
24338fd1498Szrj /* Dump given varpool node to stderr. */
debug(void)24438fd1498Szrj void varpool_node::debug (void)
24538fd1498Szrj {
24638fd1498Szrj varpool_node::dump (stderr);
24738fd1498Szrj }
24838fd1498Szrj
24938fd1498Szrj /* Dump the variable pool to F. */
25038fd1498Szrj void
dump_varpool(FILE * f)25138fd1498Szrj varpool_node::dump_varpool (FILE *f)
25238fd1498Szrj {
25338fd1498Szrj varpool_node *node;
25438fd1498Szrj
25538fd1498Szrj fprintf (f, "variable pool:\n\n");
25638fd1498Szrj FOR_EACH_VARIABLE (node)
25738fd1498Szrj node->dump (f);
25838fd1498Szrj }
25938fd1498Szrj
26038fd1498Szrj /* Dump the variable pool to stderr. */
26138fd1498Szrj
26238fd1498Szrj DEBUG_FUNCTION void
debug_varpool(void)26338fd1498Szrj varpool_node::debug_varpool (void)
26438fd1498Szrj {
26538fd1498Szrj dump_varpool (stderr);
26638fd1498Szrj }
26738fd1498Szrj
26838fd1498Szrj /* Given an assembler name, lookup node. */
26938fd1498Szrj varpool_node *
get_for_asmname(tree asmname)27038fd1498Szrj varpool_node::get_for_asmname (tree asmname)
27138fd1498Szrj {
27238fd1498Szrj if (symtab_node *node = symtab_node::get_for_asmname (asmname))
27338fd1498Szrj return dyn_cast <varpool_node *> (node);
27438fd1498Szrj else
27538fd1498Szrj return NULL;
27638fd1498Szrj }
27738fd1498Szrj
27838fd1498Szrj /* When doing LTO, read variable's constructor from disk if
27938fd1498Szrj it is not already present. */
28038fd1498Szrj
28138fd1498Szrj tree
get_constructor(void)28238fd1498Szrj varpool_node::get_constructor (void)
28338fd1498Szrj {
28438fd1498Szrj lto_file_decl_data *file_data;
28538fd1498Szrj const char *data, *name;
28638fd1498Szrj size_t len;
28738fd1498Szrj
28838fd1498Szrj if (DECL_INITIAL (decl) != error_mark_node
28938fd1498Szrj || !in_lto_p
29038fd1498Szrj || !lto_file_data)
29138fd1498Szrj return DECL_INITIAL (decl);
29238fd1498Szrj
29338fd1498Szrj timevar_push (TV_IPA_LTO_CTORS_IN);
29438fd1498Szrj
29538fd1498Szrj file_data = lto_file_data;
29638fd1498Szrj name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
29738fd1498Szrj
29838fd1498Szrj /* We may have renamed the declaration, e.g., a static function. */
29938fd1498Szrj name = lto_get_decl_name_mapping (file_data, name);
30038fd1498Szrj struct lto_in_decl_state *decl_state
30138fd1498Szrj = lto_get_function_in_decl_state (file_data, decl);
30238fd1498Szrj
30338fd1498Szrj data = lto_get_section_data (file_data, LTO_section_function_body,
30438fd1498Szrj name, &len, decl_state->compressed);
30538fd1498Szrj if (!data)
30638fd1498Szrj fatal_error (input_location, "%s: section %s is missing",
30738fd1498Szrj file_data->file_name,
30838fd1498Szrj name);
30938fd1498Szrj
31038fd1498Szrj lto_input_variable_constructor (file_data, this, data);
31138fd1498Szrj gcc_assert (DECL_INITIAL (decl) != error_mark_node);
31238fd1498Szrj lto_stats.num_function_bodies++;
31338fd1498Szrj lto_free_section_data (file_data, LTO_section_function_body, name,
31438fd1498Szrj data, len, decl_state->compressed);
31538fd1498Szrj lto_free_function_in_decl_state_for_node (this);
31638fd1498Szrj timevar_pop (TV_IPA_LTO_CTORS_IN);
31738fd1498Szrj return DECL_INITIAL (decl);
31838fd1498Szrj }
31938fd1498Szrj
32038fd1498Szrj /* Return true if variable has constructor that can be used for folding. */
32138fd1498Szrj
32238fd1498Szrj bool
ctor_useable_for_folding_p(void)32338fd1498Szrj varpool_node::ctor_useable_for_folding_p (void)
32438fd1498Szrj {
32538fd1498Szrj varpool_node *real_node = this;
32638fd1498Szrj
32738fd1498Szrj if (real_node->alias && real_node->definition)
32838fd1498Szrj real_node = ultimate_alias_target ();
32938fd1498Szrj
33038fd1498Szrj if (TREE_CODE (decl) == CONST_DECL
33138fd1498Szrj || DECL_IN_CONSTANT_POOL (decl))
33238fd1498Szrj return true;
33338fd1498Szrj if (TREE_THIS_VOLATILE (decl))
33438fd1498Szrj return false;
33538fd1498Szrj
336*58e805e6Szrj /* Avoid attempts to load constructors that was not streamed. */
337*58e805e6Szrj if (in_lto_p && DECL_INITIAL (real_node->decl) == error_mark_node
338*58e805e6Szrj && real_node->body_removed)
339*58e805e6Szrj return false;
340*58e805e6Szrj
34138fd1498Szrj /* If we do not have a constructor, we can't use it. */
34238fd1498Szrj if (DECL_INITIAL (real_node->decl) == error_mark_node
34338fd1498Szrj && !real_node->lto_file_data)
34438fd1498Szrj return false;
34538fd1498Szrj
34638fd1498Szrj /* Vtables are defined by their types and must match no matter of interposition
34738fd1498Szrj rules. */
34838fd1498Szrj if (DECL_VIRTUAL_P (decl))
34938fd1498Szrj {
35038fd1498Szrj /* The C++ front end creates VAR_DECLs for vtables of typeinfo
35138fd1498Szrj classes not defined in the current TU so that it can refer
35238fd1498Szrj to them from typeinfo objects. Avoid returning NULL_TREE. */
35338fd1498Szrj return DECL_INITIAL (real_node->decl) != NULL;
35438fd1498Szrj }
35538fd1498Szrj
35638fd1498Szrj /* Alias of readonly variable is also readonly, since the variable is stored
35738fd1498Szrj in readonly memory. We also accept readonly aliases of non-readonly
35838fd1498Szrj locations assuming that user knows what he is asking for. */
35938fd1498Szrj if (!TREE_READONLY (decl) && !TREE_READONLY (real_node->decl))
36038fd1498Szrj return false;
36138fd1498Szrj
36238fd1498Szrj /* Variables declared 'const' without an initializer
36338fd1498Szrj have zero as the initializer if they may not be
36438fd1498Szrj overridden at link or run time.
36538fd1498Szrj
36638fd1498Szrj It is actually requirement for C++ compiler to optimize const variables
36738fd1498Szrj consistently. As a GNU extension, do not enfore this rule for user defined
36838fd1498Szrj weak variables, so we support interposition on:
36938fd1498Szrj static const int dummy = 0;
37038fd1498Szrj extern const int foo __attribute__((__weak__, __alias__("dummy")));
37138fd1498Szrj */
37238fd1498Szrj if ((!DECL_INITIAL (real_node->decl)
37338fd1498Szrj || (DECL_WEAK (decl) && !DECL_COMDAT (decl)))
37438fd1498Szrj && (DECL_EXTERNAL (decl) || decl_replaceable_p (decl)))
37538fd1498Szrj return false;
37638fd1498Szrj
37738fd1498Szrj /* Variables declared `const' with an initializer are considered
37838fd1498Szrj to not be overwritable with different initializer by default.
37938fd1498Szrj
38038fd1498Szrj ??? Previously we behaved so for scalar variables but not for array
38138fd1498Szrj accesses. */
38238fd1498Szrj return true;
38338fd1498Szrj }
38438fd1498Szrj
38538fd1498Szrj /* If DECLARATION is constant variable and its initial value is known
38638fd1498Szrj (so we can do constant folding), return its constructor (DECL_INITIAL).
38738fd1498Szrj This may be an expression or NULL when DECL is initialized to 0.
38838fd1498Szrj Return ERROR_MARK_NODE otherwise.
38938fd1498Szrj
39038fd1498Szrj In LTO this may actually trigger reading the constructor from disk.
39138fd1498Szrj For this reason varpool_ctor_useable_for_folding_p should be used when
39238fd1498Szrj the actual constructor value is not needed. */
39338fd1498Szrj
39438fd1498Szrj tree
ctor_for_folding(tree decl)39538fd1498Szrj ctor_for_folding (tree decl)
39638fd1498Szrj {
39738fd1498Szrj varpool_node *node, *real_node;
39838fd1498Szrj tree real_decl;
39938fd1498Szrj
40038fd1498Szrj if (!VAR_P (decl) && TREE_CODE (decl) != CONST_DECL)
40138fd1498Szrj return error_mark_node;
40238fd1498Szrj
40338fd1498Szrj /* Static constant bounds are created to be
40438fd1498Szrj used instead of constants and therefore
40538fd1498Szrj do not let folding it. */
40638fd1498Szrj if (POINTER_BOUNDS_P (decl))
40738fd1498Szrj return error_mark_node;
40838fd1498Szrj
40938fd1498Szrj if (TREE_CODE (decl) == CONST_DECL
41038fd1498Szrj || DECL_IN_CONSTANT_POOL (decl))
41138fd1498Szrj return DECL_INITIAL (decl);
41238fd1498Szrj
41338fd1498Szrj if (TREE_THIS_VOLATILE (decl))
41438fd1498Szrj return error_mark_node;
41538fd1498Szrj
41638fd1498Szrj /* Do not care about automatic variables. Those are never initialized
41738fd1498Szrj anyway, because gimplifier exapnds the code. */
41838fd1498Szrj if (!TREE_STATIC (decl) && !DECL_EXTERNAL (decl))
41938fd1498Szrj {
42038fd1498Szrj gcc_assert (!TREE_PUBLIC (decl));
42138fd1498Szrj return error_mark_node;
42238fd1498Szrj }
42338fd1498Szrj
42438fd1498Szrj gcc_assert (VAR_P (decl));
42538fd1498Szrj
42638fd1498Szrj real_node = node = varpool_node::get (decl);
42738fd1498Szrj if (node)
42838fd1498Szrj {
42938fd1498Szrj real_node = node->ultimate_alias_target ();
43038fd1498Szrj real_decl = real_node->decl;
43138fd1498Szrj }
43238fd1498Szrj else
43338fd1498Szrj real_decl = decl;
43438fd1498Szrj
43538fd1498Szrj /* See if we are dealing with alias.
43638fd1498Szrj In most cases alias is just alternative symbol pointing to a given
43738fd1498Szrj constructor. This allows us to use interposition rules of DECL
43838fd1498Szrj constructor of REAL_NODE. However weakrefs are special by being just
43938fd1498Szrj alternative name of their target (if defined). */
44038fd1498Szrj if (decl != real_decl)
44138fd1498Szrj {
44238fd1498Szrj gcc_assert (!DECL_INITIAL (decl)
44338fd1498Szrj || (node->alias && node->get_alias_target () == real_node)
44438fd1498Szrj || DECL_INITIAL (decl) == error_mark_node);
44538fd1498Szrj while (node->transparent_alias && node->analyzed)
44638fd1498Szrj {
44738fd1498Szrj node = node->get_alias_target ();
44838fd1498Szrj decl = node->decl;
44938fd1498Szrj }
45038fd1498Szrj }
45138fd1498Szrj
45238fd1498Szrj if ((!DECL_VIRTUAL_P (real_decl)
45338fd1498Szrj || DECL_INITIAL (real_decl) == error_mark_node
45438fd1498Szrj || !DECL_INITIAL (real_decl))
45538fd1498Szrj && (!node || !node->ctor_useable_for_folding_p ()))
45638fd1498Szrj return error_mark_node;
45738fd1498Szrj
45838fd1498Szrj /* OK, we can return constructor. See if we need to fetch it from disk
45938fd1498Szrj in LTO mode. */
46038fd1498Szrj if (DECL_INITIAL (real_decl) != error_mark_node
46138fd1498Szrj || !in_lto_p)
46238fd1498Szrj return DECL_INITIAL (real_decl);
46338fd1498Szrj return real_node->get_constructor ();
46438fd1498Szrj }
46538fd1498Szrj
46638fd1498Szrj /* Add the variable DECL to the varpool.
46738fd1498Szrj Unlike finalize_decl function is intended to be used
46838fd1498Szrj by middle end and allows insertion of new variable at arbitrary point
46938fd1498Szrj of compilation. */
47038fd1498Szrj void
add(tree decl)47138fd1498Szrj varpool_node::add (tree decl)
47238fd1498Szrj {
47338fd1498Szrj varpool_node *node;
47438fd1498Szrj varpool_node::finalize_decl (decl);
47538fd1498Szrj node = varpool_node::get_create (decl);
47638fd1498Szrj symtab->call_varpool_insertion_hooks (node);
47738fd1498Szrj if (node->externally_visible_p ())
47838fd1498Szrj node->externally_visible = true;
47938fd1498Szrj if (lookup_attribute ("no_reorder", DECL_ATTRIBUTES (decl)))
48038fd1498Szrj node->no_reorder = 1;
48138fd1498Szrj }
48238fd1498Szrj
48338fd1498Szrj /* Return variable availability. See cgraph.h for description of individual
48438fd1498Szrj return values. */
48538fd1498Szrj enum availability
get_availability(symtab_node * ref)48638fd1498Szrj varpool_node::get_availability (symtab_node *ref)
48738fd1498Szrj {
48838fd1498Szrj if (!definition)
48938fd1498Szrj return AVAIL_NOT_AVAILABLE;
49038fd1498Szrj if (!TREE_PUBLIC (decl))
49138fd1498Szrj return AVAIL_AVAILABLE;
49238fd1498Szrj if (DECL_IN_CONSTANT_POOL (decl)
49338fd1498Szrj || DECL_VIRTUAL_P (decl))
49438fd1498Szrj return AVAIL_AVAILABLE;
49538fd1498Szrj if (transparent_alias && definition)
49638fd1498Szrj {
49738fd1498Szrj enum availability avail;
49838fd1498Szrj
49938fd1498Szrj ultimate_alias_target (&avail, ref);
50038fd1498Szrj return avail;
50138fd1498Szrj }
50238fd1498Szrj /* If this is a reference from symbol itself and there are no aliases, we
50338fd1498Szrj may be sure that the symbol was not interposed by something else because
50438fd1498Szrj the symbol itself would be unreachable otherwise. */
50538fd1498Szrj if ((this == ref && !has_aliases_p ())
50638fd1498Szrj || (ref && get_comdat_group ()
50738fd1498Szrj && get_comdat_group () == ref->get_comdat_group ()))
50838fd1498Szrj return AVAIL_AVAILABLE;
50938fd1498Szrj /* If the variable can be overwritten, return OVERWRITABLE. Takes
51038fd1498Szrj care of at least one notable extension - the COMDAT variables
51138fd1498Szrj used to share template instantiations in C++. */
51238fd1498Szrj if (decl_replaceable_p (decl)
51338fd1498Szrj || DECL_EXTERNAL (decl))
51438fd1498Szrj return AVAIL_INTERPOSABLE;
51538fd1498Szrj return AVAIL_AVAILABLE;
51638fd1498Szrj }
51738fd1498Szrj
51838fd1498Szrj void
analyze(void)51938fd1498Szrj varpool_node::analyze (void)
52038fd1498Szrj {
52138fd1498Szrj /* When reading back varpool at LTO time, we re-construct the queue in order
52238fd1498Szrj to have "needed" list right by inserting all needed nodes into varpool.
52338fd1498Szrj We however don't want to re-analyze already analyzed nodes. */
52438fd1498Szrj if (!analyzed)
52538fd1498Szrj {
52638fd1498Szrj gcc_assert (!in_lto_p || symtab->function_flags_ready);
52738fd1498Szrj /* Compute the alignment early so function body expanders are
52838fd1498Szrj already informed about increased alignment. */
52938fd1498Szrj align_variable (decl, 0);
53038fd1498Szrj }
53138fd1498Szrj if (alias)
53238fd1498Szrj resolve_alias (varpool_node::get (alias_target));
53338fd1498Szrj else if (DECL_INITIAL (decl))
53438fd1498Szrj record_references_in_initializer (decl, analyzed);
53538fd1498Szrj analyzed = true;
53638fd1498Szrj }
53738fd1498Szrj
53838fd1498Szrj /* Assemble thunks and aliases associated to varpool node. */
53938fd1498Szrj
54038fd1498Szrj void
assemble_aliases(void)54138fd1498Szrj varpool_node::assemble_aliases (void)
54238fd1498Szrj {
54338fd1498Szrj ipa_ref *ref;
54438fd1498Szrj
54538fd1498Szrj FOR_EACH_ALIAS (this, ref)
54638fd1498Szrj {
54738fd1498Szrj varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
54838fd1498Szrj if (!alias->transparent_alias)
54938fd1498Szrj do_assemble_alias (alias->decl,
55038fd1498Szrj DECL_ASSEMBLER_NAME (decl));
55138fd1498Szrj alias->assemble_aliases ();
55238fd1498Szrj }
55338fd1498Szrj }
55438fd1498Szrj
55538fd1498Szrj /* Output one variable, if necessary. Return whether we output it. */
55638fd1498Szrj
55738fd1498Szrj bool
assemble_decl(void)55838fd1498Szrj varpool_node::assemble_decl (void)
55938fd1498Szrj {
56038fd1498Szrj /* Aliases are outout when their target is produced or by
56138fd1498Szrj output_weakrefs. */
56238fd1498Szrj if (alias)
56338fd1498Szrj return false;
56438fd1498Szrj
56538fd1498Szrj /* Constant pool is output from RTL land when the reference
56638fd1498Szrj survive till this level. */
56738fd1498Szrj if (DECL_IN_CONSTANT_POOL (decl) && TREE_ASM_WRITTEN (decl))
56838fd1498Szrj return false;
56938fd1498Szrj
57038fd1498Szrj /* Decls with VALUE_EXPR should not be in the varpool at all. They
57138fd1498Szrj are not real variables, but just info for debugging and codegen.
57238fd1498Szrj Unfortunately at the moment emutls is not updating varpool correctly
57338fd1498Szrj after turning real vars into value_expr vars. */
57438fd1498Szrj if (DECL_HAS_VALUE_EXPR_P (decl)
57538fd1498Szrj && !targetm.have_tls)
57638fd1498Szrj return false;
57738fd1498Szrj
57838fd1498Szrj /* Hard register vars do not need to be output. */
57938fd1498Szrj if (DECL_HARD_REGISTER (decl))
58038fd1498Szrj return false;
58138fd1498Szrj
58238fd1498Szrj gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
58338fd1498Szrj && VAR_P (decl)
58438fd1498Szrj && !DECL_HAS_VALUE_EXPR_P (decl));
58538fd1498Szrj
58638fd1498Szrj if (!in_other_partition
58738fd1498Szrj && !DECL_EXTERNAL (decl))
58838fd1498Szrj {
58938fd1498Szrj get_constructor ();
59038fd1498Szrj assemble_variable (decl, 0, 1, 0);
59138fd1498Szrj gcc_assert (TREE_ASM_WRITTEN (decl));
59238fd1498Szrj gcc_assert (definition);
59338fd1498Szrj assemble_aliases ();
59438fd1498Szrj /* After the parser has generated debugging information, augment
59538fd1498Szrj this information with any new location/etc information that may
59638fd1498Szrj have become available after the compilation proper. */
59738fd1498Szrj debug_hooks->late_global_decl (decl);
59838fd1498Szrj return true;
59938fd1498Szrj }
60038fd1498Szrj
60138fd1498Szrj return false;
60238fd1498Szrj }
60338fd1498Szrj
60438fd1498Szrj /* Add NODE to queue starting at FIRST.
60538fd1498Szrj The queue is linked via AUX pointers and terminated by pointer to 1. */
60638fd1498Szrj
60738fd1498Szrj static void
enqueue_node(varpool_node * node,varpool_node ** first)60838fd1498Szrj enqueue_node (varpool_node *node, varpool_node **first)
60938fd1498Szrj {
61038fd1498Szrj if (node->aux)
61138fd1498Szrj return;
61238fd1498Szrj gcc_checking_assert (*first);
61338fd1498Szrj node->aux = *first;
61438fd1498Szrj *first = node;
61538fd1498Szrj }
61638fd1498Szrj
61738fd1498Szrj /* Optimization of function bodies might've rendered some variables as
61838fd1498Szrj unnecessary so we want to avoid these from being compiled. Re-do
61938fd1498Szrj reachability starting from variables that are either externally visible
62038fd1498Szrj or was referred from the asm output routines. */
62138fd1498Szrj
62238fd1498Szrj void
remove_unreferenced_decls(void)62338fd1498Szrj symbol_table::remove_unreferenced_decls (void)
62438fd1498Szrj {
62538fd1498Szrj varpool_node *next, *node;
62638fd1498Szrj varpool_node *first = (varpool_node *)(void *)1;
62738fd1498Szrj int i;
62838fd1498Szrj ipa_ref *ref = NULL;
62938fd1498Szrj hash_set<varpool_node *> referenced;
63038fd1498Szrj
63138fd1498Szrj if (seen_error ())
63238fd1498Szrj return;
63338fd1498Szrj
63438fd1498Szrj if (dump_file)
63538fd1498Szrj fprintf (dump_file, "Trivially needed variables:");
63638fd1498Szrj FOR_EACH_DEFINED_VARIABLE (node)
63738fd1498Szrj {
63838fd1498Szrj if (node->analyzed
63938fd1498Szrj && (!node->can_remove_if_no_refs_p ()
64038fd1498Szrj /* We just expanded all function bodies. See if any of
64138fd1498Szrj them needed the variable. */
64238fd1498Szrj || DECL_RTL_SET_P (node->decl)))
64338fd1498Szrj {
64438fd1498Szrj enqueue_node (node, &first);
64538fd1498Szrj if (dump_file)
64638fd1498Szrj fprintf (dump_file, " %s", node->asm_name ());
64738fd1498Szrj }
64838fd1498Szrj }
64938fd1498Szrj while (first != (varpool_node *)(void *)1)
65038fd1498Szrj {
65138fd1498Szrj node = first;
65238fd1498Szrj first = (varpool_node *)first->aux;
65338fd1498Szrj
65438fd1498Szrj if (node->same_comdat_group)
65538fd1498Szrj {
65638fd1498Szrj symtab_node *next;
65738fd1498Szrj for (next = node->same_comdat_group;
65838fd1498Szrj next != node;
65938fd1498Szrj next = next->same_comdat_group)
66038fd1498Szrj {
66138fd1498Szrj varpool_node *vnext = dyn_cast <varpool_node *> (next);
66238fd1498Szrj if (vnext && vnext->analyzed && !next->comdat_local_p ())
66338fd1498Szrj enqueue_node (vnext, &first);
66438fd1498Szrj }
66538fd1498Szrj }
66638fd1498Szrj for (i = 0; node->iterate_reference (i, ref); i++)
66738fd1498Szrj {
66838fd1498Szrj varpool_node *vnode = dyn_cast <varpool_node *> (ref->referred);
66938fd1498Szrj if (vnode
67038fd1498Szrj && !vnode->in_other_partition
67138fd1498Szrj && (!DECL_EXTERNAL (ref->referred->decl)
67238fd1498Szrj || vnode->alias)
67338fd1498Szrj && vnode->analyzed)
67438fd1498Szrj enqueue_node (vnode, &first);
67538fd1498Szrj else
67638fd1498Szrj {
67738fd1498Szrj referenced.add (vnode);
67838fd1498Szrj while (vnode && vnode->alias && vnode->definition)
67938fd1498Szrj {
68038fd1498Szrj vnode = vnode->get_alias_target ();
68138fd1498Szrj referenced.add (vnode);
68238fd1498Szrj }
68338fd1498Szrj }
68438fd1498Szrj }
68538fd1498Szrj }
68638fd1498Szrj if (dump_file)
68738fd1498Szrj fprintf (dump_file, "\nRemoving variables:");
68838fd1498Szrj for (node = first_defined_variable (); node; node = next)
68938fd1498Szrj {
69038fd1498Szrj next = next_defined_variable (node);
69138fd1498Szrj if (!node->aux && !node->no_reorder)
69238fd1498Szrj {
69338fd1498Szrj if (dump_file)
69438fd1498Szrj fprintf (dump_file, " %s", node->asm_name ());
69538fd1498Szrj if (referenced.contains(node))
69638fd1498Szrj node->remove_initializer ();
69738fd1498Szrj else
69838fd1498Szrj node->remove ();
69938fd1498Szrj }
70038fd1498Szrj }
70138fd1498Szrj
70238fd1498Szrj if (dump_file)
70338fd1498Szrj fprintf (dump_file, "\n");
70438fd1498Szrj }
70538fd1498Szrj
70638fd1498Szrj /* For variables in named sections make sure get_variable_section
70738fd1498Szrj is called before we switch to those sections. Then section
70838fd1498Szrj conflicts between read-only and read-only requiring relocations
70938fd1498Szrj sections can be resolved. */
71038fd1498Szrj void
finalize_named_section_flags(void)71138fd1498Szrj varpool_node::finalize_named_section_flags (void)
71238fd1498Szrj {
71338fd1498Szrj if (!TREE_ASM_WRITTEN (decl)
71438fd1498Szrj && !alias
71538fd1498Szrj && !in_other_partition
71638fd1498Szrj && !DECL_EXTERNAL (decl)
71738fd1498Szrj && VAR_P (decl)
71838fd1498Szrj && !DECL_HAS_VALUE_EXPR_P (decl)
71938fd1498Szrj && get_section ())
72038fd1498Szrj get_variable_section (decl, false);
72138fd1498Szrj }
72238fd1498Szrj
72338fd1498Szrj /* Output all variables enqueued to be assembled. */
72438fd1498Szrj bool
output_variables(void)72538fd1498Szrj symbol_table::output_variables (void)
72638fd1498Szrj {
72738fd1498Szrj bool changed = false;
72838fd1498Szrj varpool_node *node;
72938fd1498Szrj
73038fd1498Szrj if (seen_error ())
73138fd1498Szrj return false;
73238fd1498Szrj
73338fd1498Szrj remove_unreferenced_decls ();
73438fd1498Szrj
73538fd1498Szrj timevar_push (TV_VAROUT);
73638fd1498Szrj
73738fd1498Szrj FOR_EACH_DEFINED_VARIABLE (node)
73838fd1498Szrj {
73938fd1498Szrj /* Handled in output_in_order. */
74038fd1498Szrj if (node->no_reorder)
74138fd1498Szrj continue;
74238fd1498Szrj
74338fd1498Szrj node->finalize_named_section_flags ();
74438fd1498Szrj }
74538fd1498Szrj
74638fd1498Szrj /* There is a similar loop in output_in_order. Please keep them in sync. */
74738fd1498Szrj FOR_EACH_VARIABLE (node)
74838fd1498Szrj {
74938fd1498Szrj /* Handled in output_in_order. */
75038fd1498Szrj if (node->no_reorder)
75138fd1498Szrj continue;
75238fd1498Szrj if (DECL_HARD_REGISTER (node->decl)
75338fd1498Szrj || DECL_HAS_VALUE_EXPR_P (node->decl))
75438fd1498Szrj continue;
75538fd1498Szrj if (node->definition)
75638fd1498Szrj changed |= node->assemble_decl ();
75738fd1498Szrj else
75838fd1498Szrj assemble_undefined_decl (node->decl);
75938fd1498Szrj }
76038fd1498Szrj timevar_pop (TV_VAROUT);
76138fd1498Szrj return changed;
76238fd1498Szrj }
76338fd1498Szrj
76438fd1498Szrj /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
76538fd1498Szrj Extra name aliases are output whenever DECL is output. */
76638fd1498Szrj
76738fd1498Szrj varpool_node *
create_alias(tree alias,tree decl)76838fd1498Szrj varpool_node::create_alias (tree alias, tree decl)
76938fd1498Szrj {
77038fd1498Szrj varpool_node *alias_node;
77138fd1498Szrj
77238fd1498Szrj gcc_assert (VAR_P (decl));
77338fd1498Szrj gcc_assert (VAR_P (alias));
77438fd1498Szrj alias_node = varpool_node::get_create (alias);
77538fd1498Szrj alias_node->alias = true;
77638fd1498Szrj alias_node->definition = true;
77738fd1498Szrj alias_node->alias_target = decl;
77838fd1498Szrj if (lookup_attribute ("weakref", DECL_ATTRIBUTES (alias)) != NULL)
77938fd1498Szrj alias_node->weakref = alias_node->transparent_alias = true;
78038fd1498Szrj return alias_node;
78138fd1498Szrj }
78238fd1498Szrj
78338fd1498Szrj /* Attempt to mark ALIAS as an alias to DECL. Return TRUE if successful.
78438fd1498Szrj Extra name aliases are output whenever DECL is output. */
78538fd1498Szrj
78638fd1498Szrj varpool_node *
create_extra_name_alias(tree alias,tree decl)78738fd1498Szrj varpool_node::create_extra_name_alias (tree alias, tree decl)
78838fd1498Szrj {
78938fd1498Szrj varpool_node *alias_node;
79038fd1498Szrj
79138fd1498Szrj /* If aliases aren't supported by the assembler, fail. */
79238fd1498Szrj if (!TARGET_SUPPORTS_ALIASES)
79338fd1498Szrj return NULL;
79438fd1498Szrj
79538fd1498Szrj alias_node = varpool_node::create_alias (alias, decl);
79638fd1498Szrj alias_node->cpp_implicit_alias = true;
79738fd1498Szrj
79838fd1498Szrj /* Extra name alias mechanizm creates aliases really late
79938fd1498Szrj via DECL_ASSEMBLER_NAME mechanizm.
80038fd1498Szrj This is unfortunate because they are not going through the
80138fd1498Szrj standard channels. Ensure they get output. */
80238fd1498Szrj if (symtab->cpp_implicit_aliases_done)
80338fd1498Szrj alias_node->resolve_alias (varpool_node::get_create (decl));
80438fd1498Szrj return alias_node;
80538fd1498Szrj }
80638fd1498Szrj
80738fd1498Szrj /* Worker for call_for_symbol_and_aliases. */
80838fd1498Szrj
80938fd1498Szrj bool
call_for_symbol_and_aliases_1(bool (* callback)(varpool_node *,void *),void * data,bool include_overwritable)81038fd1498Szrj varpool_node::call_for_symbol_and_aliases_1 (bool (*callback) (varpool_node *,
81138fd1498Szrj void *),
81238fd1498Szrj void *data,
81338fd1498Szrj bool include_overwritable)
81438fd1498Szrj {
81538fd1498Szrj ipa_ref *ref;
81638fd1498Szrj
81738fd1498Szrj FOR_EACH_ALIAS (this, ref)
81838fd1498Szrj {
81938fd1498Szrj varpool_node *alias = dyn_cast <varpool_node *> (ref->referring);
82038fd1498Szrj if (include_overwritable
82138fd1498Szrj || alias->get_availability () > AVAIL_INTERPOSABLE)
82238fd1498Szrj if (alias->call_for_symbol_and_aliases (callback, data,
82338fd1498Szrj include_overwritable))
82438fd1498Szrj return true;
82538fd1498Szrj }
82638fd1498Szrj return false;
82738fd1498Szrj }
828