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 /* A pretty-printer for slim rtl printing. */
51 static bool rtl_slim_pp_initialized
= false;
52 static pretty_printer rtl_slim_pp
;
54 /* For insns we print patterns, and for some patterns we print insns... */
55 static void print_insn_with_notes (pretty_printer
*, const_rtx
);
57 /* This recognizes rtx'en classified as expressions. These are always
58 represent some action on values or results of other expression, that
59 may be stored in objects representing values. */
62 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
70 for (i
= 0; i
< 4; i
++)
80 if (CONST_INT_P (XEXP (x
, 1))
81 && INTVAL (XEXP (x
, 1)) < 0)
84 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
241 fun
= (verbose
) ? "sign_extract" : "sxt";
247 fun
= (verbose
) ? "zero_extract" : "zxt";
253 fun
= (verbose
) ? "sign_extend" : "sxn";
257 fun
= (verbose
) ? "zero_extend" : "zxn";
261 fun
= (verbose
) ? "float_extend" : "fxn";
265 fun
= (verbose
) ? "trunc" : "trn";
269 fun
= (verbose
) ? "float_trunc" : "ftr";
273 fun
= (verbose
) ? "float" : "flt";
277 fun
= (verbose
) ? "uns_float" : "ufl";
285 fun
= (verbose
) ? "uns_fix" : "ufx";
306 op
[0] = XEXP (XEXP (x
, 1), 0);
308 op
[1] = XEXP (XEXP (x
, 1), 1);
312 op
[0] = XEXP (XEXP (x
, 1), 0);
314 op
[1] = XEXP (XEXP (x
, 1), 1);
336 op
[0] = TRAP_CONDITION (x
);
345 case UNSPEC_VOLATILE
:
347 pp_string (pp
, "unspec");
348 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
349 pp_string (pp
, "/v");
350 pp_left_bracket (pp
);
351 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
355 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
357 pp_string (pp
, "] ");
358 pp_decimal_int (pp
, XINT (x
, 1));
363 /* Most unhandled codes can be printed as pseudo-functions. */
364 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
366 fun
= GET_RTX_NAME (GET_CODE (x
));
369 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
370 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
371 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
372 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
374 fun
= GET_RTX_NAME (GET_CODE (x
));
378 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
380 fun
= GET_RTX_NAME (GET_CODE (x
));
386 /* Give up, just print the RTX name. */
387 st
[0] = GET_RTX_NAME (GET_CODE (x
));
392 /* Print this as a function? */
399 for (i
= 0; i
< 4; i
++)
402 pp_string (pp
, st
[i
]);
408 print_value (pp
, op
[i
], verbose
);
416 /* Prints rtxes, I customarily classified as values. They're constants,
417 registers, labels, symbols and memory accesses. */
420 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
426 pp_string (pp
, "(nil)");
429 switch (GET_CODE (x
))
432 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
433 (unsigned HOST_WIDE_INT
) INTVAL (x
));
436 if (FLOAT_MODE_P (GET_MODE (x
)))
438 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
443 pp_printf (pp
, "<%wx,%wx>",
444 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
445 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
448 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
452 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
455 pp_printf (pp
, "`%s'", XSTR (x
, 0));
458 pp_printf (pp
, "L%d", INSN_UID (XEXP (x
, 0)));
462 case STRICT_LOW_PART
:
463 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
464 print_value (pp
, XEXP (x
, 0), verbose
);
468 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
470 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
472 pp_string (pp
, reg_names
[REGNO (x
)]);
475 pp_printf (pp
, "r%d", REGNO (x
));
477 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
480 print_value (pp
, SUBREG_REG (x
), verbose
);
481 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
486 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
489 pp_left_bracket (pp
);
490 print_value (pp
, XEXP (x
, 0), verbose
);
491 pp_right_bracket (pp
);
494 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
497 print_exp (pp
, x
, verbose
);
502 /* The next step in insn detalization, its pattern recognition. */
505 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
509 pp_string (pp
, "(nil)");
513 switch (GET_CODE (x
))
516 print_value (pp
, SET_DEST (x
), verbose
);
518 print_value (pp
, SET_SRC (x
), verbose
);
523 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
526 print_exp (pp
, x
, verbose
);
530 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
531 print_value (pp
, XEXP (x
, 0), verbose
);
534 pp_string (pp
, "loc ");
535 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
539 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
540 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
541 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
542 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
543 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
546 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
549 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
550 pp_string (pp
, ") ");
551 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
558 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
560 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
568 pp_string (pp
, "sequence{");
569 if (INSN_P (XVECEXP (x
, 0, 0)))
571 /* Print the sequence insns indented. */
572 const char * save_print_rtx_head
= print_rtx_head
;
573 char indented_print_rtx_head
[32];
576 gcc_assert (strlen (print_rtx_head
) < sizeof (indented_print_rtx_head
) - 4);
577 snprintf (indented_print_rtx_head
,
578 sizeof (indented_print_rtx_head
),
579 "%s ", print_rtx_head
);
580 print_rtx_head
= indented_print_rtx_head
;
581 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
582 print_insn_with_notes (pp
, XVECEXP (x
, 0, i
));
583 pp_printf (pp
, "%s ", save_print_rtx_head
);
584 print_rtx_head
= save_print_rtx_head
;
588 for (int i
= 0; i
< XVECLEN (x
, 0); i
++)
590 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
598 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
603 print_value (pp
, XEXP (x
, 0), verbose
);
606 pp_string (pp
, "trap_if ");
607 print_value (pp
, TRAP_CONDITION (x
), verbose
);
610 case UNSPEC_VOLATILE
:
611 /* Fallthru -- leave UNSPECs to print_exp. */
613 print_value (pp
, x
, verbose
);
615 } /* print_pattern */
617 /* This is the main function in slim rtl visualization mechanism.
619 X is an insn, to be printed into PP.
621 This function tries to print it properly in human-readable form,
622 resembling assembler mnemonics (instead of the older Lisp-style
625 If VERBOSE is TRUE, insns are printed with more complete (but
626 longer) pattern names and with extra information, and prefixed
627 with their INSN_UIDs. */
630 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
634 /* Blech, pretty-print can't print integers with a specified width. */
636 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
637 pp_string (pp
, uid_prefix
);
640 switch (GET_CODE (x
))
643 print_pattern (pp
, PATTERN (x
), verbose
);
648 const char *name
= "?";
650 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
652 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
655 name
= IDENTIFIER_POINTER (id
);
656 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
659 sprintf (idbuf
, "D#%i",
660 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
665 sprintf (idbuf
, "D.%i",
666 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
670 pp_printf (pp
, "debug %s => ", name
);
671 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
672 pp_string (pp
, "optimized away");
674 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
679 print_pattern (pp
, PATTERN (x
), verbose
);
682 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
683 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
685 print_pattern (pp
, PATTERN (x
), verbose
);
688 pp_printf (pp
, "L%d:", INSN_UID (x
));
690 case JUMP_TABLE_DATA
:
691 pp_string (pp
, "jump_table_data{\n");
692 print_pattern (pp
, PATTERN (x
), verbose
);
696 pp_string (pp
, "barrier");
700 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
701 switch (NOTE_KIND (x
))
703 case NOTE_INSN_EH_REGION_BEG
:
704 case NOTE_INSN_EH_REGION_END
:
705 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
708 case NOTE_INSN_BLOCK_BEG
:
709 case NOTE_INSN_BLOCK_END
:
710 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
713 case NOTE_INSN_BASIC_BLOCK
:
714 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
717 case NOTE_INSN_DELETED_LABEL
:
718 case NOTE_INSN_DELETED_DEBUG_LABEL
:
720 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
723 pp_printf (pp
, " (\"%s\")", label
);
727 case NOTE_INSN_VAR_LOCATION
:
728 case NOTE_INSN_CALL_ARG_LOCATION
:
730 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
744 /* Pretty-print a slim dump of X (an insn) to PP, including any register
745 note attached to the instruction. */
748 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
750 pp_string (pp
, print_rtx_head
);
751 print_insn (pp
, x
, 1);
753 if (INSN_P (x
) && REG_NOTES (x
))
754 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
756 pp_printf (pp
, "%s %s ", print_rtx_head
,
757 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
758 print_pattern (pp
, XEXP (note
, 0), 1);
763 /* Return a pretty-print buffer set up to print to file F. */
765 static pretty_printer
*
766 init_rtl_slim_pretty_print (FILE *f
)
768 if (! rtl_slim_pp_initialized
)
770 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
771 rtl_slim_pp_initialized
= true;
774 /* Clean out any data that str_insn_slim may have left here. */
775 pp_clear_output_area (&rtl_slim_pp
);
777 rtl_slim_pp
.buffer
->stream
= f
;
781 /* Print X, an RTL value node, to file F in slim format. Include
782 additional information if VERBOSE is nonzero.
784 Value nodes are constants, registers, labels, symbols and
788 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
790 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
791 print_value (pp
, x
, verbose
);
795 /* Emit a slim dump of X (an insn) to the file F, including any register
796 note attached to the instruction. */
798 dump_insn_slim (FILE *f
, const_rtx x
)
800 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
801 print_insn_with_notes (pp
, x
);
805 /* Same as above, but stop at LAST or when COUNT == 0.
806 If COUNT < 0 it will stop only at LAST or NULL rtx. */
809 dump_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
810 int count
, int flags ATTRIBUTE_UNUSED
)
812 const_rtx insn
, tail
;
813 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
815 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
817 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
818 insn
= NEXT_INSN (insn
))
820 print_insn_with_notes (pp
, insn
);
828 /* Dumps basic block BB to pretty-printer PP in slim form and without and
829 no indentation, for use as a label of a DOT graph record-node. */
832 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
837 /* TODO: inter-bb stuff. */
838 FOR_BB_INSNS (bb
, insn
)
843 pp_write_text_to_stream (pp
);
846 print_insn_with_notes (pp
, insn
);
847 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
851 /* Pretty-print pattern X of some insn in non-verbose mode.
852 Return a string pointer to the pretty-printer buffer.
854 This function is only exported exists only to accommodate some older users
855 of the slim RTL pretty printers. Please do not use it for new code. */
858 str_pattern_slim (const_rtx x
)
860 pretty_printer
*pp
= init_rtl_slim_pretty_print (NULL
);
861 print_pattern (pp
, x
, 0);
862 return pp_base_formatted_text (pp
);
865 /* Emit a slim dump of X (an insn) to stderr. */
866 extern void debug_insn_slim (const_rtx
);
868 debug_insn_slim (const_rtx x
)
870 dump_insn_slim (stderr
, x
);
873 /* Same as above, but using dump_rtl_slim. */
874 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
876 debug_rtl_slim (const_rtx first
, const_rtx last
, int count
, int flags
)
878 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
881 extern void debug_bb_slim (basic_block
);
883 debug_bb_slim (basic_block bb
)
885 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
888 extern void debug_bb_n_slim (int);
890 debug_bb_n_slim (int n
)
892 basic_block bb
= BASIC_BLOCK (n
);