]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* cgraph.h (symtab_node_base): Add definition, alias and analyzed
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 May 2013 20:42:50 +0000 (20:42 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 29 May 2013 20:42:50 +0000 (20:42 +0000)
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

* decl.c (java_mark_decl_local): Update for new symtab flags.

* tree.c (cp_fix_function_decl_p): Update for new symtab flags.
* decl2.c )var_finalized_p, cp_write_global_declarations): Likewise.

* lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab
flags.
* lto-partition.c (get_symbol_class, lto_balanced_map): Likewise.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@199422 138bc75d-0d04-0410-961f-82ee72b054a4

40 files changed:
gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/cgraphunit.c
gcc/config/i386/i386.c
gcc/cp/ChangeLog
gcc/cp/decl2.c
gcc/cp/tree.c
gcc/dbxout.c
gcc/dwarf2out.c
gcc/gimple-fold.c
gcc/ipa-cp.c
gcc/ipa-inline-analysis.c
gcc/ipa-inline-transform.c
gcc/ipa-inline.c
gcc/ipa-prop.c
gcc/ipa-pure-const.c
gcc/ipa-reference.c
gcc/ipa-split.c
gcc/ipa-utils.c
gcc/ipa.c
gcc/java/ChangeLog
gcc/java/decl.c
gcc/lto-cgraph.c
gcc/lto-streamer-out.c
gcc/lto-symtab.c
gcc/lto/ChangeLog
gcc/lto/lto-partition.c
gcc/lto/lto.c
gcc/passes.c
gcc/symtab.c
gcc/toplev.c
gcc/trans-mem.c
gcc/tree-eh.c
gcc/tree-emutls.c
gcc/tree-inline.c
gcc/tree-ssa-structalias.c
gcc/varasm.c
gcc/varpool.c

index e93f2099d40a313d27336bf33ae75c6ebfa37fdd..54f944a50ec2aa987be46515503389765fcc5dad 100644 (file)
@@ -1,3 +1,120 @@
+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.
index 2a2973bc6e444773d9633106cd2b6a57ae1032af..735f48a88910a3cb4daf39066c17f8713e378b44 100644 (file)
@@ -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"
index fcb9261ff62c1e160d190d0ce7b3c9bcfbf28d99..0dcc1a691df644011e31a380e2d9e6004e70ccd9 100644 (file)
@@ -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)
index a002c689db952d67592dbe08b93d5e2b3412e65e..d82eb371798c4e7a333268b2362b2de34e209a60 100644 (file)
@@ -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");
index 6ebf8d4aa062793ad5dbf072b91f42493b07951a..ca314a684763b8951f9fa46d1aa2f1b02f3e92e6 100644 (file)
@@ -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 ();
index a025909ccede3699fb5fdbc4dddc1198e40382c0..9d05a7b4cbdcfd61c192ecc8324ea4cd9c015fbc 100644 (file)
@@ -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;
index ed1d4796624ef9b79a40effc52d665f867470a51..ed26fa0de231a9201dc8eb80788d9c68b83a92c6 100644 (file)
@@ -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
index 8119210fb06a8ea797885020c2abe003ca742e33..409a7436dca74a95b55399e136333a275fd14242 100644 (file)
@@ -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.  */
index 0fbb33d2042dba52397d5df3d7054def733c116d..8524f6cff913451610ae2457f7643c42802ecefa 100644 (file)
@@ -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;
     }
index 4d9fc4ea3e6bed1eeaa6889bbad87e9baff541d8..1cc5d5242057167030f33cb362d944baad2fdae0 100644 (file)
@@ -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 */
index e4a3c075520bd3760c17e55c7ae2081e80e97132..b615b181a3b4da56807d01367cd958fa2616c8a4 100644 (file)
@@ -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.  */
index 1de281a97d5da79a60c57dabe521c2e066d3a6ce..181d28d1b617d969476044e48615a6deb3566f0a 100644 (file)
@@ -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;
index 4bb1754d2b5b20446590b5f93c3dc299e972e3e4..af4e94862d3acefa72a6723f281aa08d83b2033c 100644 (file)
@@ -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;
index c6f127ebbd238e2744ac7816d97e6bcd51058559..a25f51755e3b0b46d3d4f2a955e9c761ce98e1a7 100644 (file)
@@ -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;
index cb819d7cbb2588f1d84bc3e267895035841c2c71..9e131a4aa0e78c9ea428004196fbc4763c0ed711 100644 (file)
@@ -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)
index 35fce6d4a1a541886dc2b5b2add293985b907311..a378c08f42f7ab538377633bb97a3164cdea85f9 100644 (file)
@@ -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);
 
