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