This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

tree profiling merge: removal of variables whose references was optimized out


Hi,
currently we output all variables early and look back into actual symbol
names output to assembly to discover what functions needs to be output
too.  This sucks and blocks about any IPA working on variables.  THis
patch reorganize the varpool in a way so "needed" variables are
discovered early by walking the variable and function bodies (by same
way as we build cgraph now) and complette list of reachable variables is
constructed.  This list is kept until end of compilation where only the
variables really referenced are output.

This patch also brings us closer to removal of TREE_SYMBOL_REFERNCED
flag.  In current implementation we still use it to discover variables
really referenced but it is pretty straighforward to replace it by
re-walking of optimized bodies just before we go to RTL.  I didn't
implemented it as it only makes compiler slower and less accurate so it
don't seem to be profitable until we really start caring about removing
these beasts (and this patch is nasty enought already)

Patch was bootstrapped/regtested i686-pc-gnu-linux with no measurable
compilation time slowdowns (in fact the times are slightly better, but
in noise factor) and I am testing ppc-linux and checking disabled on
both architectures now too.  In the case these will pass and there will
be no complains, I will commit it tomorrow.

Honza

2004-11-02  Jan Hubicka  <jh@suse.cz>

	* cgraph.c (cgraph_varpool_node_name): New function.
	(dump_cgraph_varpool_node): New function.
	(dump_varpool): New function.
	* cgraphunit.c (cgraph_optimize): Dump varpool.

2004-10-16  Jan Hubicka  <jh@suse.cz>

	* cgraph.c (decide_is_variable_needed): New function.
	(cgraph_varpool_finalize_decl): Use it.
	* cgraphunit.c (cgraph_optimize): Assemble_pending_decls when not doing
	unit-at-a-time.
	* final.c (output_addr_const): Do not call mark_referenced.
	* passes.c (rest_of_decl_compilation): ifdef out DECL_RTL_SET_P hack;
	always go via cgraph.
	* toplev.c (wrapup_global_declarations): Kill non-unit-at-a-time code.
	(check_global_declarations): Ifdef out code clearing DECL_RTL.
	* tree-optimize.c (execute_inline): Mark functions called.
	* i386.c (output_pic_addr_const): Do not call mark_decl_referenced.

2004-10-11  Jan Hubicka  <jh@suse.cz>

	* cgraph.c (cgraph_varpool_first_unanalyzed_node): New global voriable
	(cgraph_varpool_last_needed_node): New static variable.
	(enqueue_needed_varpool_node): Break out from ...; add items to the end of queue;
	update first pointers.
	(cgraph_varpool_mark_needed_node): ... here.
	(cgraph_varpool_finalize_decl): Use enqueue_needed_varpool_node.
	(cgraph_varpool_assemble_pending_decls): Move to cgraphunit.c
	* cgraph.h (cgraph_varpool_node): Add analyzed field.
	(cgraph_varpool_first_unanalyzed_node): Declare.
	* cgraphunit.c: Include output.h.
	(cgraph_varpool_analyze_pending_decls): New function.
	(cgraph_varpool_assemble_pending_decls): Move from cgraph.c; bail out for errors,
	analyze pending decls.
	(cgraph_finalize_compilation_unit): Only analyze decls.
	(cgraph_optimize): Assemble the decls after expanding.

	* decl2.c (finish_objects): Mark ctor as needed.
	(cp_finish_file): Output variables only in nonunit-at-a-time.

	* Make-lang.in (class.o, decl.o): Depend on cgraph.h.
	* class.c: Include cgraph.h
	(make_local_functoin_alias): Mark aslias as needed.
	* resource.c: Include cgraph.h
	(compile_resource_data): Go via cgraph interface.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.68
diff -c -3 -p -r1.68 cgraph.c
*** cgraph.c	20 Mar 2005 15:27:18 -0000	1.68
--- cgraph.c	28 Mar 2005 16:01:57 -0000
*************** The varpool data structure:
*** 84,89 ****
--- 84,90 ----
  #include "coretypes.h"
  #include "tm.h"
  #include "tree.h"
+ #include "tree-inline.h"
  #include "langhooks.h"
  #include "hashtab.h"
  #include "toplev.h"
*************** The varpool data structure:
*** 91,96 ****
--- 92,98 ----
  #include "ggc.h"
  #include "debug.h"
  #include "target.h"
