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