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