+ #include "basic-block.h"
  #include "cgraph.h"
  #include "varray.h"
  #include "output.h"
*************** int cgraph_max_uid;
*** 118,131 ****
  /* Set when whole unit has been analyzed so we can access global info.  */
  bool cgraph_global_info_ready = false;
  
  /* Hash table used to convert declarations into nodes.  */
  static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
  
  /* Queue of cgraph nodes scheduled to be lowered and output.  */
! struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
  
  /* The linked list of cgraph varpool nodes.  */
! static GTY(())  struct cgraph_varpool_node *cgraph_varpool_nodes;
  
  static hashval_t hash_node (const void *);
  static int eq_node (const void *, const void *);
--- 120,140 ----
  /* Set when whole unit has been analyzed so we can access global info.  */
  bool cgraph_global_info_ready = false;
  
+ /* Set when the cgraph is fully build and the basic flags are computed.  */
+ bool cgraph_function_flags_ready = false;
+ 
  /* Hash table used to convert declarations into nodes.  */
  static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
  
  /* Queue of cgraph nodes scheduled to be lowered and output.  */
! struct cgraph_varpool_node *cgraph_varpool_nodes_queue, *cgraph_varpool_first_unanalyzed_node;
! 
  
  /* The linked list of cgraph varpool nodes.  */
! static GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes;
! 
! /* End of the varpool queue.  Needs to be QTYed to work with PCH.  */
! static GTY(()) struct cgraph_varpool_node *cgraph_varpool_last_needed_node;
  
  static hashval_t hash_node (const void *);
  static int eq_node (const void *, const void *);
*************** cgraph_node_name (struct cgraph_node *no
*** 533,538 ****
--- 542,554 ----
    return lang_hooks.decl_printable_name (node->decl, 2);
  }
  
+ /* Return name of the node used in debug output.  */
+ static const char *
+ cgraph_varpool_node_name (struct cgraph_varpool_node *node)
+ {
+   return lang_hooks.decl_printable_name (node->decl, 2);
+ }
+ 
  /* Dump given cgraph node.  */
  void
  dump_cgraph_node (FILE *f, struct cgraph_node *node)
*************** dump_cgraph (FILE *f)
*** 598,603 ****
--- 614,649 ----
      dump_cgraph_node (f, node);
  }
  
+ /* Dump given cgraph node.  */
+ void
+ dump_cgraph_varpool_node (FILE *f, struct cgraph_varpool_node *node)
+ {
+   fprintf (f, "%s:", cgraph_varpool_node_name (node));
+   if (DECL_INITIAL (node->decl))
+     fprintf (f, " initialized");
+   if (node->needed)
+     fprintf (f, " needed");
+   if (node->analyzed)
+     fprintf (f, " analyzed");
+   if (node->finalized)
+     fprintf (f, " finalized");
+   if (node->output)
+     fprintf (f, " output");
+   fprintf (f, "\n");
+ }
+ 
+ /* Dump the callgraph.  */
+ 
+ void
+ dump_varpool (FILE *f)
+ {
+   struct cgraph_varpool_node *node;
+ 
+   fprintf (f, "variable pool:\n\n");
+   for (node = cgraph_varpool_nodes; node; node = node->next_needed)
+     dump_cgraph_varpool_node (f, node);
+ }
+ 
  /* Returns a hash code for P.  */
  
  static hashval_t
*************** change_decl_assembler_name (tree decl, t
*** 671,690 ****
    SET_DECL_ASSEMBLER_NAME (decl, name);
  }
  
  /* Notify finalize_compilation_unit that given node is reachable
     or needed.  */
  void
  cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
  {
    if (!node->needed && node->finalized)
!     {
!       node->next_needed = cgraph_varpool_nodes_queue;
!       cgraph_varpool_nodes_queue = node;
!       notice_global_symbol (node->decl);
!     }
    node->needed = 1;
  }
  
  void
  cgraph_varpool_finalize_decl (tree decl)
  {
--- 717,798 ----
    SET_DECL_ASSEMBLER_NAME (decl, name);
  }
  
