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