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"
34 #include "tree.h" /* FIXME: To dump INSN_VAR_LOCATION_DECL. */
36 #include "hard-reg-set.h"
39 #include "dominance.h"
41 #include "basic-block.h"
42 #include "dumpfile.h" /* for the TDF_* flags */
43 #include "pretty-print.h"
45 /* The functions in this file try to print RTL in a form resembling assembler
46 mnemonics. Because this form is more concise than the "traditional" form
47 of RTL printing in Lisp-style, the form printed by this file is called
48 "slim". RTL dumps in slim format can be obtained by appending the "-slim"
49 option to -fdump-rtl-<pass>. Control flow graph output as a DOT file is
50 always printed in slim form.
52 The normal interface to the functionality provided in this pretty-printer
53 is through the dump_*_slim functions to print to a stream, or via the
54 print_*_slim functions to print into a user's pretty-printer.
56 It is also possible to obtain a string for a single pattern as a string
57 pointer, via str_pattern_slim, but this usage is discouraged. */
59 /* For insns we print patterns, and for some patterns we print insns... */
60 static void print_insn_with_notes (pretty_printer
*, const rtx_insn
*);
62 /* This recognizes rtx'en classified as expressions. These are always
63 represent some action on values or results of other expression, that
64 may be stored in objects representing values. */
67 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
75 for (i
= 0; i
< 4; i
++)
85 if (CONST_INT_P (XEXP (x
, 1))
86 && INTVAL (XEXP (x
, 1)) < 0)
89 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
246 fun
= (verbose
) ? "sign_extract" : "sxt";
252 fun
= (verbose
) ? "zero_extract" : "zxt";
258 fun
= (verbose
) ? "sign_extend" : "sxn";
262 fun
= (verbose
) ? "zero_extend" : "zxn";
266 fun
= (verbose
) ? "float_extend" : "fxn";
270 fun
= (verbose
) ? "trunc" : "trn";
274 fun
= (verbose
) ? "float_trunc" : "ftr";
278 fun
= (verbose
) ? "float" : "flt";
282 fun
= (verbose
) ? "uns_float" : "ufl";
290 fun
= (verbose
) ? "uns_fix" : "ufx";
311 op
[0] = XEXP (XEXP (x
, 1), 0);
313 op
[1] = XEXP (XEXP (x
, 1), 1);
317 op
[0] = XEXP (XEXP (x
, 1), 0);
319 op
[1] = XEXP (XEXP (x
, 1), 1);
341 op
[0] = TRAP_CONDITION (x
);
350 case UNSPEC_VOLATILE
:
352 pp_string (pp
, "unspec");
353 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
354 pp_string (pp
, "/v");
355 pp_left_bracket (pp
);
356 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
360 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
362 pp_string (pp
, "] ");
363 pp_decimal_int (pp
, XINT (x
, 1));
368 /* Most unhandled codes can be printed as pseudo-functions. */
369 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
371 fun
= GET_RTX_NAME (GET_CODE (x
));
374 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
375 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
376 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
377 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
379 fun
= GET_RTX_NAME (GET_CODE (x
));
383 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
385 fun
= GET_RTX_NAME (GET_CODE (x
));
391 /* Give up, just print the RTX name. */
392 st
[0] = GET_RTX_NAME (GET_CODE (x
));
397 /* Print this as a function? */
404 for (i
= 0; i
< 4; i
++)
407 pp_string (pp
, st
[i
]);
413 print_value (pp
, op
[i
], verbose
);
421 /* Prints rtxes, I customarily classified as values. They're constants,
422 registers, labels, symbols and memory accesses. */
425 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
431 pp_string (pp
, "(nil)");
434 switch (GET_CODE (x
))
437 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
438 (unsigned HOST_WIDE_INT
) INTVAL (x
));
443 const char *sep
= "<";
445 for (i
= CONST_WIDE_INT_NUNITS (x
) - 1; i
>= 0; i
--)
449 sprintf (tmp
, HOST_WIDE_INT_PRINT_HEX
,
450 (unsigned HOST_WIDE_INT
) CONST_WIDE_INT_ELT (x
, i
));
458 if (FLOAT_MODE_P (GET_MODE (x
)))
460 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
465 pp_printf (pp
, "<%wx,%wx>",
466 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
467 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
470 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
474 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
477 pp_printf (pp
, "`%s'", XSTR (x
, 0));
480 pp_printf (pp
, "L%d", INSN_UID (LABEL_REF_LABEL (x
)));
484 case STRICT_LOW_PART
:
485 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
486 print_value (pp
, XEXP (x
, 0), verbose
);
490 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
492 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
494 pp_string (pp
, reg_names
[REGNO (x
)]);
497 pp_printf (pp
, "r%d", REGNO (x
));
499 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
502 print_value (pp
, SUBREG_REG (x
), verbose
);
503 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
508 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
511 pp_left_bracket (pp
);
512 print_value (pp
, XEXP (x
, 0), verbose
);
513 pp_right_bracket (pp
);
516 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
519 print_exp (pp
, x
, verbose
);
524 /* The next step in insn detalization, its pattern recognition. */
527 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
531 pp_string (pp
, "(nil)");
535 switch (GET_CODE (x
))
538 print_value (pp
, SET_DEST (x
), verbose
);
540 print_value (pp
, SET_SRC (x
), verbose
);
545 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
548 print_exp (pp
, x
, verbose
);
552 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
553 print_value (pp
, XEXP (x
, 0), verbose
);
556 pp_string (pp
, "loc ");
557 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
561 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
562 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
563 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
564 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
565 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
568 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
571 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
572 pp_string (pp
, ") ");
573 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
580 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
582 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
590 const rtx_sequence
*seq
= as_a
<const rtx_sequence
*> (x
);
591 pp_string (pp
, "sequence{");
592 if (INSN_P (seq
->element (0)))
594 /* Print the sequence insns indented. */
595 const char * save_print_rtx_head
= print_rtx_head
;
596 char indented_print_rtx_head
[32];
599 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
600 snprintf (indented_print_rtx_head
,
601 sizeof (indented_print_rtx_head
),
602 "%s ", print_rtx_head
);
603 print_rtx_head
= indented_print_rtx_head
;
604 for (int i
= 0; i
< seq
->len (); i
++)
605 print_insn_with_notes (pp
, seq
->insn (i
));
606 pp_printf (pp
, "%s ", save_print_rtx_head
);
607 print_rtx_head
= save_print_rtx_head
;
611 for (int i
= 0; i
< seq
->len (); i
++)
613 print_pattern (pp
, seq
->element (i
), verbose
);
621 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
624 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
626 print_value (pp
, XVECEXP (x
, 0, i
), verbose
);
631 for (int i
= 0; i
< XVECLEN (x
, 1); i
++)
633 print_value (pp
, XVECEXP (x
, 1, i
), verbose
);
638 pp_string (pp
, "trap_if ");
639 print_value (pp
, TRAP_CONDITION (x
), verbose
);
642 case UNSPEC_VOLATILE
:
643 /* Fallthru -- leave UNSPECs to print_exp. */
645 print_value (pp
, x
, verbose
);
647 } /* print_pattern */
649 /* This is the main function in slim rtl visualization mechanism.
651 X is an insn, to be printed into PP.
653 This function tries to print it properly in human-readable form,
654 resembling assembler mnemonics (instead of the older Lisp-style
657 If VERBOSE is TRUE, insns are printed with more complete (but
658 longer) pattern names and with extra information, and prefixed
659 with their INSN_UIDs. */
662 print_insn (pretty_printer
*pp
, const rtx_insn
*x
, int verbose
)
666 /* Blech, pretty-print can't print integers with a specified width. */
668 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
669 pp_string (pp
, uid_prefix
);
672 switch (GET_CODE (x
))
675 print_pattern (pp
, PATTERN (x
), verbose
);
680 const char *name
= "?";
682 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
684 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
687 name
= IDENTIFIER_POINTER (id
);
688 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
691 sprintf (idbuf
, "D#%i",
692 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
697 sprintf (idbuf
, "D.%i",
698 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
702 pp_printf (pp
, "debug %s => ", name
);
703 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
704 pp_string (pp
, "optimized away");
706 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
711 print_pattern (pp
, PATTERN (x
), verbose
);
714 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
715 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
717 print_pattern (pp
, PATTERN (x
), verbose
);
720 pp_printf (pp
, "L%d:", INSN_UID (x
));
722 case JUMP_TABLE_DATA
:
723 pp_string (pp
, "jump_table_data{\n");
724 print_pattern (pp
, PATTERN (x
), verbose
);
728 pp_string (pp
, "barrier");
732 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
733 switch (NOTE_KIND (x
))
735 case NOTE_INSN_EH_REGION_BEG
:
736 case NOTE_INSN_EH_REGION_END
:
737 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
740 case NOTE_INSN_BLOCK_BEG
:
741 case NOTE_INSN_BLOCK_END
:
742 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
745 case NOTE_INSN_BASIC_BLOCK
:
746 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
749 case NOTE_INSN_DELETED_LABEL
:
750 case NOTE_INSN_DELETED_DEBUG_LABEL
:
752 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
755 pp_printf (pp
, " (\"%s\")", label
);
759 case NOTE_INSN_VAR_LOCATION
:
760 case NOTE_INSN_CALL_ARG_LOCATION
:
762 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
776 /* Pretty-print a slim dump of X (an insn) to PP, including any register
777 note attached to the instruction. */
780 print_insn_with_notes (pretty_printer
*pp
, const rtx_insn
*x
)
782 pp_string (pp
, print_rtx_head
);
783 print_insn (pp
, x
, 1);
785 if (INSN_P (x
) && REG_NOTES (x
))
786 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
788 pp_printf (pp
, "%s %s ", print_rtx_head
,
789 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
790 if (GET_CODE (note
) == INT_LIST
)
791 pp_printf (pp
, "%d", XINT (note
, 0));
793 print_pattern (pp
, XEXP (note
, 0), 1);
798 /* Print X, an RTL value node, to file F in slim format. Include
799 additional information if VERBOSE is nonzero.
801 Value nodes are constants, registers, labels, symbols and
805 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
807 pretty_printer rtl_slim_pp
;
808 rtl_slim_pp
.buffer
->stream
= f
;
809 print_value (&rtl_slim_pp
, x
, verbose
);
810 pp_flush (&rtl_slim_pp
);
813 /* Emit a slim dump of X (an insn) to the file F, including any register
814 note attached to the instruction. */
816 dump_insn_slim (FILE *f
, const rtx_insn
*x
)
818 pretty_printer rtl_slim_pp
;
819 rtl_slim_pp
.buffer
->stream
= f
;
820 print_insn_with_notes (&rtl_slim_pp
, x
);
821 pp_flush (&rtl_slim_pp
);
824 /* Same as above, but stop at LAST or when COUNT == 0.
825 If COUNT < 0 it will stop only at LAST or NULL rtx. */
828 dump_rtl_slim (FILE *f
, const rtx_insn
*first
, const rtx_insn
*last
,
829 int count
, int flags ATTRIBUTE_UNUSED
)
831 const rtx_insn
*insn
, *tail
;
832 pretty_printer rtl_slim_pp
;
833 rtl_slim_pp
.buffer
->stream
= f
;
835 tail
= last
? NEXT_INSN (last
) : NULL
;
837 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
838 insn
= NEXT_INSN (insn
))
840 print_insn_with_notes (&rtl_slim_pp
, insn
);
845 pp_flush (&rtl_slim_pp
);
848 /* Dumps basic block BB to pretty-printer PP in slim form and without and
849 no indentation, for use as a label of a DOT graph record-node. */
852 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
857 /* TODO: inter-bb stuff. */
858 FOR_BB_INSNS (bb
, insn
)
863 pp_write_text_to_stream (pp
);
866 print_insn_with_notes (pp
, insn
);
867 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
871 /* Pretty-print pattern X of some insn in non-verbose mode.
872 Return a string pointer to the pretty-printer buffer.
874 This function is only exported exists only to accommodate some older users
875 of the slim RTL pretty printers. Please do not use it for new code. */
878 str_pattern_slim (const_rtx x
)
880 pretty_printer rtl_slim_pp
;
881 print_pattern (&rtl_slim_pp
, x
, 0);
882 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
885 /* Emit a slim dump of X (an insn) to stderr. */
886 extern void debug_insn_slim (const rtx_insn
*);
888 debug_insn_slim (const rtx_insn
*x
)
890 dump_insn_slim (stderr
, x
);
893 /* Same as above, but using dump_rtl_slim. */
894 extern void debug_rtl_slim (FILE *, const rtx_insn
*, const rtx_insn
*,
897 debug_rtl_slim (const rtx_insn
*first
, const rtx_insn
*last
, int count
,
900 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
903 extern void debug_bb_slim (basic_block
);
905 debug_bb_slim (basic_block bb
)
907 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
910 extern void debug_bb_n_slim (int);
912 debug_bb_n_slim (int n
)
914 basic_block bb
= BASIC_BLOCK_FOR_FN (cfun
, n
);