This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Unify tree/RTL dump file handling (4/5)


This part augments the dump file manager to handle enabling/disabling
of RTL dumps, and to be able to dump RTL files.

Some of the changes in tree-dump.c expose information that I'll need
in part 5, when open_dump_file, close_dump_file, and
enable_rtl_dump_file will go through the routines in tree-dump.c.

The changes in tree-optimize.c, instead, augment execute_todo and
execute_one_pass so that it can dump RTL, and start adding support for
-fdump-rtl-* flags.

Paolo

2004-08-13  Paolo Bonzini  <bonzini@gnu.org>

	* Makefile.in (tree-dump.o): Add new dependencies.
	* cgraph.c (cgraph_remove_node): TDF_all -> TDF_tree_all.
	* cgraphunit.c (cgraph_preserve_function_body_p, cgraph_optimize):
	Likewise.
	* toplev.c (dump_file_name): New.
	* tree-dump.c (dump_enable_all): Add LETTER parameter.
	(struct dump_file_info): Add NUM and LETTER fields.
	(dump_files): Adjust and add RTL dump files.
	(dump_register): Add NUM and LETTER fields.
	(get_dump_file_name, dump_initialized_p, enable_rtl_dump_file): New.
	(dump_begin): Use get_dump_file_name.
	(dump_switch_p_1): Adjust call to dump_enable_all.
	* tree-dump.h (dump_register): Adjust prototype.
	* tree-optimize.c (register_one_dump_file): Take dump file index.
	Support flags for RTL dumps.
	(register_dump_files): Fill in NUM field of struct dump_file_info.
	Track properties both when the gate is executed and when it is not.
	(execute_todo): Dump RTL.  Add PROPERTIES parameter.
	(execute_one_pass): Pass properties to execute_todo.  Handle VCG
	dumps of RTL.
	* tree-pass.h (dump_file_name): New.
	* tree.h (TDF_TREE, TDF_RTL, get_dump_file_name, dump_initialized_p): New.

diff -rpu gcc-backup/gcc/Makefile.in gcc-pass/gcc/Makefile.in
--- gcc-backup/gcc/Makefile.in	2004-08-09 19:40:24.000000000 +0200
+++ gcc-pass/gcc/Makefile.in	2004-08-13 15:15:59.000000000 +0200
@@ -1573,7 +1573,7 @@
    real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H)
 tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(C_TREE_H) $(FLAGS_H) langhooks.h toplev.h output.h $(C_PRAGMA_H) $(RTL_H) \
-   $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h
+   $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h tree-pass.h
 tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \
    $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