+ /* Helper function for finalization code - add node into lists so it will
+    be analyzed and compiled.  */
+ void
+ cgraph_varpool_enqueue_needed_node (struct cgraph_varpool_node *node)
+ {
+   if (cgraph_varpool_last_needed_node)
+     cgraph_varpool_last_needed_node->next_needed = node;
+   cgraph_varpool_last_needed_node = node;
+   node->next_needed = NULL;
+   if (!cgraph_varpool_nodes_queue)
+     cgraph_varpool_nodes_queue = node;
+   if (!cgraph_varpool_first_unanalyzed_node)
+     cgraph_varpool_first_unanalyzed_node = node;
+   notice_global_symbol (node->decl);
+ }
+ 
+ /* Reset the queue of needed nodes.  */
+ void
+ cgraph_varpool_reset_queue (void)
+ {
+   cgraph_varpool_last_needed_node = NULL;
+   cgraph_varpool_nodes_queue = NULL;
+   cgraph_varpool_first_unanalyzed_node = NULL;
+ }
+ 
  /* Notify finalize_compilation_unit that given node is reachable
     or needed.  */
  void
  cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
  {
    if (!node->needed && node->finalized)
!     cgraph_varpool_enqueue_needed_node (node);
    node->needed = 1;
  }
  
+ /* Determine if variable DECL is needed.  That is, visible to something
+    either outside this translation unit, something magic in the system
+    configury, or (if not doing unit-at-a-time) to something we haven't
+    seen yet.  */
+ 
+ static bool
+ decide_is_variable_needed (struct cgraph_varpool_node *node, tree decl)
+ {
+   /* If the user told us it is used, then it must be so.  */
+   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+     return true;
+ 
+   /* ??? If the assembler name is set by hand, it is possible to assemble
+      the name later after finalizing the function and the fact is noticed
+      in assemble_name then.  This is arguably a bug.  */
+   if (DECL_ASSEMBLER_NAME_SET_P (decl)
+       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
+     return true;
+ 
+   /* If we decided it was needed before, but at the time we didn't have
+      the definition available, then it's still needed.  */
+   if (node->needed)
+     return true;
+ 
+   /* Externally visible functions must be output.  The exception is
+      COMDAT functions that must be output only when they are needed.  */
+   if (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
+     return true;
+ 
+   if (flag_unit_at_a_time)
+     return false;
+ 
+   /* If not doing unit at a time, then we'll only defer this function
+      if its marked for inlining.  Otherwise we want to emit it now.  */
+ 
+   /* We want to emit COMDAT variables only when absolutely necessary.  */
+   if (DECL_COMDAT (decl))
+     return false;
+   return true;
+ }
+ 
  void
  cgraph_varpool_finalize_decl (tree decl)
  {
*************** cgraph_varpool_finalize_decl (tree decl)
*** 695,742 ****
       or local (in C, has internal linkage).  So do nothing more
       if this function has already run.  */
    if (node->finalized)
-     return;
-   if (node->needed)
      {
!       node->next_needed = cgraph_varpool_nodes_queue;
!       cgraph_varpool_nodes_queue = node;
!       notice_global_symbol (decl);
      }
    node->finalized = true;
  
!   if (/* Externally visible variables must be output.  The exception are
! 	 COMDAT functions that must be output only when they are needed.  */
!       (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
!       /* Function whose name is output to the assembler file must be produced.
! 	 It is possible to assemble the name later after finalizing the function
! 	 and the fact is noticed in assemble_name then.  */
!       || (DECL_ASSEMBLER_NAME_SET_P (decl)
! 	  && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
!     {
!       cgraph_varpool_mark_needed_node (node);
!     }
  }
  
- bool
- cgraph_varpool_assemble_pending_decls (void)
- {
-   bool changed = false;
- 
-   while (cgraph_varpool_nodes_queue)
-     {
-       tree decl = cgraph_varpool_nodes_queue->decl;
-       struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
- 
-       cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
-       if (!TREE_ASM_WRITTEN (decl))
- 	{
- 	  assemble_variable (decl, 0, 1, 0);
- 	  changed = true;
- 	}
-       node->next_needed = NULL;
-     }
-   return changed;
- }
  
  /* Return true when the DECL can possibly be inlined.  */
  bool
--- 803,823 ----
       or local (in C, has internal linkage).  So do nothing more
       if this function has already run.  */
    if (node->finalized)
      {
!       if (cgraph_global_info_ready || !flag_unit_at_a_time)
! 	cgraph_varpool_assemble_pending_decls ();
!       return;
      }
+   if (node->needed)
+     cgraph_varpool_enqueue_needed_node (node);
    node->finalized = true;
  
!   if (decide_is_variable_needed (node, decl))
!     cgraph_varpool_mark_needed_node (node);
!   if (cgraph_global_info_ready || !flag_unit_at_a_time)
!     cgraph_varpool_assemble_pending_decls ();
  }
  
  
  /* Return true when the DECL can possibly be inlined.  */
  bool
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.46
diff -c -3 -p -r1.46 cgraph.h
*** cgraph.h	20 Mar 2005 15:27:18 -0000	1.46
--- cgraph.h	28 Mar 2005 16:01:57 -0000
*************** struct cgraph_varpool_node GTY(())
*** 149,154 ****
--- 149,157 ----
    /* Set when function must be output - it is externally visible
       or its address is taken.  */
    bool needed;
+   /* Set once the variable has been instantiated and its callee
+      lists created.  */
+   bool analyzed;
    /* Set once it has been finalized so we consider it to be output.  */
    bool finalized;
    /* Set when function is scheduled to be assembled.  */
*************** extern GTY(()) int cgraph_max_uid;
*** 161,171 ****
--- 164,177 ----
  extern bool cgraph_global_info_ready;
  extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
  
+ extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
  extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
  
  /* In cgraph.c  */
  void dump_cgraph (FILE *);
  void dump_cgraph_node (FILE *, struct cgraph_node *);
+ void dump_varpool (FILE *);
+ void dump_cgraph_varpool_node (FILE *, struct cgraph_varpool_node *);
  void cgraph_remove_edge (struct cgraph_edge *);
  void cgraph_remove_node (struct cgraph_node *);
  void cgraph_node_remove_callees (struct cgraph_node *node);
*************** struct cgraph_varpool_node *cgraph_varpo
*** 186,199 ****
  struct cgraph_varpool_node *cgraph_varpool_node_for_asm (tree asmname);
  void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
  void cgraph_varpool_finalize_decl (tree);
- bool cgraph_varpool_assemble_pending_decls (void);
  void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
  
  bool cgraph_function_possibly_inlined_p (tree);
  void cgraph_unnest_node (struct cgraph_node *node);
  
  /* In cgraphunit.c  */
  bool cgraph_assemble_pending_functions (void);
  void cgraph_finalize_function (tree, bool);
  void cgraph_finalize_compilation_unit (void);
  void cgraph_create_edges (struct cgraph_node *, tree);
--- 192,207 ----
  struct cgraph_varpool_node *cgraph_varpool_node_for_asm (tree asmname);
  void cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *);
  void cgraph_varpool_finalize_decl (tree);
  void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
  
  bool cgraph_function_possibly_inlined_p (tree);
  void cgraph_unnest_node (struct cgraph_node *node);
+ void cgraph_varpool_enqueue_needed_node (struct cgraph_varpool_node *);
+ void cgraph_varpool_reset_queue (void);
  
  /* In cgraphunit.c  */
  bool cgraph_assemble_pending_functions (void);
+ bool cgraph_varpool_assemble_pending_decls (void);
  void cgraph_finalize_function (tree, bool);
  void cgraph_finalize_compilation_unit (void);
  void cgraph_create_edges (struct cgraph_node *, tree);
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.96
diff -c -3 -p -r1.96 cgraphunit.c
*** cgraphunit.c	22 Mar 2005 20:53:22 -0000	1.96
--- cgraphunit.c	28 Mar 2005 16:01:57 -0000
*************** Software Foundation, 59 Temple Place - S
*** 189,194 ****
--- 189,195 ----
  #include "intl.h"
  #include "function.h"
  #include "tree-gimple.h"
+ #include "output.h"
  
  #define INSNS_PER_CALL 10
  
*************** record_call_1 (tree *tp, int *walk_subtr
*** 419,425 ****
        /* ??? Really, we should mark this decl as *potentially* referenced
  	 by this function and re-examine whether the decl is actually used
  	 after rtl has been generated.  */
!       if (TREE_STATIC (t))
  	{
  	  cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
  	  if (lang_hooks.callgraph.analyze_expr)
--- 420,426 ----
        /* ??? Really, we should mark this decl as *potentially* referenced
  	 by this function and re-examine whether the decl is actually used
  	 after rtl has been generated.  */
!       if (TREE_STATIC (t) || DECL_EXTERNAL (t))
  	{
  	  cgraph_varpool_mark_needed_node (cgraph_varpool_node (t));
  	  if (lang_hooks.callgraph.analyze_expr)
*************** verify_cgraph (void)
*** 637,642 ****
--- 638,697 ----
      verify_cgraph_node (node);
  }
  
+ /* Walk the decls we marked as neccesary and see if they reference new variables
+    or functions and add them into the worklists.  */
+ static bool
+ cgraph_varpool_analyze_pending_decls (void)
+ {
+   bool changed = false;
+   timevar_push (TV_CGRAPH);
+ 
+   while (cgraph_varpool_first_unanalyzed_node)
+     {
+       tree decl = cgraph_varpool_first_unanalyzed_node->decl;
+ 
+       cgraph_varpool_first_unanalyzed_node->analyzed = true;
+ 
+       cgraph_varpool_first_unanalyzed_node = cgraph_varpool_first_unanalyzed_node->next_needed;
+ 
+       if (DECL_INITIAL (decl))
+ 	cgraph_create_edges (NULL, DECL_INITIAL (decl));
+       changed = true;
+     }
+   timevar_pop (TV_CGRAPH);
+   return changed;
+ }
+ 
+ /* Output all variables enqueued to be assembled.  */
+ bool
+ cgraph_varpool_assemble_pending_decls (void)
+ {
+   bool changed = false;
+ 
+   if (errorcount || sorrycount)
+     return false;
+  
+   /* EH might mark decls as needed during expansion.  This should be safe since
+      we don't create references to new function, but it should not be used
+      elsewhere.  */
+   cgraph_varpool_analyze_pending_decls ();
+ 
+   while (cgraph_varpool_nodes_queue)
+     {
+       tree decl = cgraph_varpool_nodes_queue->decl;
+       struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
+ 
+       cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
+       if (!TREE_ASM_WRITTEN (decl) && !DECL_EXTERNAL (decl))
+ 	{
+ 	  assemble_variable (decl, 0, 1, 0);
+ 	  changed = true;
+ 	}
+       node->next_needed = NULL;
+     }
+   return changed;
+ }
+ 
  /* Analyze the function scheduled to be output.  */
  static void
  cgraph_analyze_function (struct cgraph_node *node)
*************** void
*** 679,684 ****
--- 734,742 ----
  cgraph_finalize_compilation_unit (void)
  {
    struct cgraph_node *node;
+   /* Keep track of already processed nodes when called multiple times for
+      intermodule optmization.  */
+   static struct cgraph_node *first_analyzed;
  
    finish_aliases_1 ();
  
*************** cgraph_finalize_compilation_unit (void)
*** 688,702 ****
        return;
      }
  
-   cgraph_varpool_assemble_pending_decls ();
    if (!quiet_flag)
!     fprintf (stderr, "\nAnalyzing compilation unit\n");
  
    timevar_push (TV_CGRAPH);
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "Initial entry points:");
!       for (node = cgraph_nodes; node; node = node->next)
  	if (node->needed && DECL_SAVED_TREE (node->decl))
  	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
        fprintf (cgraph_dump_file, "\n");
--- 746,763 ----
        return;
      }
  
    if (!quiet_flag)
!     {
!       fprintf (stderr, "\nAnalyzing compilation unit");
!       fflush (stderr);
!     }
  
    timevar_push (TV_CGRAPH);
+   cgraph_varpool_analyze_pending_decls ();
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "Initial entry points:");
!       for (node = cgraph_nodes; node != first_analyzed; node = node->next)
  	if (node->needed && DECL_SAVED_TREE (node->decl))
  	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
        fprintf (cgraph_dump_file, "\n");
*************** cgraph_finalize_compilation_unit (void)
*** 730,736 ****
  	if (!edge->callee->reachable)
  	  cgraph_mark_reachable_node (edge->callee);
  
!       cgraph_varpool_assemble_pending_decls ();
      }
  
    /* Collect entry points to the unit.  */
--- 791,797 ----
  	if (!edge->callee->reachable)
  	  cgraph_mark_reachable_node (edge->callee);
  
!       cgraph_varpool_analyze_pending_decls ();
      }
  
    /* Collect entry points to the unit.  */
