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