xref: /dflybsd-src/contrib/gcc-4.7/gcc/graph.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Output routines for graphical representation.
2*e4b17023SJohn Marino    Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2007, 2008, 2010
3*e4b17023SJohn Marino    Free Software Foundation, Inc.
4*e4b17023SJohn Marino    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino This file is part of GCC.
7*e4b17023SJohn Marino 
8*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
9*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
10*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
11*e4b17023SJohn Marino version.
12*e4b17023SJohn Marino 
13*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
15*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16*e4b17023SJohn Marino for more details.
17*e4b17023SJohn Marino 
18*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
19*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
20*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
21*e4b17023SJohn Marino 
22*e4b17023SJohn Marino #include "config.h"
23*e4b17023SJohn Marino #include "system.h"
24*e4b17023SJohn Marino #include "coretypes.h"
25*e4b17023SJohn Marino #include "tm.h"
26*e4b17023SJohn Marino #include "rtl.h"
27*e4b17023SJohn Marino #include "flags.h"
28*e4b17023SJohn Marino #include "output.h"
29*e4b17023SJohn Marino #include "function.h"
30*e4b17023SJohn Marino #include "hard-reg-set.h"
31*e4b17023SJohn Marino #include "obstack.h"
32*e4b17023SJohn Marino #include "basic-block.h"
33*e4b17023SJohn Marino #include "diagnostic-core.h"
34*e4b17023SJohn Marino #include "graph.h"
35*e4b17023SJohn Marino #include "emit-rtl.h"
36*e4b17023SJohn Marino 
37*e4b17023SJohn Marino static const char *const graph_ext[] =
38*e4b17023SJohn Marino {
39*e4b17023SJohn Marino   /* no_graph */ "",
40*e4b17023SJohn Marino   /* vcg */      ".vcg",
41*e4b17023SJohn Marino };
42*e4b17023SJohn Marino 
43*e4b17023SJohn Marino /* The flag to indicate if output is inside of a building block.  */
44*e4b17023SJohn Marino static int inbb = 0;
45*e4b17023SJohn Marino 
46*e4b17023SJohn Marino static void start_fct (FILE *);
47*e4b17023SJohn Marino static void start_bb (FILE *, int);
48*e4b17023SJohn Marino static void node_data (FILE *, rtx);
49*e4b17023SJohn Marino static void draw_edge (FILE *, int, int, int, int);
50*e4b17023SJohn Marino static void end_fct (FILE *);
51*e4b17023SJohn Marino static void end_bb (FILE *);
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino /* Output text for new basic block.  */
54*e4b17023SJohn Marino static void
start_fct(FILE * fp)55*e4b17023SJohn Marino start_fct (FILE *fp)
56*e4b17023SJohn Marino {
57*e4b17023SJohn Marino   switch (graph_dump_format)
58*e4b17023SJohn Marino     {
59*e4b17023SJohn Marino     case vcg:
60*e4b17023SJohn Marino       fprintf (fp, "\
61*e4b17023SJohn Marino graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n",
62*e4b17023SJohn Marino 	       current_function_name (), current_function_name ());
63*e4b17023SJohn Marino       break;
64*e4b17023SJohn Marino     case no_graph:
65*e4b17023SJohn Marino       break;
66*e4b17023SJohn Marino     }
67*e4b17023SJohn Marino }
68*e4b17023SJohn Marino 
69*e4b17023SJohn Marino static void
start_bb(FILE * fp,int bb)70*e4b17023SJohn Marino start_bb (FILE *fp, int bb)
71*e4b17023SJohn Marino {
72*e4b17023SJohn Marino #if 0
73*e4b17023SJohn Marino   reg_set_iterator rsi;
74*e4b17023SJohn Marino #endif
75*e4b17023SJohn Marino 
76*e4b17023SJohn Marino   switch (graph_dump_format)
77*e4b17023SJohn Marino     {
78*e4b17023SJohn Marino     case vcg:
79*e4b17023SJohn Marino       fprintf (fp, "\
80*e4b17023SJohn Marino graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\
81*e4b17023SJohn Marino label: \"basic block %d",
82*e4b17023SJohn Marino 	       current_function_name (), bb, bb);
83*e4b17023SJohn Marino       inbb = 1; /* Now We are inside of a building block.  */
84*e4b17023SJohn Marino       break;
85*e4b17023SJohn Marino     case no_graph:
86*e4b17023SJohn Marino       break;
87*e4b17023SJohn Marino     }
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino #if 0
90*e4b17023SJohn Marino   /* FIXME Should this be printed?  It makes the graph significantly larger.  */
91*e4b17023SJohn Marino 
92*e4b17023SJohn Marino   /* Print the live-at-start register list.  */
93*e4b17023SJohn Marino   fputc ('\n', fp);
94*e4b17023SJohn Marino   EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[bb], 0, i, rsi)
95*e4b17023SJohn Marino     {
96*e4b17023SJohn Marino       fprintf (fp, " %d", i);
97*e4b17023SJohn Marino       if (i < FIRST_PSEUDO_REGISTER)
98*e4b17023SJohn Marino 	fprintf (fp, " [%s]", reg_names[i]);
99*e4b17023SJohn Marino     }
100*e4b17023SJohn Marino #endif
101*e4b17023SJohn Marino 
102*e4b17023SJohn Marino   switch (graph_dump_format)
103*e4b17023SJohn Marino     {
104*e4b17023SJohn Marino     case vcg:
105*e4b17023SJohn Marino       fputs ("\"\n\n", fp);
106*e4b17023SJohn Marino       break;
107*e4b17023SJohn Marino     case no_graph:
108*e4b17023SJohn Marino       break;
109*e4b17023SJohn Marino     }
110*e4b17023SJohn Marino }
111*e4b17023SJohn Marino 
112*e4b17023SJohn Marino static void
node_data(FILE * fp,rtx tmp_rtx)113*e4b17023SJohn Marino node_data (FILE *fp, rtx tmp_rtx)
114*e4b17023SJohn Marino {
115*e4b17023SJohn Marino   if (PREV_INSN (tmp_rtx) == 0)
116*e4b17023SJohn Marino     {
117*e4b17023SJohn Marino       /* This is the first instruction.  Add an edge from the starting
118*e4b17023SJohn Marino 	 block.  */
119*e4b17023SJohn Marino       switch (graph_dump_format)
120*e4b17023SJohn Marino 	{
121*e4b17023SJohn Marino 	case vcg:
122*e4b17023SJohn Marino 	  fprintf (fp, "\
123*e4b17023SJohn Marino edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
124*e4b17023SJohn Marino 		   current_function_name (),
125*e4b17023SJohn Marino 		   current_function_name (), XINT (tmp_rtx, 0));
126*e4b17023SJohn Marino 	  break;
127*e4b17023SJohn Marino 	case no_graph:
128*e4b17023SJohn Marino 	  break;
129*e4b17023SJohn Marino 	}
130*e4b17023SJohn Marino     }
131*e4b17023SJohn Marino 
132*e4b17023SJohn Marino   switch (graph_dump_format)
133*e4b17023SJohn Marino     {
134*e4b17023SJohn Marino     case vcg:
135*e4b17023SJohn Marino       fprintf (fp, "node: {\n  title: \"%s.%d\"\n  color: %s\n  \
136*e4b17023SJohn Marino label: \"%s %d\n",
137*e4b17023SJohn Marino 	       current_function_name (), XINT (tmp_rtx, 0),
138*e4b17023SJohn Marino 	       NOTE_P (tmp_rtx) ? "lightgrey"
139*e4b17023SJohn Marino 	       : NONJUMP_INSN_P (tmp_rtx) ? "green"
140*e4b17023SJohn Marino 	       : JUMP_P (tmp_rtx) ? "darkgreen"
141*e4b17023SJohn Marino 	       : CALL_P (tmp_rtx) ? "darkgreen"
142*e4b17023SJohn Marino 	       : LABEL_P (tmp_rtx) ?  "\
143*e4b17023SJohn Marino darkgrey\n  shape: ellipse" : "white",
144*e4b17023SJohn Marino 	       GET_RTX_NAME (GET_CODE (tmp_rtx)), XINT (tmp_rtx, 0));
145*e4b17023SJohn Marino       break;
146*e4b17023SJohn Marino     case no_graph:
147*e4b17023SJohn Marino       break;
148*e4b17023SJohn Marino     }
149*e4b17023SJohn Marino 
150*e4b17023SJohn Marino   /* Print the RTL.  */
151*e4b17023SJohn Marino   if (NOTE_P (tmp_rtx))
152*e4b17023SJohn Marino     {
153*e4b17023SJohn Marino       const char *name;
154*e4b17023SJohn Marino       name =  GET_NOTE_INSN_NAME (NOTE_KIND (tmp_rtx));
155*e4b17023SJohn Marino       fprintf (fp, " %s", name);
156*e4b17023SJohn Marino     }
157*e4b17023SJohn Marino   else if (INSN_P (tmp_rtx))
158*e4b17023SJohn Marino     print_rtl_single (fp, PATTERN (tmp_rtx));
159*e4b17023SJohn Marino   else
160*e4b17023SJohn Marino     print_rtl_single (fp, tmp_rtx);
161*e4b17023SJohn Marino 
162*e4b17023SJohn Marino   switch (graph_dump_format)
163*e4b17023SJohn Marino     {
164*e4b17023SJohn Marino     case vcg:
165*e4b17023SJohn Marino       fputs ("\"\n}\n", fp);
166*e4b17023SJohn Marino       break;
167*e4b17023SJohn Marino     case no_graph:
168*e4b17023SJohn Marino       break;
169*e4b17023SJohn Marino     }
170*e4b17023SJohn Marino }
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino static void
draw_edge(FILE * fp,int from,int to,int bb_edge,int color_class)173*e4b17023SJohn Marino draw_edge (FILE *fp, int from, int to, int bb_edge, int color_class)
174*e4b17023SJohn Marino {
175*e4b17023SJohn Marino   const char * color;
176*e4b17023SJohn Marino   switch (graph_dump_format)
177*e4b17023SJohn Marino     {
178*e4b17023SJohn Marino     case vcg:
179*e4b17023SJohn Marino       color = "";
180*e4b17023SJohn Marino       if (color_class == 2)
181*e4b17023SJohn Marino 	color = "color: red ";
182*e4b17023SJohn Marino       else if (bb_edge)
183*e4b17023SJohn Marino 	color = "color: blue ";
184*e4b17023SJohn Marino       else if (color_class == 3)
185*e4b17023SJohn Marino 	color = "color: green ";
186*e4b17023SJohn Marino       fprintf (fp,
187*e4b17023SJohn Marino 	       "edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
188*e4b17023SJohn Marino 	       current_function_name (), from,
189*e4b17023SJohn Marino 	       current_function_name (), to, color);
190*e4b17023SJohn Marino       if (color_class)
191*e4b17023SJohn Marino 	fprintf (fp, "class: %d ", color_class);
192*e4b17023SJohn Marino       fputs ("}\n", fp);
193*e4b17023SJohn Marino       break;
194*e4b17023SJohn Marino     case no_graph:
195*e4b17023SJohn Marino       break;
196*e4b17023SJohn Marino     }
197*e4b17023SJohn Marino }
198*e4b17023SJohn Marino 
199*e4b17023SJohn Marino static void
end_bb(FILE * fp)200*e4b17023SJohn Marino end_bb (FILE *fp)
201*e4b17023SJohn Marino {
202*e4b17023SJohn Marino   switch (graph_dump_format)
203*e4b17023SJohn Marino     {
204*e4b17023SJohn Marino     case vcg:
205*e4b17023SJohn Marino       /* Check if we are inside of a building block.  */
206*e4b17023SJohn Marino       if (inbb != 0)
207*e4b17023SJohn Marino         {
208*e4b17023SJohn Marino           fputs ("}\n", fp);
209*e4b17023SJohn Marino           inbb = 0; /* Now we are outside of a building block.  */
210*e4b17023SJohn Marino         }
211*e4b17023SJohn Marino       break;
212*e4b17023SJohn Marino     case no_graph:
213*e4b17023SJohn Marino       break;
214*e4b17023SJohn Marino     }
215*e4b17023SJohn Marino }
216*e4b17023SJohn Marino 
217*e4b17023SJohn Marino static void
end_fct(FILE * fp)218*e4b17023SJohn Marino end_fct (FILE *fp)
219*e4b17023SJohn Marino {
220*e4b17023SJohn Marino   switch (graph_dump_format)
221*e4b17023SJohn Marino     {
222*e4b17023SJohn Marino     case vcg:
223*e4b17023SJohn Marino       fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n",
224*e4b17023SJohn Marino 	       current_function_name ());
225*e4b17023SJohn Marino       break;
226*e4b17023SJohn Marino     case no_graph:
227*e4b17023SJohn Marino       break;
228*e4b17023SJohn Marino     }
229*e4b17023SJohn Marino }
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino /* Like print_rtl, but also print out live information for the start of each
232*e4b17023SJohn Marino    basic block.  */
233*e4b17023SJohn Marino void
print_rtl_graph_with_bb(const char * base,rtx rtx_first)234*e4b17023SJohn Marino print_rtl_graph_with_bb (const char *base, rtx rtx_first)
235*e4b17023SJohn Marino {
236*e4b17023SJohn Marino   rtx tmp_rtx;
237*e4b17023SJohn Marino   size_t namelen = strlen (base);
238*e4b17023SJohn Marino   size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
239*e4b17023SJohn Marino   char *buf = XALLOCAVEC (char, namelen + extlen);
240*e4b17023SJohn Marino   FILE *fp;
241*e4b17023SJohn Marino 
242*e4b17023SJohn Marino   if (basic_block_info == NULL)
243*e4b17023SJohn Marino     return;
244*e4b17023SJohn Marino 
245*e4b17023SJohn Marino   memcpy (buf, base, namelen);
246*e4b17023SJohn Marino   memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
247*e4b17023SJohn Marino 
248*e4b17023SJohn Marino   fp = fopen (buf, "a");
249*e4b17023SJohn Marino   if (fp == NULL)
250*e4b17023SJohn Marino     return;
251*e4b17023SJohn Marino 
252*e4b17023SJohn Marino   if (rtx_first == 0)
253*e4b17023SJohn Marino     fprintf (fp, "(nil)\n");
254*e4b17023SJohn Marino   else
255*e4b17023SJohn Marino     {
256*e4b17023SJohn Marino       enum bb_state { NOT_IN_BB, IN_ONE_BB, IN_MULTIPLE_BB };
257*e4b17023SJohn Marino       int max_uid = get_max_uid ();
258*e4b17023SJohn Marino       int *start = XNEWVEC (int, max_uid);
259*e4b17023SJohn Marino       int *end = XNEWVEC (int, max_uid);
260*e4b17023SJohn Marino       enum bb_state *in_bb_p = XNEWVEC (enum bb_state, max_uid);
261*e4b17023SJohn Marino       basic_block bb;
262*e4b17023SJohn Marino       int i;
263*e4b17023SJohn Marino 
264*e4b17023SJohn Marino       for (i = 0; i < max_uid; ++i)
265*e4b17023SJohn Marino 	{
266*e4b17023SJohn Marino 	  start[i] = end[i] = -1;
267*e4b17023SJohn Marino 	  in_bb_p[i] = NOT_IN_BB;
268*e4b17023SJohn Marino 	}
269*e4b17023SJohn Marino 
270*e4b17023SJohn Marino       FOR_EACH_BB_REVERSE (bb)
271*e4b17023SJohn Marino 	{
272*e4b17023SJohn Marino 	  rtx x;
273*e4b17023SJohn Marino 	  start[INSN_UID (BB_HEAD (bb))] = bb->index;
274*e4b17023SJohn Marino 	  end[INSN_UID (BB_END (bb))] = bb->index;
275*e4b17023SJohn Marino 	  for (x = BB_HEAD (bb); x != NULL_RTX; x = NEXT_INSN (x))
276*e4b17023SJohn Marino 	    {
277*e4b17023SJohn Marino 	      in_bb_p[INSN_UID (x)]
278*e4b17023SJohn Marino 		= (in_bb_p[INSN_UID (x)] == NOT_IN_BB)
279*e4b17023SJohn Marino 		 ? IN_ONE_BB : IN_MULTIPLE_BB;
280*e4b17023SJohn Marino 	      if (x == BB_END (bb))
281*e4b17023SJohn Marino 		break;
282*e4b17023SJohn Marino 	    }
283*e4b17023SJohn Marino 	}
284*e4b17023SJohn Marino 
285*e4b17023SJohn Marino       /* Tell print-rtl that we want graph output.  */
286*e4b17023SJohn Marino       dump_for_graph = 1;
287*e4b17023SJohn Marino 
288*e4b17023SJohn Marino       /* Start new function.  */
289*e4b17023SJohn Marino       start_fct (fp);
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino       for (tmp_rtx = NEXT_INSN (rtx_first); NULL != tmp_rtx;
292*e4b17023SJohn Marino 	   tmp_rtx = NEXT_INSN (tmp_rtx))
293*e4b17023SJohn Marino 	{
294*e4b17023SJohn Marino 	  int edge_printed = 0;
295*e4b17023SJohn Marino 	  rtx next_insn;
296*e4b17023SJohn Marino 
297*e4b17023SJohn Marino 	  if (start[INSN_UID (tmp_rtx)] < 0 && end[INSN_UID (tmp_rtx)] < 0)
298*e4b17023SJohn Marino 	    {
299*e4b17023SJohn Marino 	      if (BARRIER_P (tmp_rtx))
300*e4b17023SJohn Marino 		continue;
301*e4b17023SJohn Marino 	      if (NOTE_P (tmp_rtx)
302*e4b17023SJohn Marino 		  && (1 || in_bb_p[INSN_UID (tmp_rtx)] == NOT_IN_BB))
303*e4b17023SJohn Marino 		continue;
304*e4b17023SJohn Marino 	    }
305*e4b17023SJohn Marino 
306*e4b17023SJohn Marino 	  if ((i = start[INSN_UID (tmp_rtx)]) >= 0)
307*e4b17023SJohn Marino 	    {
308*e4b17023SJohn Marino 	      /* We start a subgraph for each basic block.  */
309*e4b17023SJohn Marino 	      start_bb (fp, i);
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino 	      if (i == 0)
312*e4b17023SJohn Marino 		draw_edge (fp, 0, INSN_UID (tmp_rtx), 1, 0);
313*e4b17023SJohn Marino 	    }
314*e4b17023SJohn Marino 
315*e4b17023SJohn Marino 	  /* Print the data for this node.  */
316*e4b17023SJohn Marino 	  node_data (fp, tmp_rtx);
317*e4b17023SJohn Marino 	  next_insn = next_nonnote_insn (tmp_rtx);
318*e4b17023SJohn Marino 
319*e4b17023SJohn Marino 	  if ((i = end[INSN_UID (tmp_rtx)]) >= 0)
320*e4b17023SJohn Marino 	    {
321*e4b17023SJohn Marino 	      edge e;
322*e4b17023SJohn Marino 	      edge_iterator ei;
323*e4b17023SJohn Marino 
324*e4b17023SJohn Marino 	      bb = BASIC_BLOCK (i);
325*e4b17023SJohn Marino 
326*e4b17023SJohn Marino 	      /* End of the basic block.  */
327*e4b17023SJohn Marino 	      end_bb (fp);
328*e4b17023SJohn Marino 
329*e4b17023SJohn Marino 	      /* Now specify the edges to all the successors of this
330*e4b17023SJohn Marino 		 basic block.  */
331*e4b17023SJohn Marino 	      FOR_EACH_EDGE (e, ei, bb->succs)
332*e4b17023SJohn Marino 		{
333*e4b17023SJohn Marino 		  if (e->dest != EXIT_BLOCK_PTR)
334*e4b17023SJohn Marino 		    {
335*e4b17023SJohn Marino 		      rtx block_head = BB_HEAD (e->dest);
336*e4b17023SJohn Marino 
337*e4b17023SJohn Marino 		      draw_edge (fp, INSN_UID (tmp_rtx),
338*e4b17023SJohn Marino 				 INSN_UID (block_head),
339*e4b17023SJohn Marino 				 next_insn != block_head,
340*e4b17023SJohn Marino 				 (e->flags & EDGE_ABNORMAL ? 2 : 0));
341*e4b17023SJohn Marino 
342*e4b17023SJohn Marino 		      if (block_head == next_insn)
343*e4b17023SJohn Marino 			edge_printed = 1;
344*e4b17023SJohn Marino 		    }
345*e4b17023SJohn Marino 		  else
346*e4b17023SJohn Marino 		    {
347*e4b17023SJohn Marino 		      draw_edge (fp, INSN_UID (tmp_rtx), 999999,
348*e4b17023SJohn Marino 				 next_insn != 0,
349*e4b17023SJohn Marino 				 (e->flags & EDGE_ABNORMAL ? 2 : 0));
350*e4b17023SJohn Marino 
351*e4b17023SJohn Marino 		      if (next_insn == 0)
352*e4b17023SJohn Marino 			edge_printed = 1;
353*e4b17023SJohn Marino 		    }
354*e4b17023SJohn Marino 		}
355*e4b17023SJohn Marino 	    }
356*e4b17023SJohn Marino 
357*e4b17023SJohn Marino 	  if (!edge_printed)
358*e4b17023SJohn Marino 	    {
359*e4b17023SJohn Marino 	      /* Don't print edges to barriers.  */
360*e4b17023SJohn Marino 	      if (next_insn == 0
361*e4b17023SJohn Marino 		  || !BARRIER_P (next_insn))
362*e4b17023SJohn Marino 		draw_edge (fp, XINT (tmp_rtx, 0),
363*e4b17023SJohn Marino 			   next_insn ? INSN_UID (next_insn) : 999999, 0, 0);
364*e4b17023SJohn Marino 	      else
365*e4b17023SJohn Marino 		{
366*e4b17023SJohn Marino 		  /* We draw the remaining edges in class 3.  We have
367*e4b17023SJohn Marino 		     to skip over the barrier since these nodes are
368*e4b17023SJohn Marino 		     not printed at all.  */
369*e4b17023SJohn Marino 		  do
370*e4b17023SJohn Marino 		    next_insn = NEXT_INSN (next_insn);
371*e4b17023SJohn Marino 		  while (next_insn
372*e4b17023SJohn Marino 			 && (NOTE_P (next_insn)
373*e4b17023SJohn Marino 			     || BARRIER_P (next_insn)));
374*e4b17023SJohn Marino 
375*e4b17023SJohn Marino 		  draw_edge (fp, XINT (tmp_rtx, 0),
376*e4b17023SJohn Marino 			     next_insn ? INSN_UID (next_insn) : 999999, 0, 3);
377*e4b17023SJohn Marino 		}
378*e4b17023SJohn Marino 	    }
379*e4b17023SJohn Marino 	}
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino       dump_for_graph = 0;
382*e4b17023SJohn Marino 
383*e4b17023SJohn Marino       end_fct (fp);
384*e4b17023SJohn Marino 
385*e4b17023SJohn Marino       /* Clean up.  */
386*e4b17023SJohn Marino       free (start);
387*e4b17023SJohn Marino       free (end);
388*e4b17023SJohn Marino       free (in_bb_p);
389*e4b17023SJohn Marino     }
390*e4b17023SJohn Marino 
391*e4b17023SJohn Marino   fclose (fp);
392*e4b17023SJohn Marino }
393*e4b17023SJohn Marino 
394*e4b17023SJohn Marino 
395*e4b17023SJohn Marino /* Similar as clean_dump_file, but this time for graph output files.  */
396*e4b17023SJohn Marino 
397*e4b17023SJohn Marino void
clean_graph_dump_file(const char * base)398*e4b17023SJohn Marino clean_graph_dump_file (const char *base)
399*e4b17023SJohn Marino {
400*e4b17023SJohn Marino   size_t namelen = strlen (base);
401*e4b17023SJohn Marino   size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
402*e4b17023SJohn Marino   char *buf = XALLOCAVEC (char, namelen + extlen);
403*e4b17023SJohn Marino   FILE *fp;
404*e4b17023SJohn Marino 
405*e4b17023SJohn Marino   memcpy (buf, base, namelen);
406*e4b17023SJohn Marino   memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
407*e4b17023SJohn Marino 
408*e4b17023SJohn Marino   fp = fopen (buf, "w");
409*e4b17023SJohn Marino 
410*e4b17023SJohn Marino   if (fp == NULL)
411*e4b17023SJohn Marino     fatal_error ("can%'t open %s: %m", buf);
412*e4b17023SJohn Marino 
413*e4b17023SJohn Marino   gcc_assert (graph_dump_format == vcg);
414*e4b17023SJohn Marino   fputs ("graph: {\nport_sharing: no\n", fp);
415*e4b17023SJohn Marino 
416*e4b17023SJohn Marino   fclose (fp);
417*e4b17023SJohn Marino }
418*e4b17023SJohn Marino 
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino /* Do final work on the graph output file.  */
421*e4b17023SJohn Marino void
finish_graph_dump_file(const char * base)422*e4b17023SJohn Marino finish_graph_dump_file (const char *base)
423*e4b17023SJohn Marino {
424*e4b17023SJohn Marino   size_t namelen = strlen (base);
425*e4b17023SJohn Marino   size_t extlen = strlen (graph_ext[graph_dump_format]) + 1;
426*e4b17023SJohn Marino   char *buf = XALLOCAVEC (char, namelen + extlen);
427*e4b17023SJohn Marino   FILE *fp;
428*e4b17023SJohn Marino 
429*e4b17023SJohn Marino   memcpy (buf, base, namelen);
430*e4b17023SJohn Marino   memcpy (buf + namelen, graph_ext[graph_dump_format], extlen);
431*e4b17023SJohn Marino 
432*e4b17023SJohn Marino   fp = fopen (buf, "a");
433*e4b17023SJohn Marino   if (fp != NULL)
434*e4b17023SJohn Marino     {
435*e4b17023SJohn Marino       gcc_assert (graph_dump_format == vcg);
436*e4b17023SJohn Marino       fputs ("}\n", fp);
437*e4b17023SJohn Marino       fclose (fp);
438*e4b17023SJohn Marino     }
439*e4b17023SJohn Marino }
440