public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* tree profiling merge: removal of variables whose references was optimized out
@ 2005-03-28 23:01 Jan Hubicka
  2005-04-01  4:48 ` Mark Mitchell
  2005-04-07  4:31 ` James E Wilson
  0 siblings, 2 replies; 7+ messages in thread
From: Jan Hubicka @ 2005-03-28 23:01 UTC (permalink / raw)
  To: gcc-patches

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);
  }

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-03-28 23:01 tree profiling merge: removal of variables whose references was optimized out Jan Hubicka
@ 2005-04-01  4:48 ` Mark Mitchell
  2005-04-01  9:14   ` Jan Hubicka
  2005-04-07  4:31 ` James E Wilson
  1 sibling, 1 reply; 7+ messages in thread
From: Mark Mitchell @ 2005-04-01  4:48 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

Jan Hubicka wrote:
> 
> 	(cp_finish_file): Output variables only in nonunit-at-a-time.

That doesn't make sense any more; the C++ front end is *always* in 
unit-at-a-time mode.  There should be no conditionals on 
flag_unit_at_a_time in the C++ front end.

Please undo this change.

Thanks,

-- 
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
(916) 791-8304

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-04-01  4:48 ` Mark Mitchell
@ 2005-04-01  9:14   ` Jan Hubicka
  0 siblings, 0 replies; 7+ messages in thread
From: Jan Hubicka @ 2005-04-01  9:14 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: Jan Hubicka, gcc-patches

> Jan Hubicka wrote:
> >
> >	(cp_finish_file): Output variables only in nonunit-at-a-time.
> 
> That doesn't make sense any more; the C++ front end is *always* in 
> unit-at-a-time mode.  There should be no conditionals on 
> flag_unit_at_a_time in the C++ front end.
> 
> Please undo this change.

Uh, thanks!
Honza
> 
> Thanks,
> 
> -- 
> Mark Mitchell
> CodeSourcery, LLC
> mark@codesourcery.com
> (916) 791-8304

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-03-28 23:01 tree profiling merge: removal of variables whose references was optimized out Jan Hubicka
  2005-04-01  4:48 ` Mark Mitchell
