OSDN Git Service

* print-rtl.c (print_decl_name): New.
[pf3gnuchains/gcc-fork.git] / gcc / print-rtl.c
1 /* Print RTL for GCC.
2    Copyright (C) 1987, 1988, 1992, 1997, 1998, 1999, 2000, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 /* This file is compiled twice: once for the generator programs,
23    once for the compiler.  */
24 #ifdef GENERATOR_FILE
25 #include "bconfig.h"
26 #else
27 #include "config.h"
28 #endif
29
30 #include "system.h"
31 #include "coretypes.h"
32 #include "tm.h"
33 #include "rtl.h"
34
35 /* These headers all define things which are not available in
36    generator programs.  */
37 #ifndef GENERATOR_FILE
38 #include "tree.h"
39 #include "real.h"
40 #include "flags.h"
41 #include "hard-reg-set.h"
42 #include "basic-block.h"
43 #endif
44
45 static FILE *outfile;
46
47 static int sawclose = 0;
48
49 static int indent;
50
51 static void print_rtx (rtx);
52
53 /* String printed at beginning of each RTL when it is dumped.
54    This string is set to ASM_COMMENT_START when the RTL is dumped in
55    the assembly output file.  */
56 const char *print_rtx_head = "";
57
58 /* Nonzero means suppress output of instruction numbers and line number
59    notes in debugging dumps.
60    This must be defined here so that programs like gencodes can be linked.  */
61 int flag_dump_unnumbered = 0;
62
63 /* Nonzero means use simplified format without flags, modes, etc.  */
64 int flag_simple = 0;
65
66 /* Nonzero if we are dumping graphical description.  */
67 int dump_for_graph;
68
69 #ifndef GENERATOR_FILE
70 static void
71 print_decl_name (FILE *outfile, tree node)
72 {
73   if (DECL_NAME (node))
74     fputs (IDENTIFIER_POINTER (DECL_NAME (node)), outfile);
75   else
76     {
77       if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
78         fprintf (outfile, "L." HOST_WIDE_INT_PRINT_DEC, LABEL_DECL_UID (node));
79       else
80         {
81           char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
82           fprintf (outfile, "%c.%u", c, DECL_UID (node));
83         }
84     }
85 }
86
87 void
88 print_mem_expr (FILE *outfile, tree expr)
89 {
90   if (TREE_CODE (expr) == COMPONENT_REF)
91     {
92       if (TREE_OPERAND (expr, 0))
93         print_mem_expr (outfile, TREE_OPERAND (expr, 0));
94       else
95         fputs (" <variable>", outfile);
96       fputc ('.', outfile);
97       print_decl_name (outfile, TREE_OPERAND (expr, 1));
98     }
99   else if (TREE_CODE (expr) == INDIRECT_REF)
100     {
101       fputs (" (*", outfile);
102       print_mem_expr (outfile, TREE_OPERAND (expr, 0));
103       fputs (")", outfile);
104     }
105   else if (TREE_CODE (expr) == RESULT_DECL)
106     fputs (" <result>", outfile);
107   else
108     {
109       fputc (' ', outfile);
110       print_decl_name (outfile, expr);
111     }
112 }
113 #endif
114
115 /* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */
116
117 static void
118 print_rtx (rtx in_rtx)
119 {
120   int i = 0;
121   int j;
122   const char *format_ptr;
123   int is_insn;
124
125   if (sawclose)
126     {
127       if (flag_simple)
128         fputc (' ', outfile);
129       else
130         fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
131       sawclose = 0;
132     }
133
134   if (in_rtx == 0)
135     {
136       fputs ("(nil)", outfile);
137       sawclose = 1;
138       return;
139     }
140   else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
141     {
142        fprintf (outfile, "(??? bad code %d\n)", GET_CODE (in_rtx));
143        sawclose = 1;
144        return;
145     }
146
147   is_insn = INSN_P (in_rtx);
148
149   /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
150      in separate nodes and therefore have to handle them special here.  */
151   if (dump_for_graph
152       && (is_insn || NOTE_P (in_rtx)
153           || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
154     {
155       i = 3;
156       indent = 0;
157     }
158   else
159     {
160       /* Print name of expression code.  */
161       if (flag_simple && GET_CODE (in_rtx) == CONST_INT)
162         fputc ('(', outfile);
163       else
164         fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));
165
166       if (! flag_simple)
167         {
168           if (RTX_FLAG (in_rtx, in_struct))
169             fputs ("/s", outfile);
170
171           if (RTX_FLAG (in_rtx, volatil))
172             fputs ("/v", outfile);
173
174           if (RTX_FLAG (in_rtx, unchanging))
175             fputs ("/u", outfile);
176
177           if (RTX_FLAG (in_rtx, frame_related))
178             fputs ("/f", outfile);
179
180           if (RTX_FLAG (in_rtx, jump))
181             fputs ("/j", outfile);
182
183           if (RTX_FLAG (in_rtx, call))
184             fputs ("/c", outfile);
185
186           if (RTX_FLAG (in_rtx, return_val))
187             fputs ("/i", outfile);
188
189           if (GET_MODE (in_rtx) != VOIDmode)
190             {
191               /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
192               if (GET_CODE (in_rtx) == EXPR_LIST
193                   || GET_CODE (in_rtx) == INSN_LIST)
194                 fprintf (outfile, ":%s",
195                          GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
196               else
197                 fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
198             }
199         }
200     }
201
202 #ifndef GENERATOR_FILE
203   if (GET_CODE (in_rtx) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (in_rtx)))
204     i = 5;
205 #endif
206
207   /* Get the format string and skip the first elements if we have handled
208      them already.  */
209   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
210   for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
211     switch (*format_ptr++)
212       {
213         const char *str;
214
215       case 'T':
216         str = XTMPL (in_rtx, i);
217         goto string;
218
219       case 'S':
220       case 's':
221         str = XSTR (in_rtx, i);
222       string:
223
224         if (str == 0)
225           fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
226         else
227           {
228             if (dump_for_graph)
229               fprintf (outfile, " (\\\"%s\\\")", str);
230             else
231               fprintf (outfile, " (\"%s\")", str);
232           }
233         sawclose = 1;
234         break;
235
236         /* 0 indicates a field for internal use that should not be printed.
237            An exception is the third field of a NOTE, where it indicates
238            that the field has several different valid contents.  */
239       case '0':
240         if (i == 1 && REG_P (in_rtx))
241           {
242             if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
243               fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
244           }
245 #ifndef GENERATOR_FILE
246         else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
247           {
248             int flags = SYMBOL_REF_FLAGS (in_rtx);
249             if (flags)
250               fprintf (outfile, " [flags 0x%x]", flags);
251           }
252         else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF)
253           {
254             tree decl = SYMBOL_REF_DECL (in_rtx);
255             if (decl)
256               print_node_brief (outfile, "", decl, 0);
257           }
258 #endif
259         else if (i == 4 && NOTE_P (in_rtx))
260           {
261             switch (NOTE_LINE_NUMBER (in_rtx))
262               {
263               case NOTE_INSN_EH_REGION_BEG:
264               case NOTE_INSN_EH_REGION_END:
265                 if (flag_dump_unnumbered)
266                   fprintf (outfile, " #");
267                 else
268                   fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
269                 sawclose = 1;
270                 break;
271
272               case NOTE_INSN_BLOCK_BEG:
273               case NOTE_INSN_BLOCK_END:
274                 fprintf (outfile, " ");
275                 if (flag_dump_unnumbered)
276                   fprintf (outfile, "#");
277                 else
278                   fprintf (outfile, HOST_PTR_PRINTF,
279                            (char *) NOTE_BLOCK (in_rtx));
280                 sawclose = 1;
281                 break;
282
283               case NOTE_INSN_BASIC_BLOCK:
284                 {
285 #ifndef GENERATOR_FILE
286                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
287                   if (bb != 0)
288                     fprintf (outfile, " [bb %d]", bb->index);
289 #endif
290                   break;
291                 }
292
293               case NOTE_INSN_EXPECTED_VALUE:
294                 indent += 2;
295                 if (!sawclose)
296                   fprintf (outfile, " ");
297                 print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
298                 indent -= 2;
299                 break;
300
301               case NOTE_INSN_DELETED_LABEL:
302                 {
303                   const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
304                   if (label)
305                     fprintf (outfile, " (\"%s\")", label);
306                   else
307                     fprintf (outfile, " \"\"");
308                 }
309                 break;
310
311               case NOTE_INSN_UNLIKELY_EXECUTED_CODE:
312                 {
313 #ifndef GENERATOR_FILE
314                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
315                   if (bb != 0)
316                     fprintf (outfile, " [bb %d]", bb->index);
317 #endif
318                   break;
319                 }
320                 
321               case NOTE_INSN_VAR_LOCATION:
322 #ifndef GENERATOR_FILE
323                 fprintf (outfile, " (");
324                 print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
325                 fprintf (outfile, " ");
326                 print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
327                 fprintf (outfile, ")");
328 #endif
329                 break;
330
331               default:
332                 {
333                   const char * const str = X0STR (in_rtx, i);
334
335                   if (NOTE_LINE_NUMBER (in_rtx) < 0)
336                     ;
337                   else if (str == 0)
338                     fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
339                   else
340                     {
341                       if (dump_for_graph)
342                         fprintf (outfile, " (\\\"%s\\\")", str);
343                       else
344                         fprintf (outfile, " (\"%s\")", str);
345                     }
346                   break;
347                 }
348               }
349           }
350         break;
351
352       case 'e':
353       do_e:
354         indent += 2;
355         if (!sawclose)
356           fprintf (outfile, " ");
357         print_rtx (XEXP (in_rtx, i));
358         indent -= 2;
359         break;
360
361       case 'E':
362       case 'V':
363         indent += 2;
364         if (sawclose)
365           {
366             fprintf (outfile, "\n%s%*s",
367                      print_rtx_head, indent * 2, "");
368             sawclose = 0;
369           }
370         fputs (" [", outfile);
371         if (NULL != XVEC (in_rtx, i))
372           {
373             indent += 2;
374             if (XVECLEN (in_rtx, i))
375               sawclose = 1;
376
377             for (j = 0; j < XVECLEN (in_rtx, i); j++)
378               print_rtx (XVECEXP (in_rtx, i, j));
379
380             indent -= 2;
381           }
382         if (sawclose)
383           fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
384
385         fputs ("]", outfile);
386         sawclose = 1;
387         indent -= 2;
388         break;
389
390       case 'w':
391         if (! flag_simple)
392           fprintf (outfile, " ");
393         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
394         if (! flag_simple)
395           fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
396                    XWINT (in_rtx, i));
397         break;
398
399       case 'i':
400         if (i == 4 && INSN_P (in_rtx))
401           {
402 #ifndef GENERATOR_FILE
403             /*  Pretty-print insn locators.  Ignore scoping as it is mostly
404                 redundant with line number information and do not print anything
405                 when there is no location information available.  */
406             if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
407               fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
408 #endif
409           }
410         else if (i == 6 && NOTE_P (in_rtx))
411           {
412             /* This field is only used for NOTE_INSN_DELETED_LABEL, and
413                other times often contains garbage from INSN->NOTE death.  */
414             if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_DELETED_LABEL)
415               fprintf (outfile, " %d",  XINT (in_rtx, i));
416           }
417         else
418           {
419             int value = XINT (in_rtx, i);
420             const char *name;
421
422 #ifndef GENERATOR_FILE
423             if (REG_P (in_rtx) && value < FIRST_PSEUDO_REGISTER)
424               fprintf (outfile, " %d %s", REGNO (in_rtx),
425                        reg_names[REGNO (in_rtx)]);
426             else if (REG_P (in_rtx)
427                      && value <= LAST_VIRTUAL_REGISTER)
428               {
429                 if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
430                   fprintf (outfile, " %d virtual-incoming-args", value);
431                 else if (value == VIRTUAL_STACK_VARS_REGNUM)
432                   fprintf (outfile, " %d virtual-stack-vars", value);
433                 else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
434                   fprintf (outfile, " %d virtual-stack-dynamic", value);
435                 else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
436                   fprintf (outfile, " %d virtual-outgoing-args", value);
437                 else if (value == VIRTUAL_CFA_REGNUM)
438                   fprintf (outfile, " %d virtual-cfa", value);
439                 else
440                   fprintf (outfile, " %d virtual-reg-%d", value,
441                            value-FIRST_VIRTUAL_REGISTER);
442               }
443             else
444 #endif
445               if (flag_dump_unnumbered
446                      && (is_insn || NOTE_P (in_rtx)))
447               fputc ('#', outfile);
448             else
449               fprintf (outfile, " %d", value);
450
451 #ifndef GENERATOR_FILE
452             if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
453               {
454                 fputs (" [", outfile);
455                 if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
456                   fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
457                 if (REG_EXPR (in_rtx))
458                   print_mem_expr (outfile, REG_EXPR (in_rtx));
459
460                 if (REG_OFFSET (in_rtx))
461                   fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
462                            REG_OFFSET (in_rtx));
463                 fputs (" ]", outfile);
464               }
465 #endif
466
467             if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
468                 && XINT (in_rtx, i) >= 0
469                 && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
470               fprintf (outfile, " {%s}", name);
471             sawclose = 0;
472           }
473         break;
474
475       /* Print NOTE_INSN names rather than integer codes.  */
476
477       case 'n':
478         if (XINT (in_rtx, i) >= (int) NOTE_INSN_BIAS
479             && XINT (in_rtx, i) < (int) NOTE_INSN_MAX)
480           fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
481         else
482           fprintf (outfile, " %d", XINT (in_rtx, i));
483         sawclose = 0;
484         break;
485
486       case 'u':
487         if (XEXP (in_rtx, i) != NULL)
488           {
489             rtx sub = XEXP (in_rtx, i);
490             enum rtx_code subc = GET_CODE (sub);
491
492             if (GET_CODE (in_rtx) == LABEL_REF)
493               {
494                 if (subc == NOTE
495                     && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
496                   {
497                     if (flag_dump_unnumbered)
498                       fprintf (outfile, " [# deleted]");
499                     else
500                       fprintf (outfile, " [%d deleted]", INSN_UID (sub));
501                     sawclose = 0;
502                     break;
503                   }
504
505                 if (subc != CODE_LABEL)
506                   goto do_e;
507               }
508
509             if (flag_dump_unnumbered)
510               fputs (" #", outfile);
511             else
512               fprintf (outfile, " %d", INSN_UID (sub));
513           }
514         else
515           fputs (" 0", outfile);
516         sawclose = 0;
517         break;
518
519       case 'b':
520 #ifndef GENERATOR_FILE
521         if (XBITMAP (in_rtx, i) == NULL)
522           fputs (" {null}", outfile);
523         else
524           bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
525 #endif
526         sawclose = 0;
527         break;
528
529       case 't':
530         fprintf (outfile, " " HOST_PTR_PRINTF, (void *) XTREE (in_rtx, i));
531         break;
532
533       case '*':
534         fputs (" Unknown", outfile);
535         sawclose = 0;
536         break;
537
538       case 'B':
539 #ifndef GENERATOR_FILE
540         if (XBBDEF (in_rtx, i))
541           fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
542 #endif
543         break;
544
545       default:
546         fprintf (stderr,
547                  "switch format wrong in rtl.print_rtx(). format was: %c.\n",
548                  format_ptr[-1]);
549         abort ();
550       }
551
552   switch (GET_CODE (in_rtx))
553     {
554 #ifndef GENERATOR_FILE
555     case MEM:
556       fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));
557
558       if (MEM_EXPR (in_rtx))
559         print_mem_expr (outfile, MEM_EXPR (in_rtx));
560
561       if (MEM_OFFSET (in_rtx))
562         fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
563                  INTVAL (MEM_OFFSET (in_rtx)));
564
565       if (MEM_SIZE (in_rtx))
566         fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC,
567                  INTVAL (MEM_SIZE (in_rtx)));
568
569       if (MEM_ALIGN (in_rtx) != 1)
570         fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
571
572       fputc (']', outfile);
573       break;
574
575     case CONST_DOUBLE:
576       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
577         {
578           char s[60];
579
580           real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
581                            sizeof (s), 0, 1);
582           fprintf (outfile, " %s", s);
583
584           real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
585                                sizeof (s), 0, 1);
586           fprintf (outfile, " [%s]", s);
587         }
588       break;
589 #endif
590
591     case CODE_LABEL:
592       fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
593       switch (LABEL_KIND (in_rtx))
594         {
595           case LABEL_NORMAL: break;
596           case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
597           case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
598           case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
599           default: abort();
600         }
601       break;
602
603     default:
604       break;
605     }
606
607   if (dump_for_graph
608       && (is_insn || NOTE_P (in_rtx)
609           || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
610     sawclose = 0;
611   else
612     {
613       fputc (')', outfile);
614       sawclose = 1;
615     }
616 }
617
618 /* Print an rtx on the current line of FILE.  Initially indent IND
619    characters.  */
620
621 void
622 print_inline_rtx (FILE *outf, rtx x, int ind)
623 {
624   int oldsaw = sawclose;
625   int oldindent = indent;
626
627   sawclose = 0;
628   indent = ind;
629   outfile = outf;
630   print_rtx (x);
631   sawclose = oldsaw;
632   indent = oldindent;
633 }
634
635 /* Call this function from the debugger to see what X looks like.  */
636
637 void
638 debug_rtx (rtx x)
639 {
640   outfile = stderr;
641   sawclose = 0;
642   print_rtx (x);
643   fprintf (stderr, "\n");
644 }
645
646 /* Count of rtx's to print with debug_rtx_list.
647    This global exists because gdb user defined commands have no arguments.  */
648
649 int debug_rtx_count = 0;        /* 0 is treated as equivalent to 1 */
650
651 /* Call this function to print list from X on.
652
653    N is a count of the rtx's to print. Positive values print from the specified
654    rtx on.  Negative values print a window around the rtx.
655    EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
656
657 void
658 debug_rtx_list (rtx x, int n)
659 {
660   int i,count;
661   rtx insn;
662
663   count = n == 0 ? 1 : n < 0 ? -n : n;
664
665   /* If we are printing a window, back up to the start.  */
666
667   if (n < 0)
668     for (i = count / 2; i > 0; i--)
669       {
670         if (PREV_INSN (x) == 0)
671           break;
672         x = PREV_INSN (x);
673       }
674
675   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
676     {
677       debug_rtx (insn);
678       fprintf (stderr, "\n");
679     }
680 }
681
682 /* Call this function to print an rtx list from START to END inclusive.  */
683
684 void
685 debug_rtx_range (rtx start, rtx end)
686 {
687   while (1)
688     {
689       debug_rtx (start);
690       fprintf (stderr, "\n");
691       if (!start || start == end)
692         break;
693       start = NEXT_INSN (start);
694     }
695 }
696
697 /* Call this function to search an rtx list to find one with insn uid UID,
698    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
699    The found insn is returned to enable further debugging analysis.  */
700
701 rtx
702 debug_rtx_find (rtx x, int uid)
703 {
704   while (x != 0 && INSN_UID (x) != uid)
705     x = NEXT_INSN (x);
706   if (x != 0)
707     {
708       debug_rtx_list (x, debug_rtx_count);
709       return x;
710     }
711   else
712     {
713       fprintf (stderr, "insn uid %d not found\n", uid);
714       return 0;
715     }
716 }
717
718 /* External entry point for printing a chain of insns
719    starting with RTX_FIRST onto file OUTF.
720    A blank line separates insns.
721
722    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
723
724 void
725 print_rtl (FILE *outf, rtx rtx_first)
726 {
727   rtx tmp_rtx;
728
729   outfile = outf;
730   sawclose = 0;
731
732   if (rtx_first == 0)
733     {
734       fputs (print_rtx_head, outf);
735       fputs ("(nil)\n", outf);
736     }
737   else
738     switch (GET_CODE (rtx_first))
739       {
740       case INSN:
741       case JUMP_INSN:
742       case CALL_INSN:
743       case NOTE:
744       case CODE_LABEL:
745       case BARRIER:
746         for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
747           if (! flag_dump_unnumbered
748               || !NOTE_P (tmp_rtx) || NOTE_LINE_NUMBER (tmp_rtx) < 0)
749             {
750               fputs (print_rtx_head, outfile);
751               print_rtx (tmp_rtx);
752               fprintf (outfile, "\n");
753             }
754         break;
755
756       default:
757         fputs (print_rtx_head, outfile);
758         print_rtx (rtx_first);
759       }
760 }
761
762 /* Like print_rtx, except specify a file.  */
763 /* Return nonzero if we actually printed anything.  */
764
765 int
766 print_rtl_single (FILE *outf, rtx x)
767 {
768   outfile = outf;
769   sawclose = 0;
770   if (! flag_dump_unnumbered
771       || !NOTE_P (x) || NOTE_LINE_NUMBER (x) < 0)
772     {
773       fputs (print_rtx_head, outfile);
774       print_rtx (x);
775       putc ('\n', outf);
776       return 1;
777     }
778   return 0;
779 }
780
781
782 /* Like print_rtl except without all the detail; for example,
783    if RTX is a CONST_INT then print in decimal format.  */
784
785 void
786 print_simple_rtl (FILE *outf, rtx x)
787 {
788   flag_simple = 1;
789   print_rtl (outf, x);
790   flag_simple = 0;
791 }