public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Alexandre Oliva <oliva@adacore.com>,gcc-patches@gcc.gnu.org
Cc: ebotcazou@adacore.com,joseph@codesourcery.com
Subject: Re: introduce -fcallgraph-info option
Date: Sat, 26 Oct 2019 08:12:00 -0000	[thread overview]
Message-ID: <84223B6B-F6F0-4B94-835E-6661E1E1EB6A@suse.de> (raw)
In-Reply-To: <or1rv0run4.fsf@lxoliva.fsfla.org>

On October 26, 2019 6:35:43 AM GMT+02:00, Alexandre Oliva <oliva@adacore.com> wrote:
>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, 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.
>
>Compared with the earlier version, this patch does not modify cgraph,
>and instead adds the required information next to the stage usage
>function data structure, so we only hold one of those at at time.  I've
>switched to vecs from linked lists, for more compact edges and dynamic
>allocation annotations, and arranged for them to be released as soon as
>we've printed out the information.  I have NOT changed the file format,
>because existing tools such as gnatstack consume the current format.
>
>Regstrapped on x86_64-linux-gnu.  Ok to install?

How does it relate to the LTO-dump utility we have now which can in theory provide a more complete view? Maybe some infrastructure can be shared here (the actual dumping of the cgraph?) 

Thanks, 
Richard. 

