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"
31 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
37 #include "hard-reg-set.h"
40 #include "dominance.h"
42 #include "basic-block.h"
43 #include "dumpfile.h" /* for the TDF_* flags */
44 #include "pretty-print.h"
46 /* The functions in this file try to print RTL in a form resembling assembler
47 mnemonics. Because this form is more concise than the "traditional" form
48 of RTL printing in Lisp-style, the form printed by this file is called
49 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
50 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
51 always printed in slim form.
53 The normal interface to the functionality provided in this pretty-printer
54 is through the dump_*_slim functions to print to a stream, or via the
55 print_*_slim functions to print into a user's pretty-printer.
57 It is also possible to obtain a string for a single pattern as a string
58 pointer, via str_pattern_slim, but this usage is discouraged. */
60 /* For insns we print patterns, and for some patterns we print insns... */
61 static void print_insn_with_notes (pretty_printer
*, const_rtx
);
63 /* This recognizes rtx'en classified as expressions. These are always
64 represent some action on values or results of other expression, that
65 may be stored in objects representing values. */
68 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
76 for (i
= 0; i
< 4; i
++)
86 if (CONST_INT_P (XEXP (x
, 1))
87 && INTVAL (XEXP (x
, 1)) < 0)
90 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
247 fun
= (verbose
) ? "sign_extract" : "sxt";
253 fun
= (verbose
) ? "zero_extract" : "zxt";
259 fun
= (verbose
) ? "sign_extend" : "sxn";
263 fun
= (verbose
) ? "zero_extend" : "zxn";
267 fun
= (verbose
) ? "float_extend" : "fxn";
271 fun
= (verbose
) ? "trunc" : "trn";
275 fun
= (verbose
) ? "float_trunc" : "ftr";
279 fun
= (verbose
) ? "float" : "flt";
283 fun
= (verbose
) ? "uns_float" : "ufl";
291 fun
= (verbose
) ? "uns_fix" : "ufx";
312 op
[0] = XEXP (XEXP (x
, 1), 0);
314 op
[1] = XEXP (XEXP (x
, 1), 1);
318 op
[0] = XEXP (XEXP (x
, 1), 0);
320 op
[1] = XEXP (XEXP (x
, 1), 1);
342 op
[0] = TRAP_CONDITION (x
);
351 case UNSPEC_VOLATILE
:
353 pp_string (pp
, "unspec");
354 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
355 pp_string (pp
, "/v");
356 pp_left_bracket (pp
);
357 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
361 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
363 pp_string (pp
, "] ");
364 pp_decimal_int (pp
, XINT (x
, 1));
369 /* Most unhandled codes can be printed as pseudo-functions. */
370 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
372 fun
= GET_RTX_NAME (GET_CODE (x
));
375 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
376 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
377 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
378 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
380 fun
= GET_RTX_NAME (GET_CODE (x
));
384 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
386 fun
= GET_RTX_NAME (GET_CODE (x
));
392 /* Give up, just print the RTX name. */
393 st
[0] = GET_RTX_NAME (GET_CODE (x
));
398 /* Print this as a function? */
405 for (i
= 0; i
< 4; i
++)
408 pp_string (pp
, st
[i
]);
414 print_value (pp
, op
[i
], verbose
);
422 /* Prints rtxes, I customarily classified as values. They're constants,
423 registers, labels, symbols and memory accesses. */
426 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
432 pp_string (pp
, "(nil)");
435 switch (GET_CODE (x
))
438 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
439 (unsigned HOST_WIDE_INT
) INTVAL (x
));
444 const char *sep
= "<";
446 for (i
= CONST_WIDE_INT_NUNITS (x
) - 1; i
>= 0; i
--)
450 sprintf (tmp
, HOST_WIDE_INT_PRINT_HEX
,
451 (unsigned HOST_WIDE_INT
) CONST_WIDE_INT_ELT (x
, i
));
459 if (FLOAT_MODE_P (GET_MODE (x
)))
461 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
466 pp_printf (pp
, "<%wx,%wx>",
467 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
468 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
471 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
475 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
478 pp_printf (pp
, "`%s'", XSTR (x
, 0));
481 pp_printf (pp
, "L%d", INSN_UID (LABEL_REF_LABEL (x
)));
485 case STRICT_LOW_PART
:
486 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
487 print_value (pp
, XEXP (x
, 0), verbose
);
491 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
493 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
495 pp_string (pp
, reg_names
[REGNO (x
)]);
498 pp_printf (pp
, "r%d", REGNO (x
));
500 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
503 print_value (pp
, SUBREG_REG (x
), verbose
);
504 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
509 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
512 pp_left_bracket (pp
);
513 print_value (pp
, XEXP (x
, 0), verbose
);
514 pp_right_bracket (pp
);
517 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
520 print_exp (pp
, x
, verbose
);
525 /* The next step in insn detalization, its pattern recognition. */
528 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
532 pp_string (pp
, "(nil)");
536 switch (GET_CODE (x
))
539 print_value (pp
, SET_DEST (x
), verbose
);
541 print_value (pp
, SET_SRC (x
), verbose
);
546 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
549 print_exp (pp
, x
, verbose
);
553 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
554 print_value (pp
, XEXP (x
, 0), verbose
);
557 pp_string (pp
, "loc ");
558 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
562 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
563 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
564 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
565 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
566 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
569 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
572 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
573 pp_string (pp
, ") ");
574 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
581 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
583 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
591 const rtx_sequence
*seq
= as_a
<const rtx_sequence
*> (x
);
592 pp_string (pp
, "sequence{");
593 if (INSN_P (seq
->element (0)))
595 /* Print the sequence insns indented. */
596 const char * save_print_rtx_head
= print_rtx_head
;
597 char indented_print_rtx_head
[32];
600 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
601 snprintf (indented_print_rtx_head
,
602 sizeof (indented_print_rtx_head
),
603 "%s ", print_rtx_head
);
604 print_rtx_head
= indented_print_rtx_head
;
605 for (int i
= 0; i
< seq
->len (); i
++)
606 print_insn_with_notes (pp
, seq
->insn (i
));
607 pp_printf (pp
, "%s ", save_print_rtx_head
);
608 print_rtx_head
= save_print_rtx_head
;
612 for (int i
= 0; i
< seq
->len (); i
++)
614 print_pattern (pp
, seq
->element (i
), verbose
);
622 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
625 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
627 print_value (pp
, XVECEXP (x
, 0, i
), verbose
);
632 for (int i
= 0; i
< XVECLEN (x
, 1); i
++)
634 print_value (pp
, XVECEXP (x
, 1, i
), verbose
);
639 pp_string (pp
, "trap_if ");
640 print_value (pp
, TRAP_CONDITION (x
), verbose
);
643 case UNSPEC_VOLATILE
:
644 /* Fallthru -- leave UNSPECs to print_exp. */
646 print_value (pp
, x
, verbose
);
648 } /* print_pattern */
650 /* This is the main function in slim rtl visualization mechanism.
652 X is an insn, to be printed into PP.
654 This function tries to print it properly in human-readable form,
655 resembling assembler mnemonics (instead of the older Lisp-style
658 If VERBOSE is TRUE, insns are printed with more complete (but
659 longer) pattern names and with extra information, and prefixed
660 with their INSN_UIDs. */
663 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
667 /* Blech, pretty-print can't print integers with a specified width. */
669 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
670 pp_string (pp
, uid_prefix
);
673 switch (GET_CODE (x
))
676 print_pattern (pp
, PATTERN (x
), verbose
);
681 const char *name
= "?";
683 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
685 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
688 name
= IDENTIFIER_POINTER (id
);
689 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
692 sprintf (idbuf
, "D#%i",
693 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
698 sprintf (idbuf
, "D.%i",
699 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
703 pp_printf (pp
, "debug %s => ", name
);
704 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
705 pp_string (pp
, "optimized away");
707 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
712 print_pattern (pp
, PATTERN (x
), verbose
);
715 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
716 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
718 print_pattern (pp
, PATTERN (x
), verbose
);
721 pp_printf (pp
, "L%d:", INSN_UID (x
));
723 case JUMP_TABLE_DATA
:
724 pp_string (pp
, "jump_table_data{\n");
725 print_pattern (pp
, PATTERN (x
), verbose
);
729 pp_string (pp
, "barrier");
733 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
734 switch (NOTE_KIND (x
))
736 case NOTE_INSN_EH_REGION_BEG
:
737 case NOTE_INSN_EH_REGION_END
:
738 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
741 case NOTE_INSN_BLOCK_BEG
:
742 case NOTE_INSN_BLOCK_END
:
743 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
746 case NOTE_INSN_BASIC_BLOCK
:
747 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
750 case NOTE_INSN_DELETED_LABEL
:
751 case NOTE_INSN_DELETED_DEBUG_LABEL
:
753 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
756 pp_printf (pp
, " (\"%s\")", label
);
760 case NOTE_INSN_VAR_LOCATION
:
761 case NOTE_INSN_CALL_ARG_LOCATION
:
763 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
777 /* Pretty-print a slim dump of X (an insn) to PP, including any register
778 note attached to the instruction. */
781 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
783 pp_string (pp
, print_rtx_head
);
784 print_insn (pp
, x
, 1);
786 if (INSN_P (x
) && REG_NOTES (x
))
787 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
789 pp_printf (pp
, "%s %s ", print_rtx_head
,
790 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
791 if (GET_CODE (note
) == INT_LIST
)
792 pp_printf (pp
, "%d", XINT (note
, 0));
794 print_pattern (pp
, XEXP (note
, 0), 1);
799 /* Print X, an RTL value node, to file F in slim format. Include
800 additional information if VERBOSE is nonzero.
802 Value nodes are constants, registers, labels, symbols and
806 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
808 pretty_printer rtl_slim_pp
;
809 rtl_slim_pp
.buffer
->stream
= f
;
810 print_value (&rtl_slim_pp
, x
, verbose
);
811 pp_flush (&rtl_slim_pp
);
814 /* Emit a slim dump of X (an insn) to the file F, including any register
815 note attached to the instruction. */
817 dump_insn_slim (FILE *f
, const_rtx x
)
819 pretty_printer rtl_slim_pp
;
820 rtl_slim_pp
.buffer
->stream
= f
;
821 print_insn_with_notes (&rtl_slim_pp
, x
);
822 pp_flush (&rtl_slim_pp
);
825 /* Same as above, but stop at LAST or when COUNT == 0.
826 If COUNT < 0 it will stop only at LAST or NULL rtx. */
829 dump_rtl_slim (FILE *f
, const rtx_insn
*first
, const rtx_insn
*last
,
830 int count
, int flags ATTRIBUTE_UNUSED
)
832 const rtx_insn
*insn
, *tail
;
833 pretty_printer rtl_slim_pp
;
834 rtl_slim_pp
.buffer
->stream
= f
;
836 tail
= last
? NEXT_INSN (last
) : NULL
;
838 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
839 insn
= NEXT_INSN (insn
))
841 print_insn_with_notes (&rtl_slim_pp
, insn
);
846 pp_flush (&rtl_slim_pp
);
849 /* Dumps basic block BB to pretty-printer PP in slim form and without and
850 no indentation, for use as a label of a DOT graph record-node. */
853 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
858 /* TODO: inter-bb stuff. */
859 FOR_BB_INSNS (bb
, insn
)
864 pp_write_text_to_stream (pp
);
867 print_insn_with_notes (pp
, insn
);
868 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
872 /* Pretty-print pattern X of some insn in non-verbose mode.
873 Return a string pointer to the pretty-printer buffer.
875 This function is only exported exists only to accommodate some older users
876 of the slim RTL pretty printers. Please do not use it for new code. */
879 str_pattern_slim (const_rtx x
)
881 pretty_printer rtl_slim_pp
;
882 print_pattern (&rtl_slim_pp
, x
, 0);
883 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
886 /* Emit a slim dump of X (an insn) to stderr. */
887 extern void debug_insn_slim (const_rtx
);
889 debug_insn_slim (const_rtx x
)
891 dump_insn_slim (stderr
, x
);
894 /* Same as above, but using dump_rtl_slim. */
895 extern void debug_rtl_slim (FILE *, const rtx_insn
*, const rtx_insn
*,
898 debug_rtl_slim (const rtx_insn
*first
, const rtx_insn
*last
, int count
,
901 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
904 extern void debug_bb_slim (basic_block
);
906 debug_bb_slim (basic_block bb
)
908 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
911 extern void debug_bb_n_slim (int);
913 debug_bb_n_slim (int n
)
915 basic_block bb
= BASIC_BLOCK_FOR_FN (cfun
, n
);