*************** cgraph_finalize_compilation_unit (void)
*** 738,744 ****
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "Unit entry points:");
!       for (node = cgraph_nodes; node; node = node->next)
  	if (node->needed && DECL_SAVED_TREE (node->decl))
  	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
        fprintf (cgraph_dump_file, "\n\nInitial ");
--- 799,805 ----
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "Unit entry points:");
!       for (node = cgraph_nodes; node != first_analyzed; node = node->next)
  	if (node->needed && DECL_SAVED_TREE (node->decl))
  	  fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
        fprintf (cgraph_dump_file, "\n\nInitial ");
*************** cgraph_finalize_compilation_unit (void)
*** 748,754 ****
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nReclaiming functions:");
  
!   for (node = cgraph_nodes; node; node = node->next)
      {
        tree decl = node->decl;
  
--- 809,815 ----
    if (cgraph_dump_file)
      fprintf (cgraph_dump_file, "\nReclaiming functions:");
  
!   for (node = cgraph_nodes; node != first_analyzed; node = node->next)
      {
        tree decl = node->decl;
  
*************** cgraph_finalize_compilation_unit (void)
*** 766,771 ****
--- 827,833 ----
        fprintf (cgraph_dump_file, "\n\nReclaimed ");
        dump_cgraph (cgraph_dump_file);
      }
+   first_analyzed = cgraph_nodes;
    ggc_collect ();
    timevar_pop (TV_CGRAPH);
  }