@ 2005-04-07  4:31 ` James E Wilson
  2005-04-07  7:23   ` Jan Hubicka
  2005-04-08 10:50   ` Jan Hubicka
  1 sibling, 2 replies; 7+ messages in thread
From: James E Wilson @ 2005-04-07  4:31 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

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

This patch was incompletely and/or incorrectly checked in.

The patch removes a hunk of code in final.c, but this code is still in 
mainline.  There could be other problems with this patch.

You really need to audit your patch and your checkin, to make sure you 
checked in the correct patch, and that the ChangeLog entry matches what 
you checked in.

I've also noted this problem in PR 20717, in comment #3.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-04-07  4:31 ` James E Wilson
@ 2005-04-07  7:23   ` Jan Hubicka
  2005-04-07 21:39     ` James E Wilson
  2005-04-08 10:50   ` Jan Hubicka
  1 sibling, 1 reply; 7+ messages in thread
From: Jan Hubicka @ 2005-04-07  7:23 UTC (permalink / raw)
  To: James E Wilson; +Cc: Jan Hubicka, gcc-patches

> Jan Hubicka wrote:
> >	* cgraph.c (cgraph_varpool_node_name): New function.
> >	(dump_cgraph_varpool_node): New function.
> >	(dump_varpool): New function.
> >	* cgraphunit.c (cgraph_optimize): Dump varpool.
> >...
> 
> This patch was incompletely and/or incorrectly checked in.
> 
> The patch removes a hunk of code in final.c, but this code is still in 
> mainline.  There could be other problems with this patch.
> 
> You really need to audit your patch and your checkin, to make sure you 
> checked in the correct patch, and that the ChangeLog entry matches what 
> you checked in.
> 
> I've also noted this problem in PR 20717, in comment #3.

I've just returned from a trip yesterday and I am going to look into
this today.  Sorry for the problems (the commit conflicted with other
aliasing changes), however the changes in final.c should not cause any
important damage - I believe that the IA-64 problem really is the missed
FDESC_EXPR analysis.  Unforutnately my IA-64 bootstrap dies earlier on
abort in cfglayout.c I am looking into now, so I will move to this
problem once this is fixed.

Honza
> -- 
> Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-04-07  7:23   ` Jan Hubicka
@ 2005-04-07 21:39     ` James E Wilson
  0 siblings, 0 replies; 7+ messages in thread
From: James E Wilson @ 2005-04-07 21:39 UTC (permalink / raw)
  To: Jan Hubicka; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1118 bytes --]

On Thu, 2005-04-07 at 00:23, Jan Hubicka wrote:
> important damage - I believe that the IA-64 problem really is the missed
> FDESC_EXPR analysis. 

I agree.  I checked in my FDESC_EXPR patch last night, and forgot to
send it to gcc-patches when I checked it in, so I will include it here.

cgraphunit has code that walks trees, trying to find every reference to
variables/functions, so we can determine which ones need to be output. 
This code handles ADDR_EXPR but not FDESC_EXPR.  Thus targets that
require use of function descriptors when taking the address of a
function are broken, some functions used only by an FDESC_EXPR inside a
vtable initializer are not being output.  Since the first operand of an
FDESC_EXPR is always a function address, just like an ADDR_EXPR, we can
handle them the same in cgraphunit.c.

This was tested with an ia64-linux bootstrap and make check.  It works
nicely with the patch, and doesn't without the patch.  gcc-4.1 ia64 test
results are appearing on the gcc-testsuite mailing list again, after a
week long absence.
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


[-- Attachment #2: patch.cgraph.fdesc --]
[-- Type: text/plain, Size: 623 bytes --]

2005-04-04  James E Wilson  <wilson@specifixinc.com>

	PR target/20717
	* cgraphunit.c (record_call_1, case FDESC_EXPR): Handle same as
	ADDR_EXPR.

Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.99
diff -p -p -r1.99 cgraphunit.c
*** cgraphunit.c	1 Apr 2005 03:42:38 -0000	1.99
--- cgraphunit.c	5 Apr 2005 03:56:29 -0000
*************** record_call_1 (tree *tp, int *walk_subtr
*** 489,494 ****
--- 489,495 ----
  	}
        break;
  
+     case FDESC_EXPR:
      case ADDR_EXPR:
        if (flag_unit_at_a_time)
  	{

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: tree profiling merge: removal of variables whose references was optimized out
  2005-04-07  4:31 ` James E Wilson
  2005-04-07  7:23   ` Jan Hubicka
@ 2005-04-08 10:50   ` Jan Hubicka
  1 sibling, 0 replies; 7+ messages in thread
From: Jan Hubicka @ 2005-04-08 10:50 UTC (permalink / raw)
  To: James E Wilson; +Cc: Jan Hubicka, gcc-patches

> Jan Hubicka wrote:
> >	* cgraph.c (cgraph_varpool_node_name): New function.
> >	(dump_cgraph_varpool_node): New function.
> >	(dump_varpool): New function.
> >	* cgraphunit.c (cgraph_optimize): Dump varpool.
> >...
> 
> This patch was incompletely and/or incorrectly checked in.
> 
> The patch removes a hunk of code in final.c, but this code is still in 
> mainline.  There could be other problems with this patch.
> 
> You really need to audit your patch and your checkin, to make sure you 
> checked in the correct patch, and that the ChangeLog entry matches what 
> you checked in.
> 
> I've also noted this problem in PR 20717, in comment #3.
Hi,
I am going to commit this forgotten hunk of the patch,
bootstrapped&regtested i686-linux.   I am doing tree-profiling merge now
too, so I will check the diff if there is anything else, but it seems to
be fine otherwise.
The change should be perfect noop if everything is working right now
after fix to cgraphunit wrt FDESC.

Honza

*** final.c	Sat Apr  2 21:20:03 2005
--- /aux/hubicka/profiling/gcc/gcc/final.c	Sat Apr  2 22:43:08 2005
*************** output_addr_const (FILE *file, rtx x)
*** 3170,3177 ****
        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
--- 3175,3180 ----

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-04-08 10:50 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-03-28 23:01 tree profiling merge: removal of variables whose references was optimized out Jan Hubicka
2005-04-01  4:48 ` Mark Mitchell
2005-04-01  9:14   ` Jan Hubicka
2005-04-07  4:31 ` James E Wilson
2005-04-07  7:23   ` Jan Hubicka
2005-04-07 21:39     ` James E Wilson
2005-04-08 10:50   ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).