index 7c3987e222e40132ed0ccaa13522b00de6a49bd4..8918c5b3bf5b6159376c71f3d4a9531eaf7a18e1 100644 (file)
@@ -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,
index 0dd68380161b5ae873b6b95f6eeeff45ae080aad..c6c41c6657aec18f77d9c0131071bc3da7c065b0 100644 (file)
@@ -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.  */
index f3c483f67f901516a4b2be65f4cc3af6fde497ba..9c56b7f55180a531622f91e28b23ac3a3866478c 100644 (file)
@@ -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)
index 107c7a90d95fb99cd59d41f2ae33413e08d67fb2..e786478981e43731ed4489a00870b3e94dbefae5 100644 (file)
@@ -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);
index cef67de60761556fe21e7d7e91c6355b95f7c433..00e65285c54cf10273bc414b793eec6f5cc93c27 100644 (file)
@@ -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;
index 5613c26f7fae3f5f88a5d069ef8234b51ecfb192..254c09fa4fb60d30e9be99b234b559714dc909f9 100644 (file)
--- 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;
index 2857b06b400347dafe75d26fabaefb8d99853d9a..82cc49f2e4219b04a72e45082d94862f94b14689 100644 (file)
@@ -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.
index 566435fb9e7f279fcd3826edc2655358ea91650b..c5a654d1c61e0b3a6644460cd1397e18dadf3fde 100644 (file)
@@ -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));
index 34188cbf26f2af0578c6f0a784722efccd572d62..2268f240804c7e734fe02fe22d97d669c5d83a62 100644 (file)
@@ -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;
index dfaf2806b7471d9973436f3df7d6a0205879bc08..5e1a332952cc0c3756977d8b3c54e22abdf57a27 100644 (file)
@@ -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.
index 8091d36193e015dcff8c047972b547ee913dd95b..6c433f427315dfdd677a46f4781cbef6b908c431 100644 (file)
@@ -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;
     }
index 3ea106b85454600b048821367469f91e978f94c6..ded10566313c6318ae558fa064e683dc0b68b998 100644 (file)
@@ -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
index 62341c12c04b87bd0cc98a2e524608dda32a1663..921b4e26e311f4acf189d7d43f87fb9c7a8f882f 100644 (file)
@@ -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
index 09433353e88820f7073d4ca8527b03d988edda3d..f2a59d3bf743c67addb1e4b6c97764d5159c2a87 100644 (file)
@@ -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)
index eccf0b5794db44c86912510c2e953d0edce3a69f..656cf716b6c1784e1769599c820924f5ffe0891a 100644 (file)
@@ -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));
index 56f0de94d9c26ab3ce53f3c5836b1050154ff504..1a7f8262add4df90da8be7a47c7e016cfb9a569c 100644 (file)
@@ -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"
index d41283de93133353b7086269e16064479e3ca3f4..a2ee491309060dd9f0cd66fe69baeff4c2f232d2 100644 (file)
@@ -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;
index c66278c01107fc2d5918a39750d8203355622888..d7e5a40106f6d4f93296069651d00bfb1fd86bb8 100644 (file)
@@ -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)
index fc350bd945f7da9ff5b6ff69fc0a7aa6c5cac8fe..fb80b30a44cb9cb37cd760adf0a6bf408bc91e8c 100644 (file)
@@ -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))
index fc75b3144e394c998e958db7b7f3e44571ba5cdf..9fecb6cb6634e84a325cf69417dc63b2cf773d33 100644 (file)
@@ -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);
     }
 
index 57af7de2c09ecf675be11ad8b61a7b17dac97d50..bee77666497fd68d0ec249b92fd1678b8ee195f3 100644 (file)
@@ -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);
 
index 9eb06f6b09751e47b20065f0ac2694b405cd56f1..1bfe2b2476fbeaa45ea6689ef0dfc37b88ae10ad 100644 (file)
@@ -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);
index 5f62677b2cc79dc8705d0b20eb8be1d2b50a878a..72bff5a8b9a583527773dd4b7668aeb010a56526 100644 (file)
@@ -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)
index e3ad22b1cfdb469432312991cb7b5a3a22180ec3..1916b76d96031d536ba1dc7557f63f9a096140ba 100644 (file)
@@ -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