diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 733ff95fea9..ba3cca46746 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +Wed Jul 9 03:00:10 CEST 2003 Jan Hubicka + + * cgraph.c (cgraph_node_name): New function. + (dump_cgraph): Use it. + * cgraph.h (cgraph_dump_file): Declare. + (cgraph_node_name): Declare. + * cgraphunit.c: Include timevar.h + (cgraph_finalize_compilation_unit): Use timevar; reorganize dumps. + (cgraph_optimize_function): Use TV_INTEGRATION. + (cgraph_mark_local_functions): reorganize dumps. + (cgraph_mark_functions_to_inline_once): Likewise. + (cgraph_optimize): Likewise; use timevar. + * timevar.def (TV_CGRAPH, TV_CGRAPHOPT): New. + * toplev.c (dump_file_index): Add DFI_cgraph. + (dump_file_info): Likewise. + (cgraph_dump_file): New global variable. + (do_compile): Open and close cgraph dump. + * invoke.texi (-d): Document new flag; renumber. + 2003-07-08 Roger Sayle PR c/11370 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 36d9814e365..7bc065b79d3 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -316,6 +316,13 @@ cgraph_rtl_info (decl) return &node->rtl; } +/* Return name of the node used in debug output. */ +const char * +cgraph_node_name (node) + struct cgraph_node *node; +{ + return (*lang_hooks.decl_printable_name) (node->decl, 2); +} /* Dump the callgraph. */ @@ -329,10 +336,9 @@ dump_cgraph (f) for (node = cgraph_nodes; node; node = node->next) { struct cgraph_edge *edge; - fprintf (f, "%s", IDENTIFIER_POINTER (DECL_NAME (node->decl))); + fprintf (f, "%s", cgraph_node_name (node)); if (node->origin) - fprintf (f, " nested in: %s", - IDENTIFIER_POINTER (DECL_NAME (node->origin->decl))); + fprintf (f, " nested in: %s", cgraph_node_name (node->origin)); if (node->needed) fprintf (f, " needed"); else if (node->reachable) @@ -342,13 +348,11 @@ dump_cgraph (f) fprintf (f, "\n called by :"); for (edge = node->callers; edge; edge = edge->next_caller) - fprintf (f, "%s ", - IDENTIFIER_POINTER (DECL_NAME (edge->caller->decl))); + fprintf (f, "%s ", cgraph_node_name (edge->caller)); fprintf (f, "\n calls: "); for (edge = node->callees; edge; edge = edge->next_callee) - fprintf (f, "%s ", - IDENTIFIER_POINTER (DECL_NAME (edge->callee->decl))); + fprintf (f, "%s ", cgraph_node_name (edge->callee)); fprintf (f, "\n"); } } diff --git a/gcc/cgraph.h b/gcc/cgraph.h index dbd012fecce..65bda0717cc 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -126,6 +126,7 @@ extern GTY(()) struct cgraph_node *cgraph_nodes; extern GTY(()) int cgraph_n_nodes; extern bool cgraph_global_info_ready; extern GTY(()) struct cgraph_node *cgraph_nodes_queue; +extern FILE *cgraph_dump_file; extern GTY(()) int cgraph_varpool_n_nodes; extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue; @@ -142,6 +143,7 @@ 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)); struct cgraph_rtl_info *cgraph_rtl_info PARAMS ((tree)); +const char * cgraph_node_name PARAMS ((struct cgraph_node *)); struct cgraph_varpool_node *cgraph_varpool_node (tree decl); struct cgraph_varpool_node *cgraph_varpool_node_for_identifier (tree id); diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index a904eb544ea..ad504dd08e5 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -34,6 +34,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "target.h" #include "cgraph.h" #include "diagnostic.h" +#include "timevar.h" static void cgraph_expand_functions PARAMS ((void)); static void cgraph_mark_functions_to_output PARAMS ((void)); @@ -140,12 +141,14 @@ cgraph_finalize_compilation_unit () cgraph_varpool_assemble_pending_decls (); - if (!quiet_flag) + timevar_push (TV_CGRAPH); + if (cgraph_dump_file) { - fprintf (stderr, "\n\nInitial entry points:"); + fprintf (cgraph_dump_file, "\nInitial entry points:"); for (node = cgraph_nodes; node; node = node->next) if (node->needed && DECL_SAVED_TREE (node->decl)) - announce_function (node->decl); + fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); + fprintf (cgraph_dump_file, "\n"); } /* Propagate reachability flag and lower representation of all reachable @@ -198,16 +201,17 @@ cgraph_finalize_compilation_unit () } /* Collect entry points to the unit. */ - if (!quiet_flag) + if (cgraph_dump_file) { - fprintf (stderr, "\n\nUnit entry points:"); + fprintf (cgraph_dump_file, "\nUnit entry points:"); for (node = cgraph_nodes; node; node = node->next) if (node->needed && DECL_SAVED_TREE (node->decl)) - announce_function (node->decl); + fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); + fprintf (cgraph_dump_file, "\n"); } - if (!quiet_flag) - fprintf (stderr, "\n\nReclaiming functions:"); + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "\nReclaiming functions:"); for (node = cgraph_nodes; node; node = node->next) { @@ -216,10 +220,14 @@ cgraph_finalize_compilation_unit () if (!node->reachable && DECL_SAVED_TREE (decl)) { cgraph_remove_node (node); - announce_function (decl); + if (cgraph_dump_file) + fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); } } + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "\n"); ggc_collect (); + timevar_pop (TV_CGRAPH); } /* Figure out what functions we want to assemble. */ @@ -256,6 +264,7 @@ cgraph_optimize_function (node) { tree decl = node->decl; + timevar_push (TV_INTEGRATION); if (flag_inline_trees) optimize_inline_calls (decl); if (node->nested) @@ -263,6 +272,7 @@ cgraph_optimize_function (node) for (node = node->nested; node; node = node->next_nested) cgraph_optimize_function (node); } + timevar_pop (TV_INTEGRATION); } /* Expand function specified by NODE. */ @@ -385,8 +395,8 @@ cgraph_mark_local_functions () { struct cgraph_node *node; - if (!quiet_flag) - fprintf (stderr, "\n\nMarking local functions:"); + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "Marking local functions:"); /* Figure out functions we want to assemble. */ for (node = cgraph_nodes; node; node = node->next) @@ -395,9 +405,11 @@ cgraph_mark_local_functions () && DECL_SAVED_TREE (node->decl) && !DECL_COMDAT (node->decl) && !TREE_PUBLIC (node->decl)); - if (node->local.local) - announce_function (node->decl); + if (cgraph_dump_file && node->local.local) + fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); } + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "\n"); } /* Decide what function should be inlined because they are invoked once @@ -408,8 +420,8 @@ cgraph_mark_functions_to_inline_once () { struct cgraph_node *node, *node1; - if (!quiet_flag) - fprintf (stderr, "\n\nMarking functions to inline once:"); + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "\n\nMarking functions to inline once:"); /* Now look for function called only once and mark them to inline. From this point number of calls to given function won't grow. */ @@ -431,10 +443,13 @@ cgraph_mark_functions_to_inline_once () if (ok) { node->global.inline_once = true; - announce_function (node->decl); + if (cgraph_dump_file) + fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); } } } + if (cgraph_dump_file) + fprintf (cgraph_dump_file, "\n"); } @@ -446,11 +461,23 @@ cgraph_optimize () struct cgraph_node *node; bool changed = true; + timevar_push (TV_CGRAPHOPT); + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, "Initial callgraph:"); + dump_cgraph (cgraph_dump_file); + } cgraph_mark_local_functions (); cgraph_mark_functions_to_inline_once (); cgraph_global_info_ready = true; + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, "Optimized callgraph:"); + dump_cgraph (cgraph_dump_file); + } + timevar_pop (TV_CGRAPHOPT); if (!quiet_flag) fprintf (stderr, "\n\nAssembling functions:"); @@ -485,4 +512,9 @@ cgraph_optimize () } } } + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, "Final callgraph:"); + dump_cgraph (cgraph_dump_file); + } } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ade4e1f6b5e..2155e74418b 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3118,115 +3118,118 @@ meanings: Annotate the assembler output with miscellaneous debugging information. @item b @opindex db -Dump after computing branch probabilities, to @file{@var{file}.15.bp}. +Dump after computing branch probabilities, to @file{@var{file}.16.bp}. @item B @opindex dB -Dump after block reordering, to @file{@var{file}.31.bbro}. +Dump after block reordering, to @file{@var{file}.32.bbro}. @item c @opindex dc -Dump after instruction combination, to the file @file{@var{file}.21.combine}. +Dump after instruction combination, to the file @file{@var{file}.22.combine}. @item C @opindex dC -Dump after the first if conversion, to the file @file{@var{file}.16.ce1}. -Also dump after the second if conversion, to the file @file{@var{file}.22.ce2}. +Dump after the first if conversion, to the file @file{@var{file}.17.ce1}. +Also dump after the second if conversion, to the file @file{@var{file}.23.ce2}. @item d @opindex dd -Dump after branch target load optimization, to to @file{@var{file}.33.btl}. -Also dump after delayed branch scheduling, to @file{@var{file}.36.dbr}. +Dump after branch target load optimization, to to @file{@var{file}.34.btl}. +Also dump after delayed branch scheduling, to @file{@var{file}.37.dbr}. @item D @opindex dD Dump all macro definitions, at the end of preprocessing, in addition to normal output. @item e @opindex de -Dump after SSA optimizations, to @file{@var{file}.04.ssa} and -@file{@var{file}.07.ussa}. +Dump after SSA optimizations, to @file{@var{file}.05.ssa} and +@file{@var{file}.010.ussa}. @item E @opindex dE -Dump after the second if conversion, to @file{@var{file}.32.ce3}. +Dump after the second if conversion, to @file{@var{file}.33.ce3}. @item f @opindex df -Dump after control and data flow analysis, to @file{@var{file}.14.cfg}. -Also dump after life analysis, to @file{@var{file}.20.life}. +Dump after control and data flow analysis, to @file{@var{file}.15.cfg}. +Also dump after life analysis, to @file{@var{file}.21.life}. @item F @opindex dF -Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.10.addressof}. +Dump after purging @code{ADDRESSOF} codes, to @file{@var{file}.11.addressof}. @item g @opindex dg -Dump after global register allocation, to @file{@var{file}.26.greg}. +Dump after global register allocation, to @file{@var{file}.27.greg}. @item G @opindex dG -Dump after GCSE, to @file{@var{file}.11.gcse}. +Dump after GCSE, to @file{@var{file}.12.gcse}. Also dump after jump bypassing and control flow optimizations, to -@file{@var{file}.13.bypass}. +@file{@var{file}.14.bypass}. @item h @opindex dh -Dump after finalization of EH handling code, to @file{@var{file}.02.eh}. +Dump after finalization of EH handling code, to @file{@var{file}.03.eh}. @item i @opindex di -Dump after sibling call optimizations, to @file{@var{file}.01.sibling}. +Dump after sibling call optimizations, to @file{@var{file}.02.sibling}. @item j @opindex dj -Dump after the first jump optimization, to @file{@var{file}.03.jump}. +Dump after the first jump optimization, to @file{@var{file}.04.jump}. @item k @opindex dk -Dump after conversion from registers to stack, to @file{@var{file}.35.stack}. +Dump after conversion from registers to stack, to @file{@var{file}.36.stack}. @item l @opindex dl -Dump after local register allocation, to @file{@var{file}.25.lreg}. +Dump after local register allocation, to @file{@var{file}.26.lreg}. @item L @opindex dL -Dump after loop optimization passes, to @file{@var{file}.12.loop} and -@file{@var{file}.18.loop2}. +Dump after loop optimization passes, to @file{@var{file}.13.loop} and +@file{@var{file}.19.loop2}. @item M @opindex dM Dump after performing the machine dependent reorganization pass, to -@file{@var{file}.36.mach}. +@file{@var{file}.37.mach}. @item n @opindex dn -Dump after register renumbering, to @file{@var{file}.30.rnreg}. +Dump after register renumbering, to @file{@var{file}.31.rnreg}. @item N @opindex dN -Dump after the register move pass, to @file{@var{file}.23.regmove}. +Dump after the register move pass, to @file{@var{file}.24.regmove}. @item o @opindex do -Dump after post-reload optimizations, to @file{@var{file}.27.postreload}. +Dump after post-reload optimizations, to @file{@var{file}.28.postreload}. @item r @opindex dr -Dump after RTL generation, to @file{@var{file}.00.rtl}. +Dump after RTL generation, to @file{@var{file}.01.rtl}. @item R @opindex dR -Dump after the second scheduling pass, to @file{@var{file}.34.sched2}. +Dump after the second scheduling pass, to @file{@var{file}.35.sched2}. @item s @opindex ds Dump after CSE (including the jump optimization that sometimes follows -CSE), to @file{@var{file}.09.cse}. +CSE), to @file{@var{file}.019.cse}. @item S @opindex dS -Dump after the first scheduling pass, to @file{@var{file}.24.sched}. +Dump after the first scheduling pass, to @file{@var{file}.25.sched}. @item t @opindex dt Dump after the second CSE pass (including the jump optimization that -sometimes follows CSE), to @file{@var{file}.19.cse2}. +sometimes follows CSE), to @file{@var{file}.20.cse2}. @item T @opindex dT -Dump after running tracer, to @file{@var{file}.17.tracer}. +Dump after running tracer, to @file{@var{file}.18.tracer}. @item u @opindex du -Dump after null pointer elimination pass to @file{@var{file}.08.null}. -@item w +Dump after null pointer elimination pass to @file{@var{file}.018.null}. +@item U +@opindex dU +Dump callgraph and unit-at-a-time optimization @file{@var{file}.00.unit}. +@litem w @opindex dw -Dump after the second flow pass, to @file{@var{file}.28.flow2}. +Dump after the second flow pass, to @file{@var{file}.29.flow2}. @item W @opindex dW Dump after SSA conditional constant propagation, to -@file{@var{file}.05.ssaccp}. +@file{@var{file}.06.ssaccp}. @item X @opindex dX -Dump after SSA dead code elimination, to @file{@var{file}.06.ssadce}. +Dump after SSA dead code elimination, to @file{@var{file}.07.ssadce}. @item z @opindex dz -Dump after the peephole pass, to @file{@var{file}.29.peephole2}. +Dump after the peephole pass, to @file{@var{file}.30.peephole2}. @item a @opindex da Produce all the dumps listed above. @@ -3249,7 +3252,7 @@ Also turns on @option{-dp} annotation. @item v @opindex dv For each of the other indicated dump files (except for -@file{@var{file}.00.rtl}), dump a representation of the control flow graph +@file{@var{file}.01.rtl}), dump a representation of the control flow graph suitable for viewing with VCG to @file{@var{file}.@var{pass}.vcg}. @item x @opindex dx diff --git a/gcc/timevar.def b/gcc/timevar.def index f8a32f63a8f..22d3097cf6a 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -39,6 +39,8 @@ DEFTIMEVAR (TV_GC , "garbage collection") /* Time spent generating dump files. */ DEFTIMEVAR (TV_DUMP , "dump files") +DEFTIMEVAR (TV_CGRAPH , "callgraph construction") +DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization") /* Time spent by constructing CFG. */ DEFTIMEVAR (TV_CFG , "cfg construction") /* Time spent by cleaning up CFG. */ diff --git a/gcc/toplev.c b/gcc/toplev.c index b7bbe8aecbc..84f61b77636 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -247,6 +247,7 @@ struct dump_file_info enum dump_file_index { + DFI_cgraph, DFI_rtl, DFI_sibling, DFI_eh, @@ -294,11 +295,12 @@ enum dump_file_index Remaining -d letters: " m q " - " JK O Q UV YZ" + " JK O Q V YZ" */ static struct dump_file_info dump_file[DFI_MAX] = { + { "cgraph", 'U', 0, 0, 0 }, { "rtl", 'r', 0, 0, 0 }, { "sibling", 'i', 0, 0, 0 }, { "eh", 'h', 0, 0, 0 }, @@ -1567,6 +1569,7 @@ static const lang_independent_options W_options[] = FILE *asm_out_file; FILE *aux_info_file; FILE *rtl_dump_file = NULL; +FILE *cgraph_dump_file = NULL; /* Set up a default flag_random_seed and local_tick, unless the user already specified one. */ @@ -4944,10 +4947,23 @@ do_compile (void) if (!no_backend) backend_init (); + if (flag_unit_at_a_time) + { + open_dump_file (DFI_cgraph, NULL); + cgraph_dump_file = rtl_dump_file; + rtl_dump_file = NULL; + } /* Language-dependent initialization. Returns true on success. */ if (lang_dependent_init (main_input_filename)) compile_file (); + if (flag_unit_at_a_time) + { + rtl_dump_file = cgraph_dump_file; + cgraph_dump_file = NULL; + close_dump_file (DFI_cgraph, NULL, NULL_RTX); + } + finalize (); }