diff -rpu gcc-backup/gcc/cgraph.c gcc-pass/gcc/cgraph.c
--- gcc-backup/gcc/cgraph.c	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/cgraph.c	2004-08-08 10:35:32.000000000 +0200
@@ -328,7 +328,7 @@
       else
 	{
           htab_clear_slot (cgraph_hash, slot);
-	  if (!dump_enabled_p (TDI_all))
+	  if (!dump_enabled_p (TDI_tree_all))
 	    {
               DECL_SAVED_TREE (node->decl) = NULL;
 	      DECL_STRUCT_FUNCTION (node->decl) = NULL;
@@ -356,7 +356,7 @@
 	    || (!n->global.inlined_to
 		&& !TREE_ASM_WRITTEN (n->decl) && !DECL_EXTERNAL (n->decl)))
 	  break;
-      if (!n && !dump_enabled_p (TDI_all))
+      if (!n && !dump_enabled_p (TDI_tree_all))
 	{
 	  DECL_SAVED_TREE (node->decl) = NULL;
 	  DECL_STRUCT_FUNCTION (node->decl) = NULL;
diff -rpu gcc-backup/gcc/cgraphunit.c gcc-pass/gcc/cgraphunit.c
--- gcc-backup/gcc/cgraphunit.c	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/cgraphunit.c	2004-08-08 10:35:32.000000000 +0200
@@ -1712,7 +1712,7 @@
 {
   struct cgraph_node *node;
   /* Keep the body; we're going to dump it.  */
-  if (dump_enabled_p (TDI_all))
+  if (dump_enabled_p (TDI_tree_all))
     return true;
   if (!cgraph_global_info_ready)
     return (DECL_INLINE (decl) && !flag_really_no_inline);
@@ -1771,7 +1771,7 @@
   /* Double check that all inline clones are gone and that all
      function bodies have been released from memory.  */
   if (flag_unit_at_a_time
-      && !dump_enabled_p (TDI_all)
+      && !dump_enabled_p (TDI_tree_all)
       && !(sorrycount || errorcount))
     {
       struct cgraph_node *node;
diff -rpu gcc-backup/gcc/toplev.c gcc-pass/gcc/toplev.c
--- gcc-backup/gcc/toplev.c	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/toplev.c	2004-08-08 10:45:51.000000000 +0200
@@ -418,6 +418,7 @@
 FILE *aux_info_file;
 FILE *dump_file = NULL;
 FILE *cgraph_dump_file = NULL;
+char *dump_file_name;
 
 /* The current working directory of a translation.  It's generally the
    directory from which compilation was initiated, but a preprocessed
diff -rpu gcc-backup/gcc/tree-dump.c gcc-pass/gcc/tree-dump.c
--- gcc-backup/gcc/tree-dump.c	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-dump.c	2004-08-13 15:45:35.000000000 +0200
@@ -28,6 +28,7 @@
 #include "diagnostic.h"
 #include "toplev.h"
 #include "tree-dump.h"
+#include "tree-pass.h"
 #include "langhooks.h"
 #include "tree-iterator.h"
 
@@ -37,7 +38,7 @@
 static void dump_new_line (dump_info_p);
 static void dump_maybe_newline (dump_info_p);
 static void dump_string_field (dump_info_p, const char *, const char *);
-static void dump_enable_all (int);
+static int dump_enable_all (int, int);
 
 /* Add T to the end of the queue of nodes to dump.  Returns the index
    assigned to T.  */
@@ -658,15 +659,7 @@
     }
   splay_tree_delete (di.nodes);
 }
-
-/* Define a tree dump switch.  */
-struct dump_file_info
-{
-  const char *suffix;		/* suffix to give output file.  */
-  const char *swtch;		/* command line switch */
-  int flags;			/* user flags */
-  int state;			/* state of play */
-};
+
 
 /* Table of tree dump switches. This must be consistent with the
    TREE_DUMP_INDEX enumeration in tree.h */
@@ -714,7 +746,8 @@
 };
 
 unsigned int
-dump_register (const char *suffix, const char *swtch)
+dump_register (const char *suffix, const char *swtch, int flags,
+	       unsigned int num, int letter)
 {
   size_t this = extra_dump_files_in_use++;
 
@@ -732,19 +765,22 @@
   memset (&extra_dump_files[this], 0, sizeof (struct dump_file_info));
   extra_dump_files[this].suffix = suffix;
   extra_dump_files[this].swtch = swtch;
+  extra_dump_files[this].flags = flags;
+  extra_dump_files[this].num = num;
+  extra_dump_files[this].letter = letter;
 
   return this + TDI_end;
 }
 
 /* Return the dump_file_info for the given phase.  */
 
-static struct dump_file_info *
+struct dump_file_info *
 get_dump_file_info (enum tree_dump_index phase)
 {
   if (phase < TDI_end)
     return &dump_files[phase];
   else if (phase - TDI_end >= extra_dump_files_in_use)
-    abort ();
+    return NULL;
   else
     return extra_dump_files + (phase - TDI_end);
 }
@@ -755,12 +792,10 @@
    enabled, returns NULL.
    Multiple calls will reopen and append to the dump file.  */
 
-FILE *
-dump_begin (enum tree_dump_index phase, int *flag_ptr)
+char *
+get_dump_file_name (enum tree_dump_index phase)
 {
-  FILE *stream;
-  char *name;
-  char dump_id[10];
+  char dump_id[5], *p = dump_id;
   struct dump_file_info *dfi;
 
   if (phase == TDI_none)
@@ -770,10 +805,33 @@
   if (dfi->state == 0)
     return NULL;
 
-  if (snprintf (dump_id, sizeof (dump_id), ".t%02d", phase) < 0)
-    dump_id[0] = '\0';
+  if (dfi->num >= 0 && dfi->num < 100)
+    {
+      *p++ = '.';
+      if (dfi->flags & TDF_TREE)
+        *p++ = 't';
+
+      *p++ = '0' + (dfi->num / 10);
+      *p++ = '0' + (dfi->num % 10);
+    }
+
+  *p = '\0';  
+
+  return concat (dump_base_name, dump_id, dfi->suffix, NULL);
+}
+
+FILE *
+dump_begin (enum tree_dump_index phase, int *flag_ptr)
+{
+  char *name;
+  struct dump_file_info *dfi;
+  FILE *stream;
+
+  if (phase == TDI_none || !dump_enabled_p (phase))
+    return NULL;
 
-  name = concat (dump_base_name, dump_id, dfi->suffix, NULL);
+  name = get_dump_file_name (phase);
+  dfi = get_dump_file_info (phase);
   stream = fopen (name, dfi->state < 0 ? "w" : "a");
   if (!stream)
     error ("could not open dump file `%s': %s", name, strerror (errno));
@@ -796,6 +854,15 @@
   return dfi->state;
 }
 
+/* Returns nonzero if tree dump PHASE has been initialized.  */
+
+int
+dump_initialized_p (enum tree_dump_index phase)
+{
+  struct dump_file_info *dfi = get_dump_file_info (phase);
+  return dfi->state > 0;
+}
+
 /* Returns the switch name of PHASE.  */
 
 const char *
@@ -814,28 +881,33 @@
   fclose (stream);
 }
 
