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