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"
33 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
35 #include "hard-reg-set.h"
37 #include "dominance.h"
39 #include "basic-block.h"
40 #include "dumpfile.h" /* for the TDF_* flags */
41 #include "pretty-print.h"
43 /* The functions in this file try to print RTL in a form resembling assembler
44 mnemonics. Because this form is more concise than the "traditional" form
45 of RTL printing in Lisp-style, the form printed by this file is called
46 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
47 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
48 always printed in slim form.
50 The normal interface to the functionality provided in this pretty-printer
51 is through the dump_*_slim functions to print to a stream, or via the
52 print_*_slim functions to print into a user's pretty-printer.
54 It is also possible to obtain a string for a single pattern as a string
55 pointer, via str_pattern_slim, but this usage is discouraged. */
57 /* For insns we print patterns, and for some patterns we print insns... */
58 static void print_insn_with_notes (pretty_printer
*, const rtx_insn
*);
60 /* This recognizes rtx'en classified as expressions. These are always
61 represent some action on values or results of other expression, that
62 may be stored in objects representing values. */
65 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
73 for (i
= 0; i
< 4; i
++)
83 if (CONST_INT_P (XEXP (x
, 1))
84 && INTVAL (XEXP (x
, 1)) < 0)
87 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
244 fun
= (verbose
) ? "sign_extract" : "sxt";
250 fun
= (verbose
) ? "zero_extract" : "zxt";
256 fun
= (verbose
) ? "sign_extend" : "sxn";
260 fun
= (verbose
) ? "zero_extend" : "zxn";
264 fun
= (verbose
) ? "float_extend" : "fxn";
268 fun
= (verbose
) ? "trunc" : "trn";
272 fun
= (verbose
) ? "float_trunc" : "ftr";
276 fun
= (verbose
) ? "float" : "flt";
280 fun
= (verbose
) ? "uns_float" : "ufl";
288 fun
= (verbose
) ? "uns_fix" : "ufx";
309 op
[0] = XEXP (XEXP (x
, 1), 0);
311 op
[1] = XEXP (XEXP (x
, 1), 1);
315 op
[0] = XEXP (XEXP (x
, 1), 0);
317 op
[1] = XEXP (XEXP (x
, 1), 1);
339 op
[0] = TRAP_CONDITION (x
);
348 case UNSPEC_VOLATILE
:
350 pp_string (pp
, "unspec");
351 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
352 pp_string (pp
, "/v");
353 pp_left_bracket (pp
);
354 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
358 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
360 pp_string (pp
, "] ");
361 pp_decimal_int (pp
, XINT (x
, 1));
366 /* Most unhandled codes can be printed as pseudo-functions. */
367 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
369 fun
= GET_RTX_NAME (GET_CODE (x
));
372 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
373 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
374 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
375 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
377 fun
= GET_RTX_NAME (GET_CODE (x
));
381 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
383 fun
= GET_RTX_NAME (GET_CODE (x
));
389 /* Give up, just print the RTX name. */
390 st
[0] = GET_RTX_NAME (GET_CODE (x
));
395 /* Print this as a function? */
402 for (i
= 0; i
< 4; i
++)
405 pp_string (pp
, st
[i
]);
411 print_value (pp
, op
[i
], verbose
);
419 /* Prints rtxes, I customarily classified as values. They're constants,
420 registers, labels, symbols and memory accesses. */
423 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
429 pp_string (pp
, "(nil)");
432 switch (GET_CODE (x
))
435 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
436 (unsigned HOST_WIDE_INT
) INTVAL (x
));
441 const char *sep
= "<";
443 for (i
= CONST_WIDE_INT_NUNITS (x
) - 1; i
>= 0; i
--)
447 sprintf (tmp
, HOST_WIDE_INT_PRINT_HEX
,
448 (unsigned HOST_WIDE_INT
) CONST_WIDE_INT_ELT (x
, i
));
456 if (FLOAT_MODE_P (GET_MODE (x
)))
458 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
463 pp_printf (pp
, "<%wx,%wx>",
464 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
465 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
468 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
472 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
475 pp_printf (pp
, "`%s'", XSTR (x
, 0));
478 pp_printf (pp
, "L%d", INSN_UID (LABEL_REF_LABEL (x
)));
482 case STRICT_LOW_PART
:
483 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
484 print_value (pp
, XEXP (x
, 0), verbose
);
488 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
490 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
492 pp_string (pp
, reg_names
[REGNO (x
)]);
495 pp_printf (pp
, "r%d", REGNO (x
));
497 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
500 print_value (pp
, SUBREG_REG (x
), verbose
);
501 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
506 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
509 pp_left_bracket (pp
);
510 print_value (pp
, XEXP (x
, 0), verbose
);
511 pp_right_bracket (pp
);
514 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
517 print_exp (pp
, x
, verbose
);
522 /* The next step in insn detalization, its pattern recognition. */
525 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
529 pp_string (pp
, "(nil)");
533 switch (GET_CODE (x
))
536 print_value (pp
, SET_DEST (x
), verbose
);
538 print_value (pp
, SET_SRC (x
), verbose
);
543 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
546 print_exp (pp
, x
, verbose
);
550 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
551 print_value (pp
, XEXP (x
, 0), verbose
);
554 pp_string (pp
, "loc ");
555 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
559 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
560 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
561 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
562 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
563 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
566 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
569 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
570 pp_string (pp
, ") ");
571 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
578 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
580 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
588 const rtx_sequence
*seq
= as_a
<const rtx_sequence
*> (x
);
589 pp_string (pp
, "sequence{");
590 if (INSN_P (seq
->element (0)))
592 /* Print the sequence insns indented. */
593 const char * save_print_rtx_head
= print_rtx_head
;
594 char indented_print_rtx_head
[32];
597 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
598 snprintf (indented_print_rtx_head
,
599 sizeof (indented_print_rtx_head
),
600 "%s ", print_rtx_head
);
601 print_rtx_head
= indented_print_rtx_head
;
602 for (int i
= 0; i
< seq
->len (); i
++)
603 print_insn_with_notes (pp
, seq
->insn (i
));
604 pp_printf (pp
, "%s ", save_print_rtx_head
);
605 print_rtx_head
= save_print_rtx_head
;
609 for (int i
= 0; i
< seq
->len (); i
++)
611 print_pattern (pp
, seq
->element (i
), verbose
);
619 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
622 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
624 print_value (pp
, XVECEXP (x
, 0, i
), verbose
);
629 for (int i
= 0; i
< XVECLEN (x
, 1); i
++)
631 print_value (pp
, XVECEXP (x
, 1, i
), verbose
);
636 pp_string (pp
, "trap_if ");
637 print_value (pp
, TRAP_CONDITION (x
), verbose
);
640 case UNSPEC_VOLATILE
:
641 /* Fallthru -- leave UNSPECs to print_exp. */
643 print_value (pp
, x
, verbose
);
645 } /* print_pattern */
647 /* This is the main function in slim rtl visualization mechanism.
649 X is an insn, to be printed into PP.
651 This function tries to print it properly in human-readable form,
652 resembling assembler mnemonics (instead of the older Lisp-style
655 If VERBOSE is TRUE, insns are printed with more complete (but
656 longer) pattern names and with extra information, and prefixed
657 with their INSN_UIDs. */
660 print_insn (pretty_printer
*pp
, const rtx_insn
*x
, int verbose
)
664 /* Blech, pretty-print can't print integers with a specified width. */
666 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
667 pp_string (pp
, uid_prefix
);
670 switch (GET_CODE (x
))
673 print_pattern (pp
, PATTERN (x
), verbose
);
678 const char *name
= "?";
680 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
682 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
685 name
= IDENTIFIER_POINTER (id
);
686 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
689 sprintf (idbuf
, "D#%i",
690 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
695 sprintf (idbuf
, "D.%i",
696 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
700 pp_printf (pp
, "debug %s => ", name
);
701 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
702 pp_string (pp
, "optimized away");
704 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
709 print_pattern (pp
, PATTERN (x
), verbose
);
712 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
713 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
715 print_pattern (pp
, PATTERN (x
), verbose
);
718 pp_printf (pp
, "L%d:", INSN_UID (x
));
720 case JUMP_TABLE_DATA
:
721 pp_string (pp
, "jump_table_data{\n");
722 print_pattern (pp
, PATTERN (x
), verbose
);
726 pp_string (pp
, "barrier");
730 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
731 switch (NOTE_KIND (x
))
733 case NOTE_INSN_EH_REGION_BEG
:
734 case NOTE_INSN_EH_REGION_END
:
735 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
738 case NOTE_INSN_BLOCK_BEG
:
739 case NOTE_INSN_BLOCK_END
:
740 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
743 case NOTE_INSN_BASIC_BLOCK
:
744 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
747 case NOTE_INSN_DELETED_LABEL
:
748 case NOTE_INSN_DELETED_DEBUG_LABEL
:
750 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
753 pp_printf (pp
, " (\"%s\")", label
);
757 case NOTE_INSN_VAR_LOCATION
:
758 case NOTE_INSN_CALL_ARG_LOCATION
:
760 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
774 /* Pretty-print a slim dump of X (an insn) to PP, including any register
775 note attached to the instruction. */
778 print_insn_with_notes (pretty_printer
*pp
, const rtx_insn
*x
)
780 pp_string (pp
, print_rtx_head
);
781 print_insn (pp
, x
, 1);
783 if (INSN_P (x
) && REG_NOTES (x
))
784 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
786 pp_printf (pp
, "%s %s ", print_rtx_head
,
787 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
788 if (GET_CODE (note
) == INT_LIST
)
789 pp_printf (pp
, "%d", XINT (note
, 0));
791 print_pattern (pp
, XEXP (note
, 0), 1);
796 /* Print X, an RTL value node, to file F in slim format. Include
797 additional information if VERBOSE is nonzero.
799 Value nodes are constants, registers, labels, symbols and
803 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
805 pretty_printer rtl_slim_pp
;
806 rtl_slim_pp
.buffer
->stream
= f
;
807 print_value (&rtl_slim_pp
, x
, verbose
);
808 pp_flush (&rtl_slim_pp
);
811 /* Emit a slim dump of X (an insn) to the file F, including any register
812 note attached to the instruction. */
814 dump_insn_slim (FILE *f
, const rtx_insn
*x
)
816 pretty_printer rtl_slim_pp
;
817 rtl_slim_pp
.buffer
->stream
= f
;
818 print_insn_with_notes (&rtl_slim_pp
, x
);
819 pp_flush (&rtl_slim_pp
);
822 /* Same as above, but stop at LAST or when COUNT == 0.
823 If COUNT < 0 it will stop only at LAST or NULL rtx. */
826 dump_rtl_slim (FILE *f
, const rtx_insn
*first
, const rtx_insn
*last
,
827 int count
, int flags ATTRIBUTE_UNUSED
)
829 const rtx_insn
*insn
, *tail
;
830 pretty_printer rtl_slim_pp
;
831 rtl_slim_pp
.buffer
->stream
= f
;
833 tail
= last
? NEXT_INSN (last
) : NULL
;
835 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
836 insn
= NEXT_INSN (insn
))
838 print_insn_with_notes (&rtl_slim_pp
, insn
);
843 pp_flush (&rtl_slim_pp
);
846 /* Dumps basic block BB to pretty-printer PP in slim form and without and
847 no indentation, for use as a label of a DOT graph record-node. */
850 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
855 /* TODO: inter-bb stuff. */
856 FOR_BB_INSNS (bb
, insn
)
861 pp_write_text_to_stream (pp
);
864 print_insn_with_notes (pp
, insn
);
865 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
869 /* Pretty-print pattern X of some insn in non-verbose mode.
870 Return a string pointer to the pretty-printer buffer.
872 This function is only exported exists only to accommodate some older users
873 of the slim RTL pretty printers. Please do not use it for new code. */
876 str_pattern_slim (const_rtx x
)
878 pretty_printer rtl_slim_pp
;
879 print_pattern (&rtl_slim_pp
, x
, 0);
880 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
883 /* Emit a slim dump of X (an insn) to stderr. */
884 extern void debug_insn_slim (const rtx_insn
*);
886 debug_insn_slim (const rtx_insn
*x
)
888 dump_insn_slim (stderr
, x
);
891 /* Same as above, but using dump_rtl_slim. */
892 extern void debug_rtl_slim (FILE *, const rtx_insn
*, const rtx_insn
*,
895 debug_rtl_slim (const rtx_insn
*first
, const rtx_insn
*last
, int count
,
898 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
901 extern void debug_bb_slim (basic_block
);
903 debug_bb_slim (basic_block bb
)
905 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
908 extern void debug_bb_n_slim (int);
910 debug_bb_n_slim (int n
)
912 basic_block bb
= BASIC_BLOCK_FOR_FN (cfun
, n
);