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] Cleanup way the datastructures are analyzed


Hi,
This is something I meant to work on for a real while (I've had very
funny bugs in the code that made me to believe that whole program is a
lot more dificult ;)

With this patch we first analyze the datastructures similar way as we do
for functions while building the cgraph and at the end of compilation we
output all of them.

I hope to kill the current way of hooking into output functions to see
what functions/astructures are needed.  This is not done at the moment
as the way we output structures are still twisted, but I will work on
that next (I need to figure out how to analyze what variables are
*still* needed after the optimization of functions being output without
actually looking into the asembly)

Bootstrapped/regtested i686-pc-gnu-linux and comitted.
Honza

2004-10-10  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.58
diff -c -3 -p -r1.58 cgraph.c
*** cgraph.c	20 Sep 2004 20:38:16 -0000	1.58
--- cgraph.c	9 Oct 2004 21:17:35 -0000
*************** bool cgraph_global_info_ready = false;
*** 118,130 ****
  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;
  
  /* Number of nodes in existence.  */
  int cgraph_varpool_n_nodes;
  
  /* 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 *);
--- 119,135 ----
  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;
! 
  
  /* Number of nodes in existence.  */
  int cgraph_varpool_n_nodes;
  
  /* 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 *);
*************** change_decl_assembler_name (tree decl, t
*** 580,596 ****
    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;
  }
  
--- 585,613 ----
    SET_DECL_ASSEMBLER_NAME (decl, name);
  }
  
+ /* Helped function for finalization code - add node into lists so it will
+    be analyzed and compiled.  */
+ static void
+ enqueue_needed_varpool_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);
+ }
+ 
  /* 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)
!     enqueue_needed_varpool_node (node);
    node->needed = 1;
  }
  
*************** cgraph_varpool_finalize_decl (tree decl)
*** 606,616 ****
    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
--- 623,629 ----
    if (node->finalized)
      return;
    if (node->needed)
!     enqueue_needed_varpool_node (node);
    node->finalized = true;
  
    if (/* Externally visible variables must be output.  The exception are
*************** cgraph_varpool_finalize_decl (tree decl)
*** 626,651 ****
      }
  }
  
- 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
--- 639,644 ----
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.38
diff -c -3 -p -r1.38 cgraph.h
*** cgraph.h	20 Sep 2004 20:38:16 -0000	1.38
--- cgraph.h	9 Oct 2004 21:17:35 -0000
*************** struct cgraph_varpool_node GTY(())
*** 226,231 ****
--- 227,235 ----
    /* Set when function must be output - it is externally visible
       or it's 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 bool cgraph_global_info_ready;
*** 239,244 ****
--- 243,249 ----
  extern GTY(()) struct cgraph_node *cgraph_nodes_queue;
  
  extern GTY(()) int cgraph_varpool_n_nodes;
+ extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
  extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
  
  /* In cgraph.c  */
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.86
diff -c -3 -p -r1.86 cgraphunit.c
*** cgraphunit.c	1 Oct 2004 15:11:10 -0000	1.86
--- cgraphunit.c	9 Oct 2004 21:17:36 -0000
*************** Software Foundation, 59 Temple Place - S
*** 201,206 ****
--- 201,207 ----
  #include "intl.h"
  #include "function.h"
  #include "tree-gimple.h"
+ #include "output.h"
  
  #define INSNS_PER_CALL 10
  
*************** verify_cgraph (void)
*** 852,857 ****
--- 853,907 ----
      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;
+ 
+   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;
+       cgraph_create_edges (NULL, DECL_INITIAL (decl));
+       changed = true;
+     }
+   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))
+ 	{
+ 	  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)
*************** cgraph_finalize_compilation_unit (void)
*** 901,907 ****
        return;
      }
  
!   cgraph_varpool_assemble_pending_decls ();
    if (!quiet_flag)
      fprintf (stderr, "\nAnalyzing compilation unit\n");
  
--- 951,957 ----
        return;
      }
  
!   cgraph_varpool_analyze_pending_decls ();
    if (!quiet_flag)
      fprintf (stderr, "\nAnalyzing compilation unit\n");
  
*************** cgraph_finalize_compilation_unit (void)
*** 943,949 ****
  	if (!edge->callee->reachable)
  	  cgraph_mark_reachable_node (edge->callee);
  
!       cgraph_varpool_assemble_pending_decls ();
      }
  
    /* Collect entry points to the unit.  */
--- 993,999 ----
  	if (!edge->callee->reachable)
  	  cgraph_mark_reachable_node (edge->callee);
  
!       cgraph_varpool_analyze_pending_decls ();
      }
  
    /* Collect entry points to the unit.  */
*************** cgraph_optimize (void)
*** 2837,2842 ****
--- 2887,2894 ----
    cgraph_characterize_statics ();
    
    cgraph_expand_all_functions ();
+ 
+   cgraph_varpool_assemble_pending_decls ();
    if (cgraph_dump_file)
      {
        fprintf (cgraph_dump_file, "\nFinal ");
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.751
diff -c -3 -p -r1.751 decl2.c
*** cp/decl2.c	7 Oct 2004 17:48:32 -0000	1.751
--- cp/decl2.c	9 Oct 2004 21:17:39 -0000
*************** finish_objects (int method_type, int ini
*** 2142,2147 ****
--- 2142,2148 ----
    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)
*** 2991,2999 ****
        /* 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++;
--- 2992,3000 ----
        /* 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.145
diff -c -3 -p -r1.145 Make-lang.in
*** java/Make-lang.in	22 Sep 2004 11:21:21 -0000	1.145
--- java/Make-lang.in	9 Oct 2004 21:17:39 -0000
*************** java/check-init.o: java/check-init.c $(C
*** 287,299 ****
    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 
--- 287,299 ----
    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.209
diff -c -3 -p -r1.209 class.c
*** java/class.c	30 Sep 2004 23:23:52 -0000	1.209
--- java/class.c	9 Oct 2004 21:17:40 -0000
*************** The Free Software Foundation is independ
*** 44,49 ****
--- 44,50 ----
  #include "target.h"
  #include "except.h"
  #include "tree-iterator.h"
+ #include "cgraph.h"
  
  /* DOS brain-damage */
  #ifndef O_BINARY
*************** make_local_function_alias (tree method)
*** 1235,1240 ****
--- 1236,1242 ----
    TREE_USED (alias) = 1;
    SET_DECL_ASSEMBLER_NAME (alias, DECL_NAME (alias));
    TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (alias)) = 1;
+   cgraph_mark_needed_node (cgraph_node (alias));
    if (!flag_syntax_only)
      assemble_alias (alias, DECL_ASSEMBLER_NAME (method));
    return alias;
Index: java/resource.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/resource.c,v
retrieving revision 1.17
diff -c -3 -p -r1.17 resource.c
*** java/resource.c	25 Aug 2004 09:52:53 -0000	1.17
--- java/resource.c	9 Oct 2004 21:17:40 -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]