PR target/65871
[official-gcc.git] / gcc / sched-vis.c
blob32f7a7c329c6df87c34b62b4f5f909e4e083d7bc
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)
6 This file is part of GCC.
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.
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.
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/>. */
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. */
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"
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.
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.
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. */
69 /* For insns we print patterns, and for some patterns we print insns... */
70 static void print_insn_with_notes (pretty_printer *, const_rtx);
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. */
76 static void
77 print_exp (pretty_printer *pp, const_rtx x, int verbose)
79 const char *st[4];
80 const char *fun;
81 rtx op[4];
82 int i;
84 fun = (char *) 0;
85 for (i = 0; i < 4; i++)
87 st[i] = (char *) 0;
88 op[i] = NULL_RTX;
91 switch (GET_CODE (x))
93 case PLUS:
94 op[0] = XEXP (x, 0);
95 if (CONST_INT_P (XEXP (x, 1))
96 && INTVAL (XEXP (x, 1)) < 0)
98 st[1] = "-";
99 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
101 else
103 st[1] = "+";
104 op[1] = XEXP (x, 1);
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)
336 st[1] = " argc:";
337 op[1] = XEXP (x, 1);
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:
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++)
368 if (i != 0)
369 pp_comma (pp);
370 print_pattern (pp, XVECEXP (x, 0, i), verbose);
372 pp_string (pp, "] ");
373 pp_decimal_int (pp, XINT (x, 1));
375 break;
376 default:
378 /* Most unhandled codes can be printed as pseudo-functions. */
379 if (GET_RTX_CLASS (GET_CODE (x)) == RTX_UNARY)
381 fun = GET_RTX_NAME (GET_CODE (x));
382 op[0] = XEXP (x, 0);
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)
389 fun = GET_RTX_NAME (GET_CODE (x));
390 op[0] = XEXP (x, 0);
391 op[1] = XEXP (x, 1);
393 else if (GET_RTX_CLASS (GET_CODE (x)) == RTX_TERNARY)
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);
400 else
401 /* Give up, just print the RTX name. */
402 st[0] = GET_RTX_NAME (GET_CODE (x));
404 break;
407 /* Print this as a function? */
408 if (fun)
410 pp_string (pp, fun);
411 pp_left_paren (pp);
414 for (i = 0; i < 4; i++)
416 if (st[i])
417 pp_string (pp, st[i]);
419 if (op[i])
421 if (fun && i != 0)
422 pp_comma (pp);
423 print_value (pp, op[i], verbose);
427 if (fun)
428 pp_right_paren (pp);
429 } /* print_exp */
431 /* Prints rtxes, I customarily classified as values. They're constants,
432 registers, labels, symbols and memory accesses. */
434 void
435 print_value (pretty_printer *pp, const_rtx x, int verbose)
437 char tmp[1024];
439 if (!x)
441 pp_string (pp, "(nil)");
442 return;
444 switch (GET_CODE (x))
446 case CONST_INT:
447 pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
448 (unsigned HOST_WIDE_INT) INTVAL (x));
449 break;
451 case CONST_WIDE_INT:
453 const char *sep = "<";
454 int i;
455 for (i = CONST_WIDE_INT_NUNITS (x) - 1; i >= 0; i--)
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);
463 pp_greater (pp);
465 break;
467 case CONST_DOUBLE:
468 if (FLOAT_MODE_P (GET_MODE (x)))
470 real_to_decimal (tmp, CONST_DOUBLE_REAL_VALUE (x),
471 sizeof (tmp), 0, 1);
472 pp_string (pp, tmp);
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)
502 if (ISDIGIT (reg_names[REGNO (x)][0]))
503 pp_modulo (pp);
504 pp_string (pp, reg_names[REGNO (x)]);
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;
532 } /* print_value */
534 /* The next step in insn detalization, its pattern recognition. */
536 void
537 print_pattern (pretty_printer *pp, const_rtx x, int verbose)
539 if (! x)
541 pp_string (pp, "(nil)");
542 return;
545 switch (GET_CODE (x))
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)
577 pp_exclamation (pp);
578 print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
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:
587 int i;
589 pp_left_brace (pp);
590 for (i = 0; i < XVECLEN (x, 0); i++)
592 print_pattern (pp, XVECEXP (x, 0, i), verbose);
593 pp_semicolon (pp);
595 pp_right_brace (pp);
597 break;
598 case SEQUENCE:
600 const rtx_sequence *seq = as_a <const rtx_sequence *> (x);
601 pp_string (pp, "sequence{");
602 if (INSN_P (seq->element (0)))
604 /* Print the sequence insns indented. */
605 const char * save_print_rtx_head = print_rtx_head;
606 char indented_print_rtx_head[32];
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;
619 else
621 for (int i = 0; i < seq->len (); i++)
623 print_pattern (pp, seq->element (i), verbose);
624 pp_semicolon (pp);
627 pp_right_brace (pp);
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++)
636 print_value (pp, XVECEXP (x, 0, i), verbose);
637 pp_semicolon (pp);
639 break;
640 case ADDR_DIFF_VEC:
641 for (int i = 0; i < XVECLEN (x, 1); i++)
643 print_value (pp, XVECEXP (x, 1, i), verbose);
644 pp_semicolon (pp);
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);
657 } /* print_pattern */
659 /* This is the main function in slim rtl visualization mechanism.
661 X is an insn, to be printed into PP.
663 This function tries to print it properly in human-readable form,
664 resembling assembler mnemonics (instead of the older Lisp-style
665 form).
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. */
671 void
672 print_insn (pretty_printer *pp, const_rtx x, int verbose)
674 if (verbose)
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);
682 switch (GET_CODE (x))
684 case INSN:
685 print_pattern (pp, PATTERN (x), verbose);
686 break;
688 case DEBUG_INSN:
690 const char *name = "?";
692 if (DECL_P (INSN_VAR_LOCATION_DECL (x)))
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)
701 sprintf (idbuf, "D#%i",
702 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x)));
703 name = idbuf;
705 else
707 sprintf (idbuf, "D.%i",
708 DECL_UID (INSN_VAR_LOCATION_DECL (x)));
709 name = idbuf;
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);
718 break;
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:
742 pp_string (pp, GET_NOTE_INSN_NAME (NOTE_KIND (x)));
743 switch (NOTE_KIND (x))
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;
750 case NOTE_INSN_BLOCK_BEG:
751 case NOTE_INSN_BLOCK_END:
752 pp_printf (pp, " %d", BLOCK_NUMBER (NOTE_BLOCK (x)));
753 break;
755 case NOTE_INSN_BASIC_BLOCK:
756 pp_printf (pp, " %d", NOTE_BASIC_BLOCK (x)->index);
757 break;
759 case NOTE_INSN_DELETED_LABEL:
760 case NOTE_INSN_DELETED_DEBUG_LABEL:
762 const char *label = NOTE_DELETED_LABEL_NAME (x);
763 if (label == NULL)
764 label = "";
765 pp_printf (pp, " (\"%s\")", label);
767 break;
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;
776 default:
777 break;
779 break;
781 default:
782 gcc_unreachable ();
784 } /* print_insn */
786 /* Pretty-print a slim dump of X (an insn) to PP, including any register
787 note attached to the instruction. */
789 static void
790 print_insn_with_notes (pretty_printer *pp, const_rtx x)
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))
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);
808 /* Print X, an RTL value node, to file F in slim format. Include
809 additional information if VERBOSE is nonzero.
811 Value nodes are constants, registers, labels, symbols and
812 memory. */
814 void
815 dump_value_slim (FILE *f, const_rtx x, int verbose)
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);
823 /* Emit a slim dump of X (an insn) to the file F, including any register
824 note attached to the instruction. */
825 void
826 dump_insn_slim (FILE *f, const_rtx x)
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);
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. */
837 void
838 dump_rtl_slim (FILE *f, const rtx_insn *first, const rtx_insn *last,
839 int count, int flags ATTRIBUTE_UNUSED)
841 const rtx_insn *insn, *tail;
842 pretty_printer rtl_slim_pp;
843 rtl_slim_pp.buffer->stream = f;
845 tail = last ? NEXT_INSN (last) : NULL;
846 for (insn = first;
847 (insn != NULL) && (insn != tail) && (count != 0);
848 insn = NEXT_INSN (insn))
850 print_insn_with_notes (&rtl_slim_pp, insn);
851 if (count > 0)
852 count--;
855 pp_flush (&rtl_slim_pp);
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. */
861 void
862 rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
864 rtx_insn *insn;
865 bool first = true;
867 /* TODO: inter-bb stuff. */
868 FOR_BB_INSNS (bb, insn)
870 if (! first)
872 pp_bar (pp);
873 pp_write_text_to_stream (pp);
875 first = false;
876 print_insn_with_notes (pp, insn);
877 pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
881 /* Pretty-print pattern X of some insn in non-verbose mode.
882 Return a string pointer to the pretty-printer buffer.
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. */
887 const char *
888 str_pattern_slim (const_rtx x)
890 pretty_printer rtl_slim_pp;
891 print_pattern (&rtl_slim_pp, x, 0);
892 return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
895 /* Emit a slim dump of X (an insn) to stderr. */
896 extern void debug_insn_slim (const_rtx);
897 DEBUG_FUNCTION void
898 debug_insn_slim (const_rtx x)
900 dump_insn_slim (stderr, x);
903 /* Same as above, but using dump_rtl_slim. */
904 extern void debug_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
905 int, int);
906 DEBUG_FUNCTION void
907 debug_rtl_slim (const rtx_insn *first, const rtx_insn *last, int count,
908 int flags)
910 dump_rtl_slim (stderr, first, last, count, flags);
913 extern void debug_bb_slim (basic_block);
914 DEBUG_FUNCTION void
915 debug_bb_slim (basic_block bb)
917 dump_bb (stderr, bb, 0, TDF_SLIM | TDF_BLOCKS);
920 extern void debug_bb_n_slim (int);
921 DEBUG_FUNCTION void
922 debug_bb_n_slim (int n)
924 basic_block bb = BASIC_BLOCK_FOR_FN (cfun, n);
925 debug_bb_slim (bb);