[tree-profiling] fix some side corners of finalization machinery

Jan Hubicka jh@suse.cz
Tue Nov 2 16:49:00 GMT 2004


Hi,
this is cleaned up version of patch I've commited to tree-profiling.
At adds the function/variable availability classification.  I am not
quite convinced it is the best way around, so if someone have ideas, I
am all ears.
The patch also adds better dumping code

2004-11-02  Jan Hubicka  <jh@suse.cz>
	* cgraph.c (cgraph_varpool_node_name): New function.
	(availability_names): New static variable.
	(dump_cgraph_node): Dump availability.
	(dump_cgraph_varpool_node): New function.
	(dump_varpool): New function.
	(cgraph_function_body_availability): Likewise.
	(cgraph_variable_initializer_availability): Likewise.
	* cgraph.h (availability): New enum
	(dump_varpool,dump_cgraph_varpool_node,
	cgraph_function_availaibility,
	cgraph_variable_initializer_availability): New.
	* cgraphunit.c (cgraph_optimize): Dump varpool.
Index: cgraph.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v
retrieving revision 1.4.4.18.2.12
diff -c -3 -p -r1.4.4.18.2.12 cgraph.c
*** cgraph.c	26 Oct 2004 14:06:51 -0000	1.4.4.18.2.12
--- cgraph.c	31 Oct 2004 21:26:40 -0000
*************** cgraph_node_name (struct cgraph_node *no
*** 450,466 ****
--- 450,480 ----
  {
    return lang_hooks.decl_printable_name (node->decl, 2);
  }
+ /* Return name of the node used in debug output.  */
+ static const char *
+ cgraph_varpool_node_name (struct cgraph_varpool_node *node)
+ {
+   return lang_hooks.decl_printable_name (node->decl, 2);
+ }
+ 
+ /* Names used to print out the availability enum.  */
+ static const char * const availability_names[] = 
+   {"not_available", "overwrittable", "available", "local"};
  
  /* Dump given cgraph node.  */
  void
  dump_cgraph_node (FILE *f, struct cgraph_node *node)
  {
    struct cgraph_edge *edge;
+ 
    fprintf (f, "%s/%i:", cgraph_node_name (node), node->uid);
    if (node->global.inlined_to)
      fprintf (f, " (inline copy in %s/%i)",
  	     cgraph_node_name (node->global.inlined_to),
  	     node->global.inlined_to->uid);
+   fprintf (f, " availability:%s", availability_names [cgraph_function_body_availability (node)]);
+   if (node->local.self_insns)
+     fprintf (f, " %i insns", node->local.self_insns);
    if (node->local.self_insns)
      fprintf (f, " %i insns", node->local.self_insns);
    if (node->global.insns && node->global.insns != node->local.self_insns)
*************** dump_cgraph_node (FILE *f, struct cgraph
*** 503,509 ****
      }
    fprintf (f, "\n");
  }
- 
  /* Dump the callgraph.  */
  
  void
--- 517,522 ----
*************** dump_cgraph (FILE *f)
*** 516,521 ****
--- 529,567 ----
      dump_cgraph_node (f, node);
  }
  
+ /* Dump given cgraph node.  */
+ void
+ dump_cgraph_varpool_node (FILE *f, struct cgraph_varpool_node *node)
+ {
+   fprintf (f, "%s:", cgraph_varpool_node_name (node));
+   fprintf (f, " availability:%s", availability_names [cgraph_variable_initializer_availability (node)]);
+   if (DECL_INITIAL (node->decl))
+     fprintf (f, " initialized");
+   if (node->needed)
+     fprintf (f, " needed");
+   if (node->analyzed)
+     fprintf (f, " analyzed");
+   if (node->finalized)
+     fprintf (f, " finalized");
+   if (node->output)
+     fprintf (f, " output");
+   if (node->externally_visible)
+     fprintf (f, " externally_visible");
+   fprintf (f, "\n");
+ }
+ 
+ /* Dump the callgraph.  */
+ 
+ void
+ dump_varpool (FILE *f)
+ {
+   struct cgraph_varpool_node *node;
+ 
+   fprintf (f, "variable pool:\n\n");
+   for (node = cgraph_varpool_nodes; node; node = node->next_needed)
+     dump_cgraph_varpool_node (f, node);
+ }
+ 
  /* Returns a hash code for P.  */
  
  static hashval_t
*************** cgraph_unnest_node (struct cgraph_node *
*** 737,740 ****
--- 783,833 ----
    *node2 = node->next_nested;
    node->origin = NULL;
  }
