The following patch fixes a big inefficiency when using -fdump-tree-all for large source files. I found that when using this option the compile time became unreasonably slow, and I traced this to the fact that dump_begin/dump_end are called around every function/class that are dumped via -fdump-tree-original and -fdump-class-hierarchy. I fixed this by opening the .original and .class dumps once before invoking the parser and closing them once after.
For a file containing ~7000 each of functions and classes, the real time measured for the compile is: no dumping: 8s -fdump-tree-all, no patch: 10m30s -fdump-tree-all, my patch: 1m21s Bootstrapped and tested on x86_64-unknown-linux-gnu. Ok for trunk? Thanks, Teresa 2014-06-26 Teresa Johnson <tejohn...@google.com> * c-family/c-common.h (get_dump_info): Declare. * c-family/c-gimplify.c (c_genericize): Use saved dump files. * c-family/c-opts.c (c_common_parse_file): Begin and end dumps once around parsing invocation. (get_dump_info): New function. * cp/class.c (dump_class_hierarchy): Use saved dump files. (dump_vtable): Ditto. (dump_vtt): Ditto. Index: c-family/c-common.h =================================================================== --- c-family/c-common.h (revision 211980) +++ c-family/c-common.h (working copy) @@ -835,6 +835,7 @@ extern bool c_common_post_options (const char **); extern bool c_common_init (void); extern void c_common_finish (void); extern void c_common_parse_file (void); +extern FILE *get_dump_info (int, int *); extern alias_set_type c_common_get_alias_set (tree); extern void c_register_builtin_type (tree, const char*); extern bool c_promoting_integer_type_p (const_tree); Index: c-family/c-gimplify.c =================================================================== --- c-family/c-gimplify.c (revision 211980) +++ c-family/c-gimplify.c (working copy) @@ -123,7 +123,7 @@ c_genericize (tree fndecl) } /* Dump the C-specific tree IR. */ - dump_orig = dump_begin (TDI_original, &local_dump_flags); + dump_orig = get_dump_info (TDI_original, &local_dump_flags); if (dump_orig) { fprintf (dump_orig, "\n;; Function %s", @@ -140,8 +140,6 @@ c_genericize (tree fndecl) else print_c_tree (dump_orig, DECL_SAVED_TREE (fndecl)); fprintf (dump_orig, "\n"); - - dump_end (TDI_original, dump_orig); } /* Dump all nested functions now. */ Index: c-family/c-opts.c =================================================================== --- c-family/c-opts.c (revision 211980) +++ c-family/c-opts.c (working copy) @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see TARGET_FLT_EVAL_METHOD_NON_DEFAULT and TARGET_OPTF. */ #include "tm_p.h" /* For C_COMMON_OVERRIDE_OPTIONS. */ +#include "dumpfile.h" #ifndef DOLLARS_IN_IDENTIFIERS # define DOLLARS_IN_IDENTIFIERS true @@ -102,6 +103,12 @@ static size_t deferred_count; /* Number of deferred options scanned for -include. */ static size_t include_cursor; +/* Dump files/flags to use during parsing. */ +static FILE *original_dump_file = NULL; +static int original_dump_flags; +static FILE *class_dump_file = NULL; +static int class_dump_flags; + /* Whether any standard preincluded header has been preincluded. */ static bool done_preinclude; @@ -1088,6 +1095,10 @@ c_common_parse_file (void) for (;;) { c_finish_options (); + /* Open the dump files to use for the original and class dump output + here, to be used during parsing for the current file. */ + original_dump_file = dump_begin (TDI_original, &original_dump_flags); + class_dump_file = dump_begin (TDI_class, &class_dump_flags); pch_init (); push_file_scope (); c_parse_file (); @@ -1101,6 +1112,16 @@ c_common_parse_file (void) cpp_clear_file_cache (parse_in); this_input_filename = cpp_read_main_file (parse_in, in_fnames[i]); + if (original_dump_file) + { + dump_end (TDI_original, original_dump_file); + original_dump_file = NULL; + } + if (class_dump_file) + { + dump_end (TDI_class, class_dump_file); + class_dump_file = NULL; + } /* If an input file is missing, abandon further compilation. cpplib has issued a diagnostic. */ if (!this_input_filename) @@ -1108,6 +1129,23 @@ c_common_parse_file (void) } } +/* Returns the appropriate dump file for PHASE to dump with FLAGS. */ +FILE * +get_dump_info (int phase, int *flags) +{ + gcc_assert (phase == TDI_original || phase == TDI_class); + if (phase == TDI_original) + { + *flags = original_dump_flags; + return original_dump_file; + } + else + { + *flags = class_dump_flags; + return class_dump_file; + } +} + /* Common finish hook for the C, ObjC and C++ front ends. */ void c_common_finish (void) Index: cp/class.c =================================================================== --- cp/class.c (revision 211980) +++ cp/class.c (working copy) @@ -8077,12 +8077,11 @@ static void dump_class_hierarchy (tree t) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (stream) { dump_class_hierarchy_1 (stream, flags, t); - dump_end (TDI_class, stream); } } @@ -8112,7 +8111,7 @@ static void dump_vtable (tree t, tree binfo, tree vtable) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (!stream) return; @@ -8135,15 +8134,13 @@ dump_vtable (tree t, tree binfo, tree vtable) dump_array (stream, vtable); fprintf (stream, "\n"); } - - dump_end (TDI_class, stream); } static void dump_vtt (tree t, tree vtt) { int flags; - FILE *stream = dump_begin (TDI_class, &flags); + FILE *stream = get_dump_info (TDI_class, &flags); if (!stream) return; @@ -8155,8 +8152,6 @@ dump_vtt (tree t, tree vtt) dump_array (stream, vtt); fprintf (stream, "\n"); } - - dump_end (TDI_class, stream); } /* Dump a function or thunk and its thunkees. */ -- Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413