graph drawing funcationality

Ulrich Drepper drepper@cygnus.com
Tue Oct 13 17:58:00 GMT 1998


Hi,

I append below a patch which adds functionality to egcs so that it can
dump all kind of information in a form which then can be read by other
tools.  So far the only tool is VCG which can be used to draw graphs.

Instead of including a lot of explanations here I wrote a little web
pages which is available at

	http://www.cygnus.com/~drepper/vcg.html

rth already used the patch last night and it seems to be pretty
stable.  In no case it disturbs the normal compiling (except of fixing
one bug).

-- 
---------------.      drepper at gnu.org  ,-.   1325 Chesapeake Terrace
Ulrich Drepper  \    ,-------------------'   \  Sunnyvale, CA 94089 USA
Cygnus Solutions `--' drepper at cygnus.com   `------------------------

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Index: Makefile.in
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/Makefile.in,v
retrieving revision 1.179
diff -u -r1.179 Makefile.in
--- Makefile.in	1998/10/12 11:14:08	1.179
+++ Makefile.in	1998/10/13 16:37:02
@@ -645,7 +645,7 @@
  insn-peep.o reorg.o $(SCHED_PREFIX)sched.o final.o recog.o reg-stack.o \
  insn-opinit.o insn-recog.o insn-extract.o insn-output.o insn-emit.o \
  profile.o insn-attrtab.o $(out_object_file) getpwd.o $(EXTRA_OBJS) convert.o \
- mbchar.o dyn-string.o
+ mbchar.o dyn-string.o graph.o
 
 # GEN files are listed separately, so they can be built before doing parallel
 #  makes for cc1 or cc1plus.  Otherwise sequent parallel make attempts to load
@@ -1287,6 +1287,8 @@
 c-iterate.o: c-iterate.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) c-tree.h \
     flags.h toplev.h $(EXPR_H)
 mbchar.o: mbchar.c $(CONFIG_H) system.h gansidecl.h mbchar.h
+graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h rtl.h \
+    hard-reg-set.h basic-block.h
 
 collect2$(exeext): collect2.o tlink.o hash.o cplus-dem.o underscore.o \
 	version.o choose-temp.o mkstemp.o $(LIBDEPS)
Index: flags.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/flags.h,v
retrieving revision 1.21
diff -u -r1.21 flags.h
--- flags.h	1998/10/08 03:30:31	1.21
+++ flags.h	1998/10/13 16:37:02
@@ -502,3 +502,14 @@
 /* Value of the -G xx switch, and whether it was passed or not.  */
 extern int g_switch_value;
 extern int g_switch_set;
+
+/* Nonzero if we dump in VCG format, not plain text.  */
+extern int dump_for_graph;
+
+/* Selection of the graph form.  */
+enum graph_dump_types
+{
+  no_graph = 0,
+  vcg
+};
+extern enum graph_dump_types graph_dump_format;
Index: print-rtl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/print-rtl.c,v
retrieving revision 1.17
diff -u -r1.17 print-rtl.c
--- print-rtl.c	1998/10/06 09:03:35	1.17
+++ print-rtl.c	1998/10/13 16:37:02
@@ -1,5 +1,5 @@
 /* Print RTL for GNU C Compiler.
-   Copyright (C) 1987, 1988, 1992, 1997 Free Software Foundation, Inc.
+   Copyright (C) 1987, 1988, 1992, 1997, 1998 Free Software Foundation, Inc.
 
 This file is part of GNU CC.
 
@@ -60,13 +60,17 @@
    This must be defined here so that programs like gencodes can be linked.  */
 int flag_dump_unnumbered = 0;
 
