1 /* Printing of RTL in "slim", mnemonic like form.
2 Copyright (C) 1992-2012
3 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5 and currently maintained by, Jim Wilson (wilson@cygnus.com)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* Historically this form of RTL dumping was introduced along with
24 the Haifa instruction scheduling pass, hence the name of this file.
25 But there is nothing in this file left that is scheduler-specific. */
29 #include "coretypes.h"
32 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
33 #include "basic-block.h"
34 #include "dumpfile.h" /* for the TDF_* flags */
35 #include "pretty-print.h"
37 /* The functions in this file try to print RTL in a form resembling assembler
38 mnemonics. Because this form is more concise than the "traditional" form
39 of RTL printing in Lisp-style, the form printed by this file is called
40 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
41 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
42 always printed in slim form.
44 The normal interface to the functionality provided in this pretty-printer
45 is through the dump_*_slim functions to print to a stream, or via the
46 print_*_slim functions to print into a user's pretty-printer.
48 It is also possible to obtain a string for a single pattern as a string
49 pointer, via str_pattern_slim, but this usage is discouraged. */
51 /* A pretty-printer for slim rtl printing. */
52 static bool rtl_slim_pp_initialized
= false;
53 static pretty_printer rtl_slim_pp
;
55 /* This recognizes rtx'en classified as expressions. These are always
56 represent some action on values or results of other expression, that
57 may be stored in objects representing values. */
60 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
68 for (i
= 0; i
< 4; i
++)
78 if (CONST_INT_P (XEXP (x
, 1))
79 && INTVAL (XEXP (x
, 1)) < 0)
82 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
239 fun
= (verbose
) ? "sign_extract" : "sxt";
245 fun
= (verbose
) ? "zero_extract" : "zxt";
251 fun
= (verbose
) ? "sign_extend" : "sxn";
255 fun
= (verbose
) ? "zero_extend" : "zxn";
259 fun
= (verbose
) ? "float_extend" : "fxn";
263 fun
= (verbose
) ? "trunc" : "trn";
267 fun
= (verbose
) ? "float_trunc" : "ftr";
271 fun
= (verbose
) ? "float" : "flt";
275 fun
= (verbose
) ? "uns_float" : "ufl";
283 fun
= (verbose
) ? "uns_fix" : "ufx";
304 op
[0] = XEXP (XEXP (x
, 1), 0);
306 op
[1] = XEXP (XEXP (x
, 1), 1);
310 op
[0] = XEXP (XEXP (x
, 1), 0);
312 op
[1] = XEXP (XEXP (x
, 1), 1);
334 op
[0] = TRAP_CONDITION (x
);
343 case UNSPEC_VOLATILE
:
345 pp_string (pp
, "unspec");
346 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
347 pp_string (pp
, "/v");
348 pp_character (pp
, '[');
349 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
352 pp_character (pp
, ',');
353 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
355 pp_string (pp
, "] ");
356 pp_decimal_int (pp
, XINT (x
, 1));
361 /* Most unhandled codes can be printed as pseudo-functions. */
362 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
364 fun
= GET_RTX_NAME (GET_CODE (x
));
367 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
368 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
369 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
370 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
372 fun
= GET_RTX_NAME (GET_CODE (x
));
376 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
378 fun
= GET_RTX_NAME (GET_CODE (x
));
384 /* Give up, just print the RTX name. */
385 st
[0] = GET_RTX_NAME (GET_CODE (x
));
390 /* Print this as a function? */
394 pp_character (pp
, '(');
397 for (i
= 0; i
< 4; i
++)
400 pp_string (pp
, st
[i
]);
405 pp_character (pp
, ',');
406 print_value (pp
, op
[i
], verbose
);
411 pp_character (pp
, ')');
414 /* Prints rtxes, I customarily classified as values. They're constants,
415 registers, labels, symbols and memory accesses. */
418 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
424 pp_string (pp
, "(nil)");
427 switch (GET_CODE (x
))
430 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
431 (unsigned HOST_WIDE_INT
) INTVAL (x
));
434 if (FLOAT_MODE_P (GET_MODE (x
)))
436 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
441 pp_printf (pp
, "<%wx,%wx>",
442 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
443 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
446 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
450 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
453 pp_printf (pp
, "`%s'", XSTR (x
, 0));
456 pp_printf (pp
, "L%d", INSN_UID (XEXP (x
, 0)));
460 case STRICT_LOW_PART
:
461 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
462 print_value (pp
, XEXP (x
, 0), verbose
);
463 pp_character (pp
, ')');
466 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
468 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
469 pp_character (pp
, '%');
470 pp_string (pp
, reg_names
[REGNO (x
)]);
473 pp_printf (pp
, "r%d", REGNO (x
));
475 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
478 print_value (pp
, SUBREG_REG (x
), verbose
);
479 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
484 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
487 pp_character (pp
, '[');
488 print_value (pp
, XEXP (x
, 0), verbose
);
489 pp_character (pp
, ']');
492 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
495 print_exp (pp
, x
, verbose
);
500 /* The next step in insn detalization, its pattern recognition. */
503 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
507 pp_string (pp
, "(nil)");
511 switch (GET_CODE (x
))
514 print_value (pp
, SET_DEST (x
), verbose
);
515 pp_character (pp
, '=');
516 print_value (pp
, SET_SRC (x
), verbose
);
521 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
524 print_exp (pp
, x
, verbose
);
528 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
529 print_value (pp
, XEXP (x
, 0), verbose
);
532 pp_string (pp
, "loc ");
533 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
536 pp_character (pp
, '(');
537 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
538 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
539 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
540 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
541 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
543 pp_character (pp
, '!');
544 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
547 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
548 pp_string (pp
, ") ");
549 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
555 pp_character (pp
, '{');
556 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
558 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
559 pp_character (pp
, ';');
561 pp_character (pp
, '}');
568 pp_string (pp
, "sequence{");
569 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
571 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
572 pp_character (pp
, ';');
574 pp_character (pp
, '}');
578 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
583 print_value (pp
, XEXP (x
, 0), verbose
);
586 pp_string (pp
, "trap_if ");
587 print_value (pp
, TRAP_CONDITION (x
), verbose
);
590 case UNSPEC_VOLATILE
:
591 /* Fallthru -- leave UNSPECs to print_exp. */
593 print_value (pp
, x
, verbose
);
595 } /* print_pattern */
597 /* This is the main function in slim rtl visualization mechanism.
599 X is an insn, to be printed into PP.
601 This function tries to print it properly in human-readable form,
602 resembling assembler mnemonics (instead of the older Lisp-style
605 If VERBOSE is TRUE, insns are printed with more complete (but
606 longer) pattern names and with extra information, and prefixed
607 with their INSN_UIDs. */
610 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
614 /* Blech, pretty-print can't print integers with a specified width. */
616 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
617 pp_string (pp
, uid_prefix
);
620 switch (GET_CODE (x
))
623 print_pattern (pp
, PATTERN (x
), verbose
);
628 const char *name
= "?";
630 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
632 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
635 name
= IDENTIFIER_POINTER (id
);
636 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
639 sprintf (idbuf
, "D#%i",
640 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
645 sprintf (idbuf
, "D.%i",
646 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
650 pp_printf (pp
, "debug %s => ", name
);
651 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
652 pp_string (pp
, "optimized away");
654 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
659 print_pattern (pp
, PATTERN (x
), verbose
);
662 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
663 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
665 print_pattern (pp
, PATTERN (x
), verbose
);
668 pp_printf (pp
, "L%d:", INSN_UID (x
));
671 pp_string (pp
, "barrier");
675 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
676 switch (NOTE_KIND (x
))
678 case NOTE_INSN_EH_REGION_BEG
:
679 case NOTE_INSN_EH_REGION_END
:
680 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
683 case NOTE_INSN_BLOCK_BEG
:
684 case NOTE_INSN_BLOCK_END
:
685 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
688 case NOTE_INSN_BASIC_BLOCK
:
689 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
692 case NOTE_INSN_DELETED_LABEL
:
693 case NOTE_INSN_DELETED_DEBUG_LABEL
:
695 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
698 pp_printf (pp
, " (\"%s\")", label
);
702 case NOTE_INSN_VAR_LOCATION
:
703 case NOTE_INSN_CALL_ARG_LOCATION
:
704 pp_character (pp
, '{');
705 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
706 pp_character (pp
, '}');
719 /* Pretty-print a slim dump of X (an insn) to PP, including any register
720 note attached to the instruction. */
723 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
725 pp_string (pp
, print_rtx_head
);
726 print_insn (pp
, x
, 1);
728 if (INSN_P (x
) && REG_NOTES (x
))
729 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
731 pp_printf (pp
, "%s %s ", print_rtx_head
,
732 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
733 print_pattern (pp
, XEXP (note
, 0), 1);
738 /* Return a pretty-print buffer set up to print to file F. */
740 static pretty_printer
*
741 init_rtl_slim_pretty_print (FILE *f
)
743 if (! rtl_slim_pp_initialized
)
745 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
746 rtl_slim_pp_initialized
= true;
749 /* Clean out any data that str_insn_slim may have left here. */
750 pp_clear_output_area (&rtl_slim_pp
);
752 rtl_slim_pp
.buffer
->stream
= f
;
756 /* Print X, an RTL value node, to file F in slim format. Include
757 additional information if VERBOSE is nonzero.
759 Value nodes are constants, registers, labels, symbols and
763 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
765 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
766 print_value (pp
, x
, verbose
);
770 /* Emit a slim dump of X (an insn) to the file F, including any register
771 note attached to the instruction. */
773 dump_insn_slim (FILE *f
, const_rtx x
)
775 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
776 print_insn_with_notes (pp
, x
);
780 /* Same as above, but stop at LAST or when COUNT == 0.
781 If COUNT < 0 it will stop only at LAST or NULL rtx. */
784 dump_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
785 int count
, int flags ATTRIBUTE_UNUSED
)
787 const_rtx insn
, tail
;
788 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
790 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
792 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
793 insn
= NEXT_INSN (insn
))
795 print_insn_with_notes (pp
, insn
);
803 /* Dumps basic block BB to pretty-printer PP in slim form and without and
804 no indentation, for use as a label of a DOT graph record-node. */
807 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
812 /* TODO: inter-bb stuff. */
813 FOR_BB_INSNS (bb
, insn
)
817 pp_character (pp
, '|');
818 pp_write_text_to_stream (pp
);
821 print_insn_with_notes (pp
, insn
);
822 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
826 /* Pretty-print pattern X of some insn in non-verbose mode.
827 Return a string pointer to the pretty-printer buffer.
829 This function is only exported exists only to accommodate some older users
830 of the slim RTL pretty printers. Please do not use it for new code. */
833 str_pattern_slim (const_rtx x
)
835 pretty_printer
*pp
= init_rtl_slim_pretty_print (NULL
);
836 print_pattern (pp
, x
, 0);
837 return pp_base_formatted_text (pp
);
840 /* Emit a slim dump of X (an insn) to stderr. */
841 extern void debug_insn_slim (const_rtx
);
843 debug_insn_slim (const_rtx x
)
845 dump_insn_slim (stderr
, x
);
848 /* Same as above, but using dump_rtl_slim. */
849 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
851 debug_rtl_slim (const_rtx first
, const_rtx last
, int count
, int flags
)
853 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
856 extern void debug_bb_slim (basic_block
);
858 debug_bb_slim (basic_block bb
)
860 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
863 extern void debug_bb_n_slim (int);
865 debug_bb_n_slim (int n
)
867 basic_block bb
= BASIC_BLOCK (n
);