print-rtl.c (rtx_writer::print_rtx_operand_code_i): Print column information.
[platform/upstream/gcc.git] / gcc / print-rtl.c
1 /* Print RTL for GCC.
2    Copyright (C) 1987-2018 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 "alias.h"
37 #include "tree.h"
38 #include "basic-block.h"
39 #include "print-tree.h"
40 #include "flags.h"
41 #include "predict.h"
42 #include "function.h"
43 #include "cfg.h"
44 #include "basic-block.h"
45 #include "diagnostic.h"
46 #include "tree-pretty-print.h"
47 #include "alloc-pool.h"
48 #include "cselib.h"
49 #include "dumpfile.h"   /* for dump_flags */
50 #include "dwarf2out.h"
51 #include "pretty-print.h"
52 #endif
53
54 #include "print-rtl.h"
55 #include "rtl-iter.h"
56
57 /* String printed at beginning of each RTL when it is dumped.
58    This string is set to ASM_COMMENT_START when the RTL is dumped in
59    the assembly output file.  */
60 const char *print_rtx_head = "";
61
62 #ifdef GENERATOR_FILE
63 /* These are defined from the .opt file when not used in generator
64    programs.  */
65
66 /* Nonzero means suppress output of instruction numbers
67    in debugging dumps.
68    This must be defined here so that programs like gencodes can be linked.  */
69 int flag_dump_unnumbered = 0;
70
71 /* Nonzero means suppress output of instruction numbers for previous
72    and next insns in debugging dumps.
73    This must be defined here so that programs like gencodes can be linked.  */
74 int flag_dump_unnumbered_links = 0;
75 #endif
76
77 /* Constructor for rtx_writer.  */
78
79 rtx_writer::rtx_writer (FILE *outf, int ind, bool simple, bool compact,
80                         rtx_reuse_manager *reuse_manager)
81 : m_outfile (outf), m_sawclose (0), m_indent (ind),
82   m_in_call_function_usage (false), m_simple (simple), m_compact (compact),
83   m_rtx_reuse_manager (reuse_manager)
84 {
85 }
86
87 #ifndef GENERATOR_FILE
88
89 /* rtx_reuse_manager's ctor.  */
90
91 rtx_reuse_manager::rtx_reuse_manager ()
92 : m_next_id (0)
93 {
94 }
95
96 /* Determine if X is of a kind suitable for dumping via reuse_rtx.  */
97
98 static bool
99 uses_rtx_reuse_p (const_rtx x)
100 {
101   if (x == NULL)
102     return false;
103
104   switch (GET_CODE (x))
105     {
106     case DEBUG_EXPR:
107     case VALUE:
108     case SCRATCH:
109       return true;
110
111     /* We don't use reuse_rtx for consts.  */
112     CASE_CONST_UNIQUE:
113     default:
114       return false;
115     }
116 }
117
118 /* Traverse X and its descendents, determining if we see any rtx more than
119    once.  Any rtx suitable for "reuse_rtx" that is seen more than once is
120    assigned an ID.  */
121
122 void
123 rtx_reuse_manager::preprocess (const_rtx x)
124 {
125   subrtx_iterator::array_type array;
126   FOR_EACH_SUBRTX (iter, array, x, NONCONST)
127     if (uses_rtx_reuse_p (*iter))
128       {
129         if (int *count = m_rtx_occurrence_count.get (*iter))
130           {
131             if (*(count++) == 1)
132               m_rtx_reuse_ids.put (*iter, m_next_id++);
133           }
134         else
135           m_rtx_occurrence_count.put (*iter, 1);
136       }
137 }
138
139 /* Return true iff X has been assigned a reuse ID.  If it has,
140    and OUT is non-NULL, then write the reuse ID to *OUT.  */
141
142 bool
143 rtx_reuse_manager::has_reuse_id (const_rtx x, int *out)
144 {
145   int *id = m_rtx_reuse_ids.get (x);
146   if (id)
147     {
148       if (out)
149         *out = *id;
150       return true;
151     }
152   else
153     return false;
154 }
155
156 /* Determine if set_seen_def has been called for the given reuse ID.  */
157
158 bool
159 rtx_reuse_manager::seen_def_p (int reuse_id)
160 {
161   return bitmap_bit_p (m_defs_seen, reuse_id);
162 }
163
164 /* Record that the definition of the given reuse ID has been seen.  */
165
166 void
167 rtx_reuse_manager::set_seen_def (int reuse_id)
168 {
169   bitmap_set_bit (m_defs_seen, reuse_id);
170 }
171
172 #endif /* #ifndef GENERATOR_FILE */
173
174 #ifndef GENERATOR_FILE
175 void
176 print_mem_expr (FILE *outfile, const_tree expr)
177 {
178   fputc (' ', outfile);
179   print_generic_expr (outfile, CONST_CAST_TREE (expr), dump_flags);
180 }
181 #endif
182
183 /* Print X to FILE.  */
184
185 static void
186 print_poly_int (FILE *file, poly_int64 x)
187 {
188   HOST_WIDE_INT const_x;
189   if (x.is_constant (&const_x))
190     fprintf (file, HOST_WIDE_INT_PRINT_DEC, const_x);
191   else
192     {
193       fprintf (file, "[" HOST_WIDE_INT_PRINT_DEC, x.coeffs[0]);
194       for (int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
195         fprintf (file, ", " HOST_WIDE_INT_PRINT_DEC, x.coeffs[i]);
196       fprintf (file, "]");
197     }
198 }
199
200 /* Subroutine of print_rtx_operand for handling code '0'.
201    0 indicates a field for internal use that should not be printed.
202    However there are various special cases, such as the third field
203    of a NOTE, where it indicates that the field has several different
204    valid contents.  */
205
206 void
207 rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED,
208                                       int idx ATTRIBUTE_UNUSED)
209 {
210 #ifndef GENERATOR_FILE
211   if (idx == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
212     {
213       int flags = SYMBOL_REF_FLAGS (in_rtx);
214       if (flags)
215         fprintf (m_outfile, " [flags %#x]", flags);
216       tree decl = SYMBOL_REF_DECL (in_rtx);
217       if (decl)
218         print_node_brief (m_outfile, "", decl, dump_flags);
219     }
220   else if (idx == 3 && NOTE_P (in_rtx))
221     {
222       switch (NOTE_KIND (in_rtx))
223         {
224         case NOTE_INSN_EH_REGION_BEG:
225         case NOTE_INSN_EH_REGION_END:
226           if (flag_dump_unnumbered)
227             fprintf (m_outfile, " #");
228           else
229             fprintf (m_outfile, " %d", NOTE_EH_HANDLER (in_rtx));
230           m_sawclose = 1;
231           break;
232
233         case NOTE_INSN_BLOCK_BEG:
234         case NOTE_INSN_BLOCK_END:
235           dump_addr (m_outfile, " ", NOTE_BLOCK (in_rtx));
236           m_sawclose = 1;
237           break;
238
239         case NOTE_INSN_BASIC_BLOCK:
240           {
241             basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
242             if (bb != 0)
243               fprintf (m_outfile, " [bb %d]", bb->index);
244             break;
245           }
246
247         case NOTE_INSN_DELETED_LABEL:
248         case NOTE_INSN_DELETED_DEBUG_LABEL:
249           {
250             const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
251             if (label)
252               fprintf (m_outfile, " (\"%s\")", label);
253             else
254               fprintf (m_outfile, " \"\"");
255           }
256           break;
257
258         case NOTE_INSN_SWITCH_TEXT_SECTIONS:
259           {
260             basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
261             if (bb != 0)
262               fprintf (m_outfile, " [bb %d]", bb->index);
263             break;
264           }
265
266         case NOTE_INSN_VAR_LOCATION:
267           fputc (' ', m_outfile);
268           print_rtx (NOTE_VAR_LOCATION (in_rtx));
269           break;
270
271         case NOTE_INSN_CFI:
272           fputc ('\n', m_outfile);
273           output_cfi_directive (m_outfile, NOTE_CFI (in_rtx));
274           fputc ('\t', m_outfile);
275           break;
276
277         case NOTE_INSN_BEGIN_STMT:
278         case NOTE_INSN_INLINE_ENTRY:
279 #ifndef GENERATOR_FILE
280           {
281             expanded_location xloc
282               = expand_location (NOTE_MARKER_LOCATION (in_rtx));
283             fprintf (m_outfile, " %s:%i", xloc.file, xloc.line);
284           }
285 #endif
286           break;
287
288         default:
289           break;
290         }
291     }
292   else if (idx == 7 && JUMP_P (in_rtx) && JUMP_LABEL (in_rtx) != NULL
293            && !m_compact)
294     {
295       /* Output the JUMP_LABEL reference.  */
296       fprintf (m_outfile, "\n%s%*s -> ", print_rtx_head, m_indent * 2, "");
297       if (GET_CODE (JUMP_LABEL (in_rtx)) == RETURN)
298         fprintf (m_outfile, "return");
299       else if (GET_CODE (JUMP_LABEL (in_rtx)) == SIMPLE_RETURN)
300         fprintf (m_outfile, "simple_return");
301       else
302         fprintf (m_outfile, "%d", INSN_UID (JUMP_LABEL (in_rtx)));
303     }
304   else if (idx == 0 && GET_CODE (in_rtx) == VALUE)
305     {
306       cselib_val *val = CSELIB_VAL_PTR (in_rtx);
307
308       fprintf (m_outfile, " %u:%u", val->uid, val->hash);
309       dump_addr (m_outfile, " @", in_rtx);
310       dump_addr (m_outfile, "/", (void*)val);
311     }
312   else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_EXPR)
313     {
314       fprintf (m_outfile, " D#%i",
315                DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (in_rtx)));
316     }
317   else if (idx == 0 && GET_CODE (in_rtx) == ENTRY_VALUE)
318     {
319       m_indent += 2;
320       if (!m_sawclose)
321         fprintf (m_outfile, " ");
322       print_rtx (ENTRY_VALUE_EXP (in_rtx));
323       m_indent -= 2;
324     }
325 #endif
326 }
327
328 /* Subroutine of print_rtx_operand for handling code 'e'.
329    Also called by print_rtx_operand_code_u for handling code 'u'
330    for LABEL_REFs when they don't reference a CODE_LABEL.  */
331
332 void
333 rtx_writer::print_rtx_operand_code_e (const_rtx in_rtx, int idx)
334 {
335   m_indent += 2;
336   if (idx == 6 && INSN_P (in_rtx))
337     /* Put REG_NOTES on their own line.  */
338     fprintf (m_outfile, "\n%s%*s",
339              print_rtx_head, m_indent * 2, "");
340   if (!m_sawclose)
341     fprintf (m_outfile, " ");
342   if (idx == 7 && CALL_P (in_rtx))
343     {
344       m_in_call_function_usage = true;
345       print_rtx (XEXP (in_rtx, idx));
346       m_in_call_function_usage = false;
347     }
348   else
349     print_rtx (XEXP (in_rtx, idx));
350   m_indent -= 2;
351 }
352
353 /* Subroutine of print_rtx_operand for handling codes 'E' and 'V'.  */
354
355 void
356 rtx_writer::print_rtx_operand_codes_E_and_V (const_rtx in_rtx, int idx)
357 {
358   m_indent += 2;
359   if (m_sawclose)
360     {
361       fprintf (m_outfile, "\n%s%*s",
362       print_rtx_head, m_indent * 2, "");
363       m_sawclose = 0;
364     }
365   fputs (" [", m_outfile);
366   if (XVEC (in_rtx, idx) != NULL)
367     {
368       m_indent += 2;
369       if (XVECLEN (in_rtx, idx))
370         m_sawclose = 1;
371
372       for (int j = 0; j < XVECLEN (in_rtx, idx); j++)
373         print_rtx (XVECEXP (in_rtx, idx, j));
374
375       m_indent -= 2;
376     }
377   if (m_sawclose)
378     fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
379
380   fputs ("]", m_outfile);
381   m_sawclose = 1;
382   m_indent -= 2;
383 }
384
385 /* Subroutine of print_rtx_operand for handling code 'i'.  */
386
387 void
388 rtx_writer::print_rtx_operand_code_i (const_rtx in_rtx, int idx)
389 {
390   if (idx == 4 && INSN_P (in_rtx))
391     {
392 #ifndef GENERATOR_FILE
393       const rtx_insn *in_insn = as_a <const rtx_insn *> (in_rtx);
394
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_HAS_LOCATION (in_insn))
399         {
400           expanded_location xloc = insn_location (in_insn);
401           fprintf (m_outfile, " \"%s\":%i:%i", xloc.file, xloc.line,
402                    xloc.column);
403         }
404 #endif
405     }
406   else if (idx == 6 && GET_CODE (in_rtx) == ASM_OPERANDS)
407     {
408 #ifndef GENERATOR_FILE
409       if (ASM_OPERANDS_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
410         fprintf (m_outfile, " %s:%i",
411                  LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
412                  LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
413 #endif
414     }
415   else if (idx == 1 && GET_CODE (in_rtx) == ASM_INPUT)
416     {
417 #ifndef GENERATOR_FILE
418       if (ASM_INPUT_SOURCE_LOCATION (in_rtx) != UNKNOWN_LOCATION)
419         fprintf (m_outfile, " %s:%i",
420                  LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
421                  LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
422 #endif
423     }
424   else if (idx == 5 && NOTE_P (in_rtx))
425     {
426       /* This field is only used for NOTE_INSN_DELETED_LABEL, and
427          other times often contains garbage from INSN->NOTE death.  */
428       if (NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_LABEL
429           || NOTE_KIND (in_rtx) == NOTE_INSN_DELETED_DEBUG_LABEL)
430         fprintf (m_outfile, " %d",  XINT (in_rtx, idx));
431     }
432 #if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
433   else if (idx == 1
434            && GET_CODE (in_rtx) == UNSPEC_VOLATILE
435            && XINT (in_rtx, 1) >= 0
436            && XINT (in_rtx, 1) < NUM_UNSPECV_VALUES)
437     fprintf (m_outfile, " %s", unspecv_strings[XINT (in_rtx, 1)]);
438 #endif
439 #if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
440   else if (idx == 1
441            && (GET_CODE (in_rtx) == UNSPEC
442                || GET_CODE (in_rtx) == UNSPEC_VOLATILE)
443            && XINT (in_rtx, 1) >= 0
444            && XINT (in_rtx, 1) < NUM_UNSPEC_VALUES)
445     fprintf (m_outfile, " %s", unspec_strings[XINT (in_rtx, 1)]);
446 #endif
447   else
448     {
449       int value = XINT (in_rtx, idx);
450       const char *name;
451       int is_insn = INSN_P (in_rtx);
452
453       /* Don't print INSN_CODEs in compact mode.  */
454       if (m_compact && is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx))
455         {
456           m_sawclose = 0;
457           return;
458         }
459
460       if (flag_dump_unnumbered
461           && (is_insn || NOTE_P (in_rtx)))
462         fputc ('#', m_outfile);
463       else
464         fprintf (m_outfile, " %d", value);
465
466       if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, idx)
467           && XINT (in_rtx, idx) >= 0
468           && (name = get_insn_name (XINT (in_rtx, idx))) != NULL)
469         fprintf (m_outfile, " {%s}", name);
470       m_sawclose = 0;
471     }
472 }
473
474 /* Subroutine of print_rtx_operand for handling code 'r'.  */
475
476 void
477 rtx_writer::print_rtx_operand_code_r (const_rtx in_rtx)
478 {
479   int is_insn = INSN_P (in_rtx);
480   unsigned int regno = REGNO (in_rtx);
481
482 #ifndef GENERATOR_FILE
483   /* For hard registers and virtuals, always print the
484      regno, except in compact mode.  */
485   if (regno <= LAST_VIRTUAL_REGISTER && !m_compact)
486     fprintf (m_outfile, " %d", regno);
487   if (regno < FIRST_PSEUDO_REGISTER)
488     fprintf (m_outfile, " %s", reg_names[regno]);
489   else if (regno <= LAST_VIRTUAL_REGISTER)
490     {
491       if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
492         fprintf (m_outfile, " virtual-incoming-args");
493       else if (regno == VIRTUAL_STACK_VARS_REGNUM)
494         fprintf (m_outfile, " virtual-stack-vars");
495       else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
496         fprintf (m_outfile, " virtual-stack-dynamic");
497       else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
498         fprintf (m_outfile, " virtual-outgoing-args");
499       else if (regno == VIRTUAL_CFA_REGNUM)
500         fprintf (m_outfile, " virtual-cfa");
501       else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
502         fprintf (m_outfile, " virtual-preferred-stack-boundary");
503       else
504         fprintf (m_outfile, " virtual-reg-%d", regno-FIRST_VIRTUAL_REGISTER);
505     }
506   else
507 #endif
508     if (flag_dump_unnumbered && is_insn)
509       fputc ('#', m_outfile);
510     else if (m_compact)
511       {
512         /* In compact mode, print pseudos with '< and '>' wrapping the regno,
513            offseting it by (LAST_VIRTUAL_REGISTER + 1), so that the
514            first non-virtual pseudo is dumped as "<0>".  */
515         gcc_assert (regno > LAST_VIRTUAL_REGISTER);
516         fprintf (m_outfile, " <%d>", regno - (LAST_VIRTUAL_REGISTER + 1));
517       }
518     else
519       fprintf (m_outfile, " %d", regno);
520
521 #ifndef GENERATOR_FILE
522   if (REG_ATTRS (in_rtx))
523     {
524       fputs (" [", m_outfile);
525       if (regno != ORIGINAL_REGNO (in_rtx))
526         fprintf (m_outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
527       if (REG_EXPR (in_rtx))
528         print_mem_expr (m_outfile, REG_EXPR (in_rtx));
529
530       if (maybe_ne (REG_OFFSET (in_rtx), 0))
531         {
532           fprintf (m_outfile, "+");
533           print_poly_int (m_outfile, REG_OFFSET (in_rtx));
534         }
535       fputs (" ]", m_outfile);
536     }
537   if (regno != ORIGINAL_REGNO (in_rtx))
538     fprintf (m_outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
539 #endif
540 }
541
542 /* Subroutine of print_rtx_operand for handling code 'u'.  */
543
544 void
545 rtx_writer::print_rtx_operand_code_u (const_rtx in_rtx, int idx)
546 {
547   /* Don't print insn UIDs for PREV/NEXT_INSN in compact mode.  */
548   if (m_compact && INSN_CHAIN_CODE_P (GET_CODE (in_rtx)) && idx < 2)
549     return;
550
551   if (XEXP (in_rtx, idx) != NULL)
552     {
553       rtx sub = XEXP (in_rtx, idx);
554       enum rtx_code subc = GET_CODE (sub);
555
556       if (GET_CODE (in_rtx) == LABEL_REF)
557         {
558           if (subc == NOTE
559               && NOTE_KIND (sub) == NOTE_INSN_DELETED_LABEL)
560             {
561               if (flag_dump_unnumbered)
562                 fprintf (m_outfile, " [# deleted]");
563               else
564                 fprintf (m_outfile, " [%d deleted]", INSN_UID (sub));
565               m_sawclose = 0;
566               return;
567             }
568
569           if (subc != CODE_LABEL)
570             {
571               print_rtx_operand_code_e (in_rtx, idx);
572               return;
573             }
574         }
575
576       if (flag_dump_unnumbered
577           || (flag_dump_unnumbered_links && idx <= 1
578               && (INSN_P (in_rtx) || NOTE_P (in_rtx)
579                   || LABEL_P (in_rtx) || BARRIER_P (in_rtx))))
580         fputs (" #", m_outfile);
581       else
582         fprintf (m_outfile, " %d", INSN_UID (sub));
583     }
584   else
585     fputs (" 0", m_outfile);
586   m_sawclose = 0;
587 }
588
589 /* Subroutine of print_rtx.   Print operand IDX of IN_RTX.  */
590
591 void
592 rtx_writer::print_rtx_operand (const_rtx in_rtx, int idx)
593 {
594   const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
595
596   switch (format_ptr[idx])
597     {
598       const char *str;
599
600     case 'T':
601       str = XTMPL (in_rtx, idx);
602       goto string;
603
604     case 'S':
605     case 's':
606       str = XSTR (in_rtx, idx);
607     string:
608
609       if (str == 0)
610         fputs (" (nil)", m_outfile);
611       else
612         fprintf (m_outfile, " (\"%s\")", str);
613       m_sawclose = 1;
614       break;
615
616     case '0':
617       print_rtx_operand_code_0 (in_rtx, idx);
618       break;
619
620     case 'e':
621       print_rtx_operand_code_e (in_rtx, idx);
622       break;
623
624     case 'E':
625     case 'V':
626       print_rtx_operand_codes_E_and_V (in_rtx, idx);
627       break;
628
629     case 'w':
630       if (! m_simple)
631         fprintf (m_outfile, " ");
632       fprintf (m_outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, idx));
633       if (! m_simple && !m_compact)
634         fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
635                  (unsigned HOST_WIDE_INT) XWINT (in_rtx, idx));
636       break;
637
638     case 'i':
639       print_rtx_operand_code_i (in_rtx, idx);
640       break;
641
642     case 'p':
643       fprintf (m_outfile, " ");
644       print_poly_int (m_outfile, SUBREG_BYTE (in_rtx));
645       break;
646
647     case 'r':
648       print_rtx_operand_code_r (in_rtx);
649       break;
650
651     /* Print NOTE_INSN names rather than integer codes.  */
652
653     case 'n':
654       fprintf (m_outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, idx)));
655       m_sawclose = 0;
656       break;
657
658     case 'u':
659       print_rtx_operand_code_u (in_rtx, idx);
660       break;
661
662     case 't':
663 #ifndef GENERATOR_FILE
664       if (idx == 0 && GET_CODE (in_rtx) == DEBUG_IMPLICIT_PTR)
665         print_mem_expr (m_outfile, DEBUG_IMPLICIT_PTR_DECL (in_rtx));
666       else if (idx == 0 && GET_CODE (in_rtx) == DEBUG_PARAMETER_REF)
667         print_mem_expr (m_outfile, DEBUG_PARAMETER_REF_DECL (in_rtx));
668       else
669         dump_addr (m_outfile, " ", XTREE (in_rtx, idx));
670 #endif
671       break;
672
673     case '*':
674       fputs (" Unknown", m_outfile);
675       m_sawclose = 0;
676       break;
677
678     case 'B':
679       /* Don't print basic block ids in compact mode.  */
680       if (m_compact)
681         break;
682 #ifndef GENERATOR_FILE
683       if (XBBDEF (in_rtx, idx))
684         fprintf (m_outfile, " %i", XBBDEF (in_rtx, idx)->index);
685 #endif
686       break;
687
688     default:
689       gcc_unreachable ();
690     }
691 }
692
693 /* Subroutine of rtx_writer::print_rtx.
694    In compact mode, determine if operand IDX of IN_RTX is interesting
695    to dump, or (if in a trailing position) it can be omitted.  */
696
697 bool
698 rtx_writer::operand_has_default_value_p (const_rtx in_rtx, int idx)
699 {
700   const char *format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));
701
702   switch (format_ptr[idx])
703     {
704     case 'e':
705     case 'u':
706       return XEXP (in_rtx, idx) == NULL_RTX;
707
708     case 's':
709       return XSTR (in_rtx, idx) == NULL;
710
711     case '0':
712       switch (GET_CODE (in_rtx))
713         {
714         case JUMP_INSN:
715           /* JUMP_LABELs are always omitted in compact mode, so treat
716              any value here as omittable, so that earlier operands can
717              potentially be omitted also.  */
718           return m_compact;
719
720         default:
721           return false;
722
723         }
724
725     default:
726       return false;
727     }
728 }
729
730 /* Print IN_RTX onto m_outfile.  This is the recursive part of printing.  */
731
732 void
733 rtx_writer::print_rtx (const_rtx in_rtx)
734 {
735   int idx = 0;
736
737   if (m_sawclose)
738     {
739       if (m_simple)
740         fputc (' ', m_outfile);
741       else
742         fprintf (m_outfile, "\n%s%*s", print_rtx_head, m_indent * 2, "");
743       m_sawclose = 0;
744     }
745
746   if (in_rtx == 0)
747     {
748       fputs ("(nil)", m_outfile);
749       m_sawclose = 1;
750       return;
751     }
752   else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
753     {
754        fprintf (m_outfile, "(??? bad code %d\n%s%*s)", GET_CODE (in_rtx),
755                 print_rtx_head, m_indent * 2, "");
756        m_sawclose = 1;
757        return;
758     }
759
760   fputc ('(', m_outfile);
761
762   /* Print name of expression code.  */
763
764   /* Handle reuse.  */
765 #ifndef GENERATOR_FILE
766   if (m_rtx_reuse_manager)
767     {
768       int reuse_id;
769       if (m_rtx_reuse_manager->has_reuse_id (in_rtx, &reuse_id))
770         {
771           /* Have we already seen the defn of this rtx?  */
772           if (m_rtx_reuse_manager->seen_def_p (reuse_id))
773             {
774               fprintf (m_outfile, "reuse_rtx %i)", reuse_id);
775               m_sawclose = 1;
776               return;
777             }
778           else
779             {
780               /* First time we've seen this reused-rtx.  */
781               fprintf (m_outfile, "%i|", reuse_id);
782               m_rtx_reuse_manager->set_seen_def (reuse_id);
783             }
784         }
785     }
786 #endif /* #ifndef GENERATOR_FILE */
787
788   /* In compact mode, prefix the code of insns with "c",
789      giving "cinsn", "cnote" etc.  */
790   if (m_compact && is_a <const rtx_insn *, const struct rtx_def> (in_rtx))
791     {
792       /* "ccode_label" is slightly awkward, so special-case it as
793          just "clabel".  */
794       rtx_code code = GET_CODE (in_rtx);
795       if (code == CODE_LABEL)
796         fprintf (m_outfile, "clabel");
797       else
798         fprintf (m_outfile, "c%s", GET_RTX_NAME (code));
799     }
800   else if (m_simple && CONST_INT_P (in_rtx))
801     ; /* no code.  */
802   else
803     fprintf (m_outfile, "%s", GET_RTX_NAME (GET_CODE (in_rtx)));
804
805   if (! m_simple)
806     {
807       if (RTX_FLAG (in_rtx, in_struct))
808         fputs ("/s", m_outfile);
809
810       if (RTX_FLAG (in_rtx, volatil))
811         fputs ("/v", m_outfile);
812
813       if (RTX_FLAG (in_rtx, unchanging))
814         fputs ("/u", m_outfile);
815
816       if (RTX_FLAG (in_rtx, frame_related))
817         fputs ("/f", m_outfile);
818
819       if (RTX_FLAG (in_rtx, jump))
820         fputs ("/j", m_outfile);
821
822       if (RTX_FLAG (in_rtx, call))
823         fputs ("/c", m_outfile);
824
825       if (RTX_FLAG (in_rtx, return_val))
826         fputs ("/i", m_outfile);
827
828       /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
829       if ((GET_CODE (in_rtx) == EXPR_LIST
830            || GET_CODE (in_rtx) == INSN_LIST
831            || GET_CODE (in_rtx) == INT_LIST)
832           && (int)GET_MODE (in_rtx) < REG_NOTE_MAX
833           && !m_in_call_function_usage)
834         fprintf (m_outfile, ":%s",
835                  GET_REG_NOTE_NAME (GET_MODE (in_rtx)));
836
837       /* For other rtl, print the mode if it's not VOID.  */
838       else if (GET_MODE (in_rtx) != VOIDmode)
839         fprintf (m_outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
840
841 #ifndef GENERATOR_FILE
842       if (GET_CODE (in_rtx) == VAR_LOCATION)
843         {
844           if (TREE_CODE (PAT_VAR_LOCATION_DECL (in_rtx)) == STRING_CST)
845             fputs (" <debug string placeholder>", m_outfile);
846           else
847             print_mem_expr (m_outfile, PAT_VAR_LOCATION_DECL (in_rtx));
848           fputc (' ', m_outfile);
849           print_rtx (PAT_VAR_LOCATION_LOC (in_rtx));
850           if (PAT_VAR_LOCATION_STATUS (in_rtx)
851               == VAR_INIT_STATUS_UNINITIALIZED)
852             fprintf (m_outfile, " [uninit]");
853           m_sawclose = 1;
854           idx = GET_RTX_LENGTH (VAR_LOCATION);
855         }
856 #endif
857     }
858
859 #ifndef GENERATOR_FILE
860   if (CONST_DOUBLE_AS_FLOAT_P (in_rtx))
861     idx = 5;
862 #endif
863
864   /* For insns, print the INSN_UID.  */
865   if (INSN_CHAIN_CODE_P (GET_CODE (in_rtx)))
866     {
867       if (flag_dump_unnumbered)
868         fprintf (m_outfile, " #");
869       else
870         fprintf (m_outfile, " %d", INSN_UID (in_rtx));
871     }
872
873   /* Determine which is the final operand to print.
874      In compact mode, skip trailing operands that have the default values
875      e.g. trailing "(nil)" values.  */
876   int limit = GET_RTX_LENGTH (GET_CODE (in_rtx));
877   if (m_compact)
878     while (limit > idx && operand_has_default_value_p (in_rtx, limit - 1))
879       limit--;
880
881   /* Get the format string and skip the first elements if we have handled
882      them already.  */
883
884   for (; idx < limit; idx++)
885     print_rtx_operand (in_rtx, idx);
886
887   switch (GET_CODE (in_rtx))
888     {
889 #ifndef GENERATOR_FILE
890     case MEM:
891       if (__builtin_expect (final_insns_dump_p, false))
892         fprintf (m_outfile, " [");
893       else
894         fprintf (m_outfile, " [" HOST_WIDE_INT_PRINT_DEC,
895                  (HOST_WIDE_INT) MEM_ALIAS_SET (in_rtx));
896
897       if (MEM_EXPR (in_rtx))
898         print_mem_expr (m_outfile, MEM_EXPR (in_rtx));
899       else
900         fputc (' ', m_outfile);
901
902       if (MEM_OFFSET_KNOWN_P (in_rtx))
903         {
904           fprintf (m_outfile, "+");
905           print_poly_int (m_outfile, MEM_OFFSET (in_rtx));
906         }
907
908       if (MEM_SIZE_KNOWN_P (in_rtx))
909         {
910           fprintf (m_outfile, " S");
911           print_poly_int (m_outfile, MEM_SIZE (in_rtx));
912         }
913
914       if (MEM_ALIGN (in_rtx) != 1)
915         fprintf (m_outfile, " A%u", MEM_ALIGN (in_rtx));
916
917       if (!ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (in_rtx)))
918         fprintf (m_outfile, " AS%u", MEM_ADDR_SPACE (in_rtx));
919
920       fputc (']', m_outfile);
921       break;
922
923     case CONST_DOUBLE:
924       if (FLOAT_MODE_P (GET_MODE (in_rtx)))
925         {
926           char s[60];
927
928           real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
929                            sizeof (s), 0, 1);
930           fprintf (m_outfile, " %s", s);
931
932           real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
933                                sizeof (s), 0, 1);
934           fprintf (m_outfile, " [%s]", s);
935         }
936       break;
937
938     case CONST_WIDE_INT:
939       fprintf (m_outfile, " ");
940       cwi_output_hex (m_outfile, in_rtx);
941       break;
942
943     case CONST_POLY_INT:
944       fprintf (m_outfile, " [");
945       print_dec (CONST_POLY_INT_COEFFS (in_rtx)[0], m_outfile, SIGNED);
946       for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
947         {
948           fprintf (m_outfile, ", ");
949           print_dec (CONST_POLY_INT_COEFFS (in_rtx)[i], m_outfile, SIGNED);
950         }
951       fprintf (m_outfile, "]");
952       break;
953 #endif
954
955     case CODE_LABEL:
956       if (!m_compact)
957         fprintf (m_outfile, " [%d uses]", LABEL_NUSES (in_rtx));
958       switch (LABEL_KIND (in_rtx))
959         {
960           case LABEL_NORMAL: break;
961           case LABEL_STATIC_ENTRY: fputs (" [entry]", m_outfile); break;
962           case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", m_outfile); break;
963           case LABEL_WEAK_ENTRY: fputs (" [weak entry]", m_outfile); break;
964           default: gcc_unreachable ();
965         }
966       break;
967
968     default:
969       break;
970     }
971
972   fputc (')', m_outfile);
973   m_sawclose = 1;
974 }
975
976 /* Emit a closing parenthesis and newline.  */
977
978 void
979 rtx_writer::finish_directive ()
980 {
981   fprintf (m_outfile, ")\n");
982   m_sawclose = 0;
983 }
984
985 /* Print an rtx on the current line of FILE.  Initially indent IND
986    characters.  */
987
988 void
989 print_inline_rtx (FILE *outf, const_rtx x, int ind)
990 {
991   rtx_writer w (outf, ind, false, false, NULL);
992   w.print_rtx (x);
993 }
994
995 /* Call this function from the debugger to see what X looks like.  */
996
997 DEBUG_FUNCTION void
998 debug_rtx (const_rtx x)
999 {
1000   rtx_writer w (stderr, 0, false, false, NULL);
1001   w.print_rtx (x);
1002   fprintf (stderr, "\n");
1003 }
1004
1005 /* Dump rtx REF.  */
1006
1007 DEBUG_FUNCTION void
1008 debug (const rtx_def &ref)
1009 {
1010   debug_rtx (&ref);
1011 }
1012
1013 DEBUG_FUNCTION void
1014 debug (const rtx_def *ptr)
1015 {
1016   if (ptr)
1017     debug (*ptr);
1018   else
1019     fprintf (stderr, "<nil>\n");
1020 }
1021
1022 /* Like debug_rtx but with no newline, as debug_helper will add one.
1023
1024    Note: No debug_slim(rtx_insn *) variant implemented, as this
1025    function can serve for both rtx and rtx_insn.  */
1026
1027 static void
1028 debug_slim (const_rtx x)
1029 {
1030   rtx_writer w (stderr, 0, false, false, NULL);
1031   w.print_rtx (x);
1032 }
1033
1034 DEFINE_DEBUG_VEC (rtx_def *)
1035 DEFINE_DEBUG_VEC (rtx_insn *)
1036 DEFINE_DEBUG_HASH_SET (rtx_def *)
1037 DEFINE_DEBUG_HASH_SET (rtx_insn *)
1038
1039 /* Count of rtx's to print with debug_rtx_list.
1040    This global exists because gdb user defined commands have no arguments.  */
1041
1042 DEBUG_VARIABLE int debug_rtx_count = 0; /* 0 is treated as equivalent to 1 */
1043
1044 /* Call this function to print list from X on.
1045
1046    N is a count of the rtx's to print. Positive values print from the specified
1047    rtx_insn on.  Negative values print a window around the rtx_insn.
1048    EG: -5 prints 2 rtx_insn's on either side (in addition to the specified
1049    rtx_insn).  */
1050
1051 DEBUG_FUNCTION void
1052 debug_rtx_list (const rtx_insn *x, int n)
1053 {
1054   int i,count;
1055   const rtx_insn *insn;
1056
1057   count = n == 0 ? 1 : n < 0 ? -n : n;
1058
1059   /* If we are printing a window, back up to the start.  */
1060
1061   if (n < 0)
1062     for (i = count / 2; i > 0; i--)
1063       {
1064         if (PREV_INSN (x) == 0)
1065           break;
1066         x = PREV_INSN (x);
1067       }
1068
1069   for (i = count, insn = x; i > 0 && insn != 0; i--, insn = NEXT_INSN (insn))
1070     {
1071       debug_rtx (insn);
1072       fprintf (stderr, "\n");
1073     }
1074 }
1075
1076 /* Call this function to print an rtx_insn list from START to END
1077    inclusive.  */
1078
1079 DEBUG_FUNCTION void
1080 debug_rtx_range (const rtx_insn *start, const rtx_insn *end)
1081 {
1082   while (1)
1083     {
1084       debug_rtx (start);
1085       fprintf (stderr, "\n");
1086       if (!start || start == end)
1087         break;
1088       start = NEXT_INSN (start);
1089     }
1090 }
1091
1092 /* Call this function to search an rtx_insn list to find one with insn uid UID,
1093    and then call debug_rtx_list to print it, using DEBUG_RTX_COUNT.
1094    The found insn is returned to enable further debugging analysis.  */
1095
1096 DEBUG_FUNCTION const rtx_insn *
1097 debug_rtx_find (const rtx_insn *x, int uid)
1098 {
1099   while (x != 0 && INSN_UID (x) != uid)
1100     x = NEXT_INSN (x);
1101   if (x != 0)
1102     {
1103       debug_rtx_list (x, debug_rtx_count);
1104       return x;
1105     }
1106   else
1107     {
1108       fprintf (stderr, "insn uid %d not found\n", uid);
1109       return 0;
1110     }
1111 }
1112
1113 /* External entry point for printing a chain of insns
1114    starting with RTX_FIRST.
1115    A blank line separates insns.
1116
1117    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
1118
1119 void
1120 rtx_writer::print_rtl (const_rtx rtx_first)
1121 {
1122   const rtx_insn *tmp_rtx;
1123
1124   if (rtx_first == 0)
1125     {
1126       fputs (print_rtx_head, m_outfile);
1127       fputs ("(nil)\n", m_outfile);
1128     }
1129   else
1130     switch (GET_CODE (rtx_first))
1131       {
1132       case INSN:
1133       case JUMP_INSN:
1134       case CALL_INSN:
1135       case NOTE:
1136       case CODE_LABEL:
1137       case JUMP_TABLE_DATA:
1138       case BARRIER:
1139         for (tmp_rtx = as_a <const rtx_insn *> (rtx_first);
1140              tmp_rtx != 0;
1141              tmp_rtx = NEXT_INSN (tmp_rtx))
1142           {
1143             fputs (print_rtx_head, m_outfile);
1144             print_rtx (tmp_rtx);
1145             fprintf (m_outfile, "\n");
1146           }
1147         break;
1148
1149       default:
1150         fputs (print_rtx_head, m_outfile);
1151         print_rtx (rtx_first);
1152       }
1153 }
1154
1155 /* External entry point for printing a chain of insns
1156    starting with RTX_FIRST onto file OUTF.
1157    A blank line separates insns.
1158
1159    If RTX_FIRST is not an insn, then it alone is printed, with no newline.  */
1160
1161 void
1162 print_rtl (FILE *outf, const_rtx rtx_first)
1163 {
1164   rtx_writer w (outf, 0, false, false, NULL);
1165   w.print_rtl (rtx_first);
1166 }
1167
1168 /* Like print_rtx, except specify a file.  */
1169 /* Return nonzero if we actually printed anything.  */
1170
1171 int
1172 print_rtl_single (FILE *outf, const_rtx x)
1173 {
1174   rtx_writer w (outf, 0, false, false, NULL);
1175   return w.print_rtl_single_with_indent (x, 0);
1176 }
1177
1178 /* Like print_rtl_single, except specify an indentation.  */
1179
1180 int
1181 rtx_writer::print_rtl_single_with_indent (const_rtx x, int ind)
1182 {
1183   char *s_indent = (char *) alloca ((size_t) ind + 1);
1184   memset ((void *) s_indent, ' ', (size_t) ind);
1185   s_indent[ind] = '\0';
1186   fputs (s_indent, m_outfile);
1187   fputs (print_rtx_head, m_outfile);
1188
1189   int old_indent = m_indent;
1190   m_indent = ind;
1191   m_sawclose = 0;
1192   print_rtx (x);
1193   putc ('\n', m_outfile);
1194   m_indent = old_indent;
1195   return 1;
1196 }
1197
1198
1199 /* Like print_rtl except without all the detail; for example,
1200    if RTX is a CONST_INT then print in decimal format.  */
1201
1202 void
1203 print_simple_rtl (FILE *outf, const_rtx x)
1204 {
1205   rtx_writer w (outf, 0, true, false, NULL);
1206   w.print_rtl (x);
1207 }
1208
1209 /* Print the elements of VEC to FILE.  */
1210
1211 void
1212 print_rtx_insn_vec (FILE *file, const vec<rtx_insn *> &vec)
1213 {
1214   fputc('{', file);
1215
1216   unsigned int len = vec.length ();
1217   for (unsigned int i = 0; i < len; i++)
1218     {
1219       print_rtl (file, vec[i]);
1220       if (i < len - 1)
1221         fputs (", ", file);
1222     }
1223
1224   fputc ('}', file);
1225 }
1226
1227 #ifndef GENERATOR_FILE
1228 /* The functions below  try to print RTL in a form resembling assembler
1229    mnemonics.  Because this form is more concise than the "traditional" form
1230    of RTL printing in Lisp-style, the form printed by this file is called
1231    "slim".  RTL dumps in slim format can be obtained by appending the "-slim"
1232    option to -fdump-rtl-<pass>.  Control flow graph output as a DOT file is
1233    always printed in slim form.
1234
1235    The normal interface to the functionality provided in this pretty-printer
1236    is through the dump_*_slim functions to print to a stream, or via the
1237    print_*_slim functions to print into a user's pretty-printer.
1238
1239    It is also possible to obtain a string for a single pattern as a string
1240    pointer, via str_pattern_slim, but this usage is discouraged.  */
1241
1242 /* For insns we print patterns, and for some patterns we print insns...  */
1243 static void print_insn_with_notes (pretty_printer *, const rtx_insn *);
1244
1245 /* This recognizes rtx'en classified as expressions.  These are always
1246    represent some action on values or results of other expression, that
1247    may be stored in objects representing values.  */
1248
1249 static void
1250 print_exp (pretty_printer *pp, const_rtx x, int verbose)
1251 {
1252   const char *st[4];
1253   const char *fun;
1254   rtx op[4];
1255   int i;
1256
1257   fun = (char *) 0;
1258   for (i = 0; i < 4; i++)
1259     {
1260       st[i] = (char *) 0;
1261       op[i] = NULL_RTX;
1262     }
1263
1264   switch (GET_CODE (x))
1265     {
1266     case PLUS:
1267       op[0] = XEXP (x, 0);
1268       if (CONST_INT_P (XEXP (x, 1))
1269           && INTVAL (XEXP (x, 1)) < 0)
1270         {
1271           st[1] = "-";
1272           op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
1273         }
1274       else
1275         {
1276           st[1] = "+";
1277           op[1] = XEXP (x, 1);
1278         }
1279       break;
1280     case LO_SUM:
1281       op[0] = XEXP (x, 0);
1282       st[1] = "+low(";
1283       op[1] = XEXP (x, 1);
1284       st[2] = ")";
1285       break;
1286     case MINUS:
1287       op[0] = XEXP (x, 0);
1288       st[1] = "-";
1289       op[1] = XEXP (x, 1);
1290       break;
1291     case COMPARE:
1292       fun = "cmp";
1293       op[0] = XEXP (x, 0);
1294       op[1] = XEXP (x, 1);
1295       break;
1296     case NEG:
1297       st[0] = "-";
1298       op[0] = XEXP (x, 0);
1299       break;
1300     case FMA:
1301       st[0] = "{";
1302       op[0] = XEXP (x, 0);
1303       st[1] = "*";
1304       op[1] = XEXP (x, 1);
1305       st[2] = "+";
1306       op[2] = XEXP (x, 2);
1307       st[3] = "}";
1308       break;
1309     case MULT:
1310       op[0] = XEXP (x, 0);
1311       st[1] = "*";
1312       op[1] = XEXP (x, 1);
1313       break;
1314     case DIV:
1315       op[0] = XEXP (x, 0);
1316       st[1] = "/";
1317       op[1] = XEXP (x, 1);
1318       break;
1319     case UDIV:
1320       fun = "udiv";
1321       op[0] = XEXP (x, 0);
1322       op[1] = XEXP (x, 1);
1323       break;
1324     case MOD:
1325       op[0] = XEXP (x, 0);
1326       st[1] = "%";
1327       op[1] = XEXP (x, 1);
1328       break;
1329     case UMOD:
1330       fun = "umod";
1331       op[0] = XEXP (x, 0);
1332       op[1] = XEXP (x, 1);
1333       break;
1334     case SMIN:
1335       fun = "smin";
1336       op[0] = XEXP (x, 0);
1337       op[1] = XEXP (x, 1);
1338       break;
1339     case SMAX:
1340       fun = "smax";
1341       op[0] = XEXP (x, 0);
1342       op[1] = XEXP (x, 1);
1343       break;
1344     case UMIN:
1345       fun = "umin";
1346       op[0] = XEXP (x, 0);
1347       op[1] = XEXP (x, 1);
1348       break;
1349     case UMAX:
1350       fun = "umax";
1351       op[0] = XEXP (x, 0);
1352       op[1] = XEXP (x, 1);
1353       break;
1354     case NOT:
1355       st[0] = "~";
1356       op[0] = XEXP (x, 0);
1357       break;
1358     case AND:
1359       op[0] = XEXP (x, 0);
1360       st[1] = "&";
1361       op[1] = XEXP (x, 1);
1362       break;
1363     case IOR:
1364       op[0] = XEXP (x, 0);
1365       st[1] = "|";
1366       op[1] = XEXP (x, 1);
1367       break;
1368     case XOR:
1369       op[0] = XEXP (x, 0);
1370       st[1] = "^";
1371       op[1] = XEXP (x, 1);
1372       break;
1373     case ASHIFT:
1374       op[0] = XEXP (x, 0);
1375       st[1] = "<<";
1376       op[1] = XEXP (x, 1);
1377       break;
1378     case LSHIFTRT:
1379       op[0] = XEXP (x, 0);
1380       st[1] = " 0>>";
1381       op[1] = XEXP (x, 1);
1382       break;
1383     case ASHIFTRT:
1384       op[0] = XEXP (x, 0);
1385       st[1] = ">>";
1386       op[1] = XEXP (x, 1);
1387       break;
1388     case ROTATE:
1389       op[0] = XEXP (x, 0);
1390       st[1] = "<-<";
1391       op[1] = XEXP (x, 1);
1392       break;
1393     case ROTATERT:
1394       op[0] = XEXP (x, 0);
1395       st[1] = ">->";
1396       op[1] = XEXP (x, 1);
1397       break;
1398     case NE:
1399       op[0] = XEXP (x, 0);
1400       st[1] = "!=";
1401       op[1] = XEXP (x, 1);
1402       break;
1403     case EQ:
1404       op[0] = XEXP (x, 0);
1405       st[1] = "==";
1406       op[1] = XEXP (x, 1);
1407       break;
1408     case GE:
1409       op[0] = XEXP (x, 0);
1410       st[1] = ">=";
1411       op[1] = XEXP (x, 1);
1412       break;
1413     case GT:
1414       op[0] = XEXP (x, 0);
1415       st[1] = ">";
1416       op[1] = XEXP (x, 1);
1417       break;
1418     case LE:
1419       op[0] = XEXP (x, 0);
1420       st[1] = "<=";
1421       op[1] = XEXP (x, 1);
1422       break;
1423     case LT:
1424       op[0] = XEXP (x, 0);
1425       st[1] = "<";
1426       op[1] = XEXP (x, 1);
1427       break;
1428     case SIGN_EXTRACT:
1429       fun = (verbose) ? "sign_extract" : "sxt";
1430       op[0] = XEXP (x, 0);
1431       op[1] = XEXP (x, 1);
1432       op[2] = XEXP (x, 2);
1433       break;
1434     case ZERO_EXTRACT:
1435       fun = (verbose) ? "zero_extract" : "zxt";
1436       op[0] = XEXP (x, 0);
1437       op[1] = XEXP (x, 1);
1438       op[2] = XEXP (x, 2);
1439       break;
1440     case SIGN_EXTEND:
1441       fun = (verbose) ? "sign_extend" : "sxn";
1442       op[0] = XEXP (x, 0);
1443       break;
1444     case ZERO_EXTEND:
1445       fun = (verbose) ? "zero_extend" : "zxn";
1446       op[0] = XEXP (x, 0);
1447       break;
1448     case FLOAT_EXTEND:
1449       fun = (verbose) ? "float_extend" : "fxn";
1450       op[0] = XEXP (x, 0);
1451       break;
1452     case TRUNCATE:
1453       fun = (verbose) ? "trunc" : "trn";
1454       op[0] = XEXP (x, 0);
1455       break;
1456     case FLOAT_TRUNCATE:
1457       fun = (verbose) ? "float_trunc" : "ftr";
1458       op[0] = XEXP (x, 0);
1459       break;
1460     case FLOAT:
1461       fun = (verbose) ? "float" : "flt";
1462       op[0] = XEXP (x, 0);
1463       break;
1464     case UNSIGNED_FLOAT:
1465       fun = (verbose) ? "uns_float" : "ufl";
1466       op[0] = XEXP (x, 0);
1467       break;
1468     case FIX:
1469       fun = "fix";
1470       op[0] = XEXP (x, 0);
1471       break;
1472     case UNSIGNED_FIX:
1473       fun = (verbose) ? "uns_fix" : "ufx";
1474       op[0] = XEXP (x, 0);
1475       break;
1476     case PRE_DEC:
1477       st[0] = "--";
1478       op[0] = XEXP (x, 0);
1479       break;
1480     case PRE_INC:
1481       st[0] = "++";
1482       op[0] = XEXP (x, 0);
1483       break;
1484     case POST_DEC:
1485       op[0] = XEXP (x, 0);
1486       st[1] = "--";
1487       break;
1488     case POST_INC:
1489       op[0] = XEXP (x, 0);
1490       st[1] = "++";
1491       break;
1492     case PRE_MODIFY:
1493       st[0] = "pre ";
1494       op[0] = XEXP (XEXP (x, 1), 0);
1495       st[1] = "+=";
1496       op[1] = XEXP (XEXP (x, 1), 1);
1497       break;
1498     case POST_MODIFY:
1499       st[0] = "post ";
1500       op[0] = XEXP (XEXP (x, 1), 0);
1501       st[1] = "+=";
1502       op[1] = XEXP (XEXP (x, 1), 1);
1503       break;
1504     case CALL:
1505       st[0] = "call ";
1506       op[0] = XEXP (x, 0);
1507       if (verbose)
1508         {
1509           st[1] = " argc:";
1510           op[1] = XEXP (x, 1);
1511         }
1512       break;
1513     case IF_THEN_ELSE:
1514       st[0] = "{(";
1515       op[0] = XEXP (x, 0);
1516       st[1] = ")?";
1517       op[1] = XEXP (x, 1);
1518       st[2] = ":";
1519       op[2] = XEXP (x, 2);
1520       st[3] = "}";
1521       break;
1522     case TRAP_IF:
1523       fun = "trap_if";
1524       op[0] = TRAP_CONDITION (x);
1525       break;
1526     case PREFETCH:
1527       fun = "prefetch";
1528       op[0] = XEXP (x, 0);
1529       op[1] = XEXP (x, 1);
1530       op[2] = XEXP (x, 2);
1531       break;
1532     case UNSPEC:
1533     case UNSPEC_VOLATILE:
1534       {
1535         pp_string (pp, "unspec");
1536         if (GET_CODE (x) == UNSPEC_VOLATILE)
1537           pp_string (pp, "/v");
1538         pp_left_bracket (pp);
1539         for (i = 0; i < XVECLEN (x, 0); i++)
1540           {
1541             if (i != 0)
1542               pp_comma (pp);
1543             print_pattern (pp, XVECEXP (x, 0, i), verbose);
1544           }
1545         pp_string (pp, "] ");
1546         pp_decimal_int (pp, XINT (x, 1));
1547       }
1548       break;
1549     default:
1550       {
1551         /* Most unhandled codes can be printed as pseudo-functions.  */
1552         if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
1553           {
1554             fun = GET_RTX_NAME (GET_CODE (x));
1555             op[0] = XEXP (x, 0);
1556           }
1557         else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
1558                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
1559                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
1560                  || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
1561           {
1562             fun = GET_RTX_NAME (GET_CODE (x));
1563             op[0] = XEXP (x, 0);
1564             op[1] = XEXP (x, 1);
1565           }
1566         else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
1567           {
1568             fun = GET_RTX_NAME (GET_CODE (x));
1569             op[0] = XEXP (x, 0);
1570             op[1] = XEXP (x, 1);
1571             op[2] = XEXP (x, 2);
1572           }
1573         else
1574           /* Give up, just print the RTX name.  */
1575           st[0] = GET_RTX_NAME (GET_CODE (x));
1576       }
1577       break;
1578     }
1579
1580   /* Print this as a function?  */
1581   if (fun)
1582     {
1583       pp_string (pp, fun);
1584       pp_left_paren (pp);
1585     }
1586
1587   for (i = 0; i < 4; i++)
1588     {
1589       if (st[i])
1590         pp_string (pp, st[i]);
1591
1592       if (op[i])
1593         {
1594           if (fun && i != 0)
1595             pp_comma (pp);
1596           print_value (pp, op[i], verbose);
1597         }
1598     }
1599
1600   if (fun)
1601     pp_right_paren (pp);
1602 }               /* print_exp */
1603
1604 /* Prints rtxes, I customarily classified as values.  They're constants,
1605    registers, labels, symbols and memory accesses.  */
1606
1607 void
1608 print_value (pretty_printer *pp, const_rtx x, int verbose)
1609 {
1610   char tmp[1024];
1611
1612   if (!x)
1613     {
1614       pp_string (pp, "(nil)");
1615       return;
1616     }
1617   switch (GET_CODE (x))
1618     {
1619     case CONST_INT:
1620       pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
1621                  (unsigned HOST_WIDE_INT) INTVAL (x));
1622       break;
1623
1624     case CONST_WIDE_INT:
1625       {
1626         const char *sep = "<";
1627         int i;
1628         for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
1629           {
1630             pp_string (pp, sep);
1631             sep = ",";
1632             sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
1633                      (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
1634             pp_string (pp, tmp);
1635           }
1636         pp_greater (pp);
1637       }
1638       break;
1639
1640     case CONST_POLY_INT:
1641       pp_left_bracket (pp);
1642       pp_wide_int (pp, CONST_POLY_INT_COEFFS (x)[0], SIGNED);
1643       for (unsigned int i = 1; i < NUM_POLY_INT_COEFFS; ++i)
1644         {
1645           pp_string (pp, ", ");
1646           pp_wide_int (pp, CONST_POLY_INT_COEFFS (x)[i], SIGNED);
1647         }
1648       pp_right_bracket (pp);
1649       break;
1650
1651     case CONST_DOUBLE:
1652       if (FLOAT_MODE_P (GET_MODE (x)))
1653         {
1654           real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
1655                            sizeof (tmp), 0, 1);
1656           pp_string (pp, tmp);
1657         }
1658       else
1659         pp_printf (pp, "<%wx,%wx>",
1660                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
1661                    (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
1662       break;
1663     case CONST_FIXED:
1664       fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
1665       pp_string (pp, tmp);
1666       break;
1667     case CONST_STRING:
1668       pp_printf (pp, "\"%s\"", XSTR (x, 0));
1669       break;
1670     case SYMBOL_REF:
1671       pp_printf (pp, "`%s'", XSTR (x, 0));
1672       break;
1673     case LABEL_REF:
1674       pp_printf (pp, "L%d", INSN_UID (label_ref_label (x)));
1675       break;
1676     case CONST:
1677     case HIGH:
1678     case STRICT_LOW_PART:
1679       pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
1680       print_value (pp, XEXP (x, 0), verbose);
1681       pp_right_paren (pp);
1682       break;
1683     case REG:
1684       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
1685         {
1686           if (ISDIGIT (reg_names[REGNO (x)][0]))
1687             pp_modulo (pp);
1688           pp_string (pp, reg_names[REGNO (x)]);
1689         }
1690       else
1691         pp_printf (pp, "r%d", REGNO (x));
1692       if (verbose)
1693         pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
1694       break;
1695     case SUBREG:
1696       print_value (pp, SUBREG_REG (x), verbose);
1697       pp_printf (pp, "#");
1698       pp_wide_integer (pp, SUBREG_BYTE (x));
1699       break;
1700     case SCRATCH:
1701     case CC0:
1702     case PC:
1703       pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1704       break;
1705     case MEM:
1706       pp_left_bracket (pp);
1707       print_value (pp, XEXP (x, 0), verbose);
1708       pp_right_bracket (pp);
1709       break;
1710     case DEBUG_EXPR:
1711       pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
1712       break;
1713     default:
1714       print_exp (pp, x, verbose);
1715       break;
1716     }
1717 }                               /* print_value */
1718
1719 /* The next step in insn detalization, its pattern recognition.  */
1720
1721 void
1722 print_pattern (pretty_printer *pp, const_rtx x, int verbose)
1723 {
1724   if (! x)
1725     {
1726       pp_string (pp, "(nil)");
1727       return;
1728     }
1729
1730   switch (GET_CODE (x))
1731     {
1732     case SET:
1733       print_value (pp, SET_DEST (x), verbose);
1734       pp_equal (pp);
1735       print_value (pp, SET_SRC (x), verbose);
1736       break;
1737     case RETURN:
1738     case SIMPLE_RETURN:
1739     case EH_RETURN:
1740       pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
1741       break;
1742     case CALL:
1743       print_exp (pp, x, verbose);
1744       break;
1745     case CLOBBER:
1746     case CLOBBER_HIGH:
1747     case USE:
1748       pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
1749       print_value (pp, XEXP (x, 0), verbose);
1750       break;
1751     case VAR_LOCATION:
1752       pp_string (pp, "loc ");
1753       print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
1754       break;
1755     case COND_EXEC:
1756       pp_left_paren (pp);
1757       if (GET_CODE (COND_EXEC_TEST (x)) == NE
1758           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1759         print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1760       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
1761                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
1762         {
1763           pp_exclamation (pp);
1764           print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
1765         }
1766       else
1767         print_value (pp, COND_EXEC_TEST (x), verbose);
1768       pp_string (pp, ") ");
1769       print_pattern (pp, COND_EXEC_CODE (x), verbose);
1770       break;
1771     case PARALLEL:
1772       {
1773         int i;
1774
1775         pp_left_brace (pp);
1776         for (i = 0; i < XVECLEN (x, 0); i++)
1777           {
1778             print_pattern (pp, XVECEXP (x, 0, i), verbose);
1779             pp_semicolon (pp);
1780           }
1781         pp_right_brace (pp);
1782       }
1783       break;
1784     case SEQUENCE:
1785       {
1786         const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
1787         pp_string (pp, "sequence{");
1788         if (INSN_P (seq->element (0)))
1789           {
1790             /* Print the sequence insns indented.  */
1791             const char * save_print_rtx_head = print_rtx_head;
1792             char indented_print_rtx_head[32];
1793
1794             pp_newline (pp);
1795             gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
1796             snprintf (indented_print_rtx_head,
1797                       sizeof (indented_print_rtx_head),
1798                       "%s     ", print_rtx_head);
1799             print_rtx_head = indented_print_rtx_head;
1800             for (int i = 0; i < seq->len (); i++)
1801               print_insn_with_notes (pp, seq->insn (i));
1802             pp_printf (pp, "%s      ", save_print_rtx_head);
1803             print_rtx_head = save_print_rtx_head;
1804           }
1805         else
1806           {
1807             for (int i = 0; i < seq->len (); i++)
1808               {
1809                 print_pattern (pp, seq->element (i), verbose);
1810                 pp_semicolon (pp);
1811               }
1812           }
1813         pp_right_brace (pp);
1814       }
1815       break;
1816     case ASM_INPUT:
1817       pp_printf (pp, "asm {%s}", XSTR (x, 0));
1818       break;
1819     case ADDR_VEC:
1820       for (int i = 0; i < XVECLEN (x, 0); i++)
1821         {
1822           print_value (pp, XVECEXP (x, 0, i), verbose);
1823           pp_semicolon (pp);
1824         }
1825       break;
1826     case ADDR_DIFF_VEC:
1827       for (int i = 0; i < XVECLEN (x, 1); i++)
1828         {
1829           print_value (pp, XVECEXP (x, 1, i), verbose);
1830           pp_semicolon (pp);
1831         }
1832       break;
1833     case TRAP_IF:
1834       pp_string (pp, "trap_if ");
1835       print_value (pp, TRAP_CONDITION (x), verbose);
1836       break;
1837     case UNSPEC:
1838     case UNSPEC_VOLATILE:
1839       /* Fallthru -- leave UNSPECs to print_exp.  */
1840     default:
1841       print_value (pp, x, verbose);
1842     }
1843 }                               /* print_pattern */
1844
1845 /* This is the main function in slim rtl visualization mechanism.
1846
1847    X is an insn, to be printed into PP.
1848
1849    This function tries to print it properly in human-readable form,
1850    resembling assembler mnemonics (instead of the older Lisp-style
1851    form).
1852
1853    If VERBOSE is TRUE, insns are printed with more complete (but
1854    longer) pattern names and with extra information, and prefixed
1855    with their INSN_UIDs.  */
1856
1857 void
1858 print_insn (pretty_printer *pp, const rtx_insn *x, int verbose)
1859 {
1860   if (verbose)
1861     {
1862       /* Blech, pretty-print can't print integers with a specified width.  */
1863       char uid_prefix[32];
1864       snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
1865       pp_string (pp, uid_prefix);
1866     }
1867
1868   switch (GET_CODE (x))
1869     {
1870     case INSN:
1871       print_pattern (pp, PATTERN (x), verbose);
1872       break;
1873
1874     case DEBUG_INSN:
1875       {
1876         if (DEBUG_MARKER_INSN_P (x))
1877           {
1878             switch (INSN_DEBUG_MARKER_KIND (x))
1879               {
1880               case NOTE_INSN_BEGIN_STMT:
1881                 pp_string (pp, "debug begin stmt marker");
1882                 break;
1883
1884               case NOTE_INSN_INLINE_ENTRY:
1885                 pp_string (pp, "debug inline entry marker");
1886                 break;
1887
1888               default:
1889                 gcc_unreachable ();
1890               }
1891             break;
1892           }
1893
1894         const char *name = "?";
1895         char idbuf[32];
1896
1897         if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
1898           {
1899             tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
1900             if (id)
1901               name = IDENTIFIER_POINTER (id);
1902             else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
1903                      == DEBUG_EXPR_DECL)
1904               {
1905                 sprintf (idbuf, "D#%i",
1906                          DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
1907                 name = idbuf;
1908               }
1909             else
1910               {
1911                 sprintf (idbuf, "D.%i",
1912                          DECL_UID (INSN_VAR_LOCATION_DECL (x)));
1913                 name = idbuf;
1914               }
1915           }
1916         pp_printf (pp, "debug %s => ", name);
1917         if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
1918           pp_string (pp, "optimized away");
1919         else
1920           print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
1921       }
1922       break;
1923
1924     case JUMP_INSN:
1925       print_pattern (pp, PATTERN (x), verbose);
1926       break;
1927     case CALL_INSN:
1928       if (GET_CODE (PATTERN (x)) == PARALLEL)
1929         print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
1930       else
1931         print_pattern (pp, PATTERN (x), verbose);
1932       break;
1933     case CODE_LABEL:
1934       pp_printf (pp, "L%d:", INSN_UID (x));
1935       break;
1936     case JUMP_TABLE_DATA:
1937       pp_string (pp, "jump_table_data{\n");
1938       print_pattern (pp, PATTERN (x), verbose);
1939       pp_right_brace (pp);
1940       break;
1941     case BARRIER:
1942       pp_string (pp, "barrier");
1943       break;
1944     case NOTE:
1945       {
1946         pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
1947         switch (NOTE_KIND (x))
1948           {
1949           case NOTE_INSN_EH_REGION_BEG:
1950           case NOTE_INSN_EH_REGION_END:
1951             pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
1952             break;
1953
1954           case NOTE_INSN_BLOCK_BEG:
1955           case NOTE_INSN_BLOCK_END:
1956             pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
1957             break;
1958
1959           case NOTE_INSN_BASIC_BLOCK:
1960             pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
1961             break;
1962
1963           case NOTE_INSN_DELETED_LABEL:
1964           case NOTE_INSN_DELETED_DEBUG_LABEL:
1965             {
1966               const char *label = NOTE_DELETED_LABEL_NAME (x);
1967               if (label == NULL)
1968                 label = "";
1969               pp_printf (pp, " (\"%s\")", label);
1970             }
1971             break;
1972
1973           case NOTE_INSN_VAR_LOCATION:
1974             pp_left_brace (pp);
1975             print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
1976             pp_right_brace (pp);
1977             break;
1978
1979           default:
1980             break;
1981           }
1982         break;
1983       }
1984     default:
1985       gcc_unreachable ();
1986     }
1987 }                               /* print_insn */
1988
1989 /* Pretty-print a slim dump of X (an insn) to PP, including any register
1990    note attached to the instruction.  */
1991
1992 static void
1993 print_insn_with_notes (pretty_printer *pp, const rtx_insn *x)
1994 {
1995   pp_string (pp, print_rtx_head);
1996   print_insn (pp, x, 1);
1997   pp_newline (pp);
1998   if (INSN_P (x) && REG_NOTES (x))
1999     for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
2000       {
2001         pp_printf (pp, "%s      %s ", print_rtx_head,
2002                    GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
2003         if (GET_CODE (note) == INT_LIST)
2004           pp_printf (pp, "%d", XINT (note, 0));
2005         else
2006           print_pattern (pp, XEXP (note, 0), 1);
2007         pp_newline (pp);
2008       }
2009 }
2010
2011 /* Print X, an RTL value node, to file F in slim format.  Include
2012    additional information if VERBOSE is nonzero.
2013
2014    Value nodes are constants, registers, labels, symbols and
2015    memory.  */
2016
2017 void
2018 dump_value_slim (FILE *f, const_rtx x, int verbose)
2019 {
2020   pretty_printer rtl_slim_pp;
2021   rtl_slim_pp.buffer->stream = f;
2022   print_value (&rtl_slim_pp, x, verbose);
2023   pp_flush (&rtl_slim_pp);
2024 }
2025
2026 /* Emit a slim dump of X (an insn) to the file F, including any register
2027    note attached to the instruction.  */
2028 void
2029 dump_insn_slim (FILE *f, const rtx_insn *x)
2030 {
2031   pretty_printer rtl_slim_pp;
2032   rtl_slim_pp.buffer->stream = f;
2033   print_insn_with_notes (&rtl_slim_pp, x);
2034   pp_flush (&rtl_slim_pp);
2035 }
2036
2037 /* Same as above, but stop at LAST or when COUNT == 0.
2038    If COUNT < 0 it will stop only at LAST or NULL rtx.  */
2039
2040 void
2041 dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
2042                int count, int flags ATTRIBUTE_UNUSED)
2043 {
2044   const rtx_insn *insn, *tail;
2045   pretty_printer rtl_slim_pp;
2046   rtl_slim_pp.buffer->stream = f;
2047
2048   tail = last ? NEXT_INSN (last) : NULL;
2049   for (insn = first;
2050        (insn != NULL) && (insn != tail) && (count != 0);
2051        insn = NEXT_INSN (insn))
2052     {
2053       print_insn_with_notes (&rtl_slim_pp, insn);
2054       if (count > 0)
2055         count--;
2056     }
2057
2058   pp_flush (&rtl_slim_pp);
2059 }
2060
2061 /* Dumps basic block BB to pretty-printer PP in slim form and without and
2062    no indentation, for use as a label of a DOT graph record-node.  */
2063
2064 void
2065 rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
2066 {
2067   rtx_insn *insn;
2068   bool first = true;
2069
2070   /* TODO: inter-bb stuff.  */
2071   FOR_BB_INSNS (bb, insn)
2072     {
2073       if (! first)
2074         {
2075           pp_bar (pp);
2076           pp_write_text_to_stream (pp);
2077         }
2078       first = false;
2079       print_insn_with_notes (pp, insn);
2080       pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
2081     }
2082 }
2083
2084 /* Pretty-print pattern X of some insn in non-verbose mode.
2085    Return a string pointer to the pretty-printer buffer.
2086
2087    This function is only exported exists only to accommodate some older users
2088    of the slim RTL pretty printers.  Please do not use it for new code.  */
2089
2090 const char *
2091 str_pattern_slim (const_rtx x)
2092 {
2093   pretty_printer rtl_slim_pp;
2094   print_pattern (&rtl_slim_pp, x, 0);
2095   return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
2096 }
2097
2098 /* Emit a slim dump of X (an insn) to stderr.  */
2099 extern void debug_insn_slim (const rtx_insn *);
2100 DEBUG_FUNCTION void
2101 debug_insn_slim (const rtx_insn *x)
2102 {
2103   dump_insn_slim (stderr, x);
2104 }
2105
2106 /* Same as above, but using dump_rtl_slim.  */
2107 extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
2108                             int, int);
2109 DEBUG_FUNCTION void
2110 debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
2111                 int flags)
2112 {
2113   dump_rtl_slim (stderr, first, last, count, flags);
2114 }
2115
2116 extern void debug_bb_slim (basic_block);
2117 DEBUG_FUNCTION void
2118 debug_bb_slim (basic_block bb)
2119 {
2120   dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
2121 }
2122
2123 extern void debug_bb_n_slim (int);
2124 DEBUG_FUNCTION void
2125 debug_bb_n_slim (int n)
2126 {
2127   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
2128   debug_bb_slim (bb);
2129 }
2130
2131 #endif