+/* Nonzero if we are dumping graphical description.  */
+int dump_for_graph;
+
 /* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
 
 static void
 print_rtx (in_rtx)
      register rtx in_rtx;
 {
-  register int i, j;
+  register int i = 0;
+  register int j;
   register char *format_ptr;
   register int is_insn;
 
@@ -79,39 +83,54 @@
 
   if (in_rtx == 0)
     {
-      fprintf (outfile, "(nil)");
+      fputs ("(nil)", outfile);
       sawclose = 1;
       return;
     }
+
+  is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
 
-  /* print name of expression code */
-  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
+  /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
+     in separate nodes and therefore have to handle them special here.  */
+  if (dump_for_graph &&
+      (is_insn || GET_CODE (in_rtx) == NOTE || GET_CODE (in_rtx) == CODE_LABEL
+       || GET_CODE (in_rtx) == BARRIER))
+    {
+      i = 3;
+      indent = 0;
+    }
+  else
+    {
+      /* print name of expression code */
+      fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
 
-  if (in_rtx->in_struct)
-    fprintf (outfile, "/s");
+      if (in_rtx->in_struct)
+	fputs ("/s", outfile);
 
-  if (in_rtx->volatil)
-    fprintf (outfile, "/v");
+      if (in_rtx->volatil)
+	fputs ("/v", outfile);
 
-  if (in_rtx->unchanging)
-    fprintf (outfile, "/u");
+      if (in_rtx->unchanging)
+	fputs ("/u", outfile);
 
-  if (in_rtx->integrated)
-    fprintf (outfile, "/i");
+      if (in_rtx->integrated)
+	fputs ("/i", outfile);
 
-  if (GET_MODE (in_rtx) != VOIDmode)
-    {
-      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
-      if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
-	fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
-      else
-	fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+      if (GET_MODE (in_rtx) != VOIDmode)
+	{
+	  /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
+	  if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
+	    fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
+	  else
+	    fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
+	}
     }
 
-  is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
-  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
+  /* Get the format string and skip the first elements if we have handled
+     them already.  */
+  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
 
-  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
+  for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
     switch (*format_ptr++)
       {
       case 'S':
@@ -141,9 +160,10 @@
 	  }
 
 	if (XSTR (in_rtx, i) == 0)
-	  fprintf (outfile, " \"\"");
+	  fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
 	else
-	  fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
+	  fprintf (outfile, dump_for_graph ? " (\\\"%s\\\")" : " (\"%s\")",
+		   XSTR (in_rtx, i));
 	sawclose = 1;
 	break;
 
@@ -168,7 +188,7 @@
 		     (spaces + (sizeof spaces - 1 - indent * 2)));
 	    sawclose = 0;
 	  }
-	fprintf (outfile, "[ ");
+	fputs ("[ ", outfile);
 	if (NULL != XVEC (in_rtx, i))
 	  {
 	    indent += 2;
@@ -184,7 +204,7 @@
 	  fprintf (outfile, "\n%s",
 		   (spaces + (sizeof spaces - 1 - indent * 2)));
 
-	fprintf (outfile, "] ");
+	fputs ("] ", outfile);
 	sawclose = 1;
 	indent -= 2;
 	break;
@@ -205,7 +225,7 @@
 	    }
 	  else if (flag_dump_unnumbered
 		   && (is_insn || GET_CODE (in_rtx) == NOTE))
-	    fprintf (outfile, "#");
+	    fputc ('#', outfile);
 	  else
 	    fprintf (outfile, " %d", value);
 	}
@@ -230,18 +250,18 @@
 	if (XEXP (in_rtx, i) != NULL)
 	  {
 	    if (flag_dump_unnumbered)
-	      fprintf (outfile, "#");
+	      fputc ('#', outfile);
 	    else
 	      fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
 	  }
 	else
-	  fprintf (outfile, " 0");
+	  fputs (" 0", outfile);
 	sawclose = 0;
 	break;
 
       case 'b':
 	if (XBITMAP (in_rtx, i) == NULL)
-	  fprintf (outfile, " {null}");
+	  fputs (" {null}", outfile);
 	else
 	  bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
 	sawclose = 0;
@@ -253,7 +273,7 @@
 	break;
 
       case '*':
-	fprintf (outfile, " Unknown");
+	fputs (" Unknown", outfile);
 	sawclose = 0;
 	break;
 
@@ -276,8 +296,15 @@
     }
 #endif
 
-  fprintf (outfile, ")");
-  sawclose = 1;
+  if (dump_for_graph
+      && (is_insn || GET_CODE (in_rtx) == NOTE
+	  || GET_CODE (in_rtx) == CODE_LABEL || GET_CODE (in_rtx) == BARRIER))
+    sawclose = 0;
+  else
+    {
+      fputc (')', outfile);
+      sawclose = 1;
+    }
 }
 
 /* Print an rtx on the current line of FILE.  Initially indent IND
@@ -386,7 +413,7 @@
   sawclose = 0;
 
   if (rtx_first == 0)
-    fprintf (outf, "(nil)\n");
+    fputs ("(nil)\n", outf);
   else
     switch (GET_CODE (rtx_first))
       {
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.107
diff -u -r1.107 toplev.c
--- toplev.c	1998/10/10 23:18:32	1.107
+++ toplev.c	1998/10/13 16:37:04
@@ -210,6 +210,10 @@
 				      char *, char *));
 static void print_switch_values PROTO((FILE *, int, int, char *, char *,
 				       char *));
+
+void print_rtl_graph_with_bb PROTO ((const char *, const char *, rtx));
+void clean_graph_dump_file PROTO ((const char *, const char *));
+void finish_graph_dump_file PROTO ((const char *, const char *));
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
@@ -286,6 +290,7 @@
 #ifdef MACHINE_DEPENDENT_REORG
 int mach_dep_reorg_dump = 0;
 #endif
+enum graph_dump_types graph_dump_format;
 
 /* Name for output file of assembly code, specified with -o.  */
 