*************** cgraph_optimize (void)
*** 1764,1772 ****
    verify_cgraph ();
  #endif
    if (!flag_unit_at_a_time)
!     return;
  
    process_pending_assemble_externals ();
  
    timevar_push (TV_CGRAPHOPT);
    if (!quiet_flag)
--- 1826,1840 ----
    verify_cgraph ();
  #endif
    if (!flag_unit_at_a_time)
!     {
!       cgraph_varpool_assemble_pending_decls ();
!       return;
!     }
  
    process_pending_assemble_externals ();
+   /* Frontend may output common variables after the unit has been finalized.
+      It is safe to deal with them here as they are always zero initialized.  */
+   cgraph_varpool_analyze_pending_decls ();
  
    timevar_push (TV_CGRAPHOPT);
    if (!quiet_flag)
*************** cgraph_optimize (void)
*** 1799,1804 ****
--- 1867,1875 ----
    cgraph_mark_functions_to_output ();
    
    cgraph_expand_all_functions ();
+ 
+   cgraph_varpool_assemble_pending_decls ();
+ 
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "\nFinal ");
Index: final.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/final.c,v
retrieving revision 1.346
diff -c -3 -p -r1.346 final.c
*** final.c	23 Mar 2005 15:59:38 -0000	1.346
--- final.c	28 Mar 2005 16:01:58 -0000
*************** output_addr_const (FILE *file, rtx x)
*** 3249,3256 ****
        break;
  
      case SYMBOL_REF:
