From 6be777481ea7fa281c38dc84a76674e80013603b Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 2 Jul 2001 12:16:58 +0000 Subject: [PATCH] c-common.h (TDI_inlined): New ast dump phase. * c-common.h (TDI_inlined): New ast dump phase. (dump_flag_name): New function. * c-dump.c (dump_files): Add inlined phase. (dump_flag_name): Define. * doc/invoke.texi (-fdump-ast-inlined): Document. cp: * optimize.c (optimize_inline_calls): New function, broken out of ... (optimize_function): ... here. Call it. Don't inline if it is a thunk. (dump_function): Print name of dump flag causing this dump. * semantics.c (expand_body): Move thunk inline check to optimize_function. From-SVN: r43687 --- gcc/ChangeLog | 8 +++ gcc/c-common.h | 7 ++- gcc/c-dump.c | 21 ++++++-- gcc/cp/ChangeLog | 10 ++++ gcc/cp/optimize.c | 138 +++++++++++++++++++++++++++++----------------------- gcc/cp/semantics.c | 9 +--- gcc/doc/invoke.texi | 12 ++++- 7 files changed, 129 insertions(+), 76 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14fea60..c829d92 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-07-02 Nathan Sidwell + + * c-common.h (TDI_inlined): New ast dump phase. + (dump_flag_name): New function. + * c-dump.c (dump_files): Add inlined phase. + (dump_flag_name): Define. + * doc/invoke.texi (-fdump-ast-inlined): Document. + Mon Jul 2 06:29:36 2001 Richard Kenner * stor-layout.c (layout_decl): Revert change to handling of alignment diff --git a/gcc/c-common.h b/gcc/c-common.h index 95ead54..147ffa4 100644 --- a/gcc/c-common.h +++ b/gcc/c-common.h @@ -826,9 +826,11 @@ extern int c_unsafe_for_reeval PARAMS ((tree)); enum tree_dump_index { TDI_all, /* dump the whole translation unit */ - TDI_original, /* dump each function before optimizing it */ - TDI_optimized, /* dump each function after optimizing it */ TDI_class, /* dump class heirarchy */ + TDI_original, /* dump each function before optimizing it */ + TDI_optimized, /* dump each function after optimizing it */ + TDI_inlined, /* dump each function after inlining + within it. */ TDI_end }; @@ -852,6 +854,7 @@ extern FILE *dump_begin PARAMS ((enum tree_dump_index, int *)); extern void dump_end PARAMS ((enum tree_dump_index, FILE *)); extern void dump_node PARAMS ((tree, int, FILE *)); extern int dump_switch_p PARAMS ((const char *)); +extern const char *dump_flag_name PARAMS ((enum tree_dump_index)); /* Information recorded about each file examined during compilation. */ diff --git a/gcc/c-dump.c b/gcc/c-dump.c index 72de67c..0956266 100644 --- a/gcc/c-dump.c +++ b/gcc/c-dump.c @@ -799,9 +799,10 @@ struct dump_file_info static struct dump_file_info dump_files[TDI_end] = { {".tu", "dump-translation-unit", 0, 0}, + {".class", "dump-class-hierarchy", 0, 0}, {".original", "dump-ast-original", 0, 0}, {".optimized", "dump-ast-optimized", 0, 0}, - {".class", "dump-class-hierarchy", 0, 0}, + {".inlined", "dump-ast-inlined", 0, 0}, }; /* Begin a tree dump for PHASE. Stores any user supplied flag in @@ -835,16 +836,27 @@ dump_begin (phase, flag_ptr) /* Returns non-zero if tree dump PHASE is enabled. */ -int dump_enabled_p (phase) +int +dump_enabled_p (phase) enum tree_dump_index phase; { return dump_files[phase].state; } +/* Returns the switch name of PHASE. */ + +const char * +dump_flag_name (phase) + enum tree_dump_index phase; +{ + return dump_files[phase].swtch; +} + /* Finish a tree dump for PHASE. STREAM is the stream created by dump_begin. */ -void dump_end (phase, stream) +void +dump_end (phase, stream) enum tree_dump_index phase ATTRIBUTE_UNUSED; FILE *stream; { @@ -854,7 +866,8 @@ void dump_end (phase, stream) /* Parse ARG as a dump switch. Return non-zero if it is, and store the relevant details in the dump_files array. */ -int dump_switch_p (arg) +int +dump_switch_p (arg) const char *arg; { unsigned ix; diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2b55f03..dfe82c0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2001-07-02 Nathan Sidwell + + * optimize.c (optimize_inline_calls): New function, broken out + of ... + (optimize_function): ... here. Call it. Don't inline if it is + a thunk. + (dump_function): Print name of dump flag causing this dump. + * semantics.c (expand_body): Move thunk inline check to + optimize_function. + 2001-06-29 Joseph S. Myers * typeck.c (COMP_TYPE_ATTRIBUTES): Don't define. diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index aee64f5..4e713c3 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -78,7 +78,7 @@ typedef struct inline_data int inlined_stmts; /* We use the same mechanism to build clones that we do to perform inlining. However, there are a few places where we need to - distinguish between those two situations. This flag is true nif + distinguish between those two situations. This flag is true if we are cloning, rather than inlining. */ bool cloning_p; /* Hash table used to prevent walk_tree from visiting the same node @@ -98,6 +98,7 @@ static int inlinable_function_p PARAMS ((tree, inline_data *)); static tree remap_decl PARAMS ((tree, inline_data *)); static void remap_block PARAMS ((tree, tree, inline_data *)); static void copy_scope_stmt PARAMS ((tree *, int *, inline_data *)); +static void optimize_inline_calls PARAMS ((tree)); static tree calls_setjmp_r PARAMS ((tree *, int *, void *)); static void update_cloned_parm PARAMS ((tree, tree)); static void dump_function PARAMS ((enum tree_dump_index, tree)); @@ -934,6 +935,69 @@ expand_calls_inline (tp, id) walk_tree (tp, expand_call_inline, id, id->tree_pruner); } +/* Expand calls to inline functions in the body of FN. */ + +static void +optimize_inline_calls (fn) + tree fn; +{ + inline_data id; + tree prev_fn; + struct saved_scope *s; + + /* Clear out ID. */ + memset (&id, 0, sizeof (id)); + + /* Don't allow recursion into FN. */ + VARRAY_TREE_INIT (id.fns, 32, "fns"); + VARRAY_PUSH_TREE (id.fns, fn); + /* Or any functions that aren't finished yet. */ + prev_fn = NULL_TREE; + if (current_function_decl) + { + VARRAY_PUSH_TREE (id.fns, current_function_decl); + prev_fn = current_function_decl; + } + for (s = scope_chain; s; s = s->prev) + if (s->function_decl && s->function_decl != prev_fn) + { + VARRAY_PUSH_TREE (id.fns, s->function_decl); + prev_fn = s->function_decl; + } + + /* Create the stack of TARGET_EXPRs. */ + VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs"); + + /* Create the list of functions this call will inline. */ + VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns"); + + /* Keep track of the low-water mark, i.e., the point where the first + real inlining is represented in ID.FNS. */ + id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns); + + /* Replace all calls to inline functions with the bodies of those + functions. */ + id.tree_pruner = htab_create (37, htab_hash_pointer, + htab_eq_pointer, NULL); + expand_calls_inline (&DECL_SAVED_TREE (fn), &id); + + /* Clean up. */ + htab_delete (id.tree_pruner); + VARRAY_FREE (id.fns); + VARRAY_FREE (id.target_exprs); + if (DECL_LANG_SPECIFIC (fn)) + { + tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns)); + + memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0), + VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree)); + DECL_INLINED_FNS (fn) = ifn; + } + VARRAY_FREE (id.inlined_fns); + + dump_function (TDI_inlined, fn); +} + /* Optimize the body of FN. */ void @@ -953,64 +1017,14 @@ optimize_function (fn) of the function. */ ++function_depth; - /* Expand calls to inline functions. */ - if (flag_inline_trees) - { - inline_data id; - tree prev_fn; - struct saved_scope *s; - - /* Clear out ID. */ - memset (&id, 0, sizeof (id)); - - /* Don't allow recursion into FN. */ - VARRAY_TREE_INIT (id.fns, 32, "fns"); - VARRAY_PUSH_TREE (id.fns, fn); - /* Or any functions that aren't finished yet. */ - prev_fn = NULL_TREE; - if (current_function_decl) - { - VARRAY_PUSH_TREE (id.fns, current_function_decl); - prev_fn = current_function_decl; - } - for (s = scope_chain; s; s = s->prev) - if (s->function_decl && s->function_decl != prev_fn) - { - VARRAY_PUSH_TREE (id.fns, s->function_decl); - prev_fn = s->function_decl; - } - - /* Create the stack of TARGET_EXPRs. */ - VARRAY_TREE_INIT (id.target_exprs, 32, "target_exprs"); - - /* Create the list of functions this call will inline. */ - VARRAY_TREE_INIT (id.inlined_fns, 32, "inlined_fns"); - - /* Keep track of the low-water mark, i.e., the point where - the first real inlining is represented in ID.FNS. */ - id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns); - - /* Replace all calls to inline functions with the bodies of those - functions. */ - id.tree_pruner = htab_create (37, htab_hash_pointer, - htab_eq_pointer, NULL); - expand_calls_inline (&DECL_SAVED_TREE (fn), &id); - - /* Clean up. */ - htab_delete (id.tree_pruner); - VARRAY_FREE (id.fns); - VARRAY_FREE (id.target_exprs); - if (DECL_LANG_SPECIFIC (fn)) - { - tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns)); - - memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0), - VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree)); - DECL_INLINED_FNS (fn) = ifn; - } - VARRAY_FREE (id.inlined_fns); - } - + if (flag_inline_trees + /* We do not inline thunks, as (a) the backend tries to optimize + the call to the thunkee, (b) tree based inlining breaks that + optimization, (c) virtual functions are rarely inlineable, + and (d) ASM_OUTPUT_MI_THUNK is there to DTRT anyway. */ + && !DECL_THUNK_P (fn)) + optimize_inline_calls (fn); + /* Undo the call to ggc_push_context above. */ --function_depth; @@ -1246,8 +1260,10 @@ dump_function (phase, fn) { fprintf (stream, "\n;; Function %s", decl_as_string (fn, TFF_DECL_SPECIFIERS)); - fprintf (stream, " (%s)", decl_as_string (DECL_ASSEMBLER_NAME (fn), 0)); - fprintf (stream, "\n\n"); + fprintf (stream, " (%s)\n", + decl_as_string (DECL_ASSEMBLER_NAME (fn), 0)); + fprintf (stream, ";; enabled by -%s\n", dump_flag_name (phase)); + fprintf (stream, "\n"); dump_node (fn, TDF_SLIM | flags, stream); dump_end (phase, stream); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index 0dc392a..050e1be 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2408,13 +2408,8 @@ expand_body (fn) timevar_push (TV_INTEGRATION); - /* Optimize the body of the function before expanding it. We do not - optimize thunks, as (1) the backend tries to optimize the call to - the thunkee, (b) the tree based inliner breaks that optimization, - (c) virtual functions are rarely inlineable, and (d) - ASM_OUTPUT_MI_THUNK is there to DTRT anyway. */ - if (!DECL_THUNK_P (fn)) - optimize_function (fn); + /* Optimize the body of the function before expanding it. */ + optimize_function (fn); timevar_pop (TV_INTEGRATION); timevar_push (TV_EXPAND); diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 37645eb..359dcbc 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -239,6 +239,7 @@ in the following sections. -a -ax -d@var{letters} -dumpspecs -dumpmachine -dumpversion @gol -fdump-unnumbered -fdump-translation-unit@r{[}-@var{n}@r{]} -fdump-class-hierarchy@r{[}-@var{n}@r{]} @gol -fdump-ast-original@r{[}-@var{n}@r{]} -fdump-ast-optimized@r{[}-@var{n}@r{]} @gol +-fdump-ast-inlined@r{[}-@var{n}@r{]} @gol -fmem-report -fpretend-float @gol -fprofile-arcs -ftest-coverage -ftime-report @gol -g -g@var{level} -gcoff -gdwarf -gdwarf-1 -gdwarf-1+ -gdwarf-2 @gol @@ -3029,6 +3030,9 @@ The following tree dumps are possible: Dump before any tree based optimization, to @file{@var{file}.original}. @item optimized Dump after all tree based optimization, to @file{@var{file}.optimized}. +@item inlined +Dump after inlining within the body of the function, to +@file{@var{file}.inlined}. @end table @item -fpretend-float @@ -3867,8 +3871,8 @@ the directories you have specified with @option{-I} options (and the current directory, if appropriate) are searched. @xref{Directory Options}, for information on @option{-I}. -By using both @option{-nostdinc} and @option{-I-}, you can limit the include-file -search path to only those directories you specify explicitly. +By using both @option{-nostdinc} and @option{-I-}, you can limit the +include-file search path to only those directories you specify explicitly. @item -remap @opindex remap @@ -4352,6 +4356,10 @@ system header files (use @option{-isystem} for that). If you use more than one @option{-I} option, the directories are scanned in left-to-right order; the standard system directories come after. +GCC will detect and warn you, if a directory is specified with both the +@option{-I} and also is a system search directory (either by default, or +with @option{-isystem}). + @item -I- @opindex I- Any directories you specify with @option{-I} options before the @option{-I-} -- 2.7.4