-/* Enable all tree dumps.  */
+/* Enable all tree dumps.  Return number of enabled tree dumps.  */
 
-static void
-dump_enable_all (int flags)
+static int
+dump_enable_all (int flags, int letter)
 {
+  int n = 0;
   size_t i;
 
   for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
-    {
-      dump_files[i].state = -1;
-      dump_files[i].flags = flags;
-    }
+    if ((dump_files[i].flags & flags)
+	&& (letter == 0 || letter == dump_files[i].letter))
+      {
+        dump_files[i].state = -1;
+        dump_files[i].flags = flags;
+        n++;
+      }
 
   for (i = 0; i < extra_dump_files_in_use; i++)
-    {
-      extra_dump_files[i].state = -1;
-      extra_dump_files[i].flags = flags;
-    }
+    if ((extra_dump_files[i].flags & flags)
+	&& (letter == 0 || letter == extra_dump_files[i].letter))
+      {
+        extra_dump_files[i].state = -1;
+        extra_dump_files[i].flags = flags;
+	n++;
+      }
 
-  /* FIXME  -fdump-call-graph is broken.  */
-  dump_files[TDI_xml].state = 0;
-  dump_files[TDI_xml].flags = 0;
+  return n;
 }
 
 /* Parse ARG as a dump switch. Return nonzero if it is, and store the
@@ -882,11 +954,12 @@
     }
 
   dfi->state = -1;
-  dfi->flags = flags;
+  dfi->flags |= flags;
 
-  /* Process -fdump-tree-all by enabling all the known dumps.  */
+  /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
+     known dumps.  */
   if (dfi->suffix == NULL)
-    dump_enable_all (flags);
+    dump_enable_all (dfi->flags, 0);
 
   return 1;
 }
diff -rpu gcc-backup/gcc/tree-dump.h gcc-pass/gcc/tree-dump.h
--- gcc-backup/gcc/tree-dump.h	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-dump.h	2004-08-08 10:35:32.000000000 +0200
@@ -88,6 +88,6 @@
 extern void dump_function (enum tree_dump_index, tree);
 extern void dump_function_to_file (tree, FILE *, int);
 
-extern unsigned int dump_register (const char *, const char *);
+extern unsigned int dump_register (const char *, const char *, int, unsigned int, int);
 
 #endif /* ! GCC_TREE_DUMP_H */
diff -rpu gcc-backup/gcc/tree-optimize.c gcc-pass/gcc/tree-optimize.c
--- gcc-backup/gcc/tree-optimize.c	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-optimize.c	2004-08-13 15:56:32.000000000 +0200
@@ -47,6 +47,7 @@
 #include "tree-alias-common.h"
 #include "ggc.h"
 #include "cgraph.h"
