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