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