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
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
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. */
28 #include "coretypes.h"
37 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
42 #include "hard-reg-set.h"
45 #include "dominance.h"
47 #include "basic-block.h"
48 #include "dumpfile.h" /* for the TDF_* flags */
49 #include "pretty-print.h"
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.
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.
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. */
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
*);
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. */
73 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
81 for (i
= 0; i
< 4; i
++)
91 if (CONST_INT_P (XEXP (x
, 1))
92 && INTVAL (XEXP (x
, 1)) < 0)
95 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
252 fun
= (verbose
) ? "sign_extract" : "sxt";
258 fun
= (verbose
) ? "zero_extract" : "zxt";
264 fun
= (verbose
) ? "sign_extend" : "sxn";
268 fun
= (verbose
) ? "zero_extend" : "zxn";
272 fun
= (verbose
) ? "float_extend" : "fxn";
276 fun
= (verbose
) ? "trunc" : "trn";
280 fun
= (verbose
) ? "float_trunc" : "ftr";
284 fun
= (verbose
) ? "float" : "flt";
288 fun
= (verbose
) ? "uns_float" : "ufl";
296 fun
= (verbose
) ? "uns_fix" : "ufx";
317 op
[0] = XEXP (XEXP (x
, 1), 0);
319 op
[1] = XEXP (XEXP (x
, 1), 1);
323 op
[0] = XEXP (XEXP (x
, 1), 0);
325 op
[1] = XEXP (XEXP (x
, 1), 1);
347 op
[0] = TRAP_CONDITION (x
);
356 case UNSPEC_VOLATILE
:
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
++)
366 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
368 pp_string (pp
, "] ");
369 pp_decimal_int (pp
, XINT (x
, 1));
374 /* Most unhandled codes can be printed as pseudo-functions. */
375 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
377 fun
= GET_RTX_NAME (GET_CODE (x
));
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
)
385 fun
= GET_RTX_NAME (GET_CODE (x
));
389 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
391 fun
= GET_RTX_NAME (GET_CODE (x
));
397 /* Give up, just print the RTX name. */
398 st
[0] = GET_RTX_NAME (GET_CODE (x
));
403 /* Print this as a function? */
410 for (i
= 0; i
< 4; i
++)
413 pp_string (pp
, st
[i
]);
419 print_value (pp
, op
[i
], verbose
);
427 /* Prints rtxes, I customarily classified as values. They're constants,
428 registers, labels, symbols and memory accesses. */
431 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
437 pp_string (pp
, "(nil)");
440 switch (GET_CODE (x
))
443 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
444 (unsigned HOST_WIDE_INT
) INTVAL (x
));
449 const char *sep
= "<";
451 for (i
= CONST_WIDE_INT_NUNITS (x
) - 1; i
>= 0; i
--)
455 sprintf (tmp
, HOST_WIDE_INT_PRINT_HEX
,
456 (unsigned HOST_WIDE_INT
) CONST_WIDE_INT_ELT (x
, i
));
464 if (FLOAT_MODE_P (GET_MODE (x
)))
466 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
471 pp_printf (pp
, "<%wx,%wx>",
472 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
473 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
476 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
480 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
483 pp_printf (pp
, "`%s'", XSTR (x
, 0));
486 pp_printf (pp
, "L%d", INSN_UID (LABEL_REF_LABEL (x
)));
490 case STRICT_LOW_PART
:
491 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
492 print_value (pp
, XEXP (x
, 0), verbose
);
496 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
498 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
500 pp_string (pp
, reg_names
[REGNO (x
)]);
503 pp_printf (pp
, "r%d", REGNO (x
));
505 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
508 print_value (pp
, SUBREG_REG (x
), verbose
);
509 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
514 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
517 pp_left_bracket (pp
);
518 print_value (pp
, XEXP (x
, 0), verbose
);
519 pp_right_bracket (pp
);
522 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
525 print_exp (pp
, x
, verbose
);
530 /* The next step in insn detalization, its pattern recognition. */
533 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
537 pp_string (pp
, "(nil)");
541 switch (GET_CODE (x
))
544 print_value (pp
, SET_DEST (x
), verbose
);
546 print_value (pp
, SET_SRC (x
), verbose
);
551 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
554 print_exp (pp
, x
, verbose
);
558 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
559 print_value (pp
, XEXP (x
, 0), verbose
);
562 pp_string (pp
, "loc ");
563 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
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
)
574 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
577 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
578 pp_string (pp
, ") ");
579 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
586 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
588 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
596 const rtx_sequence
*seq
= as_a
<const rtx_sequence
*> (x
);
597 pp_string (pp
, "sequence{");
598 if (INSN_P (seq
->element (0)))
600 /* Print the sequence insns indented. */
601 const char * save_print_rtx_head
= print_rtx_head
;
602 char indented_print_rtx_head
[32];
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
;
617 for (int i
= 0; i
< seq
->len (); i
++)
619 print_pattern (pp
, seq
->element (i
), verbose
);
627 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
630 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
632 print_value (pp
, XVECEXP (x
, 0, i
), verbose
);
637 for (int i
= 0; i
< XVECLEN (x
, 1); i
++)
639 print_value (pp
, XVECEXP (x
, 1, i
), verbose
);
644 pp_string (pp
, "trap_if ");
645 print_value (pp
, TRAP_CONDITION (x
), verbose
);
648 case UNSPEC_VOLATILE
:
649 /* Fallthru -- leave UNSPECs to print_exp. */
651 print_value (pp
, x
, verbose
);
653 } /* print_pattern */
655 /* This is the main function in slim rtl visualization mechanism.
657 X is an insn, to be printed into PP.
659 This function tries to print it properly in human-readable form,
660 resembling assembler mnemonics (instead of the older Lisp-style
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. */
668 print_insn (pretty_printer
*pp
, const rtx_insn
*x
, int verbose
)
672 /* Blech, pretty-print can't print integers with a specified width. */
674 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
675 pp_string (pp
, uid_prefix
);
678 switch (GET_CODE (x
))
681 print_pattern (pp
, PATTERN (x
), verbose
);
686 const char *name
= "?";
688 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
690 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
693 name
= IDENTIFIER_POINTER (id
);
694 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
697 sprintf (idbuf
, "D#%i",
698 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
703 sprintf (idbuf
, "D.%i",
704 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
708 pp_printf (pp
, "debug %s => ", name
);
709 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
710 pp_string (pp
, "optimized away");
712 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
717 print_pattern (pp
, PATTERN (x
), verbose
);
720 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
721 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
723 print_pattern (pp
, PATTERN (x
), verbose
);
726 pp_printf (pp
, "L%d:", INSN_UID (x
));
728 case JUMP_TABLE_DATA
:
729 pp_string (pp
, "jump_table_data{\n");
730 print_pattern (pp
, PATTERN (x
), verbose
);
734 pp_string (pp
, "barrier");
738 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
739 switch (NOTE_KIND (x
))
741 case NOTE_INSN_EH_REGION_BEG
:
742 case NOTE_INSN_EH_REGION_END
:
743 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
746 case NOTE_INSN_BLOCK_BEG
:
747 case NOTE_INSN_BLOCK_END
:
748 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
751 case NOTE_INSN_BASIC_BLOCK
:
752 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
755 case NOTE_INSN_DELETED_LABEL
:
756 case NOTE_INSN_DELETED_DEBUG_LABEL
:
758 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
761 pp_printf (pp
, " (\"%s\")", label
);
765 case NOTE_INSN_VAR_LOCATION
:
766 case NOTE_INSN_CALL_ARG_LOCATION
:
768 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
782 /* Pretty-print a slim dump of X (an insn) to PP, including any register
783 note attached to the instruction. */
786 print_insn_with_notes (pretty_printer
*pp
, const rtx_insn
*x
)
788 pp_string (pp
, print_rtx_head
);
789 print_insn (pp
, x
, 1);
791 if (INSN_P (x
) && REG_NOTES (x
))
792 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
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));
799 print_pattern (pp
, XEXP (note
, 0), 1);
804 /* Print X, an RTL value node, to file F in slim format. Include
805 additional information if VERBOSE is nonzero.
807 Value nodes are constants, registers, labels, symbols and
811 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
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
);
819 /* Emit a slim dump of X (an insn) to the file F, including any register
820 note attached to the instruction. */
822 dump_insn_slim (FILE *f
, const rtx_insn
*x
)
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
);
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. */
834 dump_rtl_slim (FILE *f
, const rtx_insn
*first
, const rtx_insn
*last
,
835 int count
, int flags ATTRIBUTE_UNUSED
)
837 const rtx_insn
*insn
, *tail
;
838 pretty_printer rtl_slim_pp
;
839 rtl_slim_pp
.buffer
->stream
= f
;
841 tail
= last
? NEXT_INSN (last
) : NULL
;
843 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
844 insn
= NEXT_INSN (insn
))
846 print_insn_with_notes (&rtl_slim_pp
, insn
);
851 pp_flush (&rtl_slim_pp
);
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. */
858 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
863 /* TODO: inter-bb stuff. */
864 FOR_BB_INSNS (bb
, insn
)
869 pp_write_text_to_stream (pp
);
872 print_insn_with_notes (pp
, insn
);
873 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
877 /* Pretty-print pattern X of some insn in non-verbose mode.
878 Return a string pointer to the pretty-printer buffer.
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. */
884 str_pattern_slim (const_rtx x
)
886 pretty_printer rtl_slim_pp
;
887 print_pattern (&rtl_slim_pp
, x
, 0);
888 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
891 /* Emit a slim dump of X (an insn) to stderr. */
892 extern void debug_insn_slim (const rtx_insn
*);
894 debug_insn_slim (const rtx_insn
*x
)
896 dump_insn_slim (stderr
, x
);
899 /* Same as above, but using dump_rtl_slim. */
900 extern void debug_rtl_slim (FILE *, const rtx_insn
*, const rtx_insn
*,
903 debug_rtl_slim (const rtx_insn
*first
, const rtx_insn
*last
, int count
,
906 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
909 extern void debug_bb_slim (basic_block
);
911 debug_bb_slim (basic_block bb
)
913 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
916 extern void debug_bb_n_slim (int);
918 debug_bb_n_slim (int n
)
920 basic_block bb
= BASIC_BLOCK_FOR_FN (cfun
, n
);