common.opt (fdump-unnumbered-links): New.
[gcc.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 }