@@ -2587,50 +2593,122 @@
 	pfatal_with_name (aux_info_file_name);
     }
 
-  /* Clear the dump files file.  */
+  /* Clear the dump files.  */
   if (rtl_dump)
     clean_dump_file (".rtl");
   if (jump_opt_dump)
-    clean_dump_file (".jump");
+    {
+      clean_dump_file (".jump");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".jump");
+    }
   if (addressof_dump)
-    clean_dump_file (".addressof");
+    {
+      clean_dump_file (".addressof");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".addressof");
+    }
   if (cse_dump)
-    clean_dump_file (".cse");
+    {
+      clean_dump_file (".cse");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".cse");
+    }
   if (loop_dump)
-    clean_dump_file (".loop");
+    {
+      clean_dump_file (".loop");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".loop");
+    }
   if (cse2_dump)
-    clean_dump_file (".cse2");
+    {
+      clean_dump_file (".cse2");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".cse2");
+    }
   if (branch_prob_dump)
-    clean_dump_file (".bp");
+    {
+      clean_dump_file (".bp");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".bp");
+    }
   if (flow_dump)
-    clean_dump_file (".flow");
+    {
+      clean_dump_file (".flow");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".flow");
+    }
   if (combine_dump)
-    clean_dump_file (".combine");
+    {
+      clean_dump_file (".combine");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".combine");
+    }
   if (regmove_dump)
-    clean_dump_file (".regmove");
+    {
+      clean_dump_file (".regmove");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".regmove");
+    }
   if (sched_dump)
-    clean_dump_file (".sched");
+    {
+      clean_dump_file (".sched");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".sched");
+    }
   if (local_reg_dump)
-    clean_dump_file (".lreg");
+    {
+      clean_dump_file (".lreg");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".lreg");
+    }
   if (global_reg_dump)
-    clean_dump_file (".greg");
+    {
+      clean_dump_file (".greg");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".greg");
+    }
   if (sched2_dump)
-    clean_dump_file (".sched2");
+    {
+      clean_dump_file (".sched2");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".sched2");
+    }
   if (jump2_opt_dump)
-    clean_dump_file (".jump2");
+    {
+      clean_dump_file (".jump2");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".jump2");
+    }
 #ifdef DELAY_SLOTS
   if (dbr_sched_dump)
-    clean_dump_file (".dbr");
+    {
+      clean_dump_file (".dbr");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".dbr");
+    }
 #endif
   if (gcse_dump)
-    clean_dump_file (".gcse");
+    {
+      clean_dump_file (".gcse");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".gcse");
+    }
 #ifdef STACK_REGS
   if (stack_reg_dump)
-    clean_dump_file (".stack");
+    {
+      clean_dump_file (".stack");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".stack");
+    }
 #endif
 #ifdef MACHINE_DEPENDENT_REORG
   if (mach_dep_reorg_dump)
-    clean_dump_file (".mach");
+    {
+      clean_dump_file (".mach");
+      if (graph_dump_format != no_graph)
+	clean_graph_dump_file (dump_base_name, ".mach");
+    }
 #endif
 
   /* Open assembler code output file.  */
@@ -2738,7 +2816,7 @@
       Therefore, I took out that change.
       In future versions we should find another way to solve
       that dbx problem.  -- rms, 23 May 93.  */
-      
+
   /* Don't let the first function fall at the same address
      as gcc_compiled., if profiling.  */
   if (profile_flag || profile_block_flag)