>
>for  gcc/ChangeLog
From  Eric Botcazou  <ebotcazou@adacore.com>, Alexandre Oliva 
><oliva@adacore.com>
>
>	* common.opt (-fcallgraph-info[=]): New option.
>	* doc/invoke.texi (Debugging 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.
>	(rest_of_handle_thread_prologue_and_epilogue): Release callees
>	and dallocs after output_stack_usage.
>	(record_final_call, record_dynamic_alloc): New.
>	* function.h (struct callee, struct 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_indirect_emitted): 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_indirect_call_node_vcg): New.
>	(dump_final_callee_vcg, dump_final_node_vcg): New.
>	(output_stack_usage): New.
>	(lang_dependent_init): Open and start file if
>	-fcallgraph-info.
>	(finalize): If callgraph_info_file is not null, finish it,
>	close it, and reset callgraph info state.
>
>for  gcc/ada/ChangeLog
>
>	* gcc-interface/misc.c (callgraph_info_file): Delete.
>---
> gcc/ada/gcc-interface/misc.c |    3 -
> gcc/builtins.c               |    4 +
> gcc/calls.c                  |    6 +
> gcc/common.opt               |    8 ++
> gcc/doc/invoke.texi          |   17 ++++
> gcc/explow.c                 |    5 +
> gcc/flag-types.h             |   16 ++++
> gcc/function.c               |   63 ++++++++++++++--
> gcc/function.h               |   25 ++++++
> gcc/gimplify.c               |    4 +
> gcc/optabs-libfuncs.c        |    4 -
> gcc/opts.c                   |   26 ++++++
> gcc/output.h                 |    2 
> gcc/print-tree.c             |   76 +++++++++++++++++++
> gcc/print-tree.h             |    4 +
>gcc/toplev.c                 |  169
>++++++++++++++++++++++++++++++++++--------
> 16 files changed, 381 insertions(+), 51 deletions(-)
>
>diff --git a/gcc/ada/gcc-interface/misc.c
>b/gcc/ada/gcc-interface/misc.c
>index 4abd4d5708a54..d68b37384ff7f 100644
>--- a/gcc/ada/gcc-interface/misc.c
>+++ b/gcc/ada/gcc-interface/misc.c
>@@ -54,9 +54,6 @@
> #include "ada-tree.h"
> #include "gigi.h"
> 
>-/* This symbol needs to be defined for the front-end.  */
>-void *callgraph_info_file = NULL;
>-
>/* Command-line argc and argv.  These variables are global since they
>are
>    imported in back_end.adb.  */
> unsigned int save_argc;
>diff --git a/gcc/builtins.c b/gcc/builtins.c
>index 5d811f113c907..bd302383377ba 100644
>--- a/gcc/builtins.c
>+++ b/gcc/builtins.c
>@@ -5406,6 +5406,10 @@ expand_builtin_alloca (tree exp)
>= allocate_dynamic_stack_space (op0, 0, align, max_size,
>alloca_for_var);
>   result = convert_memory_address (ptr_mode, result);
> 
>+  /* Dynamic allocations for variables are recorded during
>gimplification.  */
>+  if (!alloca_for_var && (flag_callgraph_info &
>CALLGRAPH_INFO_DYNAMIC_ALLOC))
>+    record_dynamic_alloc (exp);
>+
>   return result;
> }
> 
>diff --git a/gcc/calls.c b/gcc/calls.c
>index ae904473d0dc6..67c7c77598a3f 100644
>--- a/gcc/calls.c
>+++ b/gcc/calls.c
>@@ -3759,6 +3759,9 @@ expand_call (tree exp, rtx target, int ignore)
> 
>preferred_unit_stack_boundary = preferred_stack_boundary /
>BITS_PER_UNIT;
> 
>+  if (flag_callgraph_info)
>+    record_final_call (fndecl, EXPR_LOCATION (exp));
>+
>  /* We want to make two insn chains; one for a sibling call, the other
>      for a normal call.  We will select one of the two chains after
>      initial RTL generation is complete.  */
>@@ -5343,6 +5346,9 @@ emit_library_call_value_1 (int retval, rtx
>orgfun, rtx value,
> 
>   before_call = get_last_insn ();
> 
>+  if (flag_callgraph_info)
>+    record_final_call (SYMBOL_REF_DECL (orgfun), UNKNOWN_LOCATION);
>+
>/* We pass the old value of inhibit_defer_pop + 1 to emit_call_1, which
>      will set inhibit_defer_pop to that value.  */
>/* The return type is needed to decide how many bytes the function
>pops.
>diff --git a/gcc/common.opt b/gcc/common.opt
>index cc279f411d796..63d646fba2b42 100644
>--- a/gcc/common.opt
>+++ b/gcc/common.opt
>@@ -1091,6 +1091,14 @@ fbtr-bb-exclusive
> Common Ignore
> Does nothing.  Preserved for backward compatibility.
> 
>+fcallgraph-info
>+Common Report RejectNegative Var(flag_callgraph_info)
>Init(NO_CALLGRAPH_INFO);
>+Output callgraph information on a per-file basis
>+
>+fcallgraph-info=
>+Common Report RejectNegative Joined
>+Output callgraph information on a per-file basis with decorations
>+
> fcall-saved-
> Common Joined RejectNegative Var(common_deferred_options) Defer
>-fcall-saved-<register>	Mark <register> as being preserved across
>functions.
>diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
>index 1407d019d1404..545b842eade71 100644
>--- a/gcc/doc/invoke.texi
>+++ b/gcc/doc/invoke.texi
>@@ -583,8 +583,9 @@ Objective-C and Objective-C++ Dialects}.
> @item Developer Options
> @xref{Developer Options,,GCC Developer Options}.
>@gccoptlist{-d@var{letters}  -dumpspecs  -dumpmachine  -dumpversion
>@gol
>--dumpfullversion  -fchecking  -fchecking=@var{n}  -fdbg-cnt-list @gol
>--fdbg-cnt=@var{counter-value-list} @gol
>+-dumpfullversion  -fcallgraph-info@r{[}=su,da@r{]}
>+-fchecking  -fchecking=@var{n}
>+-fdbg-cnt-list @gol  -fdbg-cnt=@var{counter-value-list} @gol
> -fdisable-ipa-@var{pass_name} @gol
> -fdisable-rtl-@var{pass_name} @gol
> -fdisable-rtl-@var{pass-name}=@var{range-list} @gol
>@@ -14533,6 +14534,18 @@ The files are created in the directory of the
>output file.
> 
> @table @gcctabopt
> 
>+@item -fcallgraph-info
>+@itemx -fcallgraph-info=@var{MARKERS}
>+@opindex fcallgraph-info
>+Makes the compiler output callgraph information for the program, on a
>+per-file basis.  The information is generated in the common VCG
>format.
>+It can be decorated with additional, per-node and/or per-edge
>information,
>+if a list of comma-separated markers is additionally specified.  When
>the
>+@code{su} marker is specified, the callgraph is decorated with stack
>usage
>+information; it is equivalent to @option{-fstack-usage}.  When the
>@code{da}
>+marker is specified, the callgraph is decorated with information about
>+dynamically allocated objects.
>+
> @item -d@var{letters}
> @itemx -fdump-rtl-@var{pass}
> @itemx -fdump-rtl-@var{pass}=@var{filename}
>diff --git a/gcc/explow.c b/gcc/explow.c
>index 7eb854bca4a6d..83c786366c1aa 100644
>--- a/gcc/explow.c
>+++ b/gcc/explow.c
>@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
> #include "dojump.h"
> #include "explow.h"
> #include "expr.h"
>+#include "stringpool.h"
> #include "common/common-target.h"
> #include "output.h"
> #include "params.h"
>@@ -1611,6 +1612,10 @@ set_stack_check_libfunc (const char
>*libfunc_name)
> {
>   gcc_assert (stack_check_libfunc == NULL_RTX);
>   stack_check_libfunc = gen_rtx_SYMBOL_REF (Pmode, libfunc_name);
>+  tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
>+			  get_identifier (libfunc_name), void_type_node);
>+  DECL_EXTERNAL (decl) = 1;
>+  SET_SYMBOL_REF_DECL (stack_check_libfunc, decl);
> }
>
> /* Emit one stack probe at ADDRESS, an address within the stack.  */
>diff --git a/gcc/flag-types.h b/gcc/flag-types.h
>index a2103282d469d..b23d3a271f1ee 100644
>--- a/gcc/flag-types.h
>+++ b/gcc/flag-types.h
>@@ -200,6 +200,22 @@ enum stack_check_type
>   FULL_BUILTIN_STACK_CHECK
> };
> 
>+/* Type of callgraph information.  */
>+enum callgraph_info_type
>+{
>+  /* No information.  */
>+  NO_CALLGRAPH_INFO = 0,
>+
>+  /* Naked callgraph.  */
>+  CALLGRAPH_INFO_NAKED = 1,
>+
>+  /* Callgraph decorated with stack usage information.  */
>+  CALLGRAPH_INFO_STACK_USAGE = 2,
>+
>+  /* Callgraph decoration with dynamic allocation information.  */
>+  CALLGRAPH_INFO_DYNAMIC_ALLOC = 4
>+};
>+
> /* Floating-point contraction mode.  */
> enum fp_contract_mode {
>   FP_CONTRACT_OFF = 0,
>diff --git a/gcc/function.c b/gcc/function.c
>index a1c76a4dd7a84..152f927097c47 100644
>--- a/gcc/function.c
>+++ b/gcc/function.c
>@@ -4725,6 +4725,16 @@ get_last_funcdef_no (void)
>   return funcdef_no;
> }
> 
>+/* Allocate and initialize the stack usage info data structure for the
>+   current function.  */
>+static void
>+allocate_stack_usage_info (void)
>+{
>+  gcc_assert (!cfun->su);
>+  cfun->su = ggc_cleared_alloc<stack_usage> ();
>+  cfun->su->static_stack_size = -1;
>+}
>+
> /* Allocate a function structure for FNDECL and set its contents
>    to the defaults.  Set cfun to the newly-allocated object.
>    Some of the helper functions invoked during initialization assume
>@@ -4802,6 +4812,9 @@ allocate_struct_function (tree fndecl, bool
>abstract_p)
> 
>       if (!profile_flag && !flag_instrument_function_entry_exit)
> 	DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl) = 1;
>+
>+      if (flag_callgraph_info)
>+	allocate_stack_usage_info ();
>     }
> 
>   /* Don't enable begin stmt markers if var-tracking at assignments is
>@@ -4846,11 +4859,8 @@ prepare_function_start (void)
>   init_expr ();
>   default_rtl_profile ();
> 
>-  if (flag_stack_usage_info)
>-    {
>-      cfun->su = ggc_cleared_alloc<stack_usage> ();
>-      cfun->su->static_stack_size = -1;
>-    }
>+  if (flag_stack_usage_info && !flag_callgraph_info)
>+    allocate_stack_usage_info ();
> 
>   cse_not_expected = ! optimize;
> 
>@@ -6373,12 +6383,51 @@ rest_of_handle_thread_prologue_and_epilogue
>(void)
>   cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
> 
>   /* The stack usage info is finalized during prologue expansion.  */
>-  if (flag_stack_usage_info)
>-    output_stack_usage ();
>+  if (flag_stack_usage_info || flag_callgraph_info)
>+    {
>+      output_stack_usage ();
>+      vec_free (cfun->su->dallocs);
>+      cfun->su->dallocs = NULL;
>+      vec_free (cfun->su->callees);
>+      cfun->su->callees = NULL;
>+    }
> 
>   return 0;
> }
> 
>+/* Record a final call to CALLEE at LOCATION.  */
>+
>+void
>+record_final_call (tree callee, location_t location)
>+{
>+  struct callee datum = { location, callee };
>+  vec_safe_push (cfun->su->callees, datum);
>+}
>+
>+/* Record a dynamic allocation made for DECL_OR_EXP.  */
>+
>+void
>+record_dynamic_alloc (tree decl_or_exp)
>+{
>+  struct dalloc datum;
>+
>+  if (DECL_P (decl_or_exp))
>+    {
>+      datum.location = DECL_SOURCE_LOCATION (decl_or_exp);
>+      const char *name = lang_hooks.decl_printable_name (decl_or_exp,
>2);
>+      const char *dot = strrchr (name, '.');
>+      if (dot)
>+	name = dot + 1;
>+      datum.name = ggc_strdup (name);
>+    }
>+  else
>+    {
>+      datum.location = EXPR_LOCATION (decl_or_exp);
>+      datum.name = NULL;
>+    }
>+  vec_safe_push (cfun->su->dallocs, datum);
>+}
>+
> namespace {
> 
> const pass_data pass_data_thread_prologue_and_epilogue =
>diff --git a/gcc/function.h b/gcc/function.h
>index 43ac5dffd2457..ec523765d6eec 100644
>--- a/gcc/function.h
>+++ b/gcc/function.h
>@@ -192,6 +192,18 @@ public:
>   poly_int64 length;
> };
> 
>+struct GTY(()) callee
>+{
>+  location_t location;
>+  tree decl;
>+};
>+
>+struct GTY(()) dalloc
>+{
>+  location_t location;
>+  char const *name;
>+};
>+
> class GTY(()) stack_usage
> {
> public:
>@@ -210,6 +222,13 @@ public:
>   /* Nonzero if the amount of stack space allocated dynamically cannot
>      be bounded at compile-time.  */
>   unsigned int has_unbounded_dynamic_stack_size : 1;
>+
>+  /* Functions called within the function, if callgraph is enabled. 
>*/
>+  vec<callee, va_gc> *callees;
>+
>+  /* Dynamic allocations enocuntered within the function, if callgraph
>+     da is enabled.  */
>+  vec<dalloc, va_gc> *dallocs;
> };
> 
>#define current_function_static_stack_size
>(cfun->su->static_stack_size)
>@@ -406,6 +425,12 @@ void add_local_decl (struct function *fun, tree
>d);
> #define FOR_EACH_LOCAL_DECL(FUN, I, D)		\
>   FOR_EACH_VEC_SAFE_ELT_REVERSE ((FUN)->local_decls, I, D)
> 
>+/* Record a final call to CALLEE at LOCATION.  */
>+void record_final_call (tree callee, location_t location);
>+
>+/* Record a dynamic allocation made for DECL_OR_EXP.  */
>+void record_dynamic_alloc (tree decl_or_exp);
>+
> /* If va_list_[gf]pr_size is set to this, it means we don't know how
>    many units need to be saved.  */
> #define VA_LIST_MAX_GPR_SIZE	255
>diff --git a/gcc/gimplify.c b/gcc/gimplify.c
>index 914bb8eb8d699..394f0fda9c98c 100644
>--- a/gcc/gimplify.c
>+++ b/gcc/gimplify.c
>@@ -1697,6 +1697,10 @@ gimplify_vla_decl (tree decl, gimple_seq *seq_p)
>   t = build2 (MODIFY_EXPR, TREE_TYPE (addr), addr, t);
> 
>   gimplify_and_add (t, seq_p);
>+
>+  /* Record the dynamic allocation associated with DECL if requested. 
>*/
>+  if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
>+    record_dynamic_alloc (decl);
> }
> 
>/* A helper function to be called via walk_tree.  Mark all labels under
>*TP
>diff --git a/gcc/optabs-libfuncs.c b/gcc/optabs-libfuncs.c
>index ef43dae12fb64..8916f7e4da0bb 100644
>--- a/gcc/optabs-libfuncs.c
>+++ b/gcc/optabs-libfuncs.c
>@@ -735,10 +735,6 @@ build_libfunc_function_visibility (const char
>*name, symbol_visibility vis)
>   DECL_VISIBILITY_SPECIFIED (decl) = 1;
>   gcc_assert (DECL_ASSEMBLER_NAME (decl));
> 
>-  /* Zap the nonsensical SYMBOL_REF_DECL for this.  What we're left
>with
>-     are the flags assigned by targetm.encode_section_info.  */
>-  SET_SYMBOL_REF_DECL (XEXP (DECL_RTL (decl), 0), NULL);
>-
>   return decl;
> }
> 
>diff --git a/gcc/opts.c b/gcc/opts.c
>index 10b9f108f8d06..f46b468a968e7 100644
>--- a/gcc/opts.c
>+++ b/gcc/opts.c
>@@ -2433,6 +2433,32 @@ common_handle_option (struct gcc_options *opts,
>       /* Deferred.  */
>       break;
> 
>+    case OPT_fcallgraph_info:
>+      opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
>+      break;
>+
>+    case OPT_fcallgraph_info_:
>+      {
>+	char *my_arg, *p;
>+	my_arg = xstrdup (arg);
>+	p = strtok (my_arg, ",");
>+	while (p)
>+	  {
>+	    if (strcmp (p, "su") == 0)
>+	      {
>+		opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
>+		opts->x_flag_stack_usage_info = true;
>+	      }
>+	    else if (strcmp (p, "da") == 0)
>+	      opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
>+	    else
>+	      return 0;
>+	    p = strtok (NULL, ",");
>+	  }
>+	free (my_arg);
>+      }
>+      break;
>+
>     case OPT_fdiagnostics_show_location_:
>  diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
>       break;
>diff --git a/gcc/output.h b/gcc/output.h
>index 835d63556e6a8..6cccada4aeb1d 100644
>--- a/gcc/output.h
>+++ b/gcc/output.h
>@@ -604,7 +604,7 @@ extern int maybe_assemble_visibility (tree);
> 
>extern int default_address_cost (rtx, machine_mode, addr_space_t,
>bool);
> 
>-/* Output stack usage information.  */
>+/* Stack usage.  */
> extern void output_stack_usage (void);
> 
> #endif /* ! GCC_OUTPUT_H */
>diff --git a/gcc/print-tree.c b/gcc/print-tree.c
>index 6dcbb2dcb1369..bd09ec4d7a7af 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
>diff --git a/gcc/print-tree.h b/gcc/print-tree.h
>index 1d4fe6e8950cc..cbea48c486e3c 100644
>--- a/gcc/print-tree.h
>+++ b/gcc/print-tree.h
>@@ -42,5 +42,9 @@ extern void print_node (FILE *, const char *, tree,
>int,
> extern void print_node_brief (FILE *, const char *, const_tree, int);
> extern void indent_to (FILE *, int);
> #endif
>+#define PRINT_DECL_ORIGIN       0x1
>+#define PRINT_DECL_NAME         0x2
>+#define PRINT_DECL_UNIQUE_NAME  0x4
>+extern void print_decl_identifier (FILE *, tree, int flags);
> 
> #endif  // GCC_PRINT_TREE_H
>diff --git a/gcc/toplev.c b/gcc/toplev.c
>index 1c7002f5c37cd..016f6d688f324 100644
>--- a/gcc/toplev.c
>+++ b/gcc/toplev.c
>@@ -84,6 +84,7 @@ along with GCC; see the file COPYING3.  If not see
> #include "dumpfile.h"
> #include "ipa-fnsummary.h"
> #include "dump-context.h"
>+#include "print-tree.h"
> #include "optinfo-emit-json.h"
> 
> #if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
>@@ -174,6 +175,8 @@ const char *user_label_prefix;
> 
> FILE *asm_out_file;
> FILE *aux_info_file;
>+FILE *callgraph_info_file = NULL;
>+static bool callgraph_info_indirect_emitted = false;
> FILE *stack_usage_file = NULL;
> 
> /* The current working directory of a translation.  It's generally the
>@@ -913,8 +916,8 @@ alloc_for_identifier_to_locale (size_t len)
> }
> 
> /* Output stack usage information.  */
>-void
>-output_stack_usage (void)
>+static void
>+output_stack_usage_1 (FILE *cf)
> {
>   static bool warning_issued = false;
>   enum stack_usage_kind_type { STATIC = 0, DYNAMIC, DYNAMIC_BOUNDED };
>@@ -970,41 +973,22 @@ output_stack_usage (void)
>       stack_usage += current_function_dynamic_stack_size;
>     }
> 
>-  if (stack_usage_file)
>+  if (flag_callgraph_info & CALLGRAPH_INFO_STACK_USAGE)
>     {
>-      expanded_location loc
>-	= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
>-      /* 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 (current_function_decl)),
>'.');
>-      const char *name
>-	= lang_hooks.decl_printable_name (current_function_decl, 2);
>-      if (suffix)
>-	{
>-	  const char *dot = strchr (name, '.');
>-	  while (dot && strcasecmp (dot, suffix) != 0)
>-	    {
>-	      name = dot + 1;
>-	      dot = strchr (name, '.');
>-	    }
>-	}
>+      if (stack_usage)
>+	fprintf (cf, "\\n" HOST_WIDE_INT_PRINT_DEC " bytes (%s)",
>+		 stack_usage,
>+		 stack_usage_kind_str[stack_usage_kind]);
>       else
>-	{
>-	  const char *dot = strrchr (name, '.');
>-	  if (dot)
>-	    name = dot + 1;
>-	}
>+	fputs ("\\n0 bytes", cf);
>+    }
> 
>-      fprintf (stack_usage_file,
>-	       "%s:%d:%d:%s\t" HOST_WIDE_INT_PRINT_DEC"\t%s\n",
>-	       loc.file == NULL ? "(artificial)" : lbasename (loc.file),
>-	       loc.line,
>-	       loc.column,
>-	       name,
>-	       stack_usage,
>-	       stack_usage_kind_str[stack_usage_kind]);
>+  if (stack_usage_file)
>+    {
>+      print_decl_identifier (stack_usage_file, current_function_decl,
>+			     PRINT_DECL_ORIGIN | PRINT_DECL_NAME);
>+      fprintf (stack_usage_file, "\t" HOST_WIDE_INT_PRINT_DEC"\t%s\n",
>+	       stack_usage, stack_usage_kind_str[stack_usage_kind]);
>     }
> 
>   if (warn_stack_usage >= 0 && warn_stack_usage < HOST_WIDE_INT_MAX)
>@@ -1026,6 +1010,106 @@ output_stack_usage (void)
>     }
> }
> 
>+/* Dump placeholder node for indirect calls in VCG format.  */
>+
>+#define INDIRECT_CALL_NAME  "__indirect_call"
>+
>+static void
>+dump_final_indirect_call_node_vcg (FILE *f)
>+{
>+  if (callgraph_info_indirect_emitted)
>+    return;
>+
>+  fputs ("node: { title: \"", f);
>+  fputs (INDIRECT_CALL_NAME, f);
>+  fputs ("\" label: \"", f);
>+  fputs ("Indirect Call Placeholder", f);
>+  fputs ("\" shape : ellipse }\n", f);
>+  callgraph_info_indirect_emitted = true;
>+}
>+
>+/* Dump final cgraph edge in VCG format.  */
>+
>+static void
>+dump_final_callee_vcg (FILE *f, struct callee *callee)
>+{
>+  fputs ("edge: { sourcename: \"", f);
>+  print_decl_identifier (f, current_function_decl,
>PRINT_DECL_UNIQUE_NAME);
>+  fputs ("\" targetname: \"", f);
>+  if (callee->decl)
>+    print_decl_identifier (f, callee->decl, PRINT_DECL_UNIQUE_NAME);
>+  else
>+    fputs (INDIRECT_CALL_NAME, f);
>+  if (LOCATION_LOCUS (callee->location) != UNKNOWN_LOCATION)
>+    {
>+      expanded_location loc;
>+      fputs ("\" label: \"", f);
>+      loc = expand_location (callee->location);
>+      fprintf (f, "%s:%d:%d", loc.file, loc.line, loc.column);
>+    }
>+  fputs ("\" }\n", f);
>+
>+  if (!callee->decl)
>+    dump_final_indirect_call_node_vcg (f);
>+}
>+
>+/* Dump final cgraph node in VCG format.  */
>+
>+static void
>+dump_final_node_vcg (FILE *f)
>+{
>+  fputs ("node: { title: \"", f);
>+  print_decl_identifier (f, current_function_decl,
>PRINT_DECL_UNIQUE_NAME);
>+  fputs ("\" label: \"", f);
>+  print_decl_identifier (f, current_function_decl, PRINT_DECL_NAME);
>+  fputs ("\\n", f);
>+  print_decl_identifier (f, current_function_decl, PRINT_DECL_ORIGIN);
>+
>+  if (DECL_EXTERNAL (current_function_decl))
>+    {
>+      fputs ("\" shape : ellipse }\n", f);
>+      return;
>+    }
>+
>+  if (flag_stack_usage_info
>+      || (flag_callgraph_info & CALLGRAPH_INFO_STACK_USAGE))
>+    output_stack_usage_1 (f);
>+
>+  if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC)
>+    {
>+      fprintf (f, "\\n%u dynamic objects", vec_safe_length
>(cfun->su->dallocs));
>+
>+      unsigned i;
>+      dalloc *cda;
>+      FOR_EACH_VEC_SAFE_ELT (cfun->su->dallocs, i, cda)
>+	{
>+	  expanded_location loc = expand_location (cda->location);
>+	  fprintf (f, "\\n %s", cda->name);
>+	  fprintf (f, " %s:%d:%d", loc.file, loc.line, loc.column);
>+	}
>+    }
>+
>+  fputs ("\" }\n", f);
>+
>+  if (flag_callgraph_info)
>+    {
>+      unsigned i;
>+      callee *c;
>+      FOR_EACH_VEC_SAFE_ELT (cfun->su->callees, i, c)
>+	dump_final_callee_vcg (f, c);
>+    }
>+}
>+
>+/* Output stack usage and callgraph info, as requested.  */
>+void
>+output_stack_usage (void)
>+{
>+  if (flag_callgraph_info)
>+    dump_final_node_vcg (callgraph_info_file);
>+  else
>+    output_stack_usage_1 (NULL);
>+}
>+
> /* Open an auxiliary output file.  */
> static FILE *
> open_auxiliary_file (const char *ext)
>@@ -1900,6 +1984,15 @@ lang_dependent_init (const char *name)
>    /* If stack usage information is desired, open the output file.  */
>       if (flag_stack_usage && !flag_generate_lto)
> 	stack_usage_file = open_auxiliary_file ("su");
>+
>+      /* If call graph information is desired, open the output file. 
>*/
>+      if (flag_callgraph_info && !flag_generate_lto)
>+	{
>+	  callgraph_info_file = open_auxiliary_file ("ci");
>+	  /* Write the file header.  */
>+	  fprintf (callgraph_info_file,
>+		   "graph: { title: \"%s\"\n", main_input_filename);
>+	}
>     }
> 
>   /* This creates various _DECL nodes, so needs to be called after the
>@@ -2044,6 +2137,14 @@ finalize (bool no_backend)
>       stack_usage_file = NULL;
>     }
> 
>+  if (callgraph_info_file)
>+    {
>+      fputs ("}\n", callgraph_info_file);
>+      fclose (callgraph_info_file);
>+      callgraph_info_file = NULL;
>+      callgraph_info_indirect_emitted = false;
>+    }
>+
>   if (seen_error ())
>     coverage_remove_note_file ();
> 

  reply	other threads:[~2019-10-26  7:53 UTC|newest]

Thread overview: 117+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-26  5:30 Alexandre Oliva
2019-10-26  8:12 ` Richard Biener [this message]
2019-10-26 11:21   ` Alexandre Oliva
2019-10-27  9:08     ` Alexandre Oliva
2019-10-28  8:38       ` Richard Biener
2019-10-30 10:12         ` Alexandre Oliva
2019-10-30 11:28           ` Richard Biener
2019-11-02 19:31             ` Alexandre Oliva
2019-11-04  8:28               ` Richard Biener
2019-11-06 10:53                 ` Alexandre Oliva
2019-11-20  4:35                   ` Alexandre Oliva
2019-11-20  9:16                     ` Richard Biener
2019-11-06 15:38                 ` Alexandre Oliva
2019-11-07  7:49                   ` Richard Biener
2019-11-07 10:50                     ` Alexandre Oliva
2019-11-07 11:48                       ` Richard Biener
2019-11-07 12:30                         ` Alexandre Oliva
2019-11-07 14:02                           ` Richard Biener
2019-11-07 22:39                             ` Alexandre Oliva
2019-11-08  8:28                               ` Richard Biener
2019-11-08 23:12                                 ` Eric Gallager
2019-11-15  1:34                                   ` Alexandre Oliva
2019-11-15  1:01                                 ` Alexandre Oliva
2019-11-15  7:30                                   ` Alexandre Oliva
2019-11-15  8:08                                     ` Richard Biener
2019-11-15 22:50                                       ` Alexandre Oliva
2019-12-03 22:44                                   ` Alexandre Oliva
2019-12-09  9:41                                     ` Richard Biener
2019-12-12  1:14                                       ` Alexandre Oliva
2019-12-25 10:05                               ` Alexandre Oliva
2019-12-26 19:00                                 ` drop -aux{dir,base}, revamp -dump{dir,base} (was: Re: introduce -fcallgraph-info option) Alexandre Oliva
2020-01-09 13:33                                   ` Richard Biener
2020-01-09 19:09                                     ` drop -aux{dir,base}, revamp -dump{dir,base} Alexandre Oliva
2020-01-16 11:06                                       ` Alexandre Oliva
2020-01-16 11:15                                         ` Alexandre Oliva
2020-01-17  2:14                                           ` Joseph Myers
2020-01-20 10:38                                         ` Richard Biener
2020-01-22  1:25                                           ` Alexandre Oliva
2020-01-22  8:15                                             ` Richard Biener
2020-01-23 20:06                                               ` Alexandre Oliva
2020-01-24  1:50                                               ` Alexandre Oliva
2020-05-19  8:51                                                 ` Alexandre Oliva
2020-05-19  8:59                                                   ` Alexandre Oliva
2020-05-19  9:29                                                     ` Richard Biener
2020-05-19  8:59                                                   ` Alexandre Oliva
2020-05-19  9:30                                                     ` Richard Biener
2020-05-19  9:00                                                   ` Alexandre Oliva
2020-05-19  9:04                                                   ` Richard Biener
2020-05-22  0:32                                                     ` Alexandre Oliva
2020-05-22  6:05                                                       ` Richard Biener
2020-05-26  7:08                                                         ` Alexandre Oliva
2020-05-26  8:52                                                           ` Richard Biener
2020-05-26  9:02                                                             ` Martin Liška
2020-05-26 10:00                                                             ` Alexandre Oliva
2020-05-26 12:14                                                             ` Alexandre Oliva
2020-05-26 13:52                                                             ` Alexandre Oliva
2020-05-26 13:56                                                               ` Richard Biener
2020-05-27 22:05                                                                 ` Alexandre Oliva
2020-05-27 23:01                                                                   ` Jeff Law
2020-06-02 11:52                                                                   ` Alexandre Oliva
2020-06-02 12:02                                                                     ` Richard Biener
2020-05-27  1:04                                                               ` Broken build (was: Re: drop -aux{dir,base}, revamp -dump{dir,base}) Hans-Peter Nilsson
2020-05-27 14:30                                                                 ` Broken build Alexandre Oliva
2020-05-27 15:04                                                                   ` Hans-Peter Nilsson
2020-05-28  0:53                                                                     ` Alexandre Oliva
2020-05-28  0:39                                                                 ` Anthony Green
2020-06-02 11:29                                                                   ` Alexandre Oliva
2020-06-02 14:07                                                                     ` Hans-Peter Nilsson
2020-05-27  9:45                                                           ` drop -aux{dir,base}, revamp -dump{dir,base} Andreas Schwab
2020-05-27 10:28                                                             ` Andreas Schwab
2020-05-27 14:41                                                               ` Alexandre Oliva
2020-05-27 14:59                                                                 ` Andreas Schwab
2020-06-09 12:29                                                           ` Thomas Schwinge
2020-06-09 12:42                                                             ` BRIG FE testsuite: Fix all dump-scans (Was: Re: drop -aux{dir, base}, revamp -dump{dir, base}) Martin Jambor
2020-06-09 18:31                                                               ` BRIG FE testsuite: Fix all dump-scans (Was: Re: drop -aux{dir,base}, revamp -dump{dir,base}) Mike Stump
2020-06-11 14:28                                                                 ` BRIG FE testsuite: Fix all dump-scans (Was: Re: drop -aux{dir, base}, revamp -dump{dir, base}) Martin Jambor
2020-06-12 20:52                                                                   ` BRIG FE testsuite: Fix all dump-scans (Was: Re: drop -aux{dir,base}, revamp -dump{dir,base}) Mike Stump
2020-06-10 21:50                                                               ` BRIG FE testsuite: Fix all dump-scans Alexandre Oliva
2020-06-23  9:44                                                             ` drop -aux{dir,base}, revamp -dump{dir,base} Alexandre Oliva
2020-06-23 11:30                                                               ` Martin Jambor
2020-06-09 13:08                                                           ` Thomas Schwinge
2020-06-10 22:24                                                             ` Alexandre Oliva
2020-06-17 10:50                                                               ` Tobias Burnus
2020-06-18  2:58                                                                 ` Alexandre Oliva
2020-06-18  6:10                                                             ` Alexandre Oliva
2020-06-18  9:41                                                               ` Tobias Burnus
2020-06-18 10:39                                                                 ` Alexandre Oliva
2020-06-18 12:06                                                                   ` Tobias Burnus
2020-06-30 16:13                                                                     ` Thomas Schwinge
2020-07-14  5:46                                                                       ` Alexandre Oliva
2020-07-24  6:08                                                                         ` Thomas Schwinge
2020-07-24 17:54                                                                           ` Alexandre Oliva
2020-07-14  5:49                                                                       ` Alexandre Oliva
2020-06-19  9:53                                                                 ` Alexandre Oliva
2020-06-19 16:09                                                                   ` Tobias Burnus
2020-06-22  6:08                                                                     ` Alexandre Oliva
2020-06-22  7:07                                                                       ` Tobias Burnus
2020-06-22 14:32                                                                         ` Alexandre Oliva
2020-06-23  8:17                                                                           ` Richard Biener
2020-06-30 16:35                                                                           ` Thomas Schwinge
2020-07-24 12:06                                                                             ` Thomas Schwinge
2020-06-30 18:52                                                                           ` Thomas Schwinge
2020-07-14  4:48                                                                             ` Alexandre Oliva
2020-07-24  6:01                                                                               ` Thomas Schwinge
2020-07-24 18:00                                                                                 ` Alexandre Oliva
2023-11-24 12:46                                                                           ` testsuite: Add 'only_for_offload_target' wrapper for 'scan-offload-tree-dump' etc. (was: drop -aux{dir,base}, revamp -dump{dir,base}) Thomas Schwinge
2020-06-23  9:50                                                             ` drop -aux{dir,base}, revamp -dump{dir,base} Alexandre Oliva
2020-06-30 16:07                                                               ` Thomas Schwinge
2020-07-23 21:12                                                               ` [PR95720] protect gluefile and wrap_flags with -Wl too (was: Re: drop -aux{dir,base}, revamp -dump{dir,base}) Alexandre Oliva
2020-07-24  6:48                                                                 ` Richard Biener
2020-05-26  8:09                                                       ` [wwwdocs] Re: drop -aux{dir,base}, revamp -dump{dir,base} Alexandre Oliva
2019-10-28 23:56 ` introduce -fcallgraph-info option Joseph Myers
2019-10-30  9:22   ` Alexandre Oliva
2019-10-30  9:43   ` Alexandre Oliva
2019-10-30 18:17     ` Joseph Myers
2019-11-06 21:27 ` Thomas Schwinge
2019-11-07 11:23   ` Alexandre Oliva

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=84223B6B-F6F0-4B94-835E-6661E1E1EB6A@suse.de \
    --to=rguenther@suse.de \
    --cc=ebotcazou@adacore.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=joseph@codesourcery.com \
    --cc=oliva@adacore.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).