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