xref: /dragonfly/contrib/gcc-8.0/gcc/print-rtl.c (revision 2b3f93ea)
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
2130