1 /* Printing of RTL in "slim", mnemonic like form.
2 Copyright (C) 1992-2013 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
));
432 if (FLOAT_MODE_P (GET_MODE (x
)))
434 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
439 pp_printf (pp
, "<%wx,%wx>",
440 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
441 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
444 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
448 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
451 pp_printf (pp
, "`%s'", XSTR (x
, 0));
454 pp_printf (pp
, "L%d", INSN_UID (XEXP (x
, 0)));
458 case STRICT_LOW_PART
:
459 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
460 print_value (pp
, XEXP (x
, 0), verbose
);
464 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
466 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
468 pp_string (pp
, reg_names
[REGNO (x
)]);
471 pp_printf (pp
, "r%d", REGNO (x
));
473 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
476 print_value (pp
, SUBREG_REG (x
), verbose
);
477 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
482 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
485 pp_left_bracket (pp
);
486 print_value (pp
, XEXP (x
, 0), verbose
);
487 pp_right_bracket (pp
);
490 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
493 print_exp (pp
, x
, verbose
);
498 /* The next step in insn detalization, its pattern recognition. */
501 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
505 pp_string (pp
, "(nil)");
509 switch (GET_CODE (x
))
512 print_value (pp
, SET_DEST (x
), verbose
);
514 print_value (pp
, SET_SRC (x
), verbose
);
519 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
522 print_exp (pp
, x
, verbose
);
526 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
527 print_value (pp
, XEXP (x
, 0), verbose
);
530 pp_string (pp
, "loc ");
531 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
535 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
536 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
537 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
538 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
539 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
542 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
545 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
546 pp_string (pp
, ") ");
547 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
554 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
556 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
564 pp_string (pp
, "sequence{");
565 if (INSN_P (XVECEXP (x
, 0, 0)))
567 /* Print the sequence insns indented. */
568 const char * save_print_rtx_head
= print_rtx_head
;
569 char indented_print_rtx_head
[32];
572 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
573 snprintf (indented_print_rtx_head
,
574 sizeof (indented_print_rtx_head
),
575 "%s ", print_rtx_head
);
576 print_rtx_head
= indented_print_rtx_head
;
577 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
578 print_insn_with_notes (pp
, XVECEXP (x
, 0, i
));
579 pp_printf (pp
, "%s ", save_print_rtx_head
);
580 print_rtx_head
= save_print_rtx_head
;
584 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
586 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
594 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
599 print_value (pp
, XEXP (x
, 0), verbose
);
602 pp_string (pp
, "trap_if ");
603 print_value (pp
, TRAP_CONDITION (x
), verbose
);
606 case UNSPEC_VOLATILE
:
607 /* Fallthru -- leave UNSPECs to print_exp. */
609 print_value (pp
, x
, verbose
);
611 } /* print_pattern */
613 /* This is the main function in slim rtl visualization mechanism.
615 X is an insn, to be printed into PP.
617 This function tries to print it properly in human-readable form,
618 resembling assembler mnemonics (instead of the older Lisp-style
621 If VERBOSE is TRUE, insns are printed with more complete (but
622 longer) pattern names and with extra information, and prefixed
623 with their INSN_UIDs. */
626 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
630 /* Blech, pretty-print can't print integers with a specified width. */
632 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
633 pp_string (pp
, uid_prefix
);
636 switch (GET_CODE (x
))
639 print_pattern (pp
, PATTERN (x
), verbose
);
644 const char *name
= "?";
646 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
648 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
651 name
= IDENTIFIER_POINTER (id
);
652 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
655 sprintf (idbuf
, "D#%i",
656 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
661 sprintf (idbuf
, "D.%i",
662 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
666 pp_printf (pp
, "debug %s => ", name
);
667 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
668 pp_string (pp
, "optimized away");
670 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
675 print_pattern (pp
, PATTERN (x
), verbose
);
678 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
679 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
681 print_pattern (pp
, PATTERN (x
), verbose
);
684 pp_printf (pp
, "L%d:", INSN_UID (x
));
686 case JUMP_TABLE_DATA
:
687 pp_string (pp
, "jump_table_data{\n");
688 print_pattern (pp
, PATTERN (x
), verbose
);
692 pp_string (pp
, "barrier");
696 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
697 switch (NOTE_KIND (x
))
699 case NOTE_INSN_EH_REGION_BEG
:
700 case NOTE_INSN_EH_REGION_END
:
701 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
704 case NOTE_INSN_BLOCK_BEG
:
705 case NOTE_INSN_BLOCK_END
:
706 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
709 case NOTE_INSN_BASIC_BLOCK
:
710 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
713 case NOTE_INSN_DELETED_LABEL
:
714 case NOTE_INSN_DELETED_DEBUG_LABEL
:
716 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
719 pp_printf (pp
, " (\"%s\")", label
);
723 case NOTE_INSN_VAR_LOCATION
:
724 case NOTE_INSN_CALL_ARG_LOCATION
:
726 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
740 /* Pretty-print a slim dump of X (an insn) to PP, including any register
741 note attached to the instruction. */
744 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
746 pp_string (pp
, print_rtx_head
);
747 print_insn (pp
, x
, 1);
749 if (INSN_P (x
) && REG_NOTES (x
))
750 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
752 pp_printf (pp
, "%s %s ", print_rtx_head
,
753 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
754 print_pattern (pp
, XEXP (note
, 0), 1);
759 /* Print X, an RTL value node, to file F in slim format. Include
760 additional information if VERBOSE is nonzero.
762 Value nodes are constants, registers, labels, symbols and
766 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
768 pretty_printer rtl_slim_pp
;
769 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
770 rtl_slim_pp
.buffer
->stream
= f
;
771 print_value (&rtl_slim_pp
, x
, verbose
);
772 pp_flush (&rtl_slim_pp
);
775 /* Emit a slim dump of X (an insn) to the file F, including any register
776 note attached to the instruction. */
778 dump_insn_slim (FILE *f
, const_rtx x
)
780 pretty_printer rtl_slim_pp
;
781 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
782 rtl_slim_pp
.buffer
->stream
= f
;
783 print_insn_with_notes (&rtl_slim_pp
, x
);
784 pp_flush (&rtl_slim_pp
);
787 /* Same as above, but stop at LAST or when COUNT == 0.
788 If COUNT < 0 it will stop only at LAST or NULL rtx. */
791 dump_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
792 int count
, int flags ATTRIBUTE_UNUSED
)
794 const_rtx insn
, tail
;
795 pretty_printer rtl_slim_pp
;
796 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
797 rtl_slim_pp
.buffer
->stream
= f
;
799 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
801 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
802 insn
= NEXT_INSN (insn
))
804 print_insn_with_notes (&rtl_slim_pp
, insn
);
809 pp_flush (&rtl_slim_pp
);
812 /* Dumps basic block BB to pretty-printer PP in slim form and without and
813 no indentation, for use as a label of a DOT graph record-node. */
816 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
821 /* TODO: inter-bb stuff. */
822 FOR_BB_INSNS (bb
, insn
)
827 pp_write_text_to_stream (pp
);
830 print_insn_with_notes (pp
, insn
);
831 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
835 /* Pretty-print pattern X of some insn in non-verbose mode.
836 Return a string pointer to the pretty-printer buffer.
838 This function is only exported exists only to accommodate some older users
839 of the slim RTL pretty printers. Please do not use it for new code. */
842 str_pattern_slim (const_rtx x
)
844 pretty_printer rtl_slim_pp
;
845 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
846 print_pattern (&rtl_slim_pp
, x
, 0);
847 return ggc_strdup (pp_formatted_text (&rtl_slim_pp
));
850 /* Emit a slim dump of X (an insn) to stderr. */
851 extern void debug_insn_slim (const_rtx
);
853 debug_insn_slim (const_rtx x
)
855 dump_insn_slim (stderr
, x
);
858 /* Same as above, but using dump_rtl_slim. */
859 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
861 debug_rtl_slim (const_rtx first
, const_rtx last
, int count
, int flags
)
863 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
866 extern void debug_bb_slim (basic_block
);
868 debug_bb_slim (basic_block bb
)
870 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
873 extern void debug_bb_n_slim (int);
875 debug_bb_n_slim (int n
)
877 basic_block bb
= BASIC_BLOCK (n
);