09ac387d18bcd0e81446f2dc12830f8fc9e3052d
[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               fprintf (outfile, " %s:%i", insn_file (in_rtx),
414                        insn_line (in_rtx));
415 #endif
416           }
417         else if (i == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
418           {
419 #ifndef GENERATOR_FILE
420             if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
421               fprintf (outfile, " %s:%i",
422                        LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
423                        LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
424 #endif
425           }
426         else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
427           {
428 #ifndef GENERATOR_FILE
429             if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
430               fprintf (outfile, " %s:%i",
431                        LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
432                        LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
433 #endif
434           }
435         else if (i == 6 && NOTE_P (in_rtx))
436           {
437             /* This field is only used for NOTE_INSN_DELETED_LABEL, and
438                other times often contains garbage from INSN->NOTE death.  */
439             if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
440                 || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
441               fprintf (outfile, " %d",  XINT (in_rtx, i));
442           }
443 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
444         else if (i == 1
445                  && GET_CODE (in_rtx) == UNSPEC_VOLATILE
446                  && XINT (in_rtx, 1) >= 0
447                  && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
448           fprintf (outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
449 #endif
450 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
451         else if (i == 1
452                  && (GET_CODE (in_rtx) == UNSPEC
453                      || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
454                  && XINT (in_rtx, 1) >= 0
455                  && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
456           fprintf (outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
457 #endif
458         else
459           {
460             int value = XINT (in_rtx, i);
461             const char *name;
462
463 #ifndef GENERATOR_FILE
464             if (REG_P (in_rtx) && (unsigned) value < FIRST_PSEUDO_REGISTER)
465               fprintf (outfile, " %d %s", value, reg_names[value]);
466             else if (REG_P (in_rtx)
467                      && (unsigned) value <= LAST_VIRTUAL_REGISTER)
468               {
469                 if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
470                   fprintf (outfile, " %d virtual-incoming-args", value);
471                 else if (value == VIRTUAL_STACK_VARS_REGNUM)
472                   fprintf (outfile, " %d virtual-stack-vars", value);
473                 else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
474                   fprintf (outfile, " %d virtual-stack-dynamic", value);
475                 else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
476                   fprintf (outfile, " %d virtual-outgoing-args", value);
477                 else if (value == VIRTUAL_CFA_REGNUM)
478                   fprintf (outfile, " %d virtual-cfa", value);
479                 else if (value == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
480                   fprintf (outfile, " %d virtual-preferred-stack-boundary",
481                            value);
482                 else
483                   fprintf (outfile, " %d virtual-reg-%d", value,
484                            value-FIRST_VIRTUAL_REGISTER);
485               }
486             else
487 #endif
488               if (flag_dump_unnumbered
489                      && (is_insn || NOTE_P (in_rtx)))
490               fputc ('#', outfile);
491             else
492               fprintf (outfile, " %d", value);
493
494 #ifndef GENERATOR_FILE
495             if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
496               {
497                 fputs (" [", outfile);
498                 if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
499                   fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
500                 if (REG_EXPR (in_rtx))
501                   print_mem_expr (outfile, REG_EXPR (in_rtx));
502
503                 if (REG_OFFSET (in_rtx))
504                   fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
505                            REG_OFFSET (in_rtx));
506                 fputs (" ]", outfile);
507               }
508 #endif
509
510             if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
511                 && XINT (in_rtx, i) >= 0
512                 && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
513               fprintf (outfile, " {%s}", name);
514             sawclose = 0;
515           }
516         break;
517
518       /* Print NOTE_INSN names rather than integer codes.  */
519
520       case 'n':
521         fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
522         sawclose = 0;
523         break;
524
525       case 'u':
526         if (XEXP (in_rtx, i) != NULL)
527           {
528             rtx sub = XEXP (in_rtx, i);
529             enum rtx_code subc = GET_CODE (sub);
530
531             if (GET_CODE (in_rtx) == LABEL_REF)
532               {
533                 if (subc == NOTE
534                     && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
535                   {
536                     if (flag_dump_unnumbered)
537                       fprintf (outfile, " [# deleted]");
538                     else
539                       fprintf (outfile, " [%d deleted]", INSN_UID (sub));
540                     sawclose = 0;
541                     break;
542                   }
543
544                 if (subc != CODE_LABEL)
545                   goto do_e;
546               }
547
548             if (flag_dump_unnumbered
549                 || (flag_dump_unnumbered_links && (i == 1 || i == 2)
550                     && (INSN_P (in_rtx) || NOTE_P (in_rtx)
551                         || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
552               fputs (" #", outfile);
553             else
554               fprintf (outfile, " %d", INSN_UID (sub));
555           }
556         else
557           fputs (" 0", outfile);
558         sawclose = 0;
559         break;
560
561       case 't':
562 #ifndef GENERATOR_FILE
563         if (i == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
564           print_mem_expr (outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
565         else if (i == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
566           print_mem_expr (outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
567         else
568           dump_addr (outfile, " ", XTREE (in_rtx, i));
569 #endif
570         break;
571
572       case '*':
573         fputs (" Unknown", outfile);
574         sawclose = 0;
575         break;
576
577       case 'B':
578 #ifndef GENERATOR_FILE
579         if (XBBDEF (in_rtx, i))
580           fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
581 #endif
582         break;
583
584       default:
585         gcc_unreachable ();
586       }
587
588   switch (GET_CODE (in_rtx))
589     {
590 #ifndef GENERATOR_FILE
591     case MEM:
592       if (__builtin_expect (final_insns_dump_p, false))
593         fprintf (outfile, " [");
594       else
595         fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC,
596                  (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
597
598       if (MEM_EXPR (in_rtx))
599         print_mem_expr (outfile, MEM_EXPR (in_rtx));
600       else
601         fputc (' ', outfile);
602
603       if (MEM_OFFSET_KNOWN_P (in_rtx))
604         fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC, MEM_OFFSET (in_rtx));
605
606       if (MEM_SIZE_KNOWN_P (in_rtx))
607         fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC, MEM_SIZE (in_rtx));
608
609       if (MEM_ALIGN (in_rtx) != 1)
610         fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));
611
612       if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
613         fprintf (outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
614
615       fputc (']', outfile);
616       break;
617
618     case CONST_DOUBLE:
619       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
620         {
621           char s[60];
622
623           real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
624                            sizeof (s), 0, 1);
625           fprintf (outfile, " %s", s);
626
627           real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
628                                sizeof (s), 0, 1);
629           fprintf (outfile, " [%s]", s);
630         }
631       break;
632 #endif
633
634     case CODE_LABEL:
635       fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
636       switch (LABEL_KIND (in_rtx))
637         {
638           case LABEL_NORMAL: break;
639           case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
640           case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
641           case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
642           default: gcc_unreachable ();
643         }
644       break;
645
646     default:
647       break;
648     }
649
650   fputc (')', outfile);
651   sawclose = 1;
652 }
653
654 /* Print an rtx on the current line of FILE.  Initially indent IND
655    characters.  */
656
657 void
658 print_inline_rtx (FILE *outf, const_rtx x, int ind)
659 {
660   int oldsaw = sawclose;
661   int oldindent = indent;
662
663   sawclose = 0;
664   indent = ind;
665   outfile = outf;
666   print_rtx (x);
667   sawclose = oldsaw;
668   indent = oldindent;
669 }
670
671 /* Call this function from the debugger to see what X looks like.  */
672
673 DEBUG_FUNCTION void
674 debug_rtx (const_rtx x)
675 {
676   outfile = stderr;
677   sawclose = 0;
678   print_rtx (x);
679   fprintf (stderr, "\n");
680 }
681
682 /* Dump rtx REF.  */
683
684 DEBUG_FUNCTION void
685 debug (const rtx_def &ref)
686 {
687   debug_rtx (&ref);
688 }
689
690 DEBUG_FUNCTION void
691 debug (const rtx_def *ptr)
692 {
693   if (ptr)
694     debug (*ptr);
695   else
696     fprintf (stderr, "<nil>\n");
697 }
698
699 /* Count of rtx's to print with debug_rtx_list.
700    This global exists because gdb user defined commands have no arguments.  */
701
702 DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
703
704 /* Call this function to print list from X on.
705
706    N is a count of the rtx's to print. Positive values print from the specified
707    rtx on.  Negative values print a window around the rtx.
708    EG: -5 prints 2 rtx's on either side (in addition to the specified rtx).  */
709
710 DEBUG_FUNCTION void
711 debug_rtx_list (const_rtx x, int n)
712 {
713   int i,count;
714   const_rtx insn;
715
716   count = n == 0 ? 1 : n < 0 ? -n : n;
717
718   /* If we are printing a window, back up to the start.  */
719
720   if (n < 0)
721     for (i = count / 2; i > 0; i--)
722       {
723         if (PREV_INSN (x) == 0)
724           break;
725         x = PREV_INSN (x);
726       }
727
728   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
729     {
730       debug_rtx (insn);
731       fprintf (stderr, "\n");
732     }
733 }
734
735 /* Call this function to print an rtx list from START to END inclusive.  */
736
737 DEBUG_FUNCTION void
738 debug_rtx_range (const_rtx start, const_rtx end)
739 {
740   while (1)
741     {
742       debug_rtx (start);
743       fprintf (stderr, "\n");
744       if (!start || start == end)
745         break;
746       start = NEXT_INSN (start);
747     }
748 }
749
750 /* Call this function to search an rtx list to find one with insn uid UID,
751    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
752    The found insn is returned to enable further debugging analysis.  */
753
754 DEBUG_FUNCTION const_rtx
755 debug_rtx_find (const_rtx x, int uid)
756 {
757   while (x != 0 && INSN_UID (x) != uid)
758     x = NEXT_INSN (x);
759   if (x != 0)
760     {
761       debug_rtx_list (x, debug_rtx_count);
762       return x;
763     }
764   else
765     {
766       fprintf (stderr, "insn uid %d not found\n", uid);
767       return 0;
768     }
769 }
770
771 /* External entry point for printing a chain of insns
772    starting with RTX_FIRST onto file OUTF.
773    A blank line separates insns.
774
775    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
776
777 void
778 print_rtl (FILE *outf, const_rtx rtx_first)
779 {
780   const_rtx tmp_rtx;
781
782   outfile = outf;
783   sawclose = 0;
784
785   if (rtx_first == 0)
786     {
787       fputs (print_rtx_head, outf);
788       fputs ("(nil)\n", outf);
789     }
790   else
791     switch (GET_CODE (rtx_first))
792       {
793       case INSN:
794       case JUMP_INSN:
795       case CALL_INSN:
796       case NOTE:
797       case CODE_LABEL:
798       case JUMP_TABLE_DATA:
799       case BARRIER:
800         for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
801           {
802             fputs (print_rtx_head, outfile);
803             print_rtx (tmp_rtx);
804             fprintf (outfile, "\n");
805           }
806         break;
807
808       default:
809         fputs (print_rtx_head, outfile);
810         print_rtx (rtx_first);
811       }
812 }
813
814 /* Like print_rtx, except specify a file.  */
815 /* Return nonzero if we actually printed anything.  */
816
817 int
818 print_rtl_single (FILE *outf, const_rtx x)
819 {
820   return print_rtl_single_with_indent (outf, x, 0);
821 }
822
823 /* Like print_rtl_single, except specify a file and indentation.  */
824
825 int
826 print_rtl_single_with_indent (FILE *outf, const_rtx x, int ind)
827 {
828   int old_indent = indent;
829   char *s_indent = (char *) alloca ((size_t) ind + 1);
830   memset ((void *) s_indent, ' ', (size_t) ind);
831   s_indent[ind] = '\0';
832
833   indent = ind;
834   outfile = outf;
835   sawclose = 0;
836   fputs (s_indent, outfile);
837   fputs (print_rtx_head, outfile);
838   print_rtx (x);
839   putc ('\n', outf);
840   indent = old_indent;
841   return 1;
842 }
843
844
845 /* Like print_rtl except without all the detail; for example,
846    if RTX is a CONST_INT then print in decimal format.  */
847
848 void
849 print_simple_rtl (FILE *outf, const_rtx x)
850 {
851   flag_simple = 1;
852   print_rtl (outf, x);
853   flag_simple = 0;
854 }