1/* Printing of RTL in "slim", mnemonic like form.
2   Copyright (C) 1992-2015 Free Software Foundation, Inc.
3   Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
4   and currently maintained by, Jim Wilson (wilson@cygnus.com)
5
6This file is part of GCC.
7
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 3, or (at your option) any later
11version.
12
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16for more details.
17
18You should have received a copy of the GNU General Public License
19along with GCC; see the file COPYING3.  If not see
20<http://www.gnu.org/licenses/>.  */
21
22/* Historically this form of RTL dumping was introduced along with
23   the Haifa instruction scheduling pass, hence the name of this file.
24   But there is nothing in this file left that is scheduler-specific.  */
25
26#include "config.h"
27#include "system.h"
28#include "coretypes.h"
29#include "tm.h"
30#include "rtl.h"
31#include "hash-set.h"
32#include "machmode.h"
33#include "vec.h"
34#include "double-int.h"
35#include "input.h"
36#include "alias.h"
37#include "symtab.h"
38#include "wide-int.h"
39#include "inchash.h"
40#include "tree.h"	/* FIXME: To dump INSN_VAR_LOCATION_DECL.  */
41#include "predict.h"
42#include "vec.h"
43#include "hashtab.h"
44#include "hash-set.h"
45#include "machmode.h"
46#include "hard-reg-set.h"
47#include "input.h"
48#include "function.h"
49#include "dominance.h"
50#include "cfg.h"
51#include "basic-block.h"
52#include "dumpfile.h"	/* for the TDF_* flags */
53#include "pretty-print.h"
54
55/* The functions in this file try to print RTL in a form resembling assembler
56   mnemonics.  Because this form is more concise than the "traditional" form
57   of RTL printing in Lisp-style, the form printed by this file is called
58   "slim".  RTL dumps in slim format can be obtained by appending the "-slim"
59   option to -fdump-rtl-<pass>.  Control flow graph output as a DOT file is
60   always printed in slim form.
61
62   The normal interface to the functionality provided in this pretty-printer
63   is through the dump_*_slim functions to print to a stream, or via the
64   print_*_slim functions to print into a user's pretty-printer.
65
66   It is also possible to obtain a string for a single pattern as a string
67   pointer, via str_pattern_slim, but this usage is discouraged.  */
68
69/* For insns we print patterns, and for some patterns we print insns...  */
70static void print_insn_with_notes (pretty_printer *, const_rtx);
71
72/* This recognizes rtx'en classified as expressions.  These are always
73   represent some action on values or results of other expression, that
74   may be stored in objects representing values.  */
75
76static void
77print_exp (pretty_printer *pp, const_rtx x, int verbose)
78{
79  const char *st[4];
80  const char *fun;
81  rtx op[4];
82  int i;
83
84  fun = (char *) 0;
85  for (i = 0; i < 4; i++)
86    {
87      st[i] = (char *) 0;
88      op[i] = NULL_RTX;
89    }
90
91  switch (GET_CODE (x))
92    {
93    case PLUS:
94      op[0] = XEXP (x, 0);
95      if (CONST_INT_P (XEXP (x, 1))
96	  && INTVAL (XEXP (x, 1)) < 0)
97	{
98	  st[1] = "-";
99	  op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
100	}
101      else
102	{
103	  st[1] = "+";
104	  op[1] = XEXP (x, 1);
105	}
106      break;
107    case LO_SUM:
108      op[0] = XEXP (x, 0);
109      st[1] = "+low(";
110      op[1] = XEXP (x, 1);
111      st[2] = ")";
112      break;
113    case MINUS:
114      op[0] = XEXP (x, 0);
115      st[1] = "-";
116      op[1] = XEXP (x, 1);
117      break;
118    case COMPARE:
119      fun = "cmp";
120      op[0] = XEXP (x, 0);
121      op[1] = XEXP (x, 1);
122      break;
123    case NEG:
124      st[0] = "-";
125      op[0] = XEXP (x, 0);
126      break;
127    case FMA:
128      st[0] = "{";
129      op[0] = XEXP (x, 0);
130      st[1] = "*";
131      op[1] = XEXP (x, 1);
132      st[2] = "+";
133      op[2] = XEXP (x, 2);
134      st[3] = "}";
135      break;
136    case MULT:
137      op[0] = XEXP (x, 0);
138      st[1] = "*";
139      op[1] = XEXP (x, 1);
140      break;
141    case DIV:
142      op[0] = XEXP (x, 0);
143      st[1] = "/";
144      op[1] = XEXP (x, 1);
145      break;
146    case UDIV:
147      fun = "udiv";
148      op[0] = XEXP (x, 0);
149      op[1] = XEXP (x, 1);
150      break;
151    case MOD:
152      op[0] = XEXP (x, 0);
153      st[1] = "%";
154      op[1] = XEXP (x, 1);
155      break;
156    case UMOD:
157      fun = "umod";
158      op[0] = XEXP (x, 0);
159      op[1] = XEXP (x, 1);
160      break;
161    case SMIN:
162      fun = "smin";
163      op[0] = XEXP (x, 0);
164      op[1] = XEXP (x, 1);
165      break;
166    case SMAX:
167      fun = "smax";
168      op[0] = XEXP (x, 0);
169      op[1] = XEXP (x, 1);
170      break;
171    case UMIN:
172      fun = "umin";
173      op[0] = XEXP (x, 0);
174      op[1] = XEXP (x, 1);
175      break;
176    case UMAX:
177      fun = "umax";
178      op[0] = XEXP (x, 0);
179      op[1] = XEXP (x, 1);
180      break;
181    case NOT:
182      st[0] = "!";
183      op[0] = XEXP (x, 0);
184      break;
185    case AND:
186      op[0] = XEXP (x, 0);
187      st[1] = "&";
188      op[1] = XEXP (x, 1);
189      break;
190    case IOR:
191      op[0] = XEXP (x, 0);
192      st[1] = "|";
193      op[1] = XEXP (x, 1);
194      break;
195    case XOR:
196      op[0] = XEXP (x, 0);
197      st[1] = "^";
198      op[1] = XEXP (x, 1);
199      break;
200    case ASHIFT:
201      op[0] = XEXP (x, 0);
202      st[1] = "<<";
203      op[1] = XEXP (x, 1);
204      break;
205    case LSHIFTRT:
206      op[0] = XEXP (x, 0);
207      st[1] = " 0>>";
208      op[1] = XEXP (x, 1);
209      break;
210    case ASHIFTRT:
211      op[0] = XEXP (x, 0);
212      st[1] = ">>";
213      op[1] = XEXP (x, 1);
214      break;
215    case ROTATE:
216      op[0] = XEXP (x, 0);
217      st[1] = "<-<";
218      op[1] = XEXP (x, 1);
219      break;
220    case ROTATERT:
221      op[0] = XEXP (x, 0);
222      st[1] = ">->";
223      op[1] = XEXP (x, 1);
224      break;
225    case NE:
226      op[0] = XEXP (x, 0);
227      st[1] = "!=";
228      op[1] = XEXP (x, 1);
229      break;
230    case EQ:
231      op[0] = XEXP (x, 0);
232      st[1] = "==";
233      op[1] = XEXP (x, 1);
234      break;
235    case GE:
236      op[0] = XEXP (x, 0);
237      st[1] = ">=";
238      op[1] = XEXP (x, 1);
239      break;
240    case GT:
241      op[0] = XEXP (x, 0);
242      st[1] = ">";
243      op[1] = XEXP (x, 1);
244      break;
245    case LE:
246      op[0] = XEXP (x, 0);
247      st[1] = "<=";
248      op[1] = XEXP (x, 1);
249      break;
250    case LT:
251      op[0] = XEXP (x, 0);
252      st[1] = "<";
253      op[1] = XEXP (x, 1);
254      break;
255    case SIGN_EXTRACT:
256      fun = (verbose) ? "sign_extract" : "sxt";
257      op[0] = XEXP (x, 0);
258      op[1] = XEXP (x, 1);
259      op[2] = XEXP (x, 2);
260      break;
261    case ZERO_EXTRACT:
262      fun = (verbose) ? "zero_extract" : "zxt";
263      op[0] = XEXP (x, 0);
264      op[1] = XEXP (x, 1);
265      op[2] = XEXP (x, 2);
266      break;
267    case SIGN_EXTEND:
268      fun = (verbose) ? "sign_extend" : "sxn";
269      op[0] = XEXP (x, 0);
270      break;
271    case ZERO_EXTEND:
272      fun = (verbose) ? "zero_extend" : "zxn";
273      op[0] = XEXP (x, 0);
274      break;
275    case FLOAT_EXTEND:
276      fun = (verbose) ? "float_extend" : "fxn";
277      op[0] = XEXP (x, 0);
278      break;
279    case TRUNCATE:
280      fun = (verbose) ? "trunc" : "trn";
281      op[0] = XEXP (x, 0);
282      break;
283    case FLOAT_TRUNCATE:
284      fun = (verbose) ? "float_trunc" : "ftr";
285      op[0] = XEXP (x, 0);
286      break;
287    case FLOAT:
288      fun = (verbose) ? "float" : "flt";
289      op[0] = XEXP (x, 0);
290      break;
291    case UNSIGNED_FLOAT:
292      fun = (verbose) ? "uns_float" : "ufl";
293      op[0] = XEXP (x, 0);
294      break;
295    case FIX:
296      fun = "fix";
297      op[0] = XEXP (x, 0);
298      break;
299    case UNSIGNED_FIX:
300      fun = (verbose) ? "uns_fix" : "ufx";
301      op[0] = XEXP (x, 0);
302      break;
303    case PRE_DEC:
304      st[0] = "--";
305      op[0] = XEXP (x, 0);
306      break;
307    case PRE_INC:
308      st[0] = "++";
309      op[0] = XEXP (x, 0);
310      break;
311    case POST_DEC:
312      op[0] = XEXP (x, 0);
313      st[1] = "--";
314      break;
315    case POST_INC:
316      op[0] = XEXP (x, 0);
317      st[1] = "++";
318      break;
319    case PRE_MODIFY:
320      st[0] = "pre ";
321      op[0] = XEXP (XEXP (x, 1), 0);
322      st[1] = "+=";
323      op[1] = XEXP (XEXP (x, 1), 1);
324      break;
325    case POST_MODIFY:
326      st[0] = "post ";
327      op[0] = XEXP (XEXP (x, 1), 0);
328      st[1] = "+=";
329      op[1] = XEXP (XEXP (x, 1), 1);
330      break;
331    case CALL:
332      st[0] = "call ";
333      op[0] = XEXP (x, 0);
334      if (verbose)
335	{
336	  st[1] = " argc:";
337	  op[1] = XEXP (x, 1);
338	}
339      break;
340    case IF_THEN_ELSE:
341      st[0] = "{(";
342      op[0] = XEXP (x, 0);
343      st[1] = ")?";
344      op[1] = XEXP (x, 1);
345      st[2] = ":";
346      op[2] = XEXP (x, 2);
347      st[3] = "}";
348      break;
349    case TRAP_IF:
350      fun = "trap_if";
351      op[0] = TRAP_CONDITION (x);
352      break;
353    case PREFETCH:
354      fun = "prefetch";
355      op[0] = XEXP (x, 0);
356      op[1] = XEXP (x, 1);
357      op[2] = XEXP (x, 2);
358      break;
359    case UNSPEC:
360    case UNSPEC_VOLATILE:
361      {
362	pp_string (pp, "unspec");
363	if (GET_CODE (x) == UNSPEC_VOLATILE)
364	  pp_string (pp, "/v");
365	pp_left_bracket (pp);
366	for (i = 0; i < XVECLEN (x, 0); i++)
367	  {
368	    if (i != 0)
369	      pp_comma (pp);
370	    print_pattern (pp, XVECEXP (x, 0, i), verbose);
371	  }
372	pp_string (pp, "] ");
373	pp_decimal_int (pp, XINT (x, 1));
374      }
375      break;
376    default:
377      {
378	/* Most unhandled codes can be printed as pseudo-functions.  */
379        if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
380	  {
381	    fun = GET_RTX_NAME (GET_CODE (x));
382	    op[0] = XEXP (x, 0);
383	  }
384        else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_COMPARE
385		 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_COMPARE
386		 || GET_RTX_CLASS (GET_CODE (x)) == RTX_BIN_ARITH
387		 || GET_RTX_CLASS (GET_CODE (x)) == RTX_COMM_ARITH)
388	  {
389	    fun = GET_RTX_NAME (GET_CODE (x));
390	    op[0] = XEXP (x, 0);
391	    op[1] = XEXP (x, 1);
392	  }
393        else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
394	  {
395	    fun = GET_RTX_NAME (GET_CODE (x));
396	    op[0] = XEXP (x, 0);
397	    op[1] = XEXP (x, 1);
398	    op[2] = XEXP (x, 2);
399	  }
400	else
401	  /* Give up, just print the RTX name.  */
402	  st[0] = GET_RTX_NAME (GET_CODE (x));
403      }
404      break;
405    }
406
407  /* Print this as a function?  */
408  if (fun)
409    {
410      pp_string (pp, fun);
411      pp_left_paren (pp);
412    }
413
414  for (i = 0; i < 4; i++)
415    {
416      if (st[i])
417        pp_string (pp, st[i]);
418
419      if (op[i])
420	{
421	  if (fun && i != 0)
422	    pp_comma (pp);
423	  print_value (pp, op[i], verbose);
424	}
425    }
426
427  if (fun)
428    pp_right_paren (pp);
429}		/* print_exp */
430
431/* Prints rtxes, I customarily classified as values.  They're constants,
432   registers, labels, symbols and memory accesses.  */
433
434void
435print_value (pretty_printer *pp, const_rtx x, int verbose)
436{
437  char tmp[1024];
438
439  if (!x)
440    {
441      pp_string (pp, "(nil)");
442      return;
443    }
444  switch (GET_CODE (x))
445    {
446    case CONST_INT:
447      pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
448		 (unsigned HOST_WIDE_INT) INTVAL (x));
449      break;
450
451    case CONST_WIDE_INT:
452      {
453	const char *sep = "<";
454	int i;
455	for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
456	  {
457	    pp_string (pp, sep);
458	    sep = ",";
459	    sprintf (tmp, HOST_WIDE_INT_PRINT_HEX,
460		     (unsigned HOST_WIDE_INT) CONST_WIDE_INT_ELT (x, i));
461	    pp_string (pp, tmp);
462	  }
463        pp_greater (pp);
464      }
465      break;
466
467    case CONST_DOUBLE:
468      if (FLOAT_MODE_P (GET_MODE (x)))
469	{
470	  real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
471			   sizeof (tmp), 0, 1);
472	  pp_string (pp, tmp);
473	}
474      else
475	pp_printf (pp, "<%wx,%wx>",
476		   (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
477		   (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
478      break;
479    case CONST_FIXED:
480      fixed_to_decimal (tmp, CONST_FIXED_VALUE (x), sizeof (tmp));
481      pp_string (pp, tmp);
482      break;
483    case CONST_STRING:
484      pp_printf (pp, "\"%s\"", XSTR (x, 0));
485      break;
486    case SYMBOL_REF:
487      pp_printf (pp, "`%s'", XSTR (x, 0));
488      break;
489    case LABEL_REF:
490      pp_printf (pp, "L%d", INSN_UID (LABEL_REF_LABEL (x)));
491      break;
492    case CONST:
493    case HIGH:
494    case STRICT_LOW_PART:
495      pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
496      print_value (pp, XEXP (x, 0), verbose);
497      pp_right_paren (pp);
498      break;
499    case REG:
500      if (REGNO (x) < FIRST_PSEUDO_REGISTER)
501	{
502	  if (ISDIGIT (reg_names[REGNO (x)][0]))
503	    pp_modulo (pp);
504	  pp_string (pp, reg_names[REGNO (x)]);
505	}
506      else
507	pp_printf (pp, "r%d", REGNO (x));
508      if (verbose)
509	pp_printf (pp, ":%s", GET_MODE_NAME (GET_MODE (x)));
510      break;
511    case SUBREG:
512      print_value (pp, SUBREG_REG (x), verbose);
513      pp_printf (pp, "#%d", SUBREG_BYTE (x));
514      break;
515    case SCRATCH:
516    case CC0:
517    case PC:
518      pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
519      break;
520    case MEM:
521      pp_left_bracket (pp);
522      print_value (pp, XEXP (x, 0), verbose);
523      pp_right_bracket (pp);
524      break;
525    case DEBUG_EXPR:
526      pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
527      break;
528    default:
529      print_exp (pp, x, verbose);
530      break;
531    }
532}				/* print_value */
533
534/* The next step in insn detalization, its pattern recognition.  */
535
536void
537print_pattern (pretty_printer *pp, const_rtx x, int verbose)
538{
539  if (! x)
540    {
541      pp_string (pp, "(nil)");
542      return;
543    }
544
545  switch (GET_CODE (x))
546    {
547    case SET:
548      print_value (pp, SET_DEST (x), verbose);
549      pp_equal (pp);
550      print_value (pp, SET_SRC (x), verbose);
551      break;
552    case RETURN:
553    case SIMPLE_RETURN:
554    case EH_RETURN:
555      pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
556      break;
557    case CALL:
558      print_exp (pp, x, verbose);
559      break;
560    case CLOBBER:
561    case USE:
562      pp_printf (pp, "%s ", GET_RTX_NAME (GET_CODE (x)));
563      print_value (pp, XEXP (x, 0), verbose);
564      break;
565    case VAR_LOCATION:
566      pp_string (pp, "loc ");
567      print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
568      break;
569    case COND_EXEC:
570      pp_left_paren (pp);
571      if (GET_CODE (COND_EXEC_TEST (x)) == NE
572	  && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
573	print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
574      else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
575	       && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
576	{
577	  pp_exclamation (pp);
578	  print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
579	}
580      else
581	print_value (pp, COND_EXEC_TEST (x), verbose);
582      pp_string (pp, ") ");
583      print_pattern (pp, COND_EXEC_CODE (x), verbose);
584      break;
585    case PARALLEL:
586      {
587	int i;
588
589	pp_left_brace (pp);
590	for (i = 0; i < XVECLEN (x, 0); i++)
591	  {
592	    print_pattern (pp, XVECEXP (x, 0, i), verbose);
593	    pp_semicolon (pp);
594	  }
595	pp_right_brace (pp);
596      }
597      break;
598    case SEQUENCE:
599      {
600	const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
601	pp_string (pp, "sequence{");
602	if (INSN_P (seq->element (0)))
603	  {
604	    /* Print the sequence insns indented.  */
605	    const char * save_print_rtx_head = print_rtx_head;
606	    char indented_print_rtx_head[32];
607
608	    pp_newline (pp);
609	    gcc_assert (strlen (print_rtx_head) < sizeof (indented_print_rtx_head) - 4);
610	    snprintf (indented_print_rtx_head,
611		      sizeof (indented_print_rtx_head),
612		      "%s     ", print_rtx_head);
613	    print_rtx_head = indented_print_rtx_head;
614	    for (int i = 0; i < seq->len (); i++)
615	      print_insn_with_notes (pp, seq->insn (i));
616	    pp_printf (pp, "%s      ", save_print_rtx_head);
617	    print_rtx_head = save_print_rtx_head;
618	  }
619	else
620	  {
621	    for (int i = 0; i < seq->len (); i++)
622	      {
623		print_pattern (pp, seq->element (i), verbose);
624		pp_semicolon (pp);
625	      }
626	  }
627	pp_right_brace (pp);
628      }
629      break;
630    case ASM_INPUT:
631      pp_printf (pp, "asm {%s}", XSTR (x, 0));
632      break;
633    case ADDR_VEC:
634      for (int i = 0; i < XVECLEN (x, 0); i++)
635	{
636	  print_value (pp, XVECEXP (x, 0, i), verbose);
637	  pp_semicolon (pp);
638	}
639      break;
640    case ADDR_DIFF_VEC:
641      for (int i = 0; i < XVECLEN (x, 1); i++)
642	{
643	  print_value (pp, XVECEXP (x, 1, i), verbose);
644	  pp_semicolon (pp);
645	}
646      break;
647    case TRAP_IF:
648      pp_string (pp, "trap_if ");
649      print_value (pp, TRAP_CONDITION (x), verbose);
650      break;
651    case UNSPEC:
652    case UNSPEC_VOLATILE:
653      /* Fallthru -- leave UNSPECs to print_exp.  */
654    default:
655      print_value (pp, x, verbose);
656    }
657}				/* print_pattern */
658
659/* This is the main function in slim rtl visualization mechanism.
660
661   X is an insn, to be printed into PP.
662
663   This function tries to print it properly in human-readable form,
664   resembling assembler mnemonics (instead of the older Lisp-style
665   form).
666
667   If VERBOSE is TRUE, insns are printed with more complete (but
668   longer) pattern names and with extra information, and prefixed
669   with their INSN_UIDs.  */
670
671void
672print_insn (pretty_printer *pp, const_rtx x, int verbose)
673{
674  if (verbose)
675    {
676      /* Blech, pretty-print can't print integers with a specified width.  */
677      char uid_prefix[32];
678      snprintf (uid_prefix, sizeof uid_prefix, " %4d: ", INSN_UID (x));
679      pp_string (pp, uid_prefix);
680    }
681
682  switch (GET_CODE (x))
683    {
684    case INSN:
685      print_pattern (pp, PATTERN (x), verbose);
686      break;
687
688    case DEBUG_INSN:
689      {
690	const char *name = "?";
691
692	if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
693	  {
694	    tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (x));
695	    char idbuf[32];
696	    if (id)
697	      name = IDENTIFIER_POINTER (id);
698	    else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x))
699		     == DEBUG_EXPR_DECL)
700	      {
701		sprintf (idbuf, "D#%i",
702			 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
703		name = idbuf;
704	      }
705	    else
706	      {
707		sprintf (idbuf, "D.%i",
708			 DECL_UID (INSN_VAR_LOCATION_DECL (x)));
709		name = idbuf;
710	      }
711	  }
712	pp_printf (pp, "debug %s => ", name);
713	if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x)))
714	  pp_string (pp, "optimized away");
715	else
716	  print_pattern (pp, INSN_VAR_LOCATION_LOC (x), verbose);
717      }
718      break;
719
720    case JUMP_INSN:
721      print_pattern (pp, PATTERN (x), verbose);
722      break;
723    case CALL_INSN:
724      if (GET_CODE (PATTERN (x)) == PARALLEL)
725        print_pattern (pp, XVECEXP (PATTERN (x), 0, 0), verbose);
726      else
727	print_pattern (pp, PATTERN (x), verbose);
728      break;
729    case CODE_LABEL:
730      pp_printf (pp, "L%d:", INSN_UID (x));
731      break;
732    case JUMP_TABLE_DATA:
733      pp_string (pp, "jump_table_data{\n");
734      print_pattern (pp, PATTERN (x), verbose);
735      pp_right_brace (pp);
736      break;
737    case BARRIER:
738      pp_string (pp, "barrier");
739      break;
740    case NOTE:
741      {
742	pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
743	switch (NOTE_KIND (x))
744	  {
745	  case NOTE_INSN_EH_REGION_BEG:
746	  case NOTE_INSN_EH_REGION_END:
747	    pp_printf (pp, " %d", NOTE_EH_HANDLER (x));
748	    break;
749
750	  case NOTE_INSN_BLOCK_BEG:
751	  case NOTE_INSN_BLOCK_END:
752	    pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
753	    break;
754
755	  case NOTE_INSN_BASIC_BLOCK:
756	    pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
757	    break;
758
759	  case NOTE_INSN_DELETED_LABEL:
760	  case NOTE_INSN_DELETED_DEBUG_LABEL:
761	    {
762	      const char *label = NOTE_DELETED_LABEL_NAME (x);
763	      if (label == NULL)
764		label = "";
765	      pp_printf (pp, " (\"%s\")", label);
766	    }
767	    break;
768
769	  case NOTE_INSN_VAR_LOCATION:
770	  case NOTE_INSN_CALL_ARG_LOCATION:
771	    pp_left_brace (pp);
772	    print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
773	    pp_right_brace (pp);
774	    break;
775
776	  default:
777	    break;
778	  }
779	break;
780      }
781    default:
782      gcc_unreachable ();
783    }
784}				/* print_insn */
785
786/* Pretty-print a slim dump of X (an insn) to PP, including any register
787   note attached to the instruction.  */
788
789static void
790print_insn_with_notes (pretty_printer *pp, const_rtx x)
791{
792  pp_string (pp, print_rtx_head);
793  print_insn (pp, x, 1);
794  pp_newline (pp);
795  if (INSN_P (x) && REG_NOTES (x))
796    for (rtx note = REG_NOTES (x); note; note = XEXP (note, 1))
797      {
798	pp_printf (pp, "%s      %s ", print_rtx_head,
799		   GET_REG_NOTE_NAME (REG_NOTE_KIND (note)));
800	if (GET_CODE (note) == INT_LIST)
801	  pp_printf (pp, "%d", XINT (note, 0));
802	else
803	  print_pattern (pp, XEXP (note, 0), 1);
804	pp_newline (pp);
805      }
806}
807
808/* Print X, an RTL value node, to file F in slim format.  Include
809   additional information if VERBOSE is nonzero.
810
811   Value nodes are constants, registers, labels, symbols and
812   memory.  */
813
814void
815dump_value_slim (FILE *f, const_rtx x, int verbose)
816{
817  pretty_printer rtl_slim_pp;
818  rtl_slim_pp.buffer->stream = f;
819  print_value (&rtl_slim_pp, x, verbose);
820  pp_flush (&rtl_slim_pp);
821}
822
823/* Emit a slim dump of X (an insn) to the file F, including any register
824   note attached to the instruction.  */
825void
826dump_insn_slim (FILE *f, const_rtx x)
827{
828  pretty_printer rtl_slim_pp;
829  rtl_slim_pp.buffer->stream = f;
830  print_insn_with_notes (&rtl_slim_pp, x);
831  pp_flush (&rtl_slim_pp);
832}
833
834/* Same as above, but stop at LAST or when COUNT == 0.
835   If COUNT < 0 it will stop only at LAST or NULL rtx.  */
836
837void
838dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
839	       int count, int flags ATTRIBUTE_UNUSED)
840{
841  const rtx_insn *insn, *tail;
842  pretty_printer rtl_slim_pp;
843  rtl_slim_pp.buffer->stream = f;
844
845  tail = last ? NEXT_INSN (last) : NULL;
846  for (insn = first;
847       (insn != NULL) && (insn != tail) && (count != 0);
848       insn = NEXT_INSN (insn))
849    {
850      print_insn_with_notes (&rtl_slim_pp, insn);
851      if (count > 0)
852        count--;
853    }
854
855  pp_flush (&rtl_slim_pp);
856}
857
858/* Dumps basic block BB to pretty-printer PP in slim form and without and
859   no indentation, for use as a label of a DOT graph record-node.  */
860
861void
862rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
863{
864  rtx_insn *insn;
865  bool first = true;
866
867  /* TODO: inter-bb stuff.  */
868  FOR_BB_INSNS (bb, insn)
869    {
870      if (! first)
871	{
872	  pp_bar (pp);
873	  pp_write_text_to_stream (pp);
874	}
875      first = false;
876      print_insn_with_notes (pp, insn);
877      pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
878    }
879}
880
881/* Pretty-print pattern X of some insn in non-verbose mode.
882   Return a string pointer to the pretty-printer buffer.
883
884   This function is only exported exists only to accommodate some older users
885   of the slim RTL pretty printers.  Please do not use it for new code.  */
886
887const char *
888str_pattern_slim (const_rtx x)
889{
890  pretty_printer rtl_slim_pp;
891  print_pattern (&rtl_slim_pp, x, 0);
892  return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
893}
894
895/* Emit a slim dump of X (an insn) to stderr.  */
896extern void debug_insn_slim (const_rtx);
897DEBUG_FUNCTION void
898debug_insn_slim (const_rtx x)
899{
900  dump_insn_slim (stderr, x);
901}
902
903/* Same as above, but using dump_rtl_slim.  */
904extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
905			    int, int);
906DEBUG_FUNCTION void
907debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
908		int flags)
909{
910  dump_rtl_slim (stderr, first, last, count, flags);
911}
912
913extern void debug_bb_slim (basic_block);
914DEBUG_FUNCTION void
915debug_bb_slim (basic_block bb)
916{
917  dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
918}
919
920extern void debug_bb_n_slim (int);
921DEBUG_FUNCTION void
922debug_bb_n_slim (int n)
923{
924  basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
925  debug_bb_slim (bb);
926}
927
928