1 /* Printing of RTL in "slim", mnemonic like form.
2 Copyright (C) 1992-2014 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. */
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 /* For insns we print patterns, and for some patterns we print insns... */
51 static void print_insn_with_notes (pretty_printer
*, const_rtx
);
53 /* This recognizes rtx'en classified as expressions. These are always
54 represent some action on values or results of other expression, that
55 may be stored in objects representing values. */
58 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
66 for (i
= 0; i
< 4; i
++)
76 if (CONST_INT_P (XEXP (x
, 1))
77 && INTVAL (XEXP (x
, 1)) < 0)
80 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
237 fun
= (verbose
) ? "sign_extract" : "sxt";
243 fun
= (verbose
) ? "zero_extract" : "zxt";
249 fun
= (verbose
) ? "sign_extend" : "sxn";
253 fun
= (verbose
) ? "zero_extend" : "zxn";
257 fun
= (verbose
) ? "float_extend" : "fxn";
261 fun
= (verbose
) ? "trunc" : "trn";
265 fun
= (verbose
) ? "float_trunc" : "ftr";
269 fun
= (verbose
) ? "float" : "flt";
273 fun
= (verbose
) ? "uns_float" : "ufl";
281 fun
= (verbose
) ? "uns_fix" : "ufx";
302 op
[0] = XEXP (XEXP (x
, 1), 0);
304 op
[1] = XEXP (XEXP (x
, 1), 1);
308 op
[0] = XEXP (XEXP (x
, 1), 0);
310 op
[1] = XEXP (XEXP (x
, 1), 1);
332 op
[0] = TRAP_CONDITION (x
);
341 case UNSPEC_VOLATILE
:
343 pp_string (pp
, "unspec");
344 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
345 pp_string (pp
, "/v");
346 pp_left_bracket (pp
);
347 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
351 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
353 pp_string (pp
, "] ");
354 pp_decimal_int (pp
, XINT (x
, 1));
359 /* Most unhandled codes can be printed as pseudo-functions. */
360 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
362 fun
= GET_RTX_NAME (GET_CODE (x
));
365 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
366 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
367 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
368 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
370 fun
= GET_RTX_NAME (GET_CODE (x
));
374 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
376 fun
= GET_RTX_NAME (GET_CODE (x
));
382 /* Give up, just print the RTX name. */
383 st
[0] = GET_RTX_NAME (GET_CODE (x
));
388 /* Print this as a function? */
395 for (i
= 0; i
< 4; i
++)
398 pp_string (pp
, st
[i
]);
404 print_value (pp
, op
[i
], verbose
);
412 /* Prints rtxes, I customarily classified as values. They're constants,
413 registers, labels, symbols and memory accesses. */
416 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
422 pp_string (pp
, "(nil)");
425 switch (GET_CODE (x
))
428 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
429 (unsigned HOST_WIDE_INT
) INTVAL (x
));
434 const char *sep
= "<";
436 for (i
= CONST_WIDE_INT_NUNITS (x
) - 1; i
>= 0; i
--)
440 sprintf (tmp
, HOST_WIDE_INT_PRINT_HEX
,
441 (unsigned HOST_WIDE_INT
) CONST_WIDE_INT_ELT (x
, i
));
449 if (FLOAT_MODE_P (GET_MODE (x
)))
451 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
456 pp_printf (pp
, "<%wx,%wx>",
457 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
458 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
461 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
465 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
468 pp_printf (pp
, "`%s'", XSTR (x
, 0));
471 pp_printf (pp
, "L%d", INSN_UID (XEXP (x
, 0)));
475 case STRICT_LOW_PART
:
476 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
477 print_value (pp
, XEXP (x
, 0), verbose
);
481 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
483 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
485 pp_string (pp
, reg_names
[REGNO (x
)]);
488 pp_printf (pp
, "r%d", REGNO (x
));
490 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
493 print_value (pp
, SUBREG_REG (x
), verbose
);
494 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
499 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
502 pp_left_bracket (pp
);
503 print_value (pp
, XEXP (x
, 0), verbose
);
504 pp_right_bracket (pp
);
507 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
510 print_exp (pp
, x
, verbose
);
515 /* The next step in insn detalization, its pattern recognition. */
518 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
522 pp_string (pp
, "(nil)");
526 switch (GET_CODE (x
))
529 print_value (pp
, SET_DEST (x
), verbose
);
531 print_value (pp
, SET_SRC (x
), verbose
);
536 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
539 print_exp (pp
, x
, verbose
);
543 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
544 print_value (pp
, XEXP (x
, 0), verbose
);
547 pp_string (pp
, "loc ");
548 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
552 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
553 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
554 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
555 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
556 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
559 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
562 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
563 pp_string (pp
, ") ");
564 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
571 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
573 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
581 const rtx_sequence
*seq
= as_a
<const rtx_sequence
*> (x
);
582 pp_string (pp
, "sequence{");
583 if (INSN_P (seq
->element (0)))
585 /* Print the sequence insns indented. */
586 const char * save_print_rtx_head
= print_rtx_head
;
587 char indented_print_rtx_head
[32];
590 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
591 snprintf (indented_print_rtx_head
,
592 sizeof (indented_print_rtx_head
),
593 "%s ", print_rtx_head
);
594 print_rtx_head
= indented_print_rtx_head
;
595 for (int i
= 0; i
< seq
->len (); i
++)
596 print_insn_with_notes (pp
, seq
->insn (i
));
597 pp_printf (pp
, "%s ", save_print_rtx_head
);
598 print_rtx_head
= save_print_rtx_head
;
602 for (int i
= 0; i
< seq
->len (); i
++)
604 print_pattern (pp
, seq
->element (i
), verbose
);
612 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
615 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
617 print_value (pp
, XVECEXP (x
, 0, i
), verbose
);
622 for (int i
= 0; i
< XVECLEN (x
, 1); i
++)
624 print_value (pp
, XVECEXP (x
, 1, i
), verbose
);
629 pp_string (pp
, "trap_if ");
630 print_value (pp
, TRAP_CONDITION (x
), verbose
);
633 case UNSPEC_VOLATILE
:
634 /* Fallthru -- leave UNSPECs to print_exp. */
636 print_value (pp
, x
, verbose
);
638 } /* print_pattern */
640 /* This is the main function in slim rtl visualization mechanism.
642 X is an insn, to be printed into PP.
644 This function tries to print it properly in human-readable form,
645 resembling assembler mnemonics (instead of the older Lisp-style
648 If VERBOSE is TRUE, insns are printed with more complete (but
649 longer) pattern names and with extra information, and prefixed
650 with their INSN_UIDs. */
653 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
657 /* Blech, pretty-print can't print integers with a specified width. */
659 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
660 pp_string (pp
, uid_prefix
);
663 switch (GET_CODE (x
))
666 print_pattern (pp
, PATTERN (x
), verbose
);
671 const char *name
= "?";
673 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
675 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
678 name
= IDENTIFIER_POINTER (id
);
679 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
682 sprintf (idbuf
, "D#%i",
683 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
688 sprintf (idbuf
, "D.%i",
689 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
693 pp_printf (pp
, "debug %s => ", name
);
694 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
695 pp_string (pp
, "optimized away");
697 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
702 print_pattern (pp
, PATTERN (x
), verbose
);
705 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
706 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
708 print_pattern (pp
, PATTERN (x
), verbose
);
711 pp_printf (pp
, "L%d:", INSN_UID (x
));
713 case JUMP_TABLE_DATA
:
714 pp_string (pp
, "jump_table_data{\n");
715 print_pattern (pp
, PATTERN (x
), verbose
);
719 pp_string (pp
, "barrier");
723 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
724 switch (NOTE_KIND (x
))
726 case NOTE_INSN_EH_REGION_BEG
:
727 case NOTE_INSN_EH_REGION_END
:
728 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
731 case NOTE_INSN_BLOCK_BEG
:
732 case NOTE_INSN_BLOCK_END
:
733 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
736 case NOTE_INSN_BASIC_BLOCK
:
737 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
740 case NOTE_INSN_DELETED_LABEL
:
741 case NOTE_INSN_DELETED_DEBUG_LABEL
:
743 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
746 pp_printf (pp
, " (\"%s\")", label
);
750 case NOTE_INSN_VAR_LOCATION
:
751 case NOTE_INSN_CALL_ARG_LOCATION
:
753 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
767 /* Pretty-print a slim dump of X (an insn) to PP, including any register
768 note attached to the instruction. */
771 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
773 pp_string (pp
, print_rtx_head
);
774 print_insn (pp
, x
, 1);
776 if (INSN_P (x
) && REG_NOTES (x
))
777 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
779 pp_printf (pp
, "%s %s ", print_rtx_head
,
780 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
781 if (GET_CODE (note
) == INT_LIST
)
782 pp_printf (pp
, "%d", XINT (note
, 0));
784 print_pattern (pp
, XEXP (note
, 0), 1);
789 /* Print X, an RTL value node, to file F in slim format. Include
790 additional information if VERBOSE is nonzero.
792 Value nodes are constants, registers, labels, symbols and
796 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
798 pretty_printer rtl_slim_pp
;
799 rtl_slim_pp
.buffer
->stream
= f
;
800 print_value (&rtl_slim_pp
, x
, verbose
);
801 pp_flush (&rtl_slim_pp
);
804 /* Emit a slim dump of X (an insn) to the file F, including any register
805 note attached to the instruction. */
807 dump_insn_slim (FILE *f
, const_rtx x
)
809 pretty_printer rtl_slim_pp
;
810 rtl_slim_pp
.buffer
->stream
= f
;
811 print_insn_with_notes (&rtl_slim_pp
, x
);
812 pp_flush (&rtl_slim_pp
);
815 /* Same as above, but stop at LAST or when COUNT == 0.
816 If COUNT < 0 it will stop only at LAST or NULL rtx. */
819 dump_rtl_slim (FILE *f
, const rtx_insn
*first
, const rtx_insn
*last
,
820 int count
, int flags ATTRIBUTE_UNUSED
)
822 const rtx_insn
*insn
, *tail
;
823 pretty_printer rtl_slim_pp
;
824 rtl_slim_pp
.buffer
->stream
= f
;
826 tail
= last
? NEXT_INSN (last
) : NULL
;
828 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
829 insn
= NEXT_INSN (insn
))
831 print_insn_with_notes (&rtl_slim_pp
, insn
);
836 pp_flush (&rtl_slim_pp
);
839 /* Dumps basic block BB to pretty-printer PP in slim form and without and
840 no indentation, for use as a label of a DOT graph record-node. */
843 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
848 /* TODO: inter-bb stuff. */
849 FOR_BB_INSNS (bb
, insn
)
854 pp_write_text_to_stream (pp
);
857 print_insn_with_notes (pp
, insn
);
858 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
862 /* Pretty-print pattern X of some insn in non-verbose mode.
863 Return a string pointer to the pretty-printer buffer.
865 This function is only exported exists only to accommodate some older users
866 of the slim RTL pretty printers. Please do not use it for new code. */
869 str_pattern_slim (const_rtx x
)
871 pretty_printer rtl_slim_pp
;
872 print_pattern (&rtl_slim_pp
, x
, 0);
873 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
876 /* Emit a slim dump of X (an insn) to stderr. */
877 extern void debug_insn_slim (const_rtx
);
879 debug_insn_slim (const_rtx x
)
881 dump_insn_slim (stderr
, x
);
884 /* Same as above, but using dump_rtl_slim. */
885 extern void debug_rtl_slim (FILE *, const rtx_insn
*, const rtx_insn
*,
888 debug_rtl_slim (const rtx_insn
*first
, const rtx_insn
*last
, int count
,
891 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
894 extern void debug_bb_slim (basic_block
);
896 debug_bb_slim (basic_block bb
)
898 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
901 extern void debug_bb_n_slim (int);
903 debug_bb_n_slim (int n
)
905 basic_block bb
= BASIC_BLOCK_FOR_FN (cfun
, n
);