discriminator support. Ported from google/gcc-4_9 branch
[platform/upstream/gcc49.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   /* Get the format string and skip the first elements if we have handled
191      them already.  */
192   format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
193   for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
194     switch (*format_ptr++)
195       {
196         const char *str;
197
198       case 'T':
199         str = XTMPL (in_rtx, i);
200         goto string;
201
202       case 'S':
203       case 's':
204         str = XSTR (in_rtx, i);
205       string:
206
207         if (str == 0)
208           fputs (" \"\"", outfile);
209         else
210           fprintf (outfile, " (\"%s\")", str);
211         sawclose = 1;
212         break;
213
214         /* 0 indicates a field for internal use that should not be printed.
215            An exception is the third field of a NOTE, where it indicates
216            that the field has several different valid contents.  */
217       case '0':
218         if (i == 1 && REG_P (in_rtx))
219           {
220             if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
221               fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
222           }
223 #ifndef GENERATOR_FILE
224         else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
225           {
226             int flags = SYMBOL_REF_FLAGS (in_rtx);
227             if (flags)
228               fprintf (outfile, " [flags %#x]", flags);
229           }
230         else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF)
231           {
232             tree decl = SYMBOL_REF_DECL (in_rtx);
233             if (decl)
234               print_node_brief (outfile, "", decl, dump_flags);
235           }
236 #endif
237         else if (i == 4 && NOTE_P (in_rtx))
238           {
239             switch (NOTE_KIND (in_rtx))
240               {
241               case NOTE_INSN_EH_REGION_BEG:
242               case NOTE_INSN_EH_REGION_END:
243                 if (flag_dump_unnumbered)
244                   fprintf (outfile, " #");
245                 else
246                   fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
247                 sawclose = 1;
248                 break;
249
250               case NOTE_INSN_BLOCK_BEG:
251               case NOTE_INSN_BLOCK_END:
252 #ifndef GENERATOR_FILE
253                 dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
254 #endif
255                 sawclose = 1;
256                 break;
257
258               case NOTE_INSN_BASIC_BLOCK:
259                 {
260 #ifndef GENERATOR_FILE
261                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
262                   if (bb != 0)
263                     fprintf (outfile, " [bb %d]", bb->index);
264 #endif
265                   break;
266                 }
267
268               case NOTE_INSN_DELETED_LABEL:
269               case NOTE_INSN_DELETED_DEBUG_LABEL:
270                 {
271                   const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
272                   if (label)
273                     fprintf (outfile, " (\"%s\")", label);
274                   else
275                     fprintf (outfile, " \"\"");
276                 }
277                 break;
278
279               case NOTE_INSN_SWITCH_TEXT_SECTIONS:
280                 {
281 #ifndef GENERATOR_FILE
282                   basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
283                   if (bb != 0)
284                     fprintf (outfile, " [bb %d]", bb->index);
285 #endif
286                   break;
287                 }
288
289               case NOTE_INSN_VAR_LOCATION:
290               case NOTE_INSN_CALL_ARG_LOCATION:
291 #ifndef GENERATOR_FILE
292                 fputc (' ', outfile);
293                 print_rtx (NOTE_VAR_LOCATION (in_rtx));
294 #endif
295                 break;
296
297               case NOTE_INSN_CFI:
298 #ifndef GENERATOR_FILE
299                 fputc ('\n', outfile);
300                 output_cfi_directive (outfile, NOTE_CFI (in_rtx));
301                 fputc ('\t', outfile);
302 #endif
303                 break;
304
305               default:
306                 break;
307               }
308           }
309         else if (i == 8 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL)
310           {
311             /* Output the JUMP_LABEL reference.  */
312             fprintf (outfile, "\n%s%*s -> ", print_rtx_head, indent * 2, "");
313             if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
314               fprintf (outfile, "return");
315             else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
316               fprintf (outfile, "simple_return");
317             else
318               fprintf (outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
319           }
320         else if (i == 0 && GET_CODE (in_rtx) == VALUE)
321           {
322 #ifndef GENERATOR_FILE
323             cselib_val *val = CSELIB_VAL_PTR (in_rtx);
324
325             fprintf (outfile, " %u:%u", val->uid, val->hash);
326             dump_addr (outfile, " @", in_rtx);
327             dump_addr (outfile, "/", (void*)val);
328 #endif
329           }
330         else if (i == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
331           {
332 #ifndef GENERATOR_FILE
333             fprintf (outfile, " D#%i",
334                      DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
335 #endif
336           }
337         else if (i == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
338           {
339             indent += 2;
340             if (!sawclose)
341               fprintf (outfile, " ");
342             print_rtx (ENTRY_VALUE_EXP (in_rtx));
343             indent -= 2;
344           }
345         break;
346
347       case 'e':
348       do_e:
349         indent += 2;
350         if (i == 7 && INSN_P (in_rtx))
351           /* Put REG_NOTES on their own line.  */
352           fprintf (outfile, "\n%s%*s",
353                    print_rtx_head, indent * 2, "");
354         if (!sawclose)
355           fprintf (outfile, " ");
356         if (i == 8 && CALL_P (in_rtx))
357           {
358             in_call_function_usage = true;
359             print_rtx (XEXP (in_rtx, i));
360             in_call_function_usage = false;
361           }
362         else
363           print_rtx (XEXP (in_rtx, i));
364         indent -= 2;
365         break;
366
367       case 'E':
368       case 'V':
369         indent += 2;
370         if (sawclose)
371           {
372             fprintf (outfile, "\n%s%*s",
373                      print_rtx_head, indent * 2, "");
374             sawclose = 0;
375           }
376         fputs (" [", outfile);
377         if (NULL != XVEC (in_rtx, i))
378           {
379             indent += 2;
380             if (XVECLEN (in_rtx, i))
381               sawclose = 1;
382
383             for (j = 0; j < XVECLEN (in_rtx, i); j++)
384               print_rtx (XVECEXP (in_rtx, i, j));
385
386             indent -= 2;
387           }
388         if (sawclose)
389           fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
390
391         fputs ("]", outfile);
392         sawclose = 1;
393         indent -= 2;
394         break;
395
396       case 'w':
397         if (! flag_simple)
398           fprintf (outfile, " ");
399         fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
400         if (! flag_simple)
401           fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
402                    (unsigned HOST_WIDE_INT) XWINT (in_rtx, i));
403         break;
404
405       case 'i':
406         if (i == 5 && INSN_P (in_rtx))
407           {
408 #ifndef GENERATOR_FILE
409             /*  Pretty-print insn locations.  Ignore scoping as it is mostly
410                 redundant with line number information and do not print anything
411                 when there is no location information available.  */
412             if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
413               {
414                 int discriminator = insn_discriminator (in_rtx);
415                 fprintf (outfile, " %s:%i", insn_file (in_rtx),
416                          insn_line (in_rtx));
417                 if (discriminator)
418                   fprintf (outfile, " discrim %d", discriminator);
419               }
420 #endif
421           }
422         else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
423           {
424 #ifndef GENERATOR_FILE
425             if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
426               fprintf (outfile, " %s:%i",
427                        LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
428                        LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
429 #endif
430           }
431         else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
432           {
433 #ifndef GENERATOR_FILE
434             if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
435               fprintf (outfile, " %s:%i",
436                        LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
437                        LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
438 #endif
439           }
440         else if (i == 6 && NOTE_P (in_rtx))
441           {
442             /* This field is only used for NOTE_INSN_DELETED_LABEL, and
443                other times often contains garbage from INSN->NOTE death.  */
444             if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
445                 || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
446               fprintf (outfile, " %d",  XINT (in_rtx, i));
447           }
448 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
449         else if (i == 1
450                  && GET_CODE (in_rtx) == UNSPEC_VOLATILE
451                  && XINT (in_rtx, 1) >= 0
452                  && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
453           fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
454 #endif
455 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
456         else if (i == 1
457                  && (GET_CODE (in_rtx) == UNSPEC
458                      || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
459                  && XINT (in_rtx, 1) >= 0
460                  && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
461           fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
462 #endif
463         else
464           {
465             int value = XINT (in_rtx, i);
466             const char *name;
467
468 #ifndef GENERATOR_FILE
469             if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER)
470               fprintf (outfile, " %d %s", value, reg_names[value]);
471             else if (REG_P (in_rtx)
472                      && (unsigned) value <= LAST_VIRTUAL_REGISTER)
473               {
474                 if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
475                   fprintf (outfile, " %d virtual-incoming-args", value);
476                 else if (value == VIRTUAL_STACK_VARS_REGNUM)
477                   fprintf (outfile, " %d virtual-stack-vars", value);
478                 else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
479                   fprintf (outfile, " %d virtual-stack-dynamic", value);
480                 else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
481                   fprintf (outfile, " %d virtual-outgoing-args", value);
482                 else if (value == VIRTUAL_CFA_REGNUM)
483                   fprintf (outfile, " %d virtual-cfa", value);
484                 else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
485                   fprintf (outfile, " %d virtual-preferred-stack-boundary",
486                            value);
487                 else
488                   fprintf (outfile, " %d virtual-reg-%d", value,
489                            value-FIRST_VIRTUAL_REGISTER);
490               }
491             else
492 #endif
493               if (flag_dump_unnumbered
494                      && (is_insn || NOTE_P (in_rtx)))
495               fputc ('#', outfile);
496             else
497               fprintf (outfile, " %d", value);
498
499 #ifndef GENERATOR_FILE
500             if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
501               {
502                 fputs (" [", outfile);
503                 if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
504                   fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
505                 if (REG_EXPR (in_rtx))
506                   print_mem_expr (outfile, REG_EXPR (in_rtx));
507
508                 if (REG_OFFSET (in_rtx))
509                   fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
510                            REG_OFFSET (in_rtx));
511                 fputs (" ]", outfile);
512               }
513 #endif
514
515             if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
516                 && XINT (in_rtx, i) >= 0
517                 && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
518               fprintf (outfile, " {%s}", name);
519             sawclose = 0;
520           }
521         break;
522
523       /* Print NOTE_INSN names rather than integer codes.  */
524
525       case 'n':
526         fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
527         sawclose = 0;
528         break;
529
530       case 'u':
531         if (XEXP (in_rtx, i) != NULL)
532           {
533             rtx sub = XEXP (in_rtx, i);
534             enum rtx_code subc = GET_CODE (sub);
535
536             if (GET_CODE (in_rtx) == LABEL_REF)
537               {
538                 if (subc == NOTE
539                     && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
540                   {
541                     if (flag_dump_unnumbered)
542                       fprintf (outfile, " [# deleted]");
543                     else
544                       fprintf (outfile, " [%d deleted]", INSN_UID (sub));
545                     sawclose = 0;
546                     break;
547                   }
548
549                 if (subc != CODE_LABEL)
550                   goto do_e;
551               }
552
553             if (flag_dump_unnumbered
554                 || (flag_dump_unnumbered_links && (i == 1 || i == 2)
555                     && (INSN_P (in_rtx) || NOTE_P (in_rtx)
556                         || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
557               fputs (" #", outfile);
558             else
559               fprintf (outfile, " %d", INSN_UID (sub));
560           }
561         else
562           fputs (" 0", outfile);
563         sawclose = 0;
564         break;
565
566       case 't':
567 #ifndef GENERATOR_FILE
568         if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
569           print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
570         else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
571           print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
572         else
573           dump_addr (outfile, " ", XTREE (in_rtx, i));
574 #endif
575         break;
576
577       case '*':
578         fputs (" Unknown", outfile);
579         sawclose = 0;
580         break;
581
582       case 'B':
583 #ifndef GENERATOR_FILE
584         if (XBBDEF (in_rtx, i))
585           fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
586 #endif
587         break;
588
589       default:
590         gcc_unreachable ();
591       }
592
593   switch (GET_CODE (in_rtx))
594     {
595 #ifndef GENERATOR_FILE
596     case MEM:
597       if (__builtin_expect (final_insns_dump_p, false))
598         fprintf (outfile, " [");
599       else
600         fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC,
601                  (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
602
603       if (MEM_EXPR (in_rtx))
604         print_mem_expr (outfile, MEM_EXPR (in_rtx));
605       else
606         fputc (' ', outfile);
607
608       if (MEM_OFFSET_KNOWN_P (in_rtx))
609         fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
610
611       if (MEM_SIZE_KNOWN_P (in_rtx))
612         fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
613
614       if (MEM_ALIGN (in_rtx) != 1)
615         fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
616
617       if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
618         fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
619
620       fputc (']', outfile);
621       break;
622
623     case CONST_DOUBLE:
624       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
625         {
626           char s[60];
627
628           real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
629                            sizeof (s), 0, 1);
630           fprintf (outfile, " %s", s);
631
632           real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
633                                sizeof (s), 0, 1);
634           fprintf (outfile, " [%s]", s);
635         }
636       break;
637 #endif
638
639     case CODE_LABEL:
640       fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
641       switch (LABEL_KIND (in_rtx))
642         {
643           case LABEL_NORMAL: break;
644           case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
645           case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
646           case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
647           default: gcc_unreachable ();
648         }
649       break;
650
651     default:
652       break;
653     }
654
655   fputc (')', outfile);
656   sawclose = 1;
657 }
658
659 /* Print an rtx on the current line of FILE.  Initially indent IND
660    characters.  */
661
662 void
663 print_inline_rtx (FILE *outf, const_rtx x, int ind)
664 {
665   int oldsaw = sawclose;
666   int oldindent = indent;
667
668   sawclose = 0;
669   indent = ind;
670   outfile = outf;
671   print_rtx (x);
672   sawclose = oldsaw;
673   indent = oldindent;
674 }
675
676 /* Call this function from the debugger to see what X looks like.  */
677
678 DEBUG_FUNCTION void
679 debug_rtx (const_rtx x)
680 {
681   outfile = stderr;
682   sawclose = 0;
683   print_rtx (x);
684   fprintf (stderr, "\n");
685 }
686
687 /* Dump rtx REF.  */
688
689 DEBUG_FUNCTION void
690 debug (const rtx_def &ref)
691 {
692   debug_rtx (&ref);
693 }
694
695 DEBUG_FUNCTION void
696 debug (const rtx_def *ptr)
697 {
698   if (ptr)
699     debug (*ptr);
700   else
701     fprintf (stderr, "<nil>\n");
702 }
703
704 /* Count of rtx's to print with debug_rtx_list.
705    This global exists because gdb user defined commands have no arguments.  */
706
707 DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
708
709 /* Call this function to print list from X on.
710
711    N is a count of the rtx's to print. Positive values print from the specified
712    rtx on.  Negative values print a window around the rtx.
713    EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
714
715 DEBUG_FUNCTION void
716 debug_rtx_list (const_rtx x, int n)
717 {
718   int i,count;
719   const_rtx insn;
720
721   count = n == 0 ? 1 : n < 0 ? -n : n;
722
723   /* If we are printing a window, back up to the start.  */
724
725   if (n < 0)
726     for (i = count / 2; i > 0; i--)
727       {
728         if (PREV_INSN (x) == 0)
729           break;
730         x = PREV_INSN (x);
731       }
732
733   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
734     {
735       debug_rtx (insn);
736       fprintf (stderr, "\n");
737     }
738 }
739
740 /* Call this function to print an rtx list from START to END inclusive.  */
741
742 DEBUG_FUNCTION void
743 debug_rtx_range (const_rtx start, const_rtx end)
744 {
745   while (1)
746     {
747       debug_rtx (start);
748       fprintf (stderr, "\n");
749       if (!start || start == end)
750         break;
751       start = NEXT_INSN (start);
752     }
753 }
754
755 /* Call this function to search an rtx list to find one with insn uid UID,
756    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
757    The found insn is returned to enable further debugging analysis.  */
758
759 DEBUG_FUNCTION const_rtx
760 debug_rtx_find (const_rtx x, int uid)
761 {
762   while (x != 0 && INSN_UID (x) != uid)
763     x = NEXT_INSN (x);
764   if (x != 0)
765     {
766       debug_rtx_list (x, debug_rtx_count);
767       return x;
768     }
769   else
770     {
771       fprintf (stderr, "insn uid %d not found\n", uid);
772       return 0;
773     }
774 }
775
776 /* External entry point for printing a chain of insns
777    starting with RTX_FIRST onto file OUTF.
778    A blank line separates insns.
779
780    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
781
782 void
783 print_rtl (FILE *outf, const_rtx rtx_first)
784 {
785   const_rtx tmp_rtx;
786
787   outfile = outf;
788   sawclose = 0;
789
790   if (rtx_first == 0)
791     {
792       fputs (print_rtx_head, outf);
793       fputs ("(nil)\n", outf);
794     }
795   else
796     switch (GET_CODE (rtx_first))
797       {
798       case INSN:
799       case JUMP_INSN:
800       case CALL_INSN:
801       case NOTE:
802       case CODE_LABEL:
803       case JUMP_TABLE_DATA:
804       case BARRIER:
805         for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
806           {
807             fputs (print_rtx_head, outfile);
808             print_rtx (tmp_rtx);
809             fprintf (outfile, "\n");
810           }
811         break;
812
813       default:
814         fputs (print_rtx_head, outfile);
815         print_rtx (rtx_first);
816       }
817 }
818
819 /* Like print_rtx, except specify a file.  */
820 /* Return nonzero if we actually printed anything.  */
821
822 int
823 print_rtl_single (FILE *outf, const_rtx x)
824 {
825   return print_rtl_single_with_indent (outf, x, 0);
826 }
827
828 /* Like print_rtl_single, except specify a file and indentation.  */
829
830 int
831 print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind)
832 {
833   int old_indent = indent;
834   char *s_indent = (char *) alloca ((size_t) ind + 1);
835   memset ((void *) s_indent, ' ', (size_t) ind);
836   s_indent[ind] = '\0';
837
838   indent = ind;
839   outfile = outf;
840   sawclose = 0;
841   fputs (s_indent, outfile);
842   fputs (print_rtx_head, outfile);
843   print_rtx (x);
844   putc ('\n', outf);
845   indent = old_indent;
846   return 1;
847 }
848
849
850 /* Like print_rtl except without all the detail; for example,
851    if RTX is a CONST_INT then print in decimal format.  */
852
853 void
854 print_simple_rtl (FILE *outf, const_rtx x)
855 {
856   flag_simple = 1;
857   print_rtl (outf, x);
858   flag_simple = 0;
859 }