+#include "graph.h"
 
 
 /* Global variables used to communicate with passes.  */
@@ -205,14 +211,11 @@
    enabled or not.  */
 
 static void
-register_one_dump_file (struct tree_opt_pass *pass)
+register_one_dump_file (struct tree_opt_pass *pass, int n)
 {
   char *dot_name, *flag_name;
   char num[10];
 
-  if (!pass->name)
-    return;
-
   /* See below in next_pass_1.  */
   num[0] = '\0';
   if (pass->static_pass_number != -1)
@@ -220,31 +223,55 @@
 			 ? 1 : pass->static_pass_number));
 
   dot_name = concat (".", pass->name, num, NULL);
-  flag_name = concat ("tree-", pass->name, num, NULL);
-
-  pass->static_pass_number = dump_register (dot_name, flag_name);
+  if (pass->properties_provided & PROP_trees)
+    {
+      flag_name = concat ("tree-", pass->name, num, NULL);
+      pass->static_pass_number = dump_register (dot_name, flag_name,
+                                                TDF_TREE, n + TDI_tree_all, 0);
+    }
+  else
+    {
+      flag_name = concat ("rtl-", pass->name, num, NULL);
+      pass->static_pass_number = dump_register (dot_name, flag_name,
+                                                TDF_RTL, n, pass->letter);
+    }
 }
 
 static int 
 register_dump_files (struct tree_opt_pass *pass, int properties)
 {
+  static int n = 0;
   do
     {
-      /* Verify that all required properties are present.  */
-      if (pass->properties_required & ~properties)
-        abort ();
-
-      if (pass->properties_destroyed & pass->properties_provided)
-        abort ();
+      int new_properties;
+      int pass_number;
 
       pass->properties_required = properties;
-      pass->properties_provided = properties =
+      new_properties =
         (properties | pass->properties_provided) & ~pass->properties_destroyed;
 
-      if (properties & PROP_trees)
-        register_one_dump_file (pass);
+      /* Reset the counter when we reach RTL-based passes.  */
+      if ((pass->properties_provided ^ pass->properties_required) & PROP_rtl)
+        n = 0;
+
+      pass_number = n;
+      if (pass->name)
+        n++;
+
       if (pass->sub)
-	properties = register_dump_files (pass->sub, properties);
+        new_properties = register_dump_files (pass->sub, new_properties);
+
+      /* If we have a gate, combine the properties that we could have with
+         and without the pass being examined.  */
+      if (pass->gate)
+        properties &= new_properties;
+      else
+        properties = new_properties;
+
+      pass->properties_provided = properties;
+      if (pass->name)
+        register_one_dump_file (pass, pass_number);
+
       pass = pass->next;
     }
   while (pass);
@@ -381,7 +408,7 @@
 static unsigned int last_verified;
 
 static void
-execute_todo (unsigned int flags)
+execute_todo (int properties, unsigned int flags)
 {
   if (flags & TODO_rename_vars)
     {
@@ -391,8 +418,13 @@
 
   if ((flags & TODO_dump_func) && dump_file)
     {
-      dump_function_to_file (current_function_decl,
-			     dump_file, dump_flags);
+      if (properties & PROP_trees)
+        dump_function_to_file (current_function_decl,
+                               dump_file, dump_flags);
+      else if (properties & PROP_cfg)
+        print_rtl_with_bb (dump_file, get_insns ());
+      else
+        print_rtl (dump_file, get_insns ());
 
       /* Flush the file.  If verification fails, we won't be able to
 	 close the file before aborting.  */
@@ -428,11 +460,13 @@
   /* Run pre-pass verification.  */
   todo = pass->todo_flags_start & ~last_verified;
   if (todo)
-    execute_todo (todo);
+    execute_todo (pass->properties_required, todo);
 
   /* If a dump file name is present, open it if enabled.  */
   if (pass->static_pass_number != -1)
     {
+      bool initializing_dump = !dump_initialized_p (pass->static_pass_number);
+      dump_file_name = get_dump_file_name (pass->static_pass_number);
       dump_file = dump_begin (pass->static_pass_number, &dump_flags);
       if (dump_file)
 	{
@@ -440,8 +474,19 @@
 	  dname = lang_hooks.decl_printable_name (current_function_decl, 2);
 	  aname = (IDENTIFIER_POINTER
 		   (DECL_ASSEMBLER_NAME (current_function_decl)));
-	  fprintf (dump_file, "\n;; Function %s (%s)\n\n", dname, aname);
+          fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
+             cfun->function_frequency == FUNCTION_FREQUENCY_HOT
+             ? " (hot)"
+             : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
+             ? " (unlikely executed)"
+             : "");
 	}
+
+      if (initializing_dump
+          && graph_dump_format != no_graph
+	  && (pass->properties_provided & (PROP_cfg | PROP_rtl))
+	      == (PROP_cfg | PROP_rtl))
+        clean_graph_dump_file (dump_file_name);
     }
 
   /* If a timevar is present, start it.  */
@@ -452,15 +497,25 @@
   if (pass->execute)
     pass->execute ();
 
+  if (dump_file
+      && (pass->properties_provided & (PROP_cfg | PROP_rtl))
+	  == (PROP_cfg | PROP_rtl))
+    print_rtl_graph_with_bb (dump_file_name, get_insns ());
+
   /* Run post-pass cleanup and verification.  */
   todo = pass->todo_flags_finish;
   last_verified = todo & TODO_verify_all;
   if (todo)
-    execute_todo (todo);
+    execute_todo (pass->properties_provided, todo);
 
   /* Close down timevar and dump file.  */
   if (pass->tv_id)
     timevar_pop (pass->tv_id);
+  if (dump_file_name)
+    {
+      free ((char *) dump_file_name);
+      dump_file_name = NULL;
+    }
   if (dump_file)
     {
       dump_end (pass->static_pass_number, dump_file);
diff -rpu gcc-backup/gcc/tree-pass.h gcc-pass/gcc/tree-pass.h
--- gcc-backup/gcc/tree-pass.h	2004-08-08 10:20:19.000000000 +0200
+++ gcc-pass/gcc/tree-pass.h	2004-08-13 15:12:53.000000000 +0200
@@ -26,9 +26,13 @@
 /* Global variables used to communicate with passes.  */
 extern FILE *dump_file;
 extern int dump_flags;
+extern const char *dump_file_name;
 
 extern struct bitmap_head_def *vars_to_rename;
 
+/* Return the dump_file_info for the given phase.  */
+extern struct dump_file_info *get_dump_file_info (enum tree_dump_index);
+
 /* Describe one pass.  */
 struct tree_opt_pass
 {
diff -rpu gcc-backup/gcc/tree.h gcc-pass/gcc/tree.h
--- gcc-backup/gcc/tree.h	2004-08-09 19:40:24.000000000 +0200
+++ gcc-pass/gcc/tree.h	2004-08-13 15:27:09.000000000 +0200
@@ -3689,8 +3689,8 @@
   TDI_end
 };
 
-/* Bit masks to control tree dumping. Not all values are applicable to
-   all tree dumps. Add new ones at the end. When you define new
+/* Bit masks to control dumping. Not all values are applicable to
+   all dumps. Add new ones at the end. When you define new
    values, extend the DUMP_OPTIONS array in tree-dump.c */
 #define TDF_ADDRESS	(1 << 0)	/* dump node addresses */
 #define TDF_SLIM	(1 << 1)	/* don't go wild following links */
@@ -3708,11 +3748,15 @@
 #define TDF_LINENO	(1 << 7)	/* display statement line numbers */
 #define TDF_UID		(1 << 8)	/* display decl UIDs */
 
+#define TDF_TREE	(1 << 9)	/* is a tree dump */
+#define TDF_RTL		(1 << 10)	/* is a RTL dump */
 
 typedef struct dump_info *dump_info_p;
 
+extern char *get_dump_file_name (enum tree_dump_index);
 extern int dump_flag (dump_info_p, int, tree);
 extern int dump_enabled_p (enum tree_dump_index);
+extern int dump_initialized_p (enum tree_dump_index);
 extern FILE *dump_begin (enum tree_dump_index, int *);
 extern void dump_end (enum tree_dump_index, FILE *);
 extern void dump_node (tree, int, FILE *);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]