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]

Stripped down unit-at-a-time fix


Hi,
The unit-at-a-time fix patch I sent contained some code that is not
needed with my new C++ patch (especially function collecting hook).  It
also handled DECL_DEFER_OUTPUT in somewhat funny semantics.  This patch
removes these parts and merely fixes handling of constructor and adds
extra flexibility to the marking code so varpool output can happen
during lowering stage.

Regtested/bootstrapped i386.  OK?
Honza

Mon May 19 22:33:55 CEST 2003  Jan Hubicka  <jh@suse.cz>

	* cgraph.c (cgraph_nodes_queue): Declare.
	(eq_node): Take identifier as p2.
	(cgraph_node): Update htab_find_slot_with_hash call.
	(cgraph_node_for_identifier): New.
	(cgraph_mark_needed_node): Move here from cgraphunit.c.
	* cgraph.h (cgraph_nodes_queue): Declare.
	(cgraph_node_for_identifier): Declare.
	* cgraphunit.c (cgraph_finalize_function): Collect entry points here
	instead of in cgraph_finalize_compilation_unit; constructors and
	destructors are entry points.
	(cgraph_finalize_compilation_unit): Reorganize debug outout; 
	examine nested functions after lowerng; call collect_functions hook.
	(cgraph_mark_local_functions): DECL_COMDAT functions are not local.
	(cgraph_finalize_compilation_unit): Do not collect entry points.
	* varasm.c: Include cgraph.h
	(assemble_name): Mark referenced identifier as needed.

diff -Nrc3p gcc.tmp/cgraph.c gcc/cgraph.c
*** gcc.tmp/cgraph.c	Sun Jun 22 01:50:19 2003
--- gcc/cgraph.c	Fri Jun 20 23:09:59 2003
*************** static htab_t cgraph_hash = 0;
*** 48,53 ****
--- 48,56 ----
  /* The linked list of cgraph nodes.  */
  struct cgraph_node *cgraph_nodes;
  
+ /* Queue of cgraph nodes scheduled to be lowered.  */
+ struct cgraph_node *cgraph_nodes_queue;
+ 
  /* Number of nodes in existence.  */
  int cgraph_n_nodes;
  
*************** eq_node (p1, p2)
*** 79,85 ****
       const PTR p2;
  {
    return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
! 	  DECL_ASSEMBLER_NAME ((tree) p2));
  }
  
  /* Return cgraph node assigned to DECL.  Create new one when needed.  */
--- 82,88 ----
       const PTR p2;
  {
    return ((DECL_ASSEMBLER_NAME (((struct cgraph_node *) p1)->decl)) ==
! 	  (tree) p2);
  }
  
  /* Return cgraph node assigned to DECL.  Create new one when needed.  */
*************** cgraph_node (decl)
*** 100,106 ****
      }
  
    slot =
!     (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash, decl,
  						      htab_hash_pointer
  						      (DECL_ASSEMBLER_NAME
  						       (decl)), 1);
--- 103,110 ----
      }
  
    slot =
!     (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash,
! 						      DECL_ASSEMBLER_NAME (decl),
  						      htab_hash_pointer
  						      (DECL_ASSEMBLER_NAME
  						       (decl)), 1);
*************** cgraph_node (decl)
*** 125,130 ****
--- 129,158 ----
    return node;
  }
  
+ /* Try to find existing function for identifier ID.  */
+ struct cgraph_node *
+ cgraph_node_for_identifier (id)
+      tree id;
+ {
+   struct cgraph_node **slot;
+ 
+   if (TREE_CODE (id) != IDENTIFIER_NODE)
+     abort ();
+ 
+   if (!cgraph_hash)
+     {
+       cgraph_hash = htab_create (10, hash_node, eq_node, NULL);
+       VARRAY_TREE_INIT (known_fns, 32, "known_fns");
+     }
+ 
+   slot =
+     (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash, id,
+ 						      htab_hash_pointer (id), 0);
+   if (!slot)
+     return NULL;
+   return *slot;
+ }
+ 
  /* Create edge from CALLER to CALLEE in the cgraph.  */
  
  static struct cgraph_edge *
*************** cgraph_remove_node (node)
*** 194,199 ****
--- 222,249 ----
    /* Do not free the structure itself so the walk over chain can continue.  */
  }
  
+ /* Notify finalize_compilation_unit that given node is reachable
+    or needed.  */
+ void
+ cgraph_mark_needed_node (node, needed)
+      struct cgraph_node *node;
+      int needed;
+ {
+   if (needed)
+     {
+       node->needed = 1;
+     }
+   if (!node->reachable)
+     {
+       node->reachable = 1;
+       if (DECL_SAVED_TREE (node->decl))
+ 	{
+ 	  node->aux = cgraph_nodes_queue;
+ 	  cgraph_nodes_queue = node;
+         }
+     }
+ }
+ 
  
  /* Record call from CALLER to CALLEE  */
  
