This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-profiling] Cleanup way the datastructures are analyzed
- From: Jan Hubicka <jh at suse dot cz>
- To: gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Mon, 11 Oct 2004 01:44:12 +0200
- Subject: [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);
}