diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2019-11-06 10:57:18 +0000 |
---|---|---|
committer | Alexandre Oliva <aoliva@gcc.gnu.org> | 2019-11-06 10:57:18 +0000 |
commit | 3cf3da88be453f3fceaa596ee78be8d1e5aa21ca (patch) | |
tree | ead0ae87adfe46ab5e364107f3cfe9d60d9d3761 /gcc/print-tree.c | |
parent | 5d183d1740d8d8b84991f186ce4d992ee799536f (diff) | |
download | gcc-3cf3da88be453f3fceaa596ee78be8d1e5aa21ca.zip gcc-3cf3da88be453f3fceaa596ee78be8d1e5aa21ca.tar.gz gcc-3cf3da88be453f3fceaa596ee78be8d1e5aa21ca.tar.bz2 |
introduce -fcallgraph-info option
This was first submitted many years ago
https://gcc.gnu.org/ml/gcc-patches/2010-10/msg02468.html
The command line option -fcallgraph-info is added and makes the
compiler generate another output file (xxx.ci) for each compilation
unit (or LTO partitoin), which is a valid VCG file (you can launch
your favorite VCG viewer on it unmodified) and contains the "final"
callgraph of the unit. "final" is a bit of a misnomer as this is
actually the callgraph at RTL expansion time, but since most
high-level optimizations are done at the Tree level and RTL doesn't
usually fiddle with calls, it's final in almost all cases. Moreover,
the nodes can be decorated with additional info: -fcallgraph-info=su
adds stack usage info and -fcallgraph-info=da dynamic allocation info.
for gcc/ChangeLog
From Eric Botcazou <ebotcazou@adacore.com>, Alexandre Oliva <oliva@adacore.com>
* common.opt (-fcallgraph-info[=]): New option.
* doc/invoke.texi (Developer options): Document it.
* opts.c (common_handle_option): Handle it.
* builtins.c (expand_builtin_alloca): Record allocation if
-fcallgraph-info=da.
* calls.c (expand_call): If -fcallgraph-info, record the call.
(emit_library_call_value_1): Likewise.
* flag-types.h (enum callgraph_info_type): New type.
* explow.c: Include stringpool.h.
(set_stack_check_libfunc): Set SET_SYMBOL_REF_DECL on the symbol.
* function.c (allocate_stack_usage_info): New.
(allocate_struct_function): Call it for -fcallgraph-info.
(prepare_function_start): Call it otherwise.
(record_final_call, record_dynamic_alloc): New.
* function.h (struct callinfo_callee): New.
(CALLEE_FROM_CGRAPH_P): New.
(struct callinfo_dalloc): New.
(struct stack_usage): Add callees and dallocs.
(record_final_call, record_dynamic_alloc): Declare.
* gimplify.c (gimplify_decl_expr): Record dynamically-allocated
object if -fcallgraph-info=da.
* optabs-libfuncs.c (build_libfunc_function): Keep SYMBOL_REF_DECL.
* print-tree.h (print_decl_identifier): Declare.
(PRINT_DECL_ORIGIN, PRINT_DECL_NAME, PRINT_DECL_UNIQUE_NAME): New.
* print-tree.c: Include print-tree.h.
(print_decl_identifier): New function.
* toplev.c: Include print-tree.h.
(callgraph_info_file): New global variable.
(callgraph_info_external_printed): Likewise.
(output_stack_usage): Rename to...
(output_stack_usage_1): ... this. Make it static, add cf
parameter. If -fcallgraph-info=su, print stack usage to cf.
If -fstack-usage, use print_decl_identifier for
pretty-printing.
(INDIRECT_CALL_NAME): New.
(dump_final_node_vcg_start): New.
(dump_final_callee_vcg, dump_final_node_vcg): New.
(output_stack_usage): New.
(lang_dependent_init): Open and start file if
-fcallgraph-info. Allocated callgraph_info_external_printed.
(finalize): If callgraph_info_file is not null, finish it,
close it, and release callgraph_info_external_printed.
for gcc/ada/ChangeLog
* gcc-interface/misc.c (callgraph_info_file): Delete.
Co-Authored-By: Alexandre Oliva <oliva@adacore.com>
From-SVN: r277876
Diffstat (limited to 'gcc/print-tree.c')
-rw-r--r-- | gcc/print-tree.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/gcc/print-tree.c b/gcc/print-tree.c index 6dcbb2d..bd09ec4 100644 --- a/gcc/print-tree.c +++ b/gcc/print-tree.c @@ -1035,6 +1035,82 @@ print_node (FILE *file, const char *prefix, tree node, int indent, fprintf (file, ">"); } +/* Print the identifier for DECL according to FLAGS. */ + +void +print_decl_identifier (FILE *file, tree decl, int flags) +{ + bool needs_colon = false; + const char *name; + char c; + + if (flags & PRINT_DECL_ORIGIN) + { + if (DECL_IS_BUILTIN (decl)) + fputs ("<built-in>", file); + else + { + expanded_location loc + = expand_location (DECL_SOURCE_LOCATION (decl)); + fprintf (file, "%s:%d:%d", loc.file, loc.line, loc.column); + } + needs_colon = true; + } + + if (flags & PRINT_DECL_UNIQUE_NAME) + { + name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + if (!TREE_PUBLIC (decl) + || (DECL_WEAK (decl) && !DECL_EXTERNAL (decl))) + /* The symbol has internal or weak linkage so its assembler name + is not necessarily unique among the compilation units of the + program. We therefore have to further mangle it. But we can't + simply use DECL_SOURCE_FILE because it contains the name of the + file the symbol originates from so, e.g. for function templates + in C++ where the templates are defined in a header file, we can + have symbols with the same assembler name and DECL_SOURCE_FILE. + That's why we use the name of the top-level source file of the + compilation unit. ??? Unnecessary for Ada. */ + name = ACONCAT ((main_input_filename, ":", name, NULL)); + } + else if (flags & PRINT_DECL_NAME) + { + /* We don't want to print the full qualified name because it can be long, + so we strip the scope prefix, but we may need to deal with the suffix + created by the compiler. */ + const char *suffix = strchr (IDENTIFIER_POINTER (DECL_NAME (decl)), '.'); + name = lang_hooks.decl_printable_name (decl, 2); + if (suffix) + { + const char *dot = strchr (name, '.'); + while (dot && strcasecmp (dot, suffix) != 0) + { + name = dot + 1; + dot = strchr (name, '.'); + } + } + else + { + const char *dot = strrchr (name, '.'); + if (dot) + name = dot + 1; + } + } + else + return; + + if (needs_colon) + fputc (':', file); + + while ((c = *name++) != '\0') + { + /* Strip double-quotes because of VCG. */ + if (c == '"') + continue; + fputc (c, file); + } +} + /* Print the node NODE on standard error, for debugging. Most nodes referred to by this one are printed recursively |