print-rtl.c revision 18334
1/* Print RTL for GNU C Compiler.
2   Copyright (C) 1987, 1988, 1992 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING.  If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA.  */
20
21
22#include "config.h"
23#include <ctype.h>
24#include <stdio.h>
25#include "rtl.h"
26
27
28/* How to print out a register name.
29   We don't use PRINT_REG because some definitions of PRINT_REG
30   don't work here.  */
31#ifndef DEBUG_PRINT_REG
32#define DEBUG_PRINT_REG(RTX, CODE, FILE) \
33  fprintf ((FILE), "%d %s", REGNO (RTX), reg_names[REGNO (RTX)])
34#endif
35
36/* Array containing all of the register names */
37
38#ifdef DEBUG_REGISTER_NAMES
39static char *reg_names[] = DEBUG_REGISTER_NAMES;
40#else
41static char *reg_names[] = REGISTER_NAMES;
42#endif
43
44static FILE *outfile;
45
46char spaces[] = "                                                                                                                                                                ";
47
48static int sawclose = 0;
49
50/* Names for patterns.  Non-zero only when linked with insn-output.c.  */
51
52extern char **insn_name_ptr;
53
54/* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
55
56static void
57print_rtx (in_rtx)
58     register rtx in_rtx;
59{
60  static int indent;
61  register int i, j;
62  register char *format_ptr;
63  register int is_insn;
64
65  if (sawclose)
66    {
67      fprintf (outfile, "\n%s",
68	       (spaces + (sizeof spaces - 1 - indent * 2)));
69      sawclose = 0;
70    }
71
72  if (in_rtx == 0)
73    {
74      fprintf (outfile, "(nil)");
75      sawclose = 1;
76      return;
77    }
78
79  /* print name of expression code */
80  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
81
82  if (in_rtx->in_struct)
83    fprintf (outfile, "/s");
84
85  if (in_rtx->volatil)
86    fprintf (outfile, "/v");
87
88  if (in_rtx->unchanging)
89    fprintf (outfile, "/u");
90
91  if (in_rtx->integrated)
92    fprintf (outfile, "/i");
93
94  if (GET_MODE (in_rtx) != VOIDmode)
95    {
96      /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
97      if (GET_CODE (in_rtx) == EXPR_LIST || GET_CODE (in_rtx) == INSN_LIST)
98	fprintf (outfile, ":%s", GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
99      else
100	fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
101    }
102
103  is_insn = (GET_RTX_CLASS (GET_CODE (in_rtx)) == 'i');
104  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
105
106  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
107    switch (*format_ptr++)
108      {
109      case 'S':
110      case 's':
111	if (XSTR (in_rtx, i) == 0)
112	  fprintf (outfile, " \"\"");
113	else
114	  fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
115	sawclose = 1;
116	break;
117
118	/* 0 indicates a field for internal use that should not be printed.  */
119      case '0':
120	break;
121
122      case 'e':
123	indent += 2;
124	if (!sawclose)
125	  fprintf (outfile, " ");
126	print_rtx (XEXP (in_rtx, i));
127	indent -= 2;
128	break;
129
130      case 'E':
131      case 'V':
132	indent += 2;
133	if (sawclose)
134	  {
135	    fprintf (outfile, "\n%s",
136		     (spaces + (sizeof spaces - 1 - indent * 2)));
137	    sawclose = 0;
138	  }
139	fprintf (outfile, "[ ");
140	if (NULL != XVEC (in_rtx, i))
141	  {
142	    indent += 2;
143	    if (XVECLEN (in_rtx, i))
144	      sawclose = 1;
145
146	    for (j = 0; j < XVECLEN (in_rtx, i); j++)
147	      print_rtx (XVECEXP (in_rtx, i, j));
148
149	    indent -= 2;
150	  }
151	if (sawclose)
152	  fprintf (outfile, "\n%s",
153		   (spaces + (sizeof spaces - 1 - indent * 2)));
154
155	fprintf (outfile, "] ");
156	sawclose = 1;
157	indent -= 2;
158	break;
159
160      case 'w':
161	fprintf (outfile,
162#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
163		 " %d",
164#else
165		 " %ld",
166#endif
167		 XWINT (in_rtx, i));
168	break;
169
170      case 'i':
171	{
172	  register int value = XINT (in_rtx, i);
173
174	  if (GET_CODE (in_rtx) == REG && value < FIRST_PSEUDO_REGISTER)
175	    {
176	      fputc (' ', outfile);
177	      DEBUG_PRINT_REG (in_rtx, 0, outfile);
178	    }
179	  else
180	    fprintf (outfile, " %d", value);
181	}
182	if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
183	    && insn_name_ptr
184	    && XINT (in_rtx, i) >= 0)
185	  fprintf (outfile, " {%s}", insn_name_ptr[XINT (in_rtx, i)]);
186	sawclose = 0;
187	break;
188
189      /* Print NOTE_INSN names rather than integer codes.  */
190
191      case 'n':
192	if (XINT (in_rtx, i) <= 0)
193	  fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
194	else
195	  fprintf (outfile, " %d", XINT (in_rtx, i));
196	sawclose = 0;
197	break;
198
199      case 'u':
200	if (XEXP (in_rtx, i) != NULL)
201	  fprintf (outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
202	else
203	  fprintf (outfile, " 0");
204	sawclose = 0;
205	break;
206
207      case '*':
208	fprintf (outfile, " Unknown");
209	sawclose = 0;
210	break;
211
212      default:
213	fprintf (stderr,
214		 "switch format wrong in rtl.print_rtx(). format was: %c.\n",
215		 format_ptr[-1]);
216	abort ();
217      }
218
219  fprintf (outfile, ")");
220  sawclose = 1;
221}
222
223/* Call this function from the debugger to see what X looks like.  */
224
225void
226debug_rtx (x)
227     rtx x;
228{
229  outfile = stderr;
230  print_rtx (x);
231  fprintf (stderr, "\n");
232}
233
234/* Count of rtx's to print with debug_rtx_list.
235   This global exists because gdb user defined commands have no arguments.  */
236
237int debug_rtx_count = 0;	/* 0 is treated as equivalent to 1 */
238
239/* Call this function to print list from X on.
240
241   N is a count of the rtx's to print. Positive values print from the specified
242   rtx on.  Negative values print a window around the rtx.
243   EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
244
245void
246debug_rtx_list (x, n)
247     rtx x;
248     int n;
249{
250  int i,count;
251  rtx insn;
252
253  count = n == 0 ? 1 : n < 0 ? -n : n;
254
255  /* If we are printing a window, back up to the start.  */
256
257  if (n < 0)
258    for (i = count / 2; i > 0; i--)
259      {
260	if (PREV_INSN (x) == 0)
261	  break;
262	x = PREV_INSN (x);
263      }
264
265  for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
266    debug_rtx (insn);
267}
268
269/* Call this function to search an rtx list to find one with insn uid UID,
270   and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
271   The found insn is returned to enable further debugging analysis.  */
272
273rtx
274debug_rtx_find(x, uid)
275     rtx x;
276     int uid;
277{
278  while (x != 0 && INSN_UID (x) != uid)
279    x = NEXT_INSN (x);
280  if (x != 0)
281    {
282      debug_rtx_list (x, debug_rtx_count);
283      return x;
284    }
285  else
286    {
287      fprintf (stderr, "insn uid %d not found\n", uid);
288      return 0;
289    }
290}
291
292/* External entry point for printing a chain of insns
293   starting with RTX_FIRST onto file OUTF.
294   A blank line separates insns.
295
296   If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
297
298void
299print_rtl (outf, rtx_first)
300     FILE *outf;
301     rtx rtx_first;
302{
303  register rtx tmp_rtx;
304
305  outfile = outf;
306  sawclose = 0;
307
308  if (rtx_first == 0)
309    fprintf (outf, "(nil)\n");
310  else
311    switch (GET_CODE (rtx_first))
312      {
313      case INSN:
314      case JUMP_INSN:
315      case CALL_INSN:
316      case NOTE:
317      case CODE_LABEL:
318      case BARRIER:
319	for (tmp_rtx = rtx_first; NULL != tmp_rtx; tmp_rtx = NEXT_INSN (tmp_rtx))
320	  {
321	    print_rtx (tmp_rtx);
322	    fprintf (outfile, "\n");
323	  }
324	break;
325
326      default:
327	print_rtx (rtx_first);
328      }
329}
330