@@ -2930,7 +3008,7 @@
 	    && ! DECL_ARTIFICIAL (decl)
 	    && ! TREE_PUBLIC (decl))
 	  {
-	    pedwarn_with_decl (decl, 
+	    pedwarn_with_decl (decl,
 			       "`%s' declared `static' but never defined");
 	    /* This symbol is effectively an "extern" declaration now.  */
 	    TREE_PUBLIC (decl) = 1;
@@ -3035,15 +3113,15 @@
   /* Output some stuff at end of file if nec.  */
 
   end_final (dump_base_name);
-   
+
   if (branch_prob_dump)
     open_dump_file (".bp", NULL);
-   
+
   TIMEVAR (dump_time, end_branch_prob (rtl_dump_file));
-   
+
   if (branch_prob_dump)
     close_dump_file (NULL, NULL_RTX);
-   
+
 #ifdef ASM_FILE_END
   ASM_FILE_END (asm_out_file);
 #endif
@@ -3077,6 +3155,53 @@
   if (ferror (asm_out_file) != 0 || fclose (asm_out_file) != 0)
     fatal_io_error (asm_file_name);
 
+  /* Do whatever is necessary to finish printing the graphs.  */
+  if (graph_dump_format != no_graph)
+    {
+      if (jump_opt_dump)
+	finish_graph_dump_file (dump_base_name, ".jump");
+      if (addressof_dump)
+	finish_graph_dump_file (dump_base_name, ".addressof");
+      if (cse_dump)
+	finish_graph_dump_file (dump_base_name, ".cse");
+      if (loop_dump)
+	finish_graph_dump_file (dump_base_name, ".loop");
+      if (cse2_dump)
+	finish_graph_dump_file (dump_base_name, ".cse2");
+      if (branch_prob_dump)
+	finish_graph_dump_file (dump_base_name, ".bp");
+      if (flow_dump)
+	finish_graph_dump_file (dump_base_name, ".flow");
+      if (combine_dump)
+	finish_graph_dump_file (dump_base_name, ".combine");
+      if (regmove_dump)
+	finish_graph_dump_file (dump_base_name, ".regmove");
+      if (sched_dump)
+	finish_graph_dump_file (dump_base_name, ".sched");
+      if (local_reg_dump)
+	finish_graph_dump_file (dump_base_name, ".lreg");
+      if (global_reg_dump)
+	finish_graph_dump_file (dump_base_name, ".greg");
+      if (sched2_dump)
+	finish_graph_dump_file (dump_base_name, ".sched2");
+      if (jump2_opt_dump)
+	finish_graph_dump_file (dump_base_name, ".jump2");
+#ifdef DELAY_SLOTS
+      if (dbr_sched_dump)
+	finish_graph_dump_file (dump_base_name, ".dbr");
+#endif
+      if (gcse_dump)
+	finish_graph_dump_file (dump_base_name, ".gcse");
+#ifdef STACK_REGS
+      if (stack_reg_dump)
+	finish_graph_dump_file (dump_base_name, ".stack");
+#endif
+#ifdef MACHINE_DEPENDENT_REORG
+      if (mach_dep_reorg_dump)
+	finish_graph_dump_file (dump_base_name, ".mach");
+#endif
+    }
+
   /* Print the times.  */
 
   if (! quiet_flag)
@@ -3499,28 +3624,40 @@
 					   !JUMP_AFTER_REGSCAN));
 
       /* Dump rtl code after cse, if we are doing that.  */
-      
+
       if (cse_dump)
-	close_dump_file (print_rtl, insns);
+	{
+	  close_dump_file (print_rtl, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".cse", insns);
+	}
     }
 
   purge_addressof (insns);
   reg_scan (insns, max_reg_num (), 1);
 
   if (addressof_dump)
-    dump_rtl (".addressof", decl, print_rtl, insns);
-  
+    {
+      dump_rtl (".addressof", decl, print_rtl, insns);
+      if (graph_dump_format != no_graph)
+	print_rtl_graph_with_bb (dump_base_name, ".addressof", insns);
+    }
+
   /* Perform global cse.  */
 
   if (optimize > 0 && flag_gcse)
     {
       if (gcse_dump)
 	open_dump_file (".gcse", IDENTIFIER_POINTER (DECL_NAME (decl)));
-      
+
       TIMEVAR (gcse_time, gcse_main (insns, rtl_dump_file));
 
       if (gcse_dump)
-	close_dump_file (print_rtl, insns);
+	{
+	  close_dump_file (print_rtl, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".gcse", insns);
+	}
     }
   /* Move constant computations out of loops.  */
 
