aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog117
-rw-r--r--gcc/cgraph.c66
-rw-r--r--gcc/cgraph.h215
-rw-r--r--gcc/cgraphclones.c12
-rw-r--r--gcc/cgraphunit.c117
-rw-r--r--gcc/config/i386/i386.c7
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/decl2.c6
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/dbxout.c2
-rw-r--r--gcc/dwarf2out.c4
-rw-r--r--gcc/gimple-fold.c4
-rw-r--r--gcc/ipa-cp.c17
-rw-r--r--gcc/ipa-inline-analysis.c12
-rw-r--r--gcc/ipa-inline-transform.c6
-rw-r--r--gcc/ipa-inline.c7
-rw-r--r--gcc/ipa-prop.c11
-rw-r--r--gcc/ipa-pure-const.c10
-rw-r--r--gcc/ipa-reference.c10
-rw-r--r--gcc/ipa-split.c40
-rw-r--r--gcc/ipa-utils.c2
-rw-r--r--gcc/ipa.c181
-rw-r--r--gcc/java/ChangeLog4
-rw-r--r--gcc/java/decl.c2
-rw-r--r--gcc/lto-cgraph.c40
-rw-r--r--gcc/lto-streamer-out.c6
-rw-r--r--gcc/lto-symtab.c41
-rw-r--r--gcc/lto/ChangeLog6
-rw-r--r--gcc/lto/lto-partition.c18
-rw-r--r--gcc/lto/lto.c5
-rw-r--r--gcc/passes.c6
-rw-r--r--gcc/symtab.c54
-rw-r--r--gcc/toplev.c6
-rw-r--r--gcc/trans-mem.c12
-rw-r--r--gcc/tree-eh.c4
-rw-r--r--gcc/tree-emutls.c12
-rw-r--r--gcc/tree-inline.c14
-rw-r--r--gcc/tree-ssa-structalias.c9
-rw-r--r--gcc/varasm.c10
-rw-r--r--gcc/varpool.c60
40 files changed, 676 insertions, 486 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e93f209..54f944a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,122 @@
2013-05-29 Jan Hubicka <jh@suse.cz>
+ * cgraph.h (symtab_node_base): Add definition, alias and analyzed
+ flags; reorder rest of fields in more consistent way.
+ (varpool_node): Remove analyzed, finalized and alias.
+ (cgraph_ndoe): Likewise.
+ (symtab_alias_ultimate_target): New function.
+ (cgraph_function_node): Move offline.
+ (cgraph_reset_node): Declare.
+ (cgraph_comdat_can_be_unshared_p): Remove.
+ (varpool_remove_initializer): Declare.
+ (varpool_first_defined_variable, varpool_next_defined_variable
+ cgraph_first_defined_function, cgraph_next_defined_function): Update.
+ (cgraph_function_with_gimple_body_p): Update.
+ (varpool_all_refs_explicit_p): Update.
+ (symtab_alias_target): New function.
+ (cgraph_alias_aliased_node, varpool_alias_aliased_node): Rename to ...
+ (cgraph_alias_target, varpool_alias_target): .. this one; simplify.
+ (cgraph_function_or_thunk_node): Simplify using symtab_alias_ultimate_target.
+ (varpool_variable_node): Likewise.
+ * cgraph.c (cgraph_create_function_alias): Update.
+ (cgraph_add_thunk): Update.
+ (cgraph_remove_node): Update.
+ (dump_cgraph_node): Do not dump removed flags.
+ (cgraph_function_body_availability): Update.
+ (cgraph_propagate_frequency): Update.
+ (verify_cgraph_node): Check sanity of local flag.
+ (cgraph_function_node): Move here from cgraph.h; revamp for
+ cgraph_function_or_thunk_node.
+ * lto-symtab.c (lto_varpool_replace_node): Update.
+ (lto_symtab_resolve_can_prevail_p): Update.
+ (lto_symtab_merge_cgraph_nodes): Update.
+ * ipa-cp.c (determine_versionability, initialize_node_lattices,
+ propagate_constants_accross_call, devirtualization_time_bonus,
+ ipcp_propagate_stage): Update.
+ * tree-emutls.c (create_emultls_var, ipa_lower_emutls): Update.
+ * ipa-inline-transform.c (clone_inlined_nodes, preserve_function_body_p): Update.
+ * ipa-reference.c (propagate): Update.
+ (write_node_summary_p): Update.
+ * toplev.c (wrapup_global_declaration_2): Update.
+ * cgraphunit.c (cgraph_analyze_function): Rename to ...
+ (analyze_function) ... this one.
+ (cgraph_process_new_functions): Update.
+ (cgraph_reset_node): Export.
+ (cgraph_finalize_function): Update.
+ (cgraph_add_new_function): Update.
+ (process_function_and_variable_attributes): Update.
+ (varpool_finalize_decl): Update.
+ (symbol_finalized): Remove.
+ (symbol_finalized_and_needed): Rename to ...
+ (symbol_defined_and_needed): ... update.
+ (cgraph_analyze_functions): Update.
+ (handle_alias_pairs): Update.
+ (mark_functions_to_output): Update.
+ (assemble_thunk): Update.
+ (output_in_order): Update.
+ (output_weakrefs): Update.
+ (finalize_compilation_unit): Update.
+ * lto-cgraph.c (reachable_from_other_partition_p, lto_output_node,
+ lto_output_varpool_node, compute_ltrans_boundary, input_overwrite_node,
+ input_node, input_varpool_node): Update.
+ * dbxout.c (dbxout_expand_expr): Update.
+ * cgraphclones.c (cgraph_clone_node): Update.
+ (cgraph_copy_node_for_versioning): Update.
+ (cgraph_materialize_clone): Update.
+ (cgraph_materialize_all_clones): Update.
+ * ipa-pure-const.c (analyze_function, pure_const_write_summary,
+ propagate_pure_const, propagate_nothrow): Update.
+ * lto-streamer-out.c (lto_output, write_symbol): Update.
+ * ipa-utils.c (ipa_reverse_postorder): Update.
+ * ipa-inline.c (can_inline_edge_p): Update.
+ (update_caller_keys, ipa_inline): Update.
+ * dwarf2out.c (reference_to_unused,
+ premark_types_used_by_global_vars_helper): Update.
+ * tree-eh.c (tree_could_trap_p): Update.
+ * ipa-split.c (consider_split, execute_split_functions): Update.
+ * ipa.c (cgraph_non_local_node_p_1, cgraph_local_node_p,
+ has_addr_references_p): Update;
+ move ahead in file for better readability.
+ (process_references): Simplify.
+ (symtab_remove_unreachable_nodes): Update; cleanup way function/var
+ bodies are removed.
+ (cgraph_comdat_can_be_unshared_p): Make static.
+ (cgraph_externally_visible_p): Update.
+ (varpool_externally_visible_p): Update.
+ (function_and_variable_visibility): Update.
+ * trans-mem.c (get_cg_data, ipa_tm_mayenterirr_function,
+ ipa_tm_mark_force_output_node): Update.
+ * ipa-inline-analysis.c (dump_inline_summary, initialize_inline_failed,
+ estimate_edge_devirt_benefit, inline_generate_summary,
+ inline_write_summary): Update.
+ * gimple-fold.c (can_refer_decl_in_current_unit_p): Update.
+ * ipa-prop.c (ipa_compute_jump_functions): Update.
+ (ipa_print_node_params, ipa_prop_read_section, ipa_update_after_lto_read,
+ read_replacements_section): Update.
+ * varasm.c (mark_decl_referenced): Update.
+ (assemble_alias, dump_tm_clone_pairs): Update.
+ * tree-inline.c (copy_bb): Update.
+ (estimate_num_insns, optimize_inline_calls, tree_function_versioning):
+ Update.
+ * symtab.c (dump_symtab_base): Print new flags.
+ (verify_symtab_base): Verify new flags.
+ (symtab_alias_ultimate_target): New function.
+ * tree-ssa-structalias.c (get_constraint_for_ssa_var,
+ create_variable_info_for, associate_varinfo_to_alias, ipa_pta_execute):
+ Update.
+ * passes.c (ipa_write_summaries, ipa_write_optimization_summaries): Update.
+ * i386.c (ix86_get_function_versions_dispatcher,
+ ix86_generate_version_dispatcher_body): Update.
+ (fold_builtin_cpu): Use varpool_add_new_variable.
+ * varpool.c (varpool_remove_initializer): Break out from ...
+ (varpool_remove_node): ... this one.
+ (dump_varpool_node, varpool_node_for_asm,
+ cgraph_variable_initializer_availability, varpool_analyze_node,
+ varpool_assemble_decl, varpool_remove_unreferenced_decls,
+ varpool_finalize_named_section_flags, varpool_create_variable_alias): Update
+
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
* passes.c (init_optimization_passes): Move OMP expansion into lowering.
2013-05-29 Easwaran Raman <eraman@google.com>
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 2a2973b..735f48a 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -563,10 +563,10 @@ cgraph_create_function_alias (tree alias, tree decl)
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
alias_node = cgraph_get_create_node (alias);
- gcc_assert (!alias_node->local.finalized);
+ gcc_assert (!alias_node->symbol.definition);
alias_node->thunk.alias = decl;
- alias_node->local.finalized = true;
- alias_node->alias = 1;
+ alias_node->symbol.definition = true;
+ alias_node->symbol.alias = true;
return alias_node;
}
@@ -613,8 +613,8 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
node = cgraph_get_node (alias);
if (node)
{
- gcc_assert (node->local.finalized);
- gcc_assert (!node->alias);
+ gcc_assert (node->symbol.definition);
+ gcc_assert (!node->symbol.alias);
gcc_assert (!node->thunk.thunk_p);
cgraph_remove_node (node);
}
@@ -629,7 +629,7 @@ cgraph_add_thunk (struct cgraph_node *decl_node ATTRIBUTE_UNUSED,
node->thunk.virtual_offset_p = virtual_offset != NULL;
node->thunk.alias = real_alias;
node->thunk.thunk_p = true;
- node->local.finalized = true;
+ node->symbol.definition = true;
return node;
}
@@ -1384,7 +1384,7 @@ cgraph_remove_node (struct cgraph_node *node)
&& (cgraph_global_info_ready
&& (TREE_ASM_WRITTEN (n->symbol.decl)
|| DECL_EXTERNAL (n->symbol.decl)
- || !n->analyzed
+ || !n->symbol.analyzed
|| n->symbol.in_other_partition))))
cgraph_release_function_body (node);
@@ -1521,8 +1521,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
cgraph_availability_names [cgraph_function_body_availability (node)]);
fprintf (f, " Function flags:");
- if (node->analyzed)
- fprintf (f, " analyzed");
if (node->count)
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
(HOST_WIDEST_INT)node->count);
@@ -1534,16 +1532,12 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " process");
if (node->local.local)
fprintf (f, " local");
- if (node->local.finalized)
- fprintf (f, " finalized");
if (node->local.redefined_extern_inline)
fprintf (f, " redefined_extern_inline");
if (node->only_called_at_startup)
fprintf (f, " only_called_at_startup");
if (node->only_called_at_exit)
fprintf (f, " only_called_at_exit");
- else if (node->alias)
- fprintf (f, " alias");
if (node->tm_clone)
fprintf (f, " tm_clone");
@@ -1559,7 +1553,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
(int)node->thunk.virtual_value,
(int)node->thunk.virtual_offset_p);
}
- if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
+ if (node->symbol.alias && node->thunk.alias
+ && DECL_P (node->thunk.alias))
{
fprintf (f, " Alias of %s",
lang_hooks.decl_printable_name (node->thunk.alias, 2));
@@ -1676,7 +1671,7 @@ cgraph_function_body_availability (struct cgraph_node *node)
{
enum availability avail;
gcc_assert (cgraph_function_flags_ready);
- if (!node->analyzed)
+ if (!node->symbol.analyzed)
avail = AVAIL_NOT_AVAILABLE;
else if (node->local.local)
avail = AVAIL_LOCAL;
@@ -1983,7 +1978,7 @@ cgraph_propagate_frequency (struct cgraph_node *node)
if (!node->local.local)
return false;
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.analyzed);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
@@ -2342,6 +2337,11 @@ verify_cgraph_node (struct cgraph_node *node)
error ("inline clone in same comdat group list");
error_found = true;
}
+ if (!node->symbol.definition && node->local.local)
+ {
+ error ("local symbols must be defined");
+ error_found = true;
+ }
if (node->global.inlined_to && node->symbol.externally_visible)
{
error ("externally visible inline clone");
@@ -2455,7 +2455,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
- if (node->analyzed && node->alias)
+ if (node->symbol.analyzed && node->symbol.alias)
{
bool ref_found = false;
int i;
@@ -2486,7 +2486,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
}
- if (node->analyzed && node->thunk.thunk_p)
+ if (node->symbol.analyzed && node->thunk.thunk_p)
{
if (!node->callees)
{
@@ -2504,7 +2504,7 @@ verify_cgraph_node (struct cgraph_node *node)
error_found = true;
}
}
- else if (node->analyzed && gimple_has_body_p (node->symbol.decl)
+ else if (node->symbol.analyzed && gimple_has_body_p (node->symbol.decl)
&& !TREE_ASM_WRITTEN (node->symbol.decl)
&& (!DECL_EXTERNAL (node->symbol.decl) || node->global.inlined_to)
&& !flag_wpa)
@@ -2653,4 +2653,32 @@ cgraph_get_create_real_symbol_node (tree decl)
node->symbol.order);
return node;
}
+
+
+/* Given NODE, walk the alias chain to return the function NODE is alias of.
+ Walk through thunk, too.
+ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+
+struct cgraph_node *
+cgraph_function_node (struct cgraph_node *node, enum availability *availability)
+{
+ do
+ {
+ node = cgraph_function_or_thunk_node (node, availability);
+ if (node->thunk.thunk_p)
+ {
+ node = node->callees->callee;
+ if (availability)
+ {
+ enum availability a;
+ a = cgraph_function_body_availability (node);
+ if (a < *availability)
+ *availability = a;
+ }
+ node = cgraph_function_or_thunk_node (node, availability);
+ }
+ } while (node && node->thunk.thunk_p);
+ return node;
+}
+
#include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index fcb9261..0dcc1a6 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-ref.h"
/* Symbol table consists of functions and variables.
- TODO: add labels, constant pool and aliases. */
+ TODO: add labels and CONST_DECLs. */
enum symtab_type
{
SYMTAB_SYMBOL,
@@ -48,15 +48,21 @@ struct GTY(()) symtab_node_base
/* The symbols resolution. */
ENUM_BITFIELD (ld_plugin_symbol_resolution) resolution : 8;
- /* Set when function has address taken.
- In current implementation it imply needed flag. */
- unsigned address_taken : 1;
- /* Set when variable is used from other LTRANS partition. */
- unsigned used_from_other_partition : 1;
- /* Set when function is available in the other LTRANS partition.
- During WPA output it is used to mark nodes that are present in
- multiple partitions. */
- unsigned in_other_partition : 1;
+ /*** Flags representing the symbol type. ***/
+
+ /* True when symbol corresponds to a definition in current unit.
+ set via cgraph_finalize_function or varpool_finalize_decl */
+ unsigned definition : 1;
+ /* True when symbol is an alias.
+ Set by assemble_alias. */
+ unsigned alias : 1;
+ /* Set once the definition was analyzed. The list of references and
+ other properties are built during analysis. */
+ unsigned analyzed : 1;
+
+
+ /*** Visibility and linkage flags. ***/
+
/* Set when function is visible by other units. */
unsigned externally_visible : 1;
/* Needed variables might become dead by optimization. This flag
@@ -65,30 +71,57 @@ struct GTY(()) symtab_node_base
/* True when the name is known to be unique and thus it does not need mangling. */
unsigned unique_name : 1;
- /* Ordering of all symtab entries. */
- int order;
- tree decl;
+ /*** WHOPR Partitioning flags.
+ These flags are used at ltrans stage when only part of the callgraph is
+ available. ***/
- /* Vectors of referring and referenced entities. */
- struct ipa_ref_list ref_list;
+ /* Set when variable is used from other LTRANS partition. */
+ unsigned used_from_other_partition : 1;
+ /* Set when function is available in the other LTRANS partition.
+ During WPA output it is used to mark nodes that are present in
+ multiple partitions. */
+ unsigned in_other_partition : 1;
- /* Circular list of nodes in the same comdat group if non-NULL. */
- symtab_node same_comdat_group;
- /* File stream where this node is being written to. */
- struct lto_file_decl_data * lto_file_data;
+
+ /*** other flags. ***/
+
+ /* Set when symbol has address taken. */
+ unsigned address_taken : 1;
+
+
+ /* Ordering of all symtab entries. */
+ int order;
+
+ /* Declaration representing the symbol. */
+ tree decl;
/* Linked list of symbol table entries starting with symtab_nodes. */
symtab_node next;
symtab_node previous;
+
/* Linked list of symbols with the same asm name. There may be multiple
- entries for single symbol name in the case of LTO resolutions,
- existence of inline clones, or duplicated declaration. The last case
- is a long standing bug frontends and builtin handling. */
+ entries for single symbol name during LTO, because symbols are renamed
+ only after partitioning.
+
+ Because inline clones are kept in the assembler name has, they also produce
+ duplicate entries.
+
+ There are also several long standing bugs where frontends and builtin
+ code produce duplicated decls. */
symtab_node next_sharing_asm_name;
symtab_node previous_sharing_asm_name;
+ /* Circular list of nodes in the same comdat group if non-NULL. */
+ symtab_node same_comdat_group;
+
+ /* Vectors of referring and referenced entities. */
+ struct ipa_ref_list ref_list;
+
+ /* File stream where this node is being written to. */
+ struct lto_file_decl_data * lto_file_data;
+
PTR GTY ((skip)) aux;
};
@@ -142,9 +175,6 @@ struct GTY(()) cgraph_local_info {
and its address is never taken. */
unsigned local : 1;
- /* Set once it has been finalized so we consider it to be output. */
- unsigned finalized : 1;
-
/* False when there is something makes versioning impossible. */
unsigned versionable : 1;
@@ -260,11 +290,7 @@ struct GTY(()) cgraph_node {
unsigned lowered : 1;
/* Set once the function has been instantiated and its callee
lists created. */
- unsigned analyzed : 1;
- /* Set when function is scheduled to be processed by local passes. */
unsigned process : 1;
- /* Set for aliases once they got through assemble_alias. */
- unsigned alias : 1;
/* Set for aliases created as C++ same body aliases. */
unsigned same_body_alias : 1;
/* How commonly executed the node is. Initialized during branch
@@ -455,16 +481,8 @@ struct GTY(()) varpool_node {
/* For aliases points to declaration DECL is alias of. */
tree alias_of;
- /* Set once the variable has been instantiated and its callee
- lists created. */
- unsigned analyzed : 1;
- /* Set once it has been finalized so we consider it to be output. */
- unsigned finalized : 1;
/* Set when variable is scheduled to be assembled. */
unsigned output : 1;
- /* Set for aliases once they got through assemble_alias. Also set for
- extra name aliases in varpool_extra_name_alias. */
- unsigned alias : 1;
unsigned extra_name_alias : 1;
};
@@ -558,6 +576,7 @@ void verify_symtab_node (symtab_node);
bool verify_symtab_base (symtab_node);
bool symtab_used_from_object_file_p (symtab_node);
void symtab_make_decl_local (tree);
+symtab_node symtab_alias_ultimate_target (symtab_node, enum availability *);
/* In cgraph.c */
void dump_cgraph (FILE *);
@@ -653,6 +672,7 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node);
+struct cgraph_node * cgraph_function_node (struct cgraph_node *, enum availability *);
/* In cgraphunit.c */
struct asm_node *add_asm_node (tree);
@@ -663,10 +683,11 @@ void compile (void);
void init_cgraph (void);
bool cgraph_process_new_functions (void);
void cgraph_process_same_body_aliases (void);
-void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias);
+void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
/* Initialize datastructures so DECL is a function in lowered gimple form.
IN_SSA is true if the gimple is in SSA. */
-basic_block init_lowered_empty_function (tree decl, bool in_ssa);
+basic_block init_lowered_empty_function (tree, bool);
+void cgraph_reset_node (struct cgraph_node *);
/* In cgraphclones.c */
@@ -728,7 +749,6 @@ void dump_varpool_node_set (FILE *, varpool_node_set);
void debug_varpool_node_set (varpool_node_set);
void free_varpool_node_set (varpool_node_set);
void ipa_discover_readonly_nonaddressable_vars (void);
-bool cgraph_comdat_can_be_unshared_p (struct cgraph_node *);
bool varpool_externally_visible_p (struct varpool_node *);
/* In predict.c */
@@ -765,6 +785,7 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
void varpool_add_new_variable (tree);
void symtab_initialize_asm_name_hash (void);
void symtab_prevail_in_asm_name_hash (symtab_node node);
+void varpool_remove_initializer (struct varpool_node *);
/* Return callgraph node for given symbol and check it is a function. */
@@ -900,7 +921,7 @@ varpool_first_defined_variable (void)
for (node = symtab_nodes; node; node = node->symbol.next)
{
varpool_node *vnode = dyn_cast <varpool_node> (node);
- if (vnode && vnode->analyzed)
+ if (vnode && vnode->symbol.definition)
return vnode;
}
return NULL;
@@ -914,7 +935,7 @@ varpool_next_defined_variable (struct varpool_node *node)
for (; node1; node1 = node1->symbol.next)
{
varpool_node *vnode1 = dyn_cast <varpool_node> (node1);
- if (vnode1 && vnode1->analyzed)
+ if (vnode1 && vnode1->symbol.definition)
return vnode1;
}
return NULL;
@@ -932,7 +953,7 @@ cgraph_first_defined_function (void)
for (node = symtab_nodes; node; node = node->symbol.next)
{
cgraph_node *cn = dyn_cast <cgraph_node> (node);
- if (cn && cn->analyzed)
+ if (cn && cn->symbol.definition)
return cn;
}
return NULL;
@@ -946,7 +967,7 @@ cgraph_next_defined_function (struct cgraph_node *node)
for (; node1; node1 = node1->symbol.next)
{
cgraph_node *cn1 = dyn_cast <cgraph_node> (node1);
- if (cn1 && cn1->analyzed)
+ if (cn1 && cn1->symbol.definition)
return cn1;
}
return NULL;
@@ -992,7 +1013,7 @@ cgraph_next_function (struct cgraph_node *node)
static inline bool
cgraph_function_with_gimple_body_p (struct cgraph_node *node)
{
- return node->analyzed && !node->thunk.thunk_p && !node->alias;
+ return node->symbol.definition && !node->thunk.thunk_p && !node->symbol.alias;
}
/* Return first function with body defined. */
@@ -1197,7 +1218,7 @@ varpool_can_remove_if_no_refs (struct varpool_node *node)
static inline bool
varpool_all_refs_explicit_p (struct varpool_node *vnode)
{
- return (vnode->analyzed
+ return (vnode->symbol.definition
&& !vnode->symbol.externally_visible
&& !vnode->symbol.used_from_other_partition
&& !vnode->symbol.force_output);
@@ -1211,60 +1232,25 @@ htab_t constant_pool_htab (void);
/* Return node that alias N is aliasing. */
-static inline struct cgraph_node *
-cgraph_alias_aliased_node (struct cgraph_node *n)
+static inline symtab_node
+symtab_alias_target (symtab_node n)
{
struct ipa_ref *ref;
-
ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
gcc_checking_assert (ref->use == IPA_REF_ALIAS);
- if (is_a <cgraph_node> (ref->referred))
- return ipa_ref_node (ref);
- return NULL;
+ return ref->referred;
}
-/* Return node that alias N is aliasing. */
-
-static inline struct varpool_node *
-varpool_alias_aliased_node (struct varpool_node *n)
+static inline struct cgraph_node *
+cgraph_alias_target (struct cgraph_node *n)
{
- struct ipa_ref *ref;
-
- ipa_ref_list_reference_iterate (&n->symbol.ref_list, 0, ref);
- gcc_checking_assert (ref->use == IPA_REF_ALIAS);
- if (is_a <varpool_node> (ref->referred))
- return ipa_ref_varpool_node (ref);
- return NULL;
+ return dyn_cast <cgraph_node> (symtab_alias_target ((symtab_node) n));
}
-/* Given NODE, walk the alias chain to return the function NODE is alias of.
- Walk through thunk, too.
- When AVAILABILITY is non-NULL, get minimal availability in the chain. */
-
-static inline struct cgraph_node *
-cgraph_function_node (struct cgraph_node *node, enum availability *availability)
+static inline struct varpool_node *
+varpool_alias_target (struct varpool_node *n)
{
- if (availability)
- *availability = cgraph_function_body_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = cgraph_alias_aliased_node (node);
- else if (node->thunk.thunk_p)
- node = node->callees->callee;
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_function_body_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
- *availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return dyn_cast <varpool_node> (symtab_alias_target ((symtab_node) n));
}
/* Given NODE, walk the alias chain to return the function NODE is alias of.
@@ -1274,27 +1260,13 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability)
static inline struct cgraph_node *
cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability)
{
- if (availability)
- *availability = cgraph_function_body_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = cgraph_alias_aliased_node (node);
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_function_body_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
+ struct cgraph_node *n;
+
+ n = dyn_cast <cgraph_node> (symtab_alias_ultimate_target ((symtab_node)node, availability));
+ if (!n)
*availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return n;
}
-
/* Given NODE, walk the alias chain to return the function NODE is alias of.
Do not walk through thunks.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */
@@ -1302,25 +1274,12 @@ cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *avai
static inline struct varpool_node *
varpool_variable_node (struct varpool_node *node, enum availability *availability)
{
- if (availability)
- *availability = cgraph_variable_initializer_availability (node);
- while (node)
- {
- if (node->alias && node->analyzed)
- node = varpool_alias_aliased_node (node);
- else
- return node;
- if (node && availability)
- {
- enum availability a;
- a = cgraph_variable_initializer_availability (node);
- if (a < *availability)
- *availability = a;
- }
- }
- if (availability)
+ struct varpool_node *n;
+
+ n = dyn_cast <varpool_node> (symtab_alias_ultimate_target ((symtab_node)node, availability));
+ if (!n)
*availability = AVAIL_NOT_AVAILABLE;
- return NULL;
+ return n;
}
/* Return true when the edge E represents a direct recursion. */
@@ -1355,7 +1314,7 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
}
/* Return true when the symbol is real symbol, i.e. it is not inline clone
- or extern function kept around just for inlining. */
+ or abstract function kept for debug info purposes only. */
static inline bool
symtab_real_symbol_p (symtab_node node)
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index a002c68..d82eb37 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -189,7 +189,8 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
new_node->next_nested = new_node->origin->nested;
new_node->origin->nested = new_node;
}
- new_node->analyzed = n->analyzed;
+ new_node->symbol.analyzed = n->symbol.analyzed;
+ new_node->symbol.definition = n->symbol.definition;
new_node->local = n->local;
new_node->symbol.externally_visible = false;
new_node->local.local = true;
@@ -638,10 +639,11 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
new_version = cgraph_create_node (new_decl);
- new_version->analyzed = old_version->analyzed;
+ new_version->symbol.analyzed = old_version->symbol.analyzed;
+ new_version->symbol.definition = old_version->symbol.definition;
new_version->local = old_version->local;
new_version->symbol.externally_visible = false;
- new_version->local.local = old_version->analyzed;
+ new_version->local.local = new_version->symbol.definition;
new_version->global = old_version->global;
new_version->rtl = old_version->rtl;
new_version->count = old_version->count;
@@ -791,7 +793,7 @@ cgraph_materialize_clone (struct cgraph_node *node)
node->clone_of->clones = node->next_sibling_clone;
node->next_sibling_clone = NULL;
node->prev_sibling_clone = NULL;
- if (!node->clone_of->analyzed && !node->clone_of->clones)
+ if (!node->clone_of->symbol.analyzed && !node->clone_of->clones)
{
cgraph_release_function_body (node->clone_of);
cgraph_node_remove_callees (node->clone_of);
@@ -874,7 +876,7 @@ cgraph_materialize_all_clones (void)
}
}
FOR_EACH_FUNCTION (node)
- if (!node->analyzed && node->callees)
+ if (!node->symbol.analyzed && node->callees)
cgraph_node_remove_callees (node);
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 6ebf8d4..ca314a6 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -202,7 +202,7 @@ cgraph_node_set cgraph_new_nodes;
static void expand_all_functions (void);
static void mark_functions_to_output (void);
static void expand_function (struct cgraph_node *);
-static void cgraph_analyze_function (struct cgraph_node *);
+static void analyze_function (struct cgraph_node *);
static void handle_alias_pairs (void);
FILE *cgraph_dump_file;
@@ -309,8 +309,8 @@ cgraph_process_new_functions (void)
cgraph but not on this function. */
gimple_register_cfg_hooks ();
- if (!node->analyzed)
- cgraph_analyze_function (node);
+ if (!node->symbol.analyzed)
+ analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
@@ -354,7 +354,7 @@ cgraph_process_new_functions (void)
??? It may make more sense to use one body for inlining and other
body for expanding the function but this is difficult to do. */
-static void
+void
cgraph_reset_node (struct cgraph_node *node)
{
/* If node->process is set, then we have already begun whole-unit analysis.
@@ -368,10 +368,11 @@ cgraph_reset_node (struct cgraph_node *node)
memset (&node->local, 0, sizeof (node->local));
memset (&node->global, 0, sizeof (node->global));
memset (&node->rtl, 0, sizeof (node->rtl));
- node->analyzed = false;
- node->local.finalized = false;
+ node->symbol.analyzed = false;
+ node->symbol.definition = false;
cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
}
/* Return true when there are references to NODE. */
@@ -401,14 +402,14 @@ cgraph_finalize_function (tree decl, bool nested)
{
struct cgraph_node *node = cgraph_get_create_node (decl);
- if (node->local.finalized)
+ if (node->symbol.definition)
{
cgraph_reset_node (node);
node->local.redefined_extern_inline = true;
}
notice_global_symbol (decl);
- node->local.finalized = true;
+ node->symbol.definition = true;
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
/* With -fkeep-inline-functions we are keeping all inline functions except
@@ -488,7 +489,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
analyzing and compilation. */
node = cgraph_get_create_node (fndecl);
node->local.local = false;
- node->local.finalized = true;
+ node->symbol.definition = true;
node->symbol.force_output = true;
if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
{
@@ -515,7 +516,8 @@ cgraph_add_new_function (tree fndecl, bool lowered)
node = cgraph_create_node (fndecl);
if (lowered)
node->lowered = true;
- cgraph_analyze_function (node);
+ node->symbol.definition = true;
+ analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
@@ -589,23 +591,23 @@ fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alia
/* Analyze the function scheduled to be output. */
static void
-cgraph_analyze_function (struct cgraph_node *node)
+analyze_function (struct cgraph_node *node)
{
tree decl = node->symbol.decl;
location_t saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (decl);
- if (node->alias && node->thunk.alias)
+ if (node->symbol.alias && node->thunk.alias)
{
struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias);
struct cgraph_node *n;
- for (n = tgt; n && n->alias;
- n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
+ for (n = tgt; n && n->symbol.alias;
+ n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
if (n == node)
{
error ("function %q+D part of alias cycle", node->symbol.decl);
- node->alias = false;
+ node->symbol.alias = false;
input_location = saved_loc;
return;
}
@@ -622,7 +624,7 @@ cgraph_analyze_function (struct cgraph_node *node)
}
if (node->symbol.address_taken)
- cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
+ cgraph_mark_address_taken_node (cgraph_alias_target (node));
}
else if (node->thunk.thunk_p)
{
@@ -677,7 +679,7 @@ cgraph_analyze_function (struct cgraph_node *node)
pop_cfun ();
}
- node->analyzed = true;
+ node->symbol.analyzed = true;
input_location = saved_loc;
}
@@ -766,7 +768,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
" attribute have effect only on public objects");
}
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
- && (node->local.finalized && !node->alias))
+ && (node->symbol.definition && !node->symbol.alias))
{
warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
"%<weakref%> attribute ignored"
@@ -803,7 +805,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
" attribute have effect only on public objects");
}
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
- && vnode->finalized
+ && vnode->symbol.definition
&& DECL_INITIAL (decl))
{
warning_at (DECL_SOURCE_LOCATION (vnode->symbol.decl), OPT_Wattributes,
@@ -828,10 +830,10 @@ varpool_finalize_decl (tree decl)
gcc_assert (TREE_STATIC (decl) || DECL_EXTERNAL (decl));
- if (node->finalized)
+ if (node->symbol.definition)
return;
notice_global_symbol (decl);
- node->finalized = true;
+ node->symbol.definition = true;
if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
/* Traditionally we do not eliminate static variables when not
optimizing and when not doing toplevel reoder. */
@@ -855,36 +857,23 @@ varpool_finalize_decl (tree decl)
/* Determine if a symbol NODE is finalized and needed. */
inline static bool
-symbol_finalized_and_needed (symtab_node node)
+symbol_defined_and_needed (symtab_node node)
{
if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
- return cnode->local.finalized
+ return cnode->symbol.definition
&& cgraph_decide_is_function_needed (cnode, cnode->symbol.decl);
if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode->finalized
+ return vnode->symbol.definition
&& !DECL_EXTERNAL (vnode->symbol.decl)
&& decide_is_variable_needed (vnode, vnode->symbol.decl);
return false;
}
-/* Determine if a symbol NODE is finalized. */
-
-inline static bool
-symbol_finalized (symtab_node node)
-{
- if (cgraph_node *cnode= dyn_cast <cgraph_node> (node))
- return cnode->local.finalized;
- if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode->finalized;
- return false;
-}
-
-
/* Discover all functions and variables that are trivially needed, analyze
them as well as all functions and variables referred by them */
static void
-cgraph_analyze_functions (void)
+analyze_functions (void)
{
/* Keep track of already processed nodes when called multiple times for
intermodule optimization. */
@@ -914,7 +903,7 @@ cgraph_analyze_functions (void)
node != (symtab_node)first_analyzed
&& node != (symtab_node)first_analyzed_var; node = node->symbol.next)
{
- if (symbol_finalized_and_needed (node))
+ if (symbol_defined_and_needed (node))
{
enqueue_node (node);
if (!changed && cgraph_dump_file)
@@ -942,7 +931,7 @@ cgraph_analyze_functions (void)
node = first;
first = (symtab_node)first->symbol.aux;
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
- if (cnode && cnode->local.finalized)
+ if (cnode && cnode->symbol.definition)
{
struct cgraph_edge *edge;
tree decl = cnode->symbol.decl;
@@ -951,7 +940,7 @@ cgraph_analyze_functions (void)
and later using weak alias attribute to kill its body.
See gcc.c-torture/compile/20011119-1.c */
if (!DECL_STRUCT_FUNCTION (decl)
- && (!cnode->alias || !cnode->thunk.alias)
+ && (!cnode->symbol.alias || !cnode->thunk.alias)
&& !cnode->thunk.thunk_p
&& !cnode->dispatcher_function)
{
@@ -960,11 +949,11 @@ cgraph_analyze_functions (void)
continue;
}
- if (!cnode->analyzed)
- cgraph_analyze_function (cnode);
+ if (!cnode->symbol.analyzed)
+ analyze_function (cnode);
for (edge = cnode->callees; edge; edge = edge->next_callee)
- if (edge->callee->local.finalized)
+ if (edge->callee->symbol.definition)
enqueue_node ((symtab_node)edge->callee);
/* If decl is a clone of an abstract function,
@@ -981,7 +970,7 @@ cgraph_analyze_functions (void)
else
{
varpool_node *vnode = dyn_cast <varpool_node> (node);
- if (vnode && vnode->finalized)
+ if (vnode && vnode->symbol.definition)
varpool_analyze_node (vnode);
}
@@ -994,7 +983,7 @@ cgraph_analyze_functions (void)
enqueue_node (next);
}
for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
- if (symbol_finalized (ref->referred))
+ if (ref->referred->symbol.definition)
enqueue_node (ref->referred);
cgraph_process_new_functions ();
}
@@ -1026,15 +1015,15 @@ cgraph_analyze_functions (void)
{
tree decl = node->symbol.decl;
- if (cnode->local.finalized && !gimple_has_body_p (decl)
- && (!cnode->alias || !cnode->thunk.alias)
+ if (cnode->symbol.definition && !gimple_has_body_p (decl)
+ && (!cnode->symbol.alias || !cnode->thunk.alias)
&& !cnode->thunk.thunk_p)
cgraph_reset_node (cnode);
- gcc_assert (!cnode->local.finalized || cnode->thunk.thunk_p
- || cnode->alias
+ gcc_assert (!cnode->symbol.definition || cnode->thunk.thunk_p
+ || cnode->symbol.alias
|| gimple_has_body_p (decl));
- gcc_assert (cnode->analyzed == cnode->local.finalized);
+ gcc_assert (cnode->symbol.analyzed == cnode->symbol.definition);
}
node->symbol.aux = NULL;
}
@@ -1071,13 +1060,13 @@ handle_alias_pairs (void)
if (TREE_CODE (p->decl) == FUNCTION_DECL)
{
struct cgraph_node *anode = cgraph_get_create_node (p->decl);
- anode->alias = true;
+ anode->symbol.alias = true;
anode->thunk.alias = p->target;
}
else
{
struct varpool_node *anode = varpool_get_node (p->decl);
- anode->alias = true;
+ anode->symbol.alias = true;
anode->alias_of = p->target;
}
DECL_EXTERNAL (p->decl) = 1;
@@ -1117,7 +1106,7 @@ handle_alias_pairs (void)
&& target_node && is_a <cgraph_node> (target_node))
{
struct cgraph_node *src_node = cgraph_get_node (p->decl);
- if (src_node && src_node->local.finalized)
+ if (src_node && src_node->symbol.definition)
cgraph_reset_node (src_node);
cgraph_create_function_alias (p->decl, target_node->symbol.decl);
alias_pairs->unordered_remove (i);
@@ -1165,9 +1154,9 @@ mark_functions_to_output (void)
/* We need to output all local functions that are used and not
always inlined, as well as those that are reachable from
outside the current compilation unit. */
- if (node->analyzed
+ if (node->symbol.analyzed
&& !node->thunk.thunk_p
- && !node->alias
+ && !node->symbol.alias
&& !node->global.inlined_to
&& !TREE_ASM_WRITTEN (decl)
&& !DECL_EXTERNAL (decl))
@@ -1179,7 +1168,7 @@ mark_functions_to_output (void)
for (next = cgraph (node->symbol.same_comdat_group);
next != node;
next = cgraph (next->symbol.same_comdat_group))
- if (!next->thunk.thunk_p && !next->alias)
+ if (!next->thunk.thunk_p && !next->symbol.alias)
next->process = 1;
}
}
@@ -1199,7 +1188,7 @@ mark_functions_to_output (void)
are inside partition, we can end up not removing the body since we no longer
have analyzed node pointing to it. */
&& !node->symbol.in_other_partition
- && !node->alias
+ && !node->symbol.alias
&& !node->clones
&& !DECL_EXTERNAL (decl))
{
@@ -1435,7 +1424,7 @@ assemble_thunk (struct cgraph_node *node)
set_cfun (NULL);
TREE_ASM_WRITTEN (thunk_fndecl) = 1;
node->thunk.thunk_p = false;
- node->analyzed = false;
+ node->symbol.analyzed = false;
}
else
{
@@ -1800,7 +1789,7 @@ output_in_order (void)
FOR_EACH_DEFINED_FUNCTION (pf)
{
- if (pf->process && !pf->thunk.thunk_p && !pf->alias)
+ if (pf->process && !pf->thunk.thunk_p && !pf->symbol.alias)
{
i = pf->symbol.order;
gcc_assert (nodes[i].kind == ORDER_UNDEFINED);
@@ -1943,14 +1932,14 @@ output_weakrefs (void)
struct cgraph_node *node;
struct varpool_node *vnode;
FOR_EACH_FUNCTION (node)
- if (node->alias && DECL_EXTERNAL (node->symbol.decl)
+ if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl)
&& !TREE_ASM_WRITTEN (node->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
do_assemble_alias (node->symbol.decl,
node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
: get_alias_symbol (node->symbol.decl));
FOR_EACH_VARIABLE (vnode)
- if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
+ if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl)
&& !TREE_ASM_WRITTEN (vnode->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
do_assemble_alias (vnode->symbol.decl,
@@ -2115,13 +2104,13 @@ finalize_compilation_unit (void)
/* Gimplify and lower all functions, compute reachability and
remove unreachable nodes. */
- cgraph_analyze_functions ();
+ analyze_functions ();
/* Mark alias targets necessary and emit diagnostics. */
handle_alias_pairs ();
/* Gimplify and lower thunks. */
- cgraph_analyze_functions ();
+ analyze_functions ();
/* Finally drive the pass manager. */
compile ();
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a025909..9d05a7b 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -29468,7 +29468,7 @@ ix86_get_function_versions_dispatcher (void *decl)
dispatcher_version_info
= insert_new_cgraph_node_version (dispatcher_node);
dispatcher_version_info->next = default_version_info;
- dispatcher_node->local.finalized = 1;
+ dispatcher_node->symbol.definition = 1;
/* Set the dispatcher for all the versions. */
it_v = default_version_info;
@@ -29623,7 +29623,7 @@ ix86_generate_version_dispatcher_body (void *node_p)
default_ver_decl = node_version_info->next->this_node->symbol.decl;
/* node is going to be an alias, so remove the finalized bit. */
- node->local.finalized = false;
+ node->symbol.definition = false;
resolver_decl = make_resolver_func (default_ver_decl,
node->symbol.decl, &empty_bb);
@@ -29817,6 +29817,9 @@ fold_builtin_cpu (tree fndecl, tree *args)
tree __cpu_model_var = make_var_decl (__processor_model_type,
"__cpu_model");
+
+ varpool_add_new_variable (__cpu_model_var);
+
gcc_assert ((args != NULL) && (*args != NULL));
param_string_cst = *args;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ed1d479..ed26fa0 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,8 @@
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (cp_fix_function_decl_p): Update for new symtab flags.
+ * decl2.c )var_finalized_p, cp_write_global_declarations): Likewise.
+
2013-05-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/25666
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 8119210..409a743 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1803,7 +1803,7 @@ import_export_class (tree ctype)
static bool
var_finalized_p (tree var)
{
- return varpool_node_for_decl (var)->finalized;
+ return varpool_node_for_decl (var)->symbol.definition;
}
/* DECL is a VAR_DECL or FUNCTION_DECL which, for whatever reason,
@@ -4202,7 +4202,7 @@ cp_write_global_declarations (void)
node = cgraph_get_node (decl);
if (node->same_body_alias)
- node = cgraph_alias_aliased_node (node);
+ node = cgraph_alias_target (node);
cgraph_for_node_and_aliases (node, clear_decl_external,
NULL, true);
@@ -4224,7 +4224,7 @@ cp_write_global_declarations (void)
if (!DECL_EXTERNAL (decl)
&& decl_needed_p (decl)
&& !TREE_ASM_WRITTEN (decl)
- && !cgraph_get_node (decl)->local.finalized)
+ && !cgraph_get_node (decl)->symbol.definition)
{
/* We will output the function; no longer consider it in this
loop. */
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 0fbb33d..8524f6c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -3980,7 +3980,7 @@ cp_fix_function_decl_p (tree decl)
/* Don't fix same_body aliases. Although they don't have their own
CFG, they share it with what they alias to. */
- if (!node || !node->alias
+ if (!node || !node->symbol.alias
|| !vec_safe_length (node->symbol.ref_list.references))
return true;
}
diff --git a/gcc/dbxout.c b/gcc/dbxout.c
index 4d9fc4e..1cc5d52 100644
--- a/gcc/dbxout.c
+++ b/gcc/dbxout.c
@@ -2480,7 +2480,7 @@ dbxout_expand_expr (tree expr)
return NULL, otherwise stabs might reference an undefined
symbol. */
struct varpool_node *node = varpool_get_node (expr);
- if (!node || !node->analyzed)
+ if (!node || !node->symbol.definition)
return NULL;
}
/* FALLTHRU */
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index e4a3c07..b615b18 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -14919,7 +14919,7 @@ reference_to_unused (tree * tp, int * walk_subtrees,
else if (TREE_CODE (*tp) == VAR_DECL)
{
struct varpool_node *node = varpool_get_node (*tp);
- if (!node || !node->analyzed)
+ if (!node || !node->symbol.definition)
return *tp;
}
else if (TREE_CODE (*tp) == FUNCTION_DECL
@@ -17597,7 +17597,7 @@ premark_types_used_by_global_vars_helper (void **slot,
/* Ask cgraph if the global variable really is to be emitted.
If yes, then we'll keep the DIE of ENTRY->TYPE. */
struct varpool_node *node = varpool_get_node (entry->var_decl);
- if (node && node->analyzed)
+ if (node && node->symbol.definition)
{
die->die_perennial_p = 1;
/* Keep the parent DIEs as well. */
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 1de281a9..181d28d 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -114,7 +114,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
The second is important when devirtualization happens during final
compilation stage when making a new reference no longer makes callee
to be compiled. */
- if (!node || !node->analyzed || node->global.inlined_to)
+ if (!node || !node->symbol.definition || node->global.inlined_to)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
@@ -123,7 +123,7 @@ can_refer_decl_in_current_unit_p (tree decl, tree from_decl)
else if (TREE_CODE (decl) == VAR_DECL)
{
vnode = varpool_get_node (decl);
- if (!vnode || !vnode->analyzed)
+ if (!vnode || !vnode->symbol.definition)
{
gcc_checking_assert (!TREE_ASM_WRITTEN (decl));
return false;
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 4bb1754..af4e948 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -440,14 +440,14 @@ determine_versionability (struct cgraph_node *node)
/* There are a number of generic reasons functions cannot be versioned. We
also cannot remove parameters if there are type attributes such as fnspec
present. */
- if (node->alias || node->thunk.thunk_p)
+ if (node->symbol.alias || node->thunk.thunk_p)
reason = "alias or thunk";
else if (!node->local.versionable)
reason = "not a tree_versionable_function";
else if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
reason = "insufficient body availability";
- if (reason && dump_file && !node->alias && !node->thunk.thunk_p)
+ if (reason && dump_file && !node->symbol.alias && !node->thunk.thunk_p)
fprintf (dump_file, "Function %s/%i is not versionable, reason: %s.\n",
cgraph_node_name (node), node->symbol.order, reason);
@@ -727,7 +727,7 @@ initialize_node_lattices (struct cgraph_node *node)
set_all_contains_variable (plats);
}
if (dump_file && (dump_flags & TDF_DETAILS)
- && !node->alias && !node->thunk.thunk_p)
+ && !node->symbol.alias && !node->thunk.thunk_p)
fprintf (dump_file, "Marking all lattices of %s/%i as %s\n",
cgraph_node_name (node), node->symbol.order,
disable ? "BOTTOM" : "VARIABLE");
@@ -1418,7 +1418,7 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
int i, args_count, parms_count;
callee = cgraph_function_node (cs->callee, &availability);
- if (!callee->analyzed)
+ if (!callee->symbol.definition)
return false;
gcc_checking_assert (cgraph_function_with_gimple_body_p (callee));
callee_info = IPA_NODE_REF (callee);
@@ -1431,8 +1431,8 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
parameter. However, we might need to uncover a thunk from below a series
of aliases first. */
alias_or_thunk = cs->callee;
- while (alias_or_thunk->alias)
- alias_or_thunk = cgraph_alias_aliased_node (alias_or_thunk);
+ while (alias_or_thunk->symbol.alias)
+ alias_or_thunk = cgraph_alias_target (alias_or_thunk);
if (alias_or_thunk->thunk.thunk_p)
{
ret |= set_all_contains_variable (ipa_get_parm_lattices (callee_info,
@@ -1601,7 +1601,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
/* Only bare minimum benefit for clearly un-inlineable targets. */
res += 1;
callee = cgraph_get_node (target);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
continue;
isummary = inline_summary (callee);
if (!isummary->inlinable)
@@ -2231,9 +2231,10 @@ ipcp_propagate_stage (struct topo_info *topo)
ipa_get_param_count (info));
initialize_node_lattices (node);
}
+ if (node->symbol.definition && !node->symbol.alias)
+ overall_size += inline_summary (node)->self_size;
if (node->count > max_count)
max_count = node->count;
- overall_size += inline_summary (node)->self_size;
}
max_new_size = overall_size;
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index c6f127e..a25f517 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -1351,7 +1351,7 @@ dump_inline_edge_summary (FILE *f, int indent, struct cgraph_node *node,
void
dump_inline_summary (FILE *f, struct cgraph_node *node)
{
- if (node->analyzed)
+ if (node->symbol.definition)
{
struct inline_summary *s = inline_summary (node);
size_time_entry *e;
@@ -1427,7 +1427,7 @@ initialize_inline_failed (struct cgraph_edge *e)
if (e->indirect_unknown_callee)
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
- else if (!callee->analyzed)
+ else if (!callee->symbol.definition)
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
else if (callee->local.redefined_extern_inline)
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
@@ -2765,7 +2765,7 @@ estimate_edge_devirt_benefit (struct cgraph_edge *ie,
gcc_checking_assert (*size >= 0);
callee = cgraph_get_node (target);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
return false;
isummary = inline_summary (callee);
return isummary->inlinable;
@@ -3683,7 +3683,7 @@ inline_generate_summary (void)
inline_free_summary ();
FOR_EACH_DEFINED_FUNCTION (node)
- if (!node->alias)
+ if (!node->symbol.alias)
inline_analyze_function (node);
}
@@ -3917,7 +3917,7 @@ inline_write_summary (void)
{
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
- if (cnode && cnode->analyzed)
+ if (cnode && cnode->symbol.definition && !cnode->symbol.alias)
count++;
}
streamer_write_uhwi (ob, count);
@@ -3926,7 +3926,7 @@ inline_write_summary (void)
{
symtab_node snode = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node> (snode);
- if (cnode && (node = cnode)->analyzed)
+ if (cnode && (node = cnode)->symbol.definition && !node->symbol.alias)
{
struct inline_summary *info = inline_summary (node);
struct bitpack_d bp;
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index cb819d7..9e131a4 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -153,7 +153,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
cgraph_remove_unreachable_functions gets rid of them. */
gcc_assert (!e->callee->global.inlined_to);
symtab_dissolve_same_comdat_group_list ((symtab_node) e->callee);
- if (e->callee->analyzed && !DECL_EXTERNAL (e->callee->symbol.decl))
+ if (e->callee->symbol.definition && !DECL_EXTERNAL (e->callee->symbol.decl))
{
if (overall_size)
*overall_size -= inline_summary (e->callee)->size;
@@ -236,7 +236,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
if (!alias->callers
&& can_remove_node_now_p (alias, e))
{
- next_alias = cgraph_alias_aliased_node (alias);
+ next_alias = cgraph_alias_target (alias);
cgraph_remove_node (alias);
alias = next_alias;
}
@@ -381,7 +381,7 @@ static bool
preserve_function_body_p (struct cgraph_node *node)
{
gcc_assert (cgraph_global_info_ready);
- gcc_assert (!node->alias && !node->thunk.thunk_p);
+ gcc_assert (!node->symbol.alias && !node->thunk.thunk_p);
/* Look if there is any clone around. */
if (node->clones)
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 35fce6d..a378c08 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -253,7 +253,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report)
gcc_assert (e->inline_failed);
- if (!callee || !callee->analyzed)
+ if (!callee || !callee->symbol.definition)
{
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
inlinable = false;
@@ -1100,7 +1100,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node,
int i;
struct ipa_ref *ref;
- if ((!node->alias && !inline_summary (node)->inlinable)
+ if ((!node->symbol.alias && !inline_summary (node)->inlinable)
|| cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE
|| node->global.inlined_to)
return;
@@ -1795,6 +1795,9 @@ ipa_inline (void)
}
inline_small_functions ();
+
+ /* Do first after-inlining removal. We want to remove all "stale" extern inline
+ functions and virtual functions so we really know what is called once. */
symtab_remove_unreachable_nodes (false, dump_file);
free (order);
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 7c3987e..8918c5b 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -1521,7 +1521,7 @@ ipa_compute_jump_functions (struct cgraph_node *node,
NULL);
/* We do not need to bother analyzing calls to unknown
functions unless they may become known during lto/whopr. */
- if (!callee->analyzed && !flag_lto)
+ if (!callee->symbol.definition && !flag_lto)
continue;
ipa_compute_jump_functions_for_edge (parms_ainfo, cs);
}
@@ -2978,7 +2978,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
tree temp;
struct ipa_node_params *info;
- if (!node->analyzed)
+ if (!node->symbol.definition)
return;
info = IPA_NODE_REF (node);
fprintf (f, " function %s/%i parameter descriptors:\n",
@@ -3972,7 +3972,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data,
index = streamer_read_uhwi (&ib_main);
encoder = file_data->symtab_node_encoder;
node = cgraph (lto_symtab_encoder_deref (encoder, index));
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
ipa_read_node_info (&ib_main, node, data_in);
}
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
@@ -4016,8 +4016,7 @@ ipa_update_after_lto_read (void)
ipa_check_create_edge_args ();
FOR_EACH_DEFINED_FUNCTION (node)
- if (node->analyzed)
- ipa_initialize_node_params (node);
+ ipa_initialize_node_params (node);
}
void
@@ -4154,7 +4153,7 @@ read_replacements_section (struct lto_file_decl_data *file_data,
index = streamer_read_uhwi (&ib_main);
encoder = file_data->symtab_node_encoder;
node = cgraph (lto_symtab_encoder_deref (encoder, index));
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
read_agg_replacement_chain (&ib_main, node, data_in);
}
lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data,
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 0dd6838..c6c41c6 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -738,7 +738,7 @@ analyze_function (struct cgraph_node *fn, bool ipa)
flags_from_decl_or_type (fn->symbol.decl),
cgraph_node_cannot_return (fn));
- if (fn->thunk.thunk_p || fn->alias)
+ if (fn->thunk.thunk_p || fn->symbol.alias)
{
/* Thunk gets propagated through, so nothing interesting happens. */
gcc_assert (ipa);
@@ -951,7 +951,7 @@ pure_const_write_summary (void)
lsei_next_function_in_partition (&lsei))
{
node = lsei_cgraph_node (lsei);
- if (node->analyzed && has_function_state (node))
+ if (node->symbol.definition && has_function_state (node))
count++;
}
@@ -962,7 +962,7 @@ pure_const_write_summary (void)
lsei_next_function_in_partition (&lsei))
{
node = lsei_cgraph_node (lsei);
- if (node->analyzed && has_function_state (node))
+ if (node->symbol.definition && has_function_state (node))
{
struct bitpack_d bp;
funct_state fs;
@@ -1124,7 +1124,7 @@ propagate_pure_const (void)
int count = 0;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1394,7 +1394,7 @@ propagate_nothrow (void)
bool can_throw = false;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
/* Find the worst state for any node in the cycle. */
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index f3c483f..9c56b7f 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -684,7 +684,7 @@ propagate (void)
|| TREE_ADDRESSABLE (vnode->symbol.decl)
|| TREE_READONLY (vnode->symbol.decl)
|| !is_proper_for_analysis (vnode->symbol.decl)
- || !vnode->analyzed)
+ || !vnode->symbol.definition)
bitmap_clear_bit (all_module_statics, DECL_UID (vnode->symbol.decl));
/* Forget info we collected "just for fun" on variables that turned out to be
@@ -716,7 +716,7 @@ propagate (void)
bool write_all = false;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
node_info = get_reference_vars_info (node);
@@ -794,7 +794,7 @@ propagate (void)
struct cgraph_node *w;
node = order[i];
- if (node->alias)
+ if (node->symbol.alias)
continue;
fprintf (dump_file,
@@ -835,7 +835,7 @@ propagate (void)
ipa_reference_optimization_summary_t opt;
node_info = get_reference_vars_info (node);
- if (!node->alias
+ if (!node->symbol.alias
&& (cgraph_function_body_availability (node) > AVAIL_OVERWRITABLE
|| (flags_from_decl_or_type (node->symbol.decl) & ECF_LEAF)))
{
@@ -894,7 +894,7 @@ write_node_summary_p (struct cgraph_node *node,
ipa_reference_optimization_summary_t info;
/* See if we have (non-empty) info. */
- if (!node->analyzed || node->global.inlined_to)
+ if (!node->symbol.definition || node->global.inlined_to)
return false;
info = get_reference_optimization_summary (node);
if (!info || (bitmap_empty_p (info->statics_not_read)
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 107c7a9..e786478 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -367,23 +367,46 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
unsigned int i;
int incoming_freq = 0;
tree retval;
+ bool back_edge = false;
if (dump_file && (dump_flags & TDF_DETAILS))
dump_split_point (dump_file, current);
FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
- if (!bitmap_bit_p (current->split_bbs, e->src->index))
- incoming_freq += EDGE_FREQUENCY (e);
+ {
+ if (e->flags & EDGE_DFS_BACK)
+ back_edge = true;
+ if (!bitmap_bit_p (current->split_bbs, e->src->index))
+ incoming_freq += EDGE_FREQUENCY (e);
+ }
/* Do not split when we would end up calling function anyway. */
if (incoming_freq
>= (ENTRY_BLOCK_PTR->frequency
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- " Refused: incoming frequency is too large.\n");
- return;
+ /* When profile is guessed, we can not expect it to give us
+ realistic estimate on likelyness of function taking the
+ complex path. As a special case, when tail of the function is
+ a loop, enable splitting since inlining code skipping the loop
+ is likely noticeable win. */
+ if (back_edge
+ && profile_status != PROFILE_READ
+ && incoming_freq < ENTRY_BLOCK_PTR->frequency)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " Split before loop, accepting despite low frequencies %i %i.\n",
+ incoming_freq,
+ ENTRY_BLOCK_PTR->frequency);
+ }
+ else
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ " Refused: incoming frequency is too large.\n");
+ return;
+ }
}
if (!current->header_size)
@@ -1533,6 +1556,11 @@ execute_split_functions (void)
return 0;
}
+ /* We enforce splitting after loop headers when profile info is not
+ available. */
+ if (profile_status != PROFILE_READ)
+ mark_dfs_back_edges ();
+
/* Initialize bitmap to track forbidden calls. */
forbidden_dominators = BITMAP_ALLOC (NULL);
calculate_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index cef67de..00e6528 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -287,7 +287,7 @@ ipa_reverse_postorder (struct cgraph_node **order)
&& (pass
|| (!node->symbol.address_taken
&& !node->global.inlined_to
- && !node->alias && !node->thunk.thunk_p
+ && !node->symbol.alias && !node->thunk.thunk_p
&& !cgraph_only_called_directly_p (node))))
{
stack_size = 0;
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 5613c26..254c09f 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -39,6 +39,53 @@ along with GCC; see the file COPYING3. If not see
#include "lto-streamer.h"
#include "data-streamer.h"
+/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
+
+static bool
+cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+ /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
+ return !(cgraph_only_called_directly_or_aliased_p (node)
+ && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
+ && node->symbol.definition
+ && !DECL_EXTERNAL (node->symbol.decl)
+ && !node->symbol.externally_visible
+ && !node->symbol.used_from_other_partition
+ && !node->symbol.in_other_partition);
+}
+
+/* Return true when function can be marked local. */
+
+static bool
+cgraph_local_node_p (struct cgraph_node *node)
+{
+ struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
+
+ /* FIXME: thunks can be considered local, but we need prevent i386
+ from attempting to change calling convention of them. */
+ if (n->thunk.thunk_p)
+ return false;
+ return !cgraph_for_node_and_aliases (n,
+ cgraph_non_local_node_p_1, NULL, true);
+
+}
+
+/* Return true when NODE has ADDR reference. */
+
+static bool
+has_addr_references_p (struct cgraph_node *node,
+ void *data ATTRIBUTE_UNUSED)
+{
+ int i;
+ struct ipa_ref *ref;
+
+ for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
+ i, ref); i++)
+ if (ref->use == IPA_REF_ADDR)
+ return true;
+ return false;
+}
+
/* Look for all functions inlined to NODE and update their inlined_to pointers
to INLINED_TO. */
@@ -89,79 +136,23 @@ process_references (struct ipa_ref_list *list,
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
{
- if (is_a <cgraph_node> (ref->referred))
- {
- struct cgraph_node *node = ipa_ref_node (ref);
-
- if (node->analyzed
- && (!DECL_EXTERNAL (node->symbol.decl)
- || node->alias
- || before_inlining_p))
- pointer_set_insert (reachable, node);
- enqueue_node ((symtab_node) node, first, reachable);
- }
- else
- {
- struct varpool_node *node = ipa_ref_varpool_node (ref);
-
- if (node->analyzed
- && (!DECL_EXTERNAL (node->symbol.decl)
- || node->alias
- || before_inlining_p))
- pointer_set_insert (reachable, node);
- enqueue_node ((symtab_node) node, first, reachable);
- }
+ symtab_node node = ref->referred;
+
+ if (node->symbol.definition
+ && (!DECL_EXTERNAL (node->symbol.decl)
+ || node->symbol.alias
+ || (before_inlining_p
+ /* We use variable constructors during late complation for
+ constant folding. Keep references alive so partitioning
+ knows about potential references. */
+ || (TREE_CODE (node->symbol.decl) == VAR_DECL
+ && flag_wpa && const_value_known_p (node->symbol.decl)))))
+ pointer_set_insert (reachable, node);
+ enqueue_node ((symtab_node) node, first, reachable);
}
}
-/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
-
-static bool
-cgraph_non_local_node_p_1 (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
-{
- /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */
- return !(cgraph_only_called_directly_or_aliased_p (node)
- && !ipa_ref_has_aliases_p (&node->symbol.ref_list)
- && node->analyzed
- && !DECL_EXTERNAL (node->symbol.decl)
- && !node->symbol.externally_visible
- && !node->symbol.used_from_other_partition
- && !node->symbol.in_other_partition);
-}
-
-/* Return true when function can be marked local. */
-
-static bool
-cgraph_local_node_p (struct cgraph_node *node)
-{
- struct cgraph_node *n = cgraph_function_or_thunk_node (node, NULL);
-
- /* FIXME: thunks can be considered local, but we need prevent i386
- from attempting to change calling convention of them. */
- if (n->thunk.thunk_p)
- return false;
- return !cgraph_for_node_and_aliases (n,
- cgraph_non_local_node_p_1, NULL, true);
-
-}
-
-/* Return true when NODE has ADDR reference. */
-
-static bool
-has_addr_references_p (struct cgraph_node *node,
- void *data ATTRIBUTE_UNUSED)
-{
- int i;
- struct ipa_ref *ref;
-
- for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list,
- i, ref); i++)
- if (ref->use == IPA_REF_ADDR)
- return true;
- return false;
-}
-
/* Perform reachability analysis and reclaim all unreachable nodes.
The algorithm is basically mark&sweep but with some extra refinements:
@@ -303,10 +294,10 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
struct cgraph_edge *e;
for (e = cnode->callees; e; e = e->next_callee)
{
- if (e->callee->analyzed
+ if (e->callee->symbol.definition
&& (!e->inline_failed
|| !DECL_EXTERNAL (e->callee->symbol.decl)
- || cnode->alias
+ || cnode->symbol.alias
|| before_inlining_p))
pointer_set_insert (reachable, e->callee);
enqueue_node ((symtab_node) e->callee, &first, reachable);
@@ -314,7 +305,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
/* When inline clone exists, mark body to be preserved so when removing
offline copy of the function we don't kill it. */
- if (!cnode->alias && cnode->global.inlined_to)
+ if (!cnode->symbol.alias && cnode->global.inlined_to)
pointer_set_insert (body_needed_for_clonning, cnode->symbol.decl);
}
@@ -339,7 +330,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
varpool_node *vnode = dyn_cast <varpool_node> (node);
if (vnode
&& DECL_EXTERNAL (node->symbol.decl)
- && !vnode->alias
+ && !vnode->symbol.alias
&& in_boundary_p)
{
struct ipa_ref *ref;
@@ -352,6 +343,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
for (node = cgraph_first_function (); node; node = next)
{
next = cgraph_next_function (node);
+
+ /* If node is not needed at all, remove it. */
if (!node->symbol.aux)
{
if (file)
@@ -359,20 +352,18 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
cgraph_remove_node (node);
changed = true;
}
+ /* If node is unreachable, remove its body. */
else if (!pointer_set_contains (reachable, node))
{
- if (node->analyzed)
+ if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
+ cgraph_release_function_body (node);
+ if (node->symbol.definition)
{
if (file)
fprintf (file, " %s", cgraph_node_name (node));
- cgraph_node_remove_callees (node);
- ipa_remove_all_references (&node->symbol.ref_list);
+ cgraph_reset_node (node);
changed = true;
}
- if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl)
- && (node->local.finalized || !DECL_ARTIFICIAL (node->symbol.decl)))
- cgraph_release_function_body (node);
- node->analyzed = false;
}
}
@@ -406,14 +397,20 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
}
else if (!pointer_set_contains (reachable, vnode))
{
- if (vnode->analyzed)
+ if (vnode->symbol.definition)
{
if (file)
fprintf (file, " %s", varpool_node_name (vnode));
changed = true;
}
- vnode->analyzed = false;
+ vnode->symbol.definition = false;
+ vnode->symbol.analyzed = false;
vnode->symbol.aux = NULL;
+
+ /* Keep body if it may be useful for constant folding. */
+ if (!const_value_known_p (vnode->symbol.decl))
+ varpool_remove_initializer (vnode);
+ ipa_remove_all_references (&vnode->symbol.ref_list);
}
else
vnode->symbol.aux = NULL;
@@ -474,7 +471,7 @@ ipa_discover_readonly_nonaddressable_vars (void)
if (dump_file)
fprintf (dump_file, "Clearing variable flags:");
FOR_EACH_VARIABLE (vnode)
- if (vnode->finalized && varpool_all_refs_explicit_p (vnode)
+ if (vnode->symbol.definition && varpool_all_refs_explicit_p (vnode)
&& (TREE_ADDRESSABLE (vnode->symbol.decl)
|| !TREE_READONLY (vnode->symbol.decl)))
{
@@ -546,12 +543,12 @@ cgraph_address_taken_from_non_vtable_p (struct cgraph_node *node)
Virtual functions do have their addresses taken from the vtables,
but in C++ there is no way to compare their addresses for equality. */
-bool
+static bool
cgraph_comdat_can_be_unshared_p (struct cgraph_node *node)
{
if ((cgraph_address_taken_from_non_vtable_p (node)
&& !DECL_VIRTUAL_P (node->symbol.decl))
- || !node->analyzed)
+ || !node->symbol.definition)
return false;
if (node->symbol.same_comdat_group)
{
@@ -575,7 +572,7 @@ static bool
cgraph_externally_visible_p (struct cgraph_node *node,
bool whole_program)
{
- if (!node->local.finalized)
+ if (!node->symbol.definition)
return false;
if (!DECL_COMDAT (node->symbol.decl)
&& (!TREE_PUBLIC (node->symbol.decl)
@@ -619,7 +616,7 @@ cgraph_externally_visible_p (struct cgraph_node *node,
|| DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object
file. In that case we don't set used_from_other_object_file. */
- && node->analyzed)
+ && node->symbol.definition)
;
else if (!whole_program)
return true;
@@ -638,7 +635,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
/* Do not touch weakrefs; while they are not externally visible,
dropping their DECL_EXTERNAL flags confuse most
of code handling them. */
- if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl))
+ if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl))
return true;
if (DECL_EXTERNAL (vnode->symbol.decl))
@@ -690,7 +687,7 @@ varpool_externally_visible_p (struct varpool_node *vnode)
|| DECL_VISIBILITY (vnode->symbol.decl) == VISIBILITY_INTERNAL)
/* Be sure that node is defined in IR file, not in other object
file. In that case we don't set used_from_other_object_file. */
- && vnode->finalized)
+ && vnode->symbol.definition)
;
else if (!flag_whole_program)
return true;
@@ -744,7 +741,7 @@ function_and_variable_visibility (bool whole_program)
We may end up marking as node external nodes where this flag is meaningless
strip it. */
if (node->symbol.force_output
- && (DECL_EXTERNAL (node->symbol.decl) || !node->analyzed))
+ && (DECL_EXTERNAL (node->symbol.decl) || !node->symbol.definition))
node->symbol.force_output = 0;
/* C++ FE on lack of COMDAT support create local COMDAT functions
@@ -781,7 +778,7 @@ function_and_variable_visibility (bool whole_program)
}
else
node->symbol.externally_visible = false;
- if (!node->symbol.externally_visible && node->analyzed
+ if (!node->symbol.externally_visible && node->symbol.definition
&& !DECL_EXTERNAL (node->symbol.decl))
{
gcc_assert (whole_program || in_lto_p
@@ -854,7 +851,7 @@ function_and_variable_visibility (bool whole_program)
}
FOR_EACH_DEFINED_VARIABLE (vnode)
{
- if (!vnode->finalized)
+ if (!vnode->symbol.definition)
continue;
if (varpool_externally_visible_p (vnode))
vnode->symbol.externally_visible = true;
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index 2857b06..82cc49f 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,7 @@
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * decl.c (java_mark_decl_local): Update for new symtab flags.
+
2013-05-22 Matthias Klose <doko@ubuntu.com>
* jvspec.c (jvgenmain_spec): Add %I to cc1 call.
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index 566435f..c5a654d 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -1904,7 +1904,7 @@ java_mark_decl_local (tree decl)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
struct cgraph_node *node = cgraph_get_node (decl);
- gcc_assert (!node || !node->local.finalized);
+ gcc_assert (!node || !node->symbol.definition);
}
#endif
gcc_assert (!DECL_RTL_SET_P (decl));
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 34188cb..2268f24 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -320,7 +320,7 @@ bool
reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t encoder)
{
struct cgraph_edge *e;
- if (!node->analyzed)
+ if (!node->symbol.definition)
return false;
if (node->global.inlined_to)
return false;
@@ -380,7 +380,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
- if (node->analyzed && !boundary_p)
+ if (node->symbol.analyzed && !boundary_p)
tag = LTO_symtab_analyzed_node;
else
tag = LTO_symtab_unavail_node;
@@ -399,7 +399,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
Cherry-picked nodes: These are nodes we pulled from other
translation units into SET during IPA-inlining. We make them as
local static nodes to prevent clashes with other local statics. */
- if (boundary_p && node->analyzed && !DECL_EXTERNAL (node->symbol.decl))
+ if (boundary_p && node->symbol.analyzed && !DECL_EXTERNAL (node->symbol.decl))
{
/* Inline clones can not be part of boundary.
gcc_assert (!node->global.inlined_to);
@@ -463,7 +463,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, node->local.local, 1);
bp_pack_value (&bp, node->symbol.externally_visible, 1);
- bp_pack_value (&bp, node->local.finalized, 1);
+ bp_pack_value (&bp, node->symbol.definition, 1);
bp_pack_value (&bp, node->local.versionable, 1);
bp_pack_value (&bp, node->local.can_change_signature, 1);
bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
@@ -485,7 +485,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
defined in other unit, we may use the info on aliases to resolve
symbol1 != symbol2 type tests that we can do only for locally defined objects
otherwise. */
- bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1);
+ bp_pack_value (&bp, node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1);
bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1);
bp_pack_value (&bp, node->only_called_at_exit, 1);
@@ -504,8 +504,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
}
- if ((node->alias || node->thunk.thunk_p)
- && (!boundary_p || (node->alias && DECL_EXTERNAL (node->symbol.decl))))
+ if ((node->symbol.alias || node->thunk.thunk_p)
+ && (!boundary_p || (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl))))
{
streamer_write_hwi_in_range (ob->main_stream, 0, 1,
node->thunk.alias != NULL);
@@ -522,7 +522,7 @@ static void
lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
lto_symtab_encoder_t encoder)
{
- bool boundary_p = (node->analyzed
+ bool boundary_p = (node->symbol.definition
&& !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node));
struct bitpack_d bp;
int ref;
@@ -535,10 +535,10 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
bp_pack_value (&bp, node->symbol.externally_visible, 1);
bp_pack_value (&bp, node->symbol.force_output, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1);
- bp_pack_value (&bp, node->finalized, 1);
- bp_pack_value (&bp, node->alias, 1);
+ bp_pack_value (&bp, node->symbol.definition, 1);
+ bp_pack_value (&bp, node->symbol.alias, 1);
bp_pack_value (&bp, node->alias_of != NULL, 1);
- gcc_assert (node->finalized || !node->analyzed);
+ gcc_assert (node->symbol.definition || !node->symbol.analyzed);
/* Constant pool initializers can be de-unified into individual ltrans units.
FIXME: Alternatively at -Os we may want to avoid generating for them the local
labels and share them across LTRANS partitions. */
@@ -551,7 +551,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
}
else
{
- bp_pack_value (&bp, node->analyzed
+ bp_pack_value (&bp, node->symbol.definition
&& referenced_from_other_partition_p (&node->symbol.ref_list,
encoder), 1);
bp_pack_value (&bp, boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1);
@@ -756,7 +756,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
{
struct varpool_node *vnode = lsei_varpool_node (lsei);
- gcc_assert (!vnode->alias || vnode->alias_of);
+ gcc_assert (!vnode->symbol.alias || vnode->alias_of);
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list);
@@ -883,7 +883,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
node->local.local = bp_unpack_value (bp, 1);
node->symbol.externally_visible = bp_unpack_value (bp, 1);
- node->local.finalized = bp_unpack_value (bp, 1);
+ node->symbol.definition = bp_unpack_value (bp, 1);
node->local.versionable = bp_unpack_value (bp, 1);
node->local.can_change_signature = bp_unpack_value (bp, 1);
node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
@@ -893,7 +893,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
node->abstract_and_needed = bp_unpack_value (bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
node->lowered = bp_unpack_value (bp, 1);
- node->analyzed = tag == LTO_symtab_analyzed_node;
+ node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
node->symbol.in_other_partition = bp_unpack_value (bp, 1);
if (node->symbol.in_other_partition
/* Avoid updating decl when we are seeing just inline clone.
@@ -909,7 +909,7 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
DECL_EXTERNAL (node->symbol.decl) = 1;
TREE_STATIC (node->symbol.decl) = 0;
}
- node->alias = bp_unpack_value (bp, 1);
+ node->symbol.alias = bp_unpack_value (bp, 1);
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
node->only_called_at_startup = bp_unpack_value (bp, 1);
node->only_called_at_exit = bp_unpack_value (bp, 1);
@@ -1004,7 +1004,7 @@ input_node (struct lto_file_decl_data *file_data,
node->thunk.virtual_value = virtual_value;
node->thunk.virtual_offset_p = (type & 4);
}
- if (node->thunk.thunk_p || node->alias)
+ if (node->thunk.thunk_p || node->symbol.alias)
{
if (streamer_read_hwi_in_range (ib, "alias nonzero flag", 0, 1))
{
@@ -1044,12 +1044,12 @@ input_varpool_node (struct lto_file_decl_data *file_data,
node->symbol.externally_visible = bp_unpack_value (&bp, 1);
node->symbol.force_output = bp_unpack_value (&bp, 1);
node->symbol.unique_name = bp_unpack_value (&bp, 1);
- node->finalized = bp_unpack_value (&bp, 1);
- node->alias = bp_unpack_value (&bp, 1);
+ node->symbol.definition = bp_unpack_value (&bp, 1);
+ node->symbol.alias = bp_unpack_value (&bp, 1);
non_null_aliasof = bp_unpack_value (&bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1);
node->symbol.in_other_partition = bp_unpack_value (&bp, 1);
- node->analyzed = (node->finalized && (!node->alias || !node->symbol.in_other_partition));
+ node->symbol.analyzed = (node->symbol.definition && (!node->symbol.alias || !node->symbol.in_other_partition));
if (node->symbol.in_other_partition)
{
DECL_EXTERNAL (node->symbol.decl) = 1;
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index dfaf280..5e1a332 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1013,7 +1013,7 @@ lto_output (void)
cgraph_node *node = dyn_cast <cgraph_node> (snode);
if (node
&& lto_symtab_encoder_encode_body_p (encoder, node)
- && !node->alias
+ && !node->symbol.alias
&& !node->thunk.thunk_p)
{
#ifdef ENABLE_CHECKING
@@ -1243,10 +1243,10 @@ write_symbol (struct streamer_tree_cache_d *cache,
/* When something is defined, it should have node attached. */
gcc_assert (alias || TREE_CODE (t) != VAR_DECL
- || varpool_get_node (t)->finalized);
+ || varpool_get_node (t)->symbol.definition);
gcc_assert (alias || TREE_CODE (t) != FUNCTION_DECL
|| (cgraph_get_node (t)
- && cgraph_get_node (t)->analyzed));
+ && cgraph_get_node (t)->symbol.definition));
}
/* Imitate what default_elf_asm_output_external do.
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index 8091d36..6c433f4 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -91,8 +91,8 @@ static void
lto_varpool_replace_node (struct varpool_node *vnode,
struct varpool_node *prevailing_node)
{
- gcc_assert (!vnode->finalized || prevailing_node->finalized);
- gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
+ gcc_assert (!vnode->symbol.definition || prevailing_node->symbol.definition);
+ gcc_assert (!vnode->symbol.analyzed || prevailing_node->symbol.analyzed);
ipa_clone_referring ((symtab_node)prevailing_node, &vnode->symbol.ref_list);
@@ -255,14 +255,7 @@ lto_symtab_resolve_can_prevail_p (symtab_node e)
if (DECL_EXTERNAL (e->symbol.decl))
return false;
- /* For functions we need a non-discarded body. */
- if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
- return (cgraph (e)->analyzed);
-
- else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
- return varpool (e)->finalized;
-
- gcc_unreachable ();
+ return e->symbol.definition;
}
/* Resolve the symbol with the candidates in the chain *SLOT and store
@@ -594,33 +587,33 @@ lto_symtab_merge_cgraph_nodes (void)
FOR_EACH_FUNCTION (cnode)
{
/* Resolve weakrefs to symbol defined in other unit. */
- if (!cnode->analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
+ if (!cnode->symbol.analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
{
symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
if (node && is_a <cgraph_node> (node))
{
struct cgraph_node *n;
- for (n = cgraph (node); n && n->alias;
- n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
+ for (n = cgraph (node); n && n->symbol.alias;
+ n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
if (n == cnode)
{
error ("function %q+D part of alias cycle", cnode->symbol.decl);
- cnode->alias = false;
+ cnode->symbol.alias = false;
break;
}
- if (cnode->alias)
+ if (cnode->symbol.alias)
{
cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
IPA_REF_ALIAS, NULL);
- cnode->analyzed = true;
+ cnode->symbol.analyzed = true;
}
}
else if (node)
error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
}
- if ((cnode->thunk.thunk_p || cnode->alias)
+ if ((cnode->thunk.thunk_p || cnode->symbol.alias)
&& cnode->thunk.alias && DECL_P (cnode->thunk.alias))
cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
cnode->symbol.aux = NULL;
@@ -628,33 +621,33 @@ lto_symtab_merge_cgraph_nodes (void)
FOR_EACH_VARIABLE (vnode)
{
/* Resolve weakrefs to symbol defined in other unit. */
- if (!vnode->analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
+ if (!vnode->symbol.analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
{
symtab_node node = symtab_node_for_asm (vnode->alias_of);
if (node && is_a <cgraph_node> (node))
{
struct varpool_node *n;
- for (n = varpool (node); n && n->alias;
- n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
+ for (n = varpool (node); n && n->symbol.alias;
+ n = n->symbol.analyzed ? varpool_alias_target (n) : NULL)
if (n == vnode)
{
error ("function %q+D part of alias cycle", vnode->symbol.decl);
- vnode->alias = false;
+ vnode->symbol.alias = false;
break;
}
- if (vnode->alias)
+ if (vnode->symbol.alias)
{
varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
IPA_REF_ALIAS, NULL);
- vnode->analyzed = true;
+ vnode->symbol.analyzed = true;
}
}
else if (node)
error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
}
- if (vnode->alias_of)
+ if (vnode->symbol.alias && DECL_P (vnode->alias_of))
vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
vnode->symbol.aux = NULL;
}
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 3ea106b..ded1056 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,9 @@
+2013-05-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab
+ flags.
+ * lto-partition.c (get_symbol_class, lto_balanced_map): Likewise.
+
2013-05-15 Jan Hubicka <jh@suse.cz>
* lto-partition.c (privatize_symbol_name): Return true when
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 62341c1..921b4e2 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -74,13 +74,13 @@ get_symbol_class (symtab_node node)
objects that can not be duplicated across partitions. */
if (DECL_IN_CONSTANT_POOL (node->symbol.decl))
return SYMBOL_DUPLICATE;
- gcc_checking_assert (vnode->analyzed);
+ gcc_checking_assert (vnode->symbol.definition);
}
/* Functions that are cloned may stay in callgraph even if they are unused.
Handle them as external; compute_ltrans_boundary take care to make
proper things to happen (i.e. to make them appear in the boundary but
with body streamed, so clone can me materialized). */
- else if (!cgraph (node)->analyzed)
+ else if (!cgraph (node)->symbol.definition)
return SYMBOL_EXTERNAL;
/* Comdats are duplicated to every use unless they are keyed.
@@ -561,12 +561,12 @@ lto_balanced_map (void)
last_visited_node++;
- gcc_assert (node->analyzed
+ gcc_assert (node->symbol.definition
|| lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)));
/* Compute boundary cost of callgraph edges. */
for (edge = node->callees; edge; edge = edge->next_callee)
- if (edge->callee->analyzed)
+ if (edge->callee->symbol.definition)
{
int edge_cost = edge->frequency;
int index;
@@ -587,7 +587,7 @@ lto_balanced_map (void)
int edge_cost = edge->frequency;
int index;
- gcc_assert (edge->caller->analyzed);
+ gcc_assert (edge->caller->symbol.definition);
if (!edge_cost)
edge_cost = 1;
gcc_assert (edge_cost > 0);
@@ -614,7 +614,7 @@ lto_balanced_map (void)
int index;
vnode = ipa_ref_varpool_node (ref);
- if (!vnode->finalized)
+ if (!vnode->symbol.definition)
continue;
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
@@ -632,7 +632,7 @@ lto_balanced_map (void)
int index;
node = ipa_ref_node (ref);
- if (!node->analyzed)
+ if (!node->symbol.definition)
continue;
index = lto_symtab_encoder_lookup (partition->encoder,
(symtab_node)node);
@@ -648,7 +648,7 @@ lto_balanced_map (void)
int index;
vnode = ipa_ref_referring_varpool_node (ref);
- gcc_assert (vnode->finalized);
+ gcc_assert (vnode->symbol.definition);
if (!symbol_partitioned_p ((symtab_node) vnode) && flag_toplevel_reorder
&& get_symbol_class ((symtab_node) vnode) == SYMBOL_PARTITION)
add_symbol_to_partition (partition, (symtab_node) vnode);
@@ -665,7 +665,7 @@ lto_balanced_map (void)
int index;
node = ipa_ref_referring_node (ref);
- gcc_assert (node->analyzed);
+ gcc_assert (node->symbol.definition);
index = lto_symtab_encoder_lookup (partition->encoder,
(symtab_node)node);
if (index != LCC_NOT_FOUND
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 0943335..f2a59d3 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -166,7 +166,7 @@ has_analyzed_clone_p (struct cgraph_node *node)
if (node)
while (node != orig)
{
- if (node->analyzed)
+ if (node->symbol.analyzed)
return true;
if (node->clones)
node = node->clones;
@@ -196,7 +196,8 @@ lto_materialize_function (struct cgraph_node *node)
decl = node->symbol.decl;
/* Read in functions with body (analyzed nodes)
and also functions that are needed to produce virtual clones. */
- if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p (node))
+ if ((cgraph_function_with_gimple_body_p (node) && node->symbol.analyzed)
+ || has_analyzed_clone_p (node))
{
/* Clones don't need to be read. */
if (node->clone_of)
diff --git a/gcc/passes.c b/gcc/passes.c
index eccf0b5..656cf71 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -2492,12 +2492,12 @@ ipa_write_summaries (void)
renumber_gimple_stmt_uids ();
pop_cfun ();
}
- if (node->analyzed)
+ if (node->symbol.definition)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
}
FOR_EACH_DEFINED_VARIABLE (vnode)
- if ((!vnode->alias || vnode->alias_of))
+ if ((!vnode->symbol.alias || vnode->alias_of))
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
@@ -2564,7 +2564,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder)
For functions newly born at WPA stage we need to initialize
the uids here. */
- if (node->analyzed
+ if (node->symbol.definition
&& gimple_has_body_p (node->symbol.decl))
{
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 56f0de9..1a7f826 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -473,9 +473,15 @@ dump_symtab_base (FILE *f, symtab_node node)
node->symbol.order,
symtab_node_name (node));
dump_addr (f, " @", (void *)node);
- fprintf (f, "\n Type: %s\n", symtab_type_names[node->symbol.type]);
- fprintf (f, " Visibility:");
-
+ fprintf (f, "\n Type: %s", symtab_type_names[node->symbol.type]);
+
+ if (node->symbol.definition)
+ fprintf (f, " definition");
+ if (node->symbol.analyzed)
+ fprintf (f, " analyzed");
+ if (node->symbol.alias)
+ fprintf (f, " alias");
+ fprintf (f, "\n Visibility:");
if (node->symbol.in_other_partition)
fprintf (f, " in_other_partition");
if (node->symbol.used_from_other_partition)
@@ -653,6 +659,12 @@ verify_symtab_base (symtab_node node)
&& node->symbol.previous_sharing_asm_name->symbol.next_sharing_asm_name != node)
{
error ("double linked list of assembler names corrupted");
+ error_found = true;
+ }
+ if (node->symbol.analyzed && !node->symbol.definition)
+ {
+ error ("node is analyzed byt it is not a definition");
+ error_found = true;
}
if (node->symbol.same_comdat_group)
{
@@ -783,4 +795,40 @@ symtab_make_decl_local (tree decl)
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
}
+
+/* Given NODE, walk the alias chain to return the symbol NODE is alias of.
+ If NODE is not an alias, return NODE.
+ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
+
+symtab_node
+symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
+{
+ if (availability)
+ {
+ if (is_a <cgraph_node> (node))
+ *availability = cgraph_function_body_availability (cgraph (node));
+ else
+ *availability = cgraph_variable_initializer_availability (varpool (node));
+ }
+ while (node)
+ {
+ if (node->symbol.alias && node->symbol.analyzed)
+ node = symtab_alias_target (node);
+ else
+ return node;
+ if (node && availability)
+ {
+ enum availability a;
+ if (is_a <cgraph_node> (node))
+ a = cgraph_function_body_availability (cgraph (node));
+ else
+ a = cgraph_variable_initializer_availability (varpool (node));
+ if (a < *availability)
+ *availability = a;
+ }
+ }
+ if (availability)
+ *availability = AVAIL_NOT_AVAILABLE;
+ return NULL;
+}
#include "gt-symtab.h"
diff --git a/gcc/toplev.c b/gcc/toplev.c
index d41283d..a2ee491 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -393,15 +393,15 @@ wrapup_global_declaration_2 (tree decl)
if (!node && flag_ltrans)
needed = false;
- else if (node && node->finalized)
+ else if (node && node->symbol.definition)
needed = false;
- else if (node && node->alias)
+ else if (node && node->symbol.alias)
needed = false;
else if (!cgraph_global_info_ready
&& (TREE_USED (decl)
|| TREE_USED (DECL_ASSEMBLER_NAME (decl))))
/* needed */;
- else if (node && node->analyzed)
+ else if (node && node->symbol.analyzed)
/* needed */;
else if (DECL_COMDAT (decl))
needed = false;
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index c66278c..d7e5a40 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -3932,7 +3932,7 @@ get_cg_data (struct cgraph_node **node, bool traverse_aliases)
{
struct tm_ipa_cg_data *d;
- if (traverse_aliases && (*node)->alias)
+ if (traverse_aliases && (*node)->symbol.alias)
*node = cgraph_get_node ((*node)->thunk.alias);
d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
@@ -4518,7 +4518,7 @@ ipa_tm_mayenterirr_function (struct cgraph_node *node)
/* Recurse on the main body for aliases. In general, this will
result in one of the bits above being set so that we will not
have to recurse next time. */
- if (node->alias)
+ if (node->symbol.alias)
return ipa_tm_mayenterirr_function (cgraph_get_node (node->thunk.alias));
/* What remains is unmarked local functions without items that force
@@ -4678,9 +4678,7 @@ static inline void
ipa_tm_mark_force_output_node (struct cgraph_node *node)
{
cgraph_mark_force_output_node (node);
- /* ??? function_and_variable_visibility will reset
- the needed bit, without actually checking. */
- node->analyzed = 1;
+ node->symbol.analyzed = true;
}
/* Callback data for ipa_tm_create_version_alias. */
@@ -5250,7 +5248,7 @@ ipa_tm_execute (void)
{
/* If this is an alias, make sure its base is queued as well.
we need not scan the callees now, as the base will do. */
- if (node->alias)
+ if (node->symbol.alias)
{
node = cgraph_get_node (node->thunk.alias);
d = get_cg_data (&node, true);
@@ -5393,7 +5391,7 @@ ipa_tm_execute (void)
for (i = 0; i < tm_callees.length (); ++i)
{
node = tm_callees[i];
- if (node->analyzed)
+ if (node->symbol.analyzed)
{
d = get_cg_data (&node, true);
if (d->clone)
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index fc350bd..fb80b30 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2580,7 +2580,7 @@ tree_could_trap_p (tree expr)
/* Assume that accesses to weak functions may trap, unless we know
they are certainly defined in current TU or in some other
LTO partition. */
- if (DECL_WEAK (expr))
+ if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
{
struct cgraph_node *node;
if (!DECL_EXTERNAL (expr))
@@ -2596,7 +2596,7 @@ tree_could_trap_p (tree expr)
/* Assume that accesses to weak vars may trap, unless we know
they are certainly defined in current TU or in some other
LTO partition. */
- if (DECL_WEAK (expr))
+ if (DECL_WEAK (expr) && !DECL_COMDAT (expr))
{
struct varpool_node *node;
if (!DECL_EXTERNAL (expr))
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index fc75b31..9fecb6c 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -704,15 +704,15 @@ create_emultls_var (struct varpool_node *var, void *data)
cvar = varpool_get_node (cdecl);
control_vars.quick_push (cvar);
- if (!var->alias)
+ if (!var->symbol.alias)
{
/* Make sure the COMMON block control variable gets initialized.
Note that there's no point in doing this for aliases; we only
need to do this once for the main variable. */
emutls_common_1 (var->symbol.decl, cdecl, (tree *)data);
}
- if (var->alias && !var->alias_of)
- cvar->alias = true;
+ if (var->symbol.alias && !var->alias_of)
+ cvar->symbol.alias = true;
/* Indicate that the value of the TLS variable may be found elsewhere,
preventing the variable from re-appearing in the GIMPLE. We cheat
@@ -743,7 +743,7 @@ ipa_lower_emutls (void)
gcc_checking_assert (TREE_STATIC (var->symbol.decl)
|| DECL_EXTERNAL (var->symbol.decl));
varpool_node_set_add (tls_vars, var);
- if (var->alias && var->analyzed)
+ if (var->symbol.alias && var->symbol.definition)
varpool_node_set_add (tls_vars, varpool_variable_node (var, NULL));
}
@@ -767,9 +767,9 @@ ipa_lower_emutls (void)
{
var = tls_vars->nodes[i];
- if (var->alias && !var->alias_of)
+ if (var->symbol.alias && !var->alias_of)
any_aliases = true;
- else if (!var->alias)
+ else if (!var->symbol.alias)
varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 57af7de..bee7766 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1726,7 +1726,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
if ((!edge
|| (edge->indirect_inlining_edge
&& id->transform_call_graph_edges == CB_CGE_MOVE_CLONES))
- && id->dst_node->analyzed
+ && id->dst_node->symbol.definition
&& (fn = gimple_call_fndecl (stmt)) != NULL)
{
struct cgraph_node *dest = cgraph_get_node (fn);
@@ -1737,10 +1737,10 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
producing dead clone (for further cloning). In all
other cases we hit a bug (incorrect node sharing is the
most common reason for missing edges). */
- gcc_assert (!dest->analyzed
+ gcc_assert (!dest->symbol.definition
|| dest->symbol.address_taken
- || !id->src_node->analyzed
- || !id->dst_node->analyzed);
+ || !id->src_node->symbol.definition
+ || !id->dst_node->symbol.definition);
if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES)
cgraph_create_edge_including_clones
(id->dst_node, dest, orig_stmt, stmt, bb->count,
@@ -3611,7 +3611,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
/* Do not special case builtins where we see the body.
This just confuse inliner. */
- if (!decl || !(node = cgraph_get_node (decl)) || node->analyzed)
+ if (!decl || !(node = cgraph_get_node (decl)) || node->symbol.definition)
;
/* For buitins that are likely expanded to nothing or
inlined do not account operand costs. */
@@ -4344,7 +4344,7 @@ optimize_inline_calls (tree fn)
memset (&id, 0, sizeof (id));
id.src_node = id.dst_node = cgraph_get_node (fn);
- gcc_assert (id.dst_node->analyzed);
+ gcc_assert (id.dst_node->symbol.definition);
id.dst_fn = fn;
/* Or any functions that aren't finished yet. */
if (current_function_decl)
@@ -5238,7 +5238,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
pointer_set_destroy (id.statements_to_fold);
fold_cond_expr_cond ();
delete_unreachable_blocks_update_callgraph (&id);
- if (id.dst_node->analyzed)
+ if (id.dst_node->symbol.definition)
cgraph_rebuild_references ();
update_ssa (TODO_update_ssa);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 9eb06f6..1bfe2b2 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -2874,7 +2874,7 @@ get_constraint_for_ssa_var (tree t, vec<ce_s> *results, bool address_p)
&& (TREE_STATIC (t) || DECL_EXTERNAL (t)))
{
struct varpool_node *node = varpool_get_node (t);
- if (node && node->alias)
+ if (node && node->symbol.alias && node->symbol.analyzed)
{
node = varpool_variable_node (node, NULL);
t = node->symbol.decl;
@@ -5751,7 +5751,7 @@ create_variable_info_for (tree decl, const char *name)
/* If this is a global variable with an initializer and we are in
IPA mode generate constraints for it. */
if (DECL_INITIAL (decl)
- && vnode->analyzed)
+ && vnode->symbol.definition)
{
vec<ce_s> rhsc = vNULL;
struct constraint_expr lhs, *rhsp;
@@ -7023,7 +7023,8 @@ struct pt_solution ipa_escaped_pt
static bool
associate_varinfo_to_alias (struct cgraph_node *node, void *data)
{
- if (node->alias || node->thunk.thunk_p)
+ if ((node->symbol.alias || node->thunk.thunk_p)
+ && node->symbol.analyzed)
insert_vi_for_tree (node->symbol.decl, (varinfo_t)data);
return false;
}
@@ -7066,7 +7067,7 @@ ipa_pta_execute (void)
/* Create constraints for global variables and their initializers. */
FOR_EACH_VARIABLE (var)
{
- if (var->alias)
+ if (var->symbol.alias && var->symbol.analyzed)
continue;
get_vi_for_tree (var->symbol.decl);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 5f62677..72bff5a 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -2256,7 +2256,7 @@ mark_decl_referenced (tree decl)
definition. */
struct cgraph_node *node = cgraph_get_create_node (decl);
if (!DECL_EXTERNAL (decl)
- && !node->local.finalized)
+ && !node->symbol.definition)
cgraph_mark_force_output_node (node);
}
else if (TREE_CODE (decl) == VAR_DECL)
@@ -5595,9 +5595,9 @@ assemble_alias (tree decl, tree target)
/* Allow aliases to aliases. */
if (TREE_CODE (decl) == FUNCTION_DECL)
- cgraph_get_create_node (decl)->alias = true;
+ cgraph_get_create_node (decl)->symbol.alias = true;
else
- varpool_node_for_decl (decl)->alias = true;
+ varpool_node_for_decl (decl)->symbol.alias = true;
/* If the target has already been emitted, we don't have to queue the
alias. This saves a tad of memory. */
@@ -5700,12 +5700,12 @@ dump_tm_clone_pairs (vec<tm_alias_pair> tm_alias_pairs)
TM_GETTMCLONE. If neither of these are true, we didn't generate
a clone, and we didn't call it indirectly... no sense keeping it
in the clone table. */
- if (!dst_n || !dst_n->analyzed)
+ if (!dst_n || !dst_n->symbol.definition)
continue;
/* This covers the case where we have optimized the original
function away, and only access the transactional clone. */
- if (!src_n || !src_n->analyzed)
+ if (!src_n || !src_n->symbol.definition)
continue;
if (!switched)
diff --git a/gcc/varpool.c b/gcc/varpool.c
index e3ad22b..1916b76 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -58,6 +58,19 @@ void
varpool_remove_node (struct varpool_node *node)
{
symtab_unregister_node ((symtab_node)node);
+
+ /* Because we remove references from external functions before final compilation,
+ we may end up removing useful constructors.
+ FIXME: We probably want to trace boundaries better. */
+ if (!const_value_known_p (node->symbol.decl))
+ varpool_remove_initializer (node);
+ ggc_free (node);
+}
+
+/* Renove node initializer when it is no longer needed. */
+void
+varpool_remove_initializer (struct varpool_node *node)
+{
if (DECL_INITIAL (node->symbol.decl)
&& !DECL_IN_CONSTANT_POOL (node->symbol.decl)
/* Keep vtables for BINFO folding. */
@@ -65,7 +78,6 @@ varpool_remove_node (struct varpool_node *node)
/* FIXME: http://gcc.gnu.org/PR55395 */
&& debug_info_level == DINFO_LEVEL_NONE)
DECL_INITIAL (node->symbol.decl) = error_mark_node;
- ggc_free (node);
}
/* Dump given cgraph node. */
@@ -80,10 +92,6 @@ dump_varpool_node (FILE *f, struct varpool_node *node)
fprintf (f, " Varpool flags:");
if (DECL_INITIAL (node->symbol.decl))
fprintf (f, " initialized");
- if (node->analyzed)
- fprintf (f, " analyzed");
- if (node->finalized)
- fprintf (f, " finalized");
if (node->output)
fprintf (f, " output");
if (TREE_READONLY (node->symbol.decl))
@@ -117,9 +125,9 @@ struct varpool_node *
varpool_node_for_asm (tree asmname)
{
if (symtab_node node = symtab_node_for_asm (asmname))
- if (varpool_node *vnode = dyn_cast <varpool_node> (node))
- return vnode;
- return NULL;
+ return dyn_cast <varpool_node> (node);
+ else
+ return NULL;
}
/* Determine if variable DECL is needed. That is, visible to something
@@ -205,12 +213,12 @@ enum availability
cgraph_variable_initializer_availability (struct varpool_node *node)
{
gcc_assert (cgraph_function_flags_ready);
- if (!node->finalized)
+ if (!node->symbol.definition)
return AVAIL_NOT_AVAILABLE;
if (!TREE_PUBLIC (node->symbol.decl))
return AVAIL_AVAILABLE;
/* If the variable can be overwritten, return OVERWRITABLE. Takes
- care of at least two notable extensions - the COMDAT variables
+ care of at least one notable extension - the COMDAT variables
used to share template instantiations in C++. */
if (!decl_replaceable_p (node->symbol.decl))
return AVAIL_OVERWRITABLE;
@@ -225,24 +233,24 @@ varpool_analyze_node (struct varpool_node *node)
/* When reading back varpool at LTO time, we re-construct the queue in order
to have "needed" list right by inserting all needed nodes into varpool.
We however don't want to re-analyze already analyzed nodes. */
- if (!node->analyzed)
+ if (!node->symbol.analyzed)
{
gcc_assert (!in_lto_p || cgraph_function_flags_ready);
/* Compute the alignment early so function body expanders are
already informed about increased alignment. */
align_variable (decl, 0);
}
- if (node->alias && node->alias_of)
+ if (node->symbol.alias && node->alias_of)
{
struct varpool_node *tgt = varpool_node_for_decl (node->alias_of);
struct varpool_node *n;
- for (n = tgt; n && n->alias;
- n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
+ for (n = tgt; n && n->symbol.alias;
+ n = n->symbol.analyzed ? varpool_alias_target (n) : NULL)
if (n == node)
{
error ("variable %q+D part of alias cycle", node->symbol.decl);
- node->alias = false;
+ node->symbol.alias = false;
continue;
}
if (!vec_safe_length (node->symbol.ref_list.references))
@@ -257,8 +265,8 @@ varpool_analyze_node (struct varpool_node *node)
}
}
else if (DECL_INITIAL (decl))
- record_references_in_initializer (decl, node->analyzed);
- node->analyzed = true;
+ record_references_in_initializer (decl, node->symbol.analyzed);
+ node->symbol.analyzed = true;
}
/* Assemble thunks and aliases associated to NODE. */
@@ -287,7 +295,7 @@ varpool_assemble_decl (struct varpool_node *node)
/* Aliases are outout when their target is produced or by
output_weakrefs. */
- if (node->alias)
+ if (node->symbol.alias)
return false;
/* Constant pool is output from RTL land when the reference
@@ -316,7 +324,7 @@ varpool_assemble_decl (struct varpool_node *node)
{
assemble_variable (decl, 0, 1, 0);
gcc_assert (TREE_ASM_WRITTEN (decl));
- node->finalized = 1;
+ node->symbol.definition = true;
assemble_aliases (node);
return true;
}
@@ -357,7 +365,7 @@ varpool_remove_unreferenced_decls (void)
fprintf (cgraph_dump_file, "Trivially needed variables:");
FOR_EACH_DEFINED_VARIABLE (node)
{
- if (node->analyzed
+ if (node->symbol.analyzed
&& (!varpool_can_remove_if_no_refs (node)
/* We just expanded all function bodies. See if any of
them needed the variable. */
@@ -381,7 +389,7 @@ varpool_remove_unreferenced_decls (void)
next = next->symbol.same_comdat_group)
{
varpool_node *vnext = dyn_cast <varpool_node> (next);
- if (vnext && vnext->analyzed)
+ if (vnext && vnext->symbol.analyzed)
enqueue_node (vnext, &first);
}
}
@@ -390,8 +398,8 @@ varpool_remove_unreferenced_decls (void)
varpool_node *vnode = dyn_cast <varpool_node> (ref->referred);
if (vnode
&& (!DECL_EXTERNAL (ref->referred->symbol.decl)
- || vnode->alias)
- && vnode->analyzed)
+ || vnode->symbol.alias)
+ && vnode->symbol.analyzed)
enqueue_node (vnode, &first);
}
}
@@ -419,7 +427,7 @@ void
varpool_finalize_named_section_flags (struct varpool_node *node)
{
if (!TREE_ASM_WRITTEN (node->symbol.decl)
- && !node->alias
+ && !node->symbol.alias
&& !node->symbol.in_other_partition
&& !DECL_EXTERNAL (node->symbol.decl)
&& TREE_CODE (node->symbol.decl) == VAR_DECL
@@ -484,8 +492,8 @@ varpool_create_variable_alias (tree alias, tree decl)
gcc_assert (TREE_CODE (decl) == VAR_DECL);
gcc_assert (TREE_CODE (alias) == VAR_DECL);
alias_node = varpool_node_for_decl (alias);
- alias_node->alias = 1;
- alias_node->finalized = 1;
+ alias_node->symbol.alias = true;
+ alias_node->symbol.definition = true;
alias_node->alias_of = decl;
/* Extra name alias mechanizm creates aliases really late