OSDN Git Service

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