-       if (SYMBOL_REF_DECL (x))
- 	mark_decl_referenced (SYMBOL_REF_DECL (x));
  #ifdef ASM_OUTPUT_SYMBOL_REF
        ASM_OUTPUT_SYMBOL_REF (file, x);
  #else
--- 3249,3254 ----
Index: passes.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/passes.c,v
retrieving revision 2.75
diff -c -3 -p -r2.75 passes.c
*** passes.c	21 Mar 2005 18:49:23 -0000	2.75
--- passes.c	28 Mar 2005 16:01:58 -0000
*************** rest_of_decl_compilation (tree decl,
*** 225,231 ****
  	 (see gcc.c-torture/compile/920624-1.c) */
        if ((at_end
  	   || !DECL_DEFER_OUTPUT (decl)
! 	   || (flag_unit_at_a_time && DECL_INITIAL (decl)))
  	  && !DECL_EXTERNAL (decl))
  	{
  	  if (flag_unit_at_a_time && !cgraph_global_info_ready
--- 225,231 ----
  	 (see gcc.c-torture/compile/920624-1.c) */
        if ((at_end
  	   || !DECL_DEFER_OUTPUT (decl)
! 	   || DECL_INITIAL (decl))
  	  && !DECL_EXTERNAL (decl))
  	{
  	  if (flag_unit_at_a_time && !cgraph_global_info_ready
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/toplev.c,v
retrieving revision 1.947
diff -c -3 -p -r1.947 toplev.c
*** toplev.c	16 Mar 2005 17:14:56 -0000	1.947
--- toplev.c	28 Mar 2005 16:01:58 -0000
*************** wrapup_global_declarations (tree *vec, i
*** 781,789 ****
  	      bool needed = 1;
  	      node = cgraph_varpool_node (decl);
  
! 	      if (flag_unit_at_a_time && node->finalized)
  		needed = 0;
! 	      else if ((flag_unit_at_a_time && !cgraph_global_info_ready)
  		       && (TREE_USED (decl)
  			   || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
  		/* needed */;
--- 781,789 ----
  	      bool needed = 1;
  	      node = cgraph_varpool_node (decl);
  
! 	      if (node->finalized)
  		needed = 0;
! 	      else if (!cgraph_global_info_ready
  		       && (TREE_USED (decl)
  			   || TREE_USED (DECL_ASSEMBLER_NAME (decl))))
  		/* needed */;
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 2.78
diff -c -3 -p -r2.78 tree-optimize.c
*** tree-optimize.c	13 Mar 2005 00:45:52 -0000	2.78
--- tree-optimize.c	28 Mar 2005 16:01:58 -0000
*************** tree_rest_of_compilation (tree fndecl)
*** 660,665 ****
--- 660,675 ----
  	  timevar_pop (TV_INTEGRATION);
  	}
      }
+   /* We are not going to maintain the cgraph edges up to date.
+      Kill it so it won't confuse us.  */
+   while (node->callees)
+     {
+       /* In non-unit-at-a-time we must mark all referenced functions as needed.
+          */
+       if (node->callees->callee->analyzed && !flag_unit_at_a_time)
+         cgraph_mark_needed_node (node->callees->callee);
+       cgraph_remove_edge (node->callees);
+     }
  
    /* We are not going to maintain the cgraph edges up to date.
       Kill it so it won't confuse us.  */
Index: config/i386/i386.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.c,v
retrieving revision 1.799
diff -c -3 -p -r1.799 i386.c
*** config/i386/i386.c	23 Mar 2005 03:55:32 -0000	1.799
--- config/i386/i386.c	28 Mar 2005 16:02:00 -0000
*************** output_pic_addr_const (FILE *file, rtx x
*** 5889,5898 ****
        break;
  
      case SYMBOL_REF:
-      /* Mark the decl as referenced so that cgraph will output the function.  */
-      if (SYMBOL_REF_DECL (x))
-        mark_decl_referenced (SYMBOL_REF_DECL (x));
- 
        assemble_name (file, XSTR (x, 0));
        if (!TARGET_MACHO && code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
  	fputs ("@PLT", file);
--- 5889,5894 ----
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.770
diff -c -3 -p -r1.770 decl2.c
*** cp/decl2.c	24 Feb 2005 21:55:14 -0000	1.770
--- cp/decl2.c	28 Mar 2005 16:02:01 -0000
*************** finish_objects (int method_type, int ini
*** 2110,2115 ****
--- 2110,2116 ----
    if (targetm.have_ctors_dtors)
      {
        rtx fnsym = XEXP (DECL_RTL (fn), 0);
+       cgraph_mark_needed_node (cgraph_node (fn));
        if (method_type == 'I')
  	(* targetm.asm_out.constructor) (fnsym, initp);
        else
*************** cp_finish_file (void)
*** 2959,2967 ****
        /* Ask the back end to emit functions and variables that are
  	 enqueued.  These emissions may result in marking more entities
  	 as needed.  */
!       if (cgraph_assemble_pending_functions ())
  	reconsider = true;
!       if (cgraph_varpool_assemble_pending_decls ())
  	reconsider = true;
  
        retries++;
--- 2960,2968 ----
        /* Ask the back end to emit functions and variables that are
  	 enqueued.  These emissions may result in marking more entities
  	 as needed.  */
!       if (!flag_unit_at_a_time && cgraph_assemble_pending_functions ())
  	reconsider = true;
!       if (!flag_unit_at_a_time && cgraph_varpool_assemble_pending_decls ())
  	reconsider = true;
  
        retries++;
Index: java/Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.155
diff -c -3 -p -r1.155 Make-lang.in
*** java/Make-lang.in	16 Mar 2005 06:03:57 -0000	1.155
--- java/Make-lang.in	28 Mar 2005 16:02:01 -0000
*************** java/check-init.o: java/check-init.c $(C
*** 299,311 ****
    coretypes.h $(TM_H) toplev.h
  java/class.o: java/class.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(JAVA_TREE_H) $(RTL_H) java/jcf.h java/parse.h toplev.h output.h $(GGC_H) \
!   $(TARGET_H) function.h gt-java-class.h
  java/constants.o: java/constants.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
    toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-constants.h
  java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
    toplev.h flags.h $(SYSTEM_H) coretypes.h $(TM_H) function.h expr.h \
    libfuncs.h except.h java/java-except.h $(GGC_H) real.h gt-java-decl.h \
!   target.h
  java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
    $(RTL_H) java/javaop.h java/java-opcodes.h except.h java/java-except.h \
    toplev.h $(SYSTEM_H) coretypes.h $(TM_H) function.h 
--- 299,311 ----
    coretypes.h $(TM_H) toplev.h
  java/class.o: java/class.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(JAVA_TREE_H) $(RTL_H) java/jcf.h java/parse.h toplev.h output.h $(GGC_H) \
!   $(TARGET_H) function.h gt-java-class.h cgraph.h
  java/constants.o: java/constants.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h \
    toplev.h $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) gt-java-constants.h
  java/decl.o: java/decl.c $(CONFIG_H) $(JAVA_TREE_H) $(RTL_H) java/jcf.h \
    toplev.h flags.h $(SYSTEM_H) coretypes.h $(TM_H) function.h expr.h \
    libfuncs.h except.h java/java-except.h $(GGC_H) real.h gt-java-decl.h \
!   target.h cgraph.h
  java/except.o: java/except.c $(CONFIG_H) $(JAVA_TREE_H) java/jcf.h real.h \
    $(RTL_H) java/javaop.h java/java-opcodes.h except.h java/java-except.h \
    toplev.h $(SYSTEM_H) coretypes.h $(TM_H) function.h 
Index: java/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/class.c,v
retrieving revision 1.221
diff -c -3 -p -r1.221 class.c
*** java/class.c	4 Mar 2005 15:38:13 -0000	1.221
--- java/class.c	28 Mar 2005 16:02:02 -0000
*************** The Free Software Foundation is independ
*** 45,50 ****
--- 45,51 ----
  #include "except.h"
  #include "cgraph.h"
  #include "tree-iterator.h"
+ #include "cgraph.h"
  
  /* DOS brain-damage */
  #ifndef O_BINARY
*************** emit_register_classes (tree *list_p)
*** 2436,2443 ****
        named_section_flags (JCR_SECTION_NAME, SECTION_WRITE);
        assemble_align (POINTER_SIZE);
        for (t = registered_class; t; t = TREE_CHAIN (t))
! 	assemble_integer (XEXP (DECL_RTL (t), 0),
! 			  POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
  #else
        /* A target has defined TARGET_USE_JCR_SECTION, but doesn't have a
  	 JCR_SECTION_NAME.  */
--- 2437,2447 ----
        named_section_flags (JCR_SECTION_NAME, SECTION_WRITE);
        assemble_align (POINTER_SIZE);
        for (t = registered_class; t; t = TREE_CHAIN (t))
! 	{
! 	  mark_decl_referenced (t);
! 	  assemble_integer (XEXP (DECL_RTL (t), 0),
! 			    POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
! 	}
  #else
        /* A target has defined TARGET_USE_JCR_SECTION, but doesn't have a
  	 JCR_SECTION_NAME.  */
Index: java/resource.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/resource.c,v
retrieving revision 1.18
diff -c -3 -p -r1.18 resource.c
*** java/resource.c	15 Oct 2004 14:55:00 -0000	1.18
--- java/resource.c	28 Mar 2005 16:02:02 -0000
*************** The Free Software Foundation is independ
*** 42,47 ****
--- 42,48 ----
  #include "target.h"
  #include "expr.h"
  #include "tree-iterator.h"
+ #include "cgraph.h"
  
  /* DOS brain-damage */
  #ifndef O_BINARY
*************** compile_resource_data (const char *name,
*** 93,99 ****
    pushdecl (decl);
    rest_of_decl_compilation (decl, global_bindings_p (), 0);
    make_decl_rtl (decl);
!   assemble_variable (decl, 1, 0, 0);
  
    resources = tree_cons (NULL_TREE, decl, resources);
  }
--- 94,100 ----
    pushdecl (decl);
    rest_of_decl_compilation (decl, global_bindings_p (), 0);
    make_decl_rtl (decl);
!   cgraph_varpool_finalize_decl (decl);
  
    resources = tree_cons (NULL_TREE, decl, resources);
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]