@@ -3528,17 +3665,17 @@
     {
       if (loop_dump)
 	open_dump_file (".loop", decl_printable_name (decl, 2));
-	
+
       TIMEVAR
 	(loop_time,
 	 {
 	   if (flag_rerun_loop_opt)
 	     {
 	       /* We only want to perform unrolling once.  */
-	       
+
 	       loop_optimize (insns, rtl_dump_file, 0, 0);
-	       
-	
+
+
 	       /* The first call to loop_optimize makes some instructions
 		  trivially dead.  We delete those instructions now in the
 		  hope that doing so will make the heuristics in loop work
@@ -3551,18 +3688,22 @@
 	     }
 	   loop_optimize (insns, rtl_dump_file, flag_unroll_loops, 1);
 	 });
-      
+
       /* Dump rtl code after loop opt, if we are doing that.  */
-      
+
       if (loop_dump)
-	close_dump_file (print_rtl, insns);
+	{
+	  close_dump_file (print_rtl, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".loop", insns);
+	}
     }
 
   if (optimize > 0)
     {
       if (cse2_dump)
 	open_dump_file (".cse2", decl_printable_name (decl, 2));
-      
+
       if (flag_rerun_cse_after_loop)
 	{
 	  /* Running another jump optimization pass before the second
@@ -3574,7 +3715,7 @@
 	  TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
 					     !JUMP_NOOP_MOVES,
 					     JUMP_AFTER_REGSCAN));
-	  
+
 	  TIMEVAR (cse2_time, reg_scan (insns, max_reg_num (), 0));
 	  TIMEVAR (cse2_time, tem = cse_main (insns, max_reg_num (),
 					      1, rtl_dump_file));
@@ -3591,28 +3732,36 @@
 	  TIMEVAR (jump_time, reg_scan (insns, max_reg_num (), 0));
 	  TIMEVAR (jump_time, thread_jumps (insns, max_reg_num (), 0));
 	}
-      
+
       /* Dump rtl code after cse, if we are doing that.  */
-      
+
       if (cse2_dump)
-	close_dump_file (print_rtl, insns);
+	{
+	  close_dump_file (print_rtl, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".cse2", insns);
+	}
     }
-  
+
   if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
     {
       if (branch_prob_dump)
 	open_dump_file (".bp", decl_printable_name (decl, 2));
-    
+
       TIMEVAR
 	(branch_prob_time,
 	 {
 	   branch_prob (insns, rtl_dump_file);
 	 });
-      
+
       if (branch_prob_dump)
-	close_dump_file (print_rtl, insns);
+	{
+	  close_dump_file (print_rtl, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".bp", insns);
+	}
     }
-  
+
   /* We are no longer anticipating cse in this function, at least.  */
 
   cse_not_expected = 1;
@@ -3631,7 +3780,7 @@
 
   if (flow_dump)
     open_dump_file (".flow", decl_printable_name (decl, 2));
-  
+
   if (obey_regdecls)
     {
       TIMEVAR (flow_time,
@@ -3663,18 +3812,26 @@
   /* Dump rtl after flow analysis.  */
 
   if (flow_dump)
-    close_dump_file (print_rtl_with_bb, insns);
-  
+    {
+      close_dump_file (print_rtl_with_bb, insns);
+      if (graph_dump_format != no_graph)
+	print_rtl_graph_with_bb (dump_base_name, ".flow", insns);
+    }
+
   /* If -opt, try combining insns through substitution.  */
 
   if (optimize > 0)
     {
       TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
-      
+
       /* Dump rtl code after insn combination.  */
-      
+
       if (combine_dump)
-	dump_rtl (".combine", decl, print_rtl_with_bb, insns);
+	{
+	  dump_rtl (".combine", decl, print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".combine", insns);
+	}
     }
 
   /* Register allocation pre-pass, to reduce number of moves
@@ -3683,12 +3840,16 @@
     {
       if (regmove_dump)
 	open_dump_file (".regmove", decl_printable_name (decl, 2));
-      
+
       TIMEVAR (regmove_time, regmove_optimize (insns, max_reg_num (),
 					       rtl_dump_file));
-      
+
       if (regmove_dump)
-	close_dump_file (print_rtl_with_bb, insns);
+	{
+	  close_dump_file (print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".regmove", insns);
+	}
     }
 
   /* Print function header into sched dump now
@@ -3698,16 +3859,20 @@
     {
       if (sched_dump)
 	open_dump_file (".sched", decl_printable_name (decl, 2));
-      
+
       /* Do control and data sched analysis,
 	 and write some of the results to dump file.  */
 
       TIMEVAR (sched_time, schedule_insns (rtl_dump_file));
-      
+
       /* Dump rtl after instruction scheduling.  */
-      
+
       if (sched_dump)
-	close_dump_file (print_rtl_with_bb, insns);
+	{
+	  close_dump_file (print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".sched", insns);
+	}
     }
 
   /* Unless we did stupid register allocation,
@@ -3726,11 +3891,13 @@
   if (local_reg_dump)
     {
       open_dump_file (".lreg", decl_printable_name (decl, 2));
-      
+
       TIMEVAR (dump_time, dump_flow_info (rtl_dump_file));
       TIMEVAR (dump_time, dump_local_alloc (rtl_dump_file));
-      
+
       close_dump_file (print_rtl_with_bb, insns);
+      if (graph_dump_format != no_graph)
+	print_rtl_graph_with_bb (dump_base_name, ".lreg", insns);
     }
 
   if (global_reg_dump)
@@ -3773,6 +3940,8 @@
     {
       TIMEVAR (dump_time, dump_global_regs (rtl_dump_file));
       close_dump_file (print_rtl_with_bb, insns);
+      if (graph_dump_format != no_graph)
+	print_rtl_graph_with_bb (dump_base_name, ".greg", insns);
     }
   if (optimize > 0 && flag_schedule_insns_after_reload)
     {
@@ -3787,7 +3956,11 @@
       /* Dump rtl after post-reorder instruction scheduling.  */
 
       if (sched2_dump)
-	close_dump_file (print_rtl_with_bb, insns);
+	{
+	  close_dump_file (print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".sched2", insns);
+	}
     }
 
 #ifdef LEAF_REGISTERS
@@ -3806,11 +3979,15 @@
       TIMEVAR (jump_time, jump_optimize (insns, JUMP_CROSS_JUMP,
 					 JUMP_NOOP_MOVES,
 					 !JUMP_AFTER_REGSCAN));
-      
+
       /* Dump rtl code after jump, if we are doing that.  */
 
       if (jump2_opt_dump)
-	dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
+	{
+	  dump_rtl (".jump2", decl, print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".jump2", insns);
+	}
     }
 
   /* If a machine dependent reorganization is needed, call it.  */
@@ -3818,7 +3995,11 @@
    MACHINE_DEPENDENT_REORG (insns);
 
    if (mach_dep_reorg_dump)
-     dump_rtl (".mach", decl, print_rtl_with_bb, insns);
+     {
+       dump_rtl (".mach", decl, print_rtl_with_bb, insns);
+       if (graph_dump_format != no_graph)
+	 print_rtl_graph_with_bb (dump_base_name, ".mach", insns);
+     }
 #endif
 
   /* If a scheduling pass for delayed branches is to be done,
@@ -3828,9 +4009,13 @@
   if (optimize > 0 && flag_delayed_branch)
     {
       TIMEVAR (dbr_sched_time, dbr_schedule (insns, rtl_dump_file));
-      
+
       if (dbr_sched_dump)
-	dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
+	{
+	  dump_rtl (".dbr", decl, print_rtl_with_bb, insns);
+	  if (graph_dump_format != no_graph)
+	    print_rtl_graph_with_bb (dump_base_name, ".dbr", insns);
+	}
     }
 #endif
 
@@ -3847,7 +4032,11 @@
   TIMEVAR (stack_reg_time, reg_to_stack (insns, rtl_dump_file));
 
   if (stack_reg_dump)
-    dump_rtl (".stack", decl, print_rtl_with_bb, insns);
+    {
+      dump_rtl (".stack", decl, print_rtl_with_bb, insns);
+      if (graph_dump_format != no_graph)
+	print_rtl_graph_with_bb (dump_base_name, ".stack", insns);
+    }
 #endif
 
   /* Now turn the rtl into assembler code.  */
@@ -3962,6 +4151,9 @@
      *except* what is spent in this function.  */
 
   parse_time -= get_run_time () - start_time;
+
+  /* Reset global variables.  */
+  free_basic_block_vars (0);
 }
 
 static void
@@ -4474,6 +4666,9 @@
 		  case 'N':
 		    regmove_dump = 1;
 		    break;
+		  case 'v':
+		    graph_dump_format = vcg;
+		    break;
 		  case 'y':
 		    set_yydebug (1);
 		    break;



More information about the Gcc-patches mailing list