+ 
+ /* Return function availability.  See cgraph.h for description of individual
+    return values.  */
+ enum availability
+ cgraph_function_body_availability (struct cgraph_node *node)
+ {
+   if (!node->local.finalized)
+     return AVAIL_NOT_AVAILABLE;
+   if (node->local.local)
+     return AVAIL_LOCAL;
+   if (!node->local.externally_visible)
+     return AVAIL_AVAILABLE;
+   /* If the function can be overwritted, return OVERWRITTABLE.  Take care
+      at least of two notable extensions - the COMDAT functions used to share
+      template instantiations in C++ (this is symmetric to code
+      cp_cannot_inline_tree_fn and probably shall be shared and the inlinability
+      hooks completelly elliminated).
+      ??? Does C++ one definition rule allow us to always return AVAIL_AVAILABLE
+      here?  That would be good reason to preserve this hook
+      Similarly deal with extern inline functions - this is aggain neccesary to
+      get C++ shared functions having keyed templates right and in the C
+      extension documentation we probably should document the requirement of
+      both versions of function (extern inline and offline) having same side
+      effect characteristics as good optimization is what this optimization
+      is about.  */
+   if (!(*targetm.binds_local_p) (node->decl)
+       && !DECL_COMDAT (node->decl) && !DECL_EXTERNAL (node->decl))
+     return AVAIL_OVERWRITTABLE;
+   return AVAIL_AVAILABLE;
+ }
+ 
+ /* Return variable availability.  See cgraph.h for description of individual
+    return values.  */
+ enum availability
+ cgraph_variable_initializer_availability (struct cgraph_varpool_node *node)
+ {
+   if (!node->finalized)
+     return AVAIL_NOT_AVAILABLE;
+   if (!TREE_PUBLIC (node->decl))
+     return AVAIL_AVAILABLE;
+   /* If the variable can be overwritted, return OVERWRITTABLE.  Take care
+      at least of two notable extensions - the COMDAT variables used to share
+      template instantiations in C++.  */
+   if (!(*targetm.binds_local_p) (node->decl) && !DECL_COMDAT (node->decl))
+     return AVAIL_OVERWRITTABLE;
+   return AVAIL_AVAILABLE;
+ }
  #include "gt-cgraph.h"
Index: cgraph.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraph.h,v
retrieving revision 1.1.4.16.2.10
diff -c -3 -p -r1.1.4.16.2.10 cgraph.h
*** cgraph.h	26 Oct 2004 14:06:51 -0000	1.1.4.16.2.10
--- cgraph.h	31 Oct 2004 21:26:40 -0000
*************** extern GTY(()) int cgraph_varpool_n_node
*** 168,176 ****
--- 168,196 ----
  extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_first_unanalyzed_node;
  extern GTY(()) struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
  
+ enum availability
+ {
+   /* Function body/variable initializer is unknown.  */
+   AVAIL_NOT_AVAILABLE,
+   /* Function body/variable initializer is known but might be replaced
+      by different on from other compilation unit and thus can be dealt with only
+      as a hint.  */
+   AVAIL_OVERWRITTABLE,
+   /* Function body/variable initializer is known and will be used in final
+      program.  */
+   AVAIL_AVAILABLE,
+   /* Function body/variable initializer is known and all it's uses are explicitly
+      visible within current unit (ie it's address is never taken and it is not
+      exported to other units).
+      Currently used only for functions.  */
+   AVAIL_LOCAL
+ };
+ 
  /* In cgraph.c  */
  void dump_cgraph (FILE *);
  void dump_cgraph_node (FILE *, struct cgraph_node *);
+ void dump_varpool (FILE *);
+ void dump_cgraph_varpool_node (FILE *, struct cgraph_varpool_node *);
  void cgraph_remove_edge (struct cgraph_edge *);
  void cgraph_remove_node (struct cgraph_node *);
  struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
*************** bool cgraph_varpool_assemble_pending_dec
*** 193,199 ****
  void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
  
  bool cgraph_function_possibly_inlined_p (tree);
! void cgraph_unnest_node (struct cgraph_node *node);
  
  /* In cgraphunit.c  */
  bool cgraph_assemble_pending_functions (void);
--- 213,221 ----
  void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
  
  bool cgraph_function_possibly_inlined_p (tree);
! void cgraph_unnest_node (struct cgraph_node *);
! enum availability cgraph_function_body_availability (struct cgraph_node *);
! enum availability cgraph_variable_initializer_availability (struct cgraph_varpool_node *);
  
  /* In cgraphunit.c  */
  bool cgraph_assemble_pending_functions (void);
Index: cgraphunit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v
retrieving revision 1.1.4.35.2.23
diff -c -3 -p -r1.1.4.35.2.23 cgraphunit.c
*** cgraphunit.c	29 Oct 2004 17:52:03 -0000	1.1.4.35.2.23
--- cgraphunit.c	31 Oct 2004 21:26:41 -0000
*************** cgraph_optimize (void)
*** 1969,1974 ****
--- 1969,1975 ----
      {
        fprintf (cgraph_dump_file, "Marked ");
        dump_cgraph (cgraph_dump_file);
+       dump_varpool (cgraph_dump_file);
      }
  
    ipa_passes ();
*************** cgraph_optimize (void)
*** 1977,1982 ****
--- 1978,1984 ----
      {
        fprintf (cgraph_dump_file, "Optimized ");
        dump_cgraph (cgraph_dump_file);
+       dump_varpool (cgraph_dump_file);
      }
    timevar_pop (TV_CGRAPHOPT);
  



More information about the Gcc-patches mailing list