diff -Nrc3p gcc.tmp/cgraph.h gcc/cgraph.h
*** gcc.tmp/cgraph.h	Sun Jun 22 01:50:19 2003
--- gcc/cgraph.h	Fri Jun 20 23:09:59 2003
*************** struct cgraph_edge
*** 100,105 ****
--- 100,106 ----
  extern struct cgraph_node *cgraph_nodes;
  extern int cgraph_n_nodes;
  extern bool cgraph_global_info_ready;
+ extern struct cgraph_node *cgraph_nodes_queue;
  
  /* In cgraph.c  */
  void dump_cgraph			PARAMS ((FILE *));
*************** void cgraph_remove_call			PARAMS ((tree,
*** 107,112 ****
--- 108,114 ----
  void cgraph_remove_node			PARAMS ((struct cgraph_node *));
  struct cgraph_edge *cgraph_record_call	PARAMS ((tree, tree));
  struct cgraph_node *cgraph_node		PARAMS ((tree decl));
+ struct cgraph_node *cgraph_node_for_identifier	PARAMS ((tree id));
  bool cgraph_calls_p			PARAMS ((tree, tree));
  struct cgraph_local_info *cgraph_local_info PARAMS ((tree));
  struct cgraph_global_info *cgraph_global_info PARAMS ((tree));
diff -Nrc3p gcc.tmp/cgraphunit.c gcc/cgraphunit.c
*** gcc.tmp/cgraphunit.c	Sun Jun 22 01:50:19 2003
--- gcc/cgraphunit.c	Sun Jun 22 02:02:21 2003
*************** cgraph_finalize_function (decl, body)
*** 55,61 ****
  
    node->decl = decl;
  
!   node->local.can_inline_once = tree_inlinable_function_p (decl, 1);
    if (flag_inline_trees)
      node->local.inline_many = tree_inlinable_function_p (decl, 0);
    else
--- 56,84 ----
  
    node->decl = decl;
  
!   if (/* Externally visible functions must be output.  The exception are
! 	 COMDAT functions that must be output only when they are needed.
! 	 Similarly are handled defered functions and
! 	 external functions (GCC extension "extern inline") */
!       (TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
!       /* ??? Constructors and destructors not called otherwise can be inlined
! 	 into single construction/destruction function per section to save some
! 	 resources.  For now just mark it as reachable.  */
!       || DECL_STATIC_CONSTRUCTOR (decl)
!       || DECL_STATIC_DESTRUCTOR (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_mark_needed_node (node, 1);
!     }
! 
!   if (!node->needed && !DECL_COMDAT (node->decl))
!     node->local.can_inline_once = tree_inlinable_function_p (decl, 1);
!   else
!     node->local.can_inline_once = 0;
    if (flag_inline_trees)
      node->local.inline_many = tree_inlinable_function_p (decl, 0);
    else
*************** cgraph_finalize_function (decl, body)
*** 64,96 ****
    (*debug_hooks->deferred_inline_function) (decl);
  }
  
- static struct cgraph_node *queue = NULL;
- 
- /* Notify finalize_compilation_unit that given node is reachable
-    or needed.  */
- 
- void
- cgraph_mark_needed_node (node, needed)
-      struct cgraph_node *node;
-      int needed;
- {
-   if (needed)
-     {
-       if (DECL_SAVED_TREE (node->decl))
-         announce_function (node->decl);
-       node->needed = 1;
-     }
-   if (!node->reachable)
-     {
-       node->reachable = 1;
-       if (DECL_SAVED_TREE (node->decl))
- 	{
- 	  node->aux = queue;
- 	  queue = node;
-         }
-     }
- }
- 
  /* Walk tree and record all calls.  Called via walk_tree.  */
  static tree
  record_call_1 (tp, walk_subtrees, data)
--- 87,92 ----
*************** cgraph_finalize_compilation_unit ()
*** 156,195 ****
    struct cgraph_node *node;
    struct cgraph_edge *edge;
  
-   /* Collect entry points to the unit.  */
- 
    if (!quiet_flag)
-     fprintf (stderr, "\n\nUnit entry points:");
- 
-   for (node = cgraph_nodes; node; node = node->next)
      {
!       tree decl = node->decl;
! 
!       if (!DECL_SAVED_TREE (decl))
! 	continue;
!       if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
! 	  || (DECL_ASSEMBLER_NAME_SET_P (decl)
! 	      && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
! 	{
! 	  /* This function can be called from outside this compliation
! 	     unit, so it most definitely is needed.  */
! 	  cgraph_mark_needed_node (node, 1);
! 	}
      }
  
    /* Propagate reachability flag and lower representation of all reachable
       functions.  In the future, lowering will introduce new functions and
       new entry points on the way (by template instantiation and virtual
       method table generation for instance).  */
!   while (queue)
      {
!       tree decl = queue->decl;
  
-       node = queue;
-       queue = queue->aux;
        if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
  	abort ();
  
        /* At the moment frontend automatically emits all nested functions.  */
        if (node->nested)
  	{
--- 147,177 ----
    struct cgraph_node *node;
    struct cgraph_edge *edge;
  
    if (!quiet_flag)
      {
!       fprintf (stderr, "\n\nInitial entry points:");
!       for (node = cgraph_nodes; node; node = node->next)
! 	if (node->needed && DECL_SAVED_TREE (node->decl))
! 	  announce_function (node->decl);
      }
  
    /* Propagate reachability flag and lower representation of all reachable
       functions.  In the future, lowering will introduce new functions and
       new entry points on the way (by template instantiation and virtual
       method table generation for instance).  */
!   while (cgraph_nodes_queue)
      {
!       tree decl = cgraph_nodes_queue->decl;
! 
!       node = cgraph_nodes_queue;
!       cgraph_nodes_queue = cgraph_nodes_queue->aux;
  
        if (node->lowered || !node->reachable || !DECL_SAVED_TREE (decl))
  	abort ();
  
+       if (lang_hooks.callgraph.lower_function)
+ 	(*lang_hooks.callgraph.lower_function) (decl);
+ 
        /* At the moment frontend automatically emits all nested functions.  */
        if (node->nested)
  	{
*************** cgraph_finalize_compilation_unit ()
*** 200,208 ****
  	      cgraph_mark_needed_node (node2, 0);
  	}
  
-       if (lang_hooks.callgraph.lower_function)
- 	(*lang_hooks.callgraph.lower_function) (decl);
- 
        /* First kill forward declaration so reverse inling works properly.  */
        cgraph_create_edges (decl, DECL_SAVED_TREE (decl));
  
--- 182,187 ----
*************** cgraph_finalize_compilation_unit ()
*** 213,218 ****
--- 192,206 ----
  	}
        node->lowered = true;
      }
+   /* Collect entry points to the unit.  */
+ 
+   if (!quiet_flag)
+     {
+       fprintf (stderr, "\n\nUnit entry points:");
+       for (node = cgraph_nodes; node; node = node->next)
+ 	if (node->needed && DECL_SAVED_TREE (node->decl))
+ 	  announce_function (node->decl);
+     }
  
    if (!quiet_flag)
      fprintf (stderr, "\n\nReclaiming functions:");
*************** cgraph_mark_functions_to_output ()
*** 248,254 ****
  	  && (node->needed
  	      || (!node->local.inline_many && !node->global.inline_once
  		  && node->reachable)
! 	      || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
  	  && !TREE_ASM_WRITTEN (decl) && !node->origin
  	  && !DECL_EXTERNAL (decl))
  	node->output = 1;
--- 236,243 ----
  	  && (node->needed
  	      || (!node->local.inline_many && !node->global.inline_once
  		  && node->reachable)
! 	      || (DECL_ASSEMBLER_NAME_SET_P (decl)
! 	          && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
  	  && !TREE_ASM_WRITTEN (decl) && !node->origin
  	  && !DECL_EXTERNAL (decl))
  	node->output = 1;
*************** cgraph_mark_local_functions ()
*** 400,405 ****
--- 389,395 ----
      {
        node->local.local = (!node->needed
  		           && DECL_SAVED_TREE (node->decl)
+ 			   && !DECL_COMDAT (node->decl)
  		           && !TREE_PUBLIC (node->decl));
        if (node->local.local)
  	announce_function (node->decl);
diff -Nrc3p gcc.tmp/varasm.c gcc/varasm.c
*** gcc.tmp/varasm.c	Sun Jun 22 01:50:24 2003
--- gcc/varasm.c	Fri Jun 20 23:09:59 2003
*************** Software Foundation, 59 Temple Place - S
*** 49,54 ****
--- 49,55 ----
  #include "tm_p.h"
  #include "debug.h"
  #include "target.h"
+ #include "cgraph.h"
  
  #ifdef XCOFF_DEBUGGING_INFO
  #include "xcoffout.h"		/* Needed for external data
*************** assemble_name (file, name)
*** 1743,1749 ****
  
    id = maybe_get_identifier (real_name);
    if (id)
!     TREE_SYMBOL_REFERENCED (id) = 1;
  
    if (name[0] == '*')
      fputs (&name[1], file);
--- 1744,1759 ----
  
    id = maybe_get_identifier (real_name);
    if (id)
!     {
!       if (!TREE_SYMBOL_REFERENCED (id)
! 	  && !cgraph_global_info_ready)
! 	{
! 	  struct cgraph_node *node = cgraph_node_for_identifier (id);
! 	  if (node)
! 	    cgraph_mark_needed_node (node, 1);
! 	}
!       TREE_SYMBOL_REFERENCED (id) = 1;
!     }
  
    if (name[0] == '*')
      fputs (&name[1], file);


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