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 /* This recognizes rtx'en classified as expressions. These are always
55 represent some action on values or results of other expression, that
56 may be stored in objects representing values. */
59 print_exp (pretty_printer
*pp
, const_rtx x
, int verbose
)
67 for (i
= 0; i
< 4; i
++)
77 if (CONST_INT_P (XEXP (x
, 1))
78 && INTVAL (XEXP (x
, 1)) < 0)
81 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
238 fun
= (verbose
) ? "sign_extract" : "sxt";
244 fun
= (verbose
) ? "zero_extract" : "zxt";
250 fun
= (verbose
) ? "sign_extend" : "sxn";
254 fun
= (verbose
) ? "zero_extend" : "zxn";
258 fun
= (verbose
) ? "float_extend" : "fxn";
262 fun
= (verbose
) ? "trunc" : "trn";
266 fun
= (verbose
) ? "float_trunc" : "ftr";
270 fun
= (verbose
) ? "float" : "flt";
274 fun
= (verbose
) ? "uns_float" : "ufl";
282 fun
= (verbose
) ? "uns_fix" : "ufx";
303 op
[0] = XEXP (XEXP (x
, 1), 0);
305 op
[1] = XEXP (XEXP (x
, 1), 1);
309 op
[0] = XEXP (XEXP (x
, 1), 0);
311 op
[1] = XEXP (XEXP (x
, 1), 1);
333 op
[0] = TRAP_CONDITION (x
);
342 case UNSPEC_VOLATILE
:
344 pp_string (pp
, "unspec");
345 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
346 pp_string (pp
, "/v");
347 pp_character (pp
, '[');
348 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
351 pp_character (pp
, ',');
352 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
354 pp_string (pp
, "] ");
355 pp_decimal_int (pp
, XINT (x
, 1));
360 /* Most unhandled codes can be printed as pseudo-functions. */
361 if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_UNARY
)
363 fun
= GET_RTX_NAME (GET_CODE (x
));
366 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMPARE
367 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_COMPARE
368 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_BIN_ARITH
369 || GET_RTX_CLASS (GET_CODE (x
)) == RTX_COMM_ARITH
)
371 fun
= GET_RTX_NAME (GET_CODE (x
));
375 else if (GET_RTX_CLASS (GET_CODE (x
)) == RTX_TERNARY
)
377 fun
= GET_RTX_NAME (GET_CODE (x
));
383 /* Give up, just print the RTX name. */
384 st
[0] = GET_RTX_NAME (GET_CODE (x
));
389 /* Print this as a function? */
393 pp_character (pp
, '(');
396 for (i
= 0; i
< 4; i
++)
399 pp_string (pp
, st
[i
]);
404 pp_character (pp
, ',');
405 print_value (pp
, op
[i
], verbose
);
410 pp_character (pp
, ')');
413 /* Prints rtxes, I customarily classified as values. They're constants,
414 registers, labels, symbols and memory accesses. */
417 print_value (pretty_printer
*pp
, const_rtx x
, int verbose
)
423 pp_string (pp
, "(nil)");
426 switch (GET_CODE (x
))
429 pp_scalar (pp
, HOST_WIDE_INT_PRINT_HEX
,
430 (unsigned HOST_WIDE_INT
) INTVAL (x
));
433 if (FLOAT_MODE_P (GET_MODE (x
)))
435 real_to_decimal (tmp
, CONST_DOUBLE_REAL_VALUE (x
),
440 pp_printf (pp
, "<%wx,%wx>",
441 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
442 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
445 fixed_to_decimal (tmp
, CONST_FIXED_VALUE (x
), sizeof (tmp
));
449 pp_printf (pp
, "\"%s\"", XSTR (x
, 0));
452 pp_printf (pp
, "`%s'", XSTR (x
, 0));
455 pp_printf (pp
, "L%d", INSN_UID (XEXP (x
, 0)));
459 case STRICT_LOW_PART
:
460 pp_printf (pp
, "%s(", GET_RTX_NAME (GET_CODE (x
)));
461 print_value (pp
, XEXP (x
, 0), verbose
);
462 pp_character (pp
, ')');
465 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
467 if (ISDIGIT (reg_names
[REGNO (x
)][0]))
468 pp_character (pp
, '%');
469 pp_string (pp
, reg_names
[REGNO (x
)]);
472 pp_printf (pp
, "r%d", REGNO (x
));
474 pp_printf (pp
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
477 print_value (pp
, SUBREG_REG (x
), verbose
);
478 pp_printf (pp
, "#%d", SUBREG_BYTE (x
));
483 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
486 pp_character (pp
, '[');
487 print_value (pp
, XEXP (x
, 0), verbose
);
488 pp_character (pp
, ']');
491 pp_printf (pp
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
494 print_exp (pp
, x
, verbose
);
499 /* The next step in insn detalization, its pattern recognition. */
502 print_pattern (pretty_printer
*pp
, const_rtx x
, int verbose
)
506 pp_string (pp
, "(nil)");
510 switch (GET_CODE (x
))
513 print_value (pp
, SET_DEST (x
), verbose
);
514 pp_character (pp
, '=');
515 print_value (pp
, SET_SRC (x
), verbose
);
520 pp_string (pp
, GET_RTX_NAME (GET_CODE (x
)));
523 print_exp (pp
, x
, verbose
);
527 pp_printf (pp
, "%s ", GET_RTX_NAME (GET_CODE (x
)));
528 print_value (pp
, XEXP (x
, 0), verbose
);
531 pp_string (pp
, "loc ");
532 print_value (pp
, PAT_VAR_LOCATION_LOC (x
), verbose
);
535 pp_character (pp
, '(');
536 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
537 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
538 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
539 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
540 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
542 pp_character (pp
, '!');
543 print_value (pp
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
546 print_value (pp
, COND_EXEC_TEST (x
), verbose
);
547 pp_string (pp
, ") ");
548 print_pattern (pp
, COND_EXEC_CODE (x
), verbose
);
554 pp_character (pp
, '{');
555 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
557 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
558 pp_character (pp
, ';');
560 pp_character (pp
, '}');
567 pp_string (pp
, "sequence{");
568 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
570 print_pattern (pp
, XVECEXP (x
, 0, i
), verbose
);
571 pp_character (pp
, ';');
573 pp_character (pp
, '}');
577 pp_printf (pp
, "asm {%s}", XSTR (x
, 0));
582 print_value (pp
, XEXP (x
, 0), verbose
);
585 pp_string (pp
, "trap_if ");
586 print_value (pp
, TRAP_CONDITION (x
), verbose
);
589 case UNSPEC_VOLATILE
:
590 /* Fallthru -- leave UNSPECs to print_exp. */
592 print_value (pp
, x
, verbose
);
594 } /* print_pattern */
596 /* This is the main function in slim rtl visualization mechanism.
598 X is an insn, to be printed into PP.
600 This function tries to print it properly in human-readable form,
601 resembling assembler mnemonics (instead of the older Lisp-style
604 If VERBOSE is TRUE, insns are printed with more complete (but
605 longer) pattern names and with extra information, and prefixed
606 with their INSN_UIDs. */
609 print_insn (pretty_printer
*pp
, const_rtx x
, int verbose
)
613 /* Blech, pretty-print can't print integers with a specified width. */
615 snprintf (uid_prefix
, sizeof uid_prefix
, " %4d: ", INSN_UID (x
));
616 pp_string (pp
, uid_prefix
);
619 switch (GET_CODE (x
))
622 print_pattern (pp
, PATTERN (x
), verbose
);
627 const char *name
= "?";
629 if (DECL_P (INSN_VAR_LOCATION_DECL (x
)))
631 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (x
));
634 name
= IDENTIFIER_POINTER (id
);
635 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (x
))
638 sprintf (idbuf
, "D#%i",
639 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (x
)));
644 sprintf (idbuf
, "D.%i",
645 DECL_UID (INSN_VAR_LOCATION_DECL (x
)));
649 pp_printf (pp
, "debug %s => ", name
);
650 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (x
)))
651 pp_string (pp
, "optimized away");
653 print_pattern (pp
, INSN_VAR_LOCATION_LOC (x
), verbose
);
658 print_pattern (pp
, PATTERN (x
), verbose
);
661 if (GET_CODE (PATTERN (x
)) == PARALLEL
)
662 print_pattern (pp
, XVECEXP (PATTERN (x
), 0, 0), verbose
);
664 print_pattern (pp
, PATTERN (x
), verbose
);
667 pp_printf (pp
, "L%d:", INSN_UID (x
));
669 case JUMP_TABLE_DATA
:
670 pp_string (pp
, "jump_table_data{\n");
671 print_pattern (pp
, PATTERN (x
), verbose
);
675 pp_string (pp
, "barrier");
679 pp_string (pp
, GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
680 switch (NOTE_KIND (x
))
682 case NOTE_INSN_EH_REGION_BEG
:
683 case NOTE_INSN_EH_REGION_END
:
684 pp_printf (pp
, " %d", NOTE_EH_HANDLER (x
));
687 case NOTE_INSN_BLOCK_BEG
:
688 case NOTE_INSN_BLOCK_END
:
689 pp_printf (pp
, " %d", BLOCK_NUMBER (NOTE_BLOCK (x
)));
692 case NOTE_INSN_BASIC_BLOCK
:
693 pp_printf (pp
, " %d", NOTE_BASIC_BLOCK (x
)->index
);
696 case NOTE_INSN_DELETED_LABEL
:
697 case NOTE_INSN_DELETED_DEBUG_LABEL
:
699 const char *label
= NOTE_DELETED_LABEL_NAME (x
);
702 pp_printf (pp
, " (\"%s\")", label
);
706 case NOTE_INSN_VAR_LOCATION
:
707 case NOTE_INSN_CALL_ARG_LOCATION
:
708 pp_character (pp
, '{');
709 print_pattern (pp
, NOTE_VAR_LOCATION (x
), verbose
);
710 pp_character (pp
, '}');
723 /* Pretty-print a slim dump of X (an insn) to PP, including any register
724 note attached to the instruction. */
727 print_insn_with_notes (pretty_printer
*pp
, const_rtx x
)
729 pp_string (pp
, print_rtx_head
);
730 print_insn (pp
, x
, 1);
732 if (INSN_P (x
) && REG_NOTES (x
))
733 for (rtx note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
735 pp_printf (pp
, "%s %s ", print_rtx_head
,
736 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)));
737 print_pattern (pp
, XEXP (note
, 0), 1);
742 /* Return a pretty-print buffer set up to print to file F. */
744 static pretty_printer
*
745 init_rtl_slim_pretty_print (FILE *f
)
747 if (! rtl_slim_pp_initialized
)
749 pp_construct (&rtl_slim_pp
, /*prefix=*/NULL
, /*linewidth=*/0);
750 rtl_slim_pp_initialized
= true;
753 /* Clean out any data that str_insn_slim may have left here. */
754 pp_clear_output_area (&rtl_slim_pp
);
756 rtl_slim_pp
.buffer
->stream
= f
;
760 /* Print X, an RTL value node, to file F in slim format. Include
761 additional information if VERBOSE is nonzero.
763 Value nodes are constants, registers, labels, symbols and
767 dump_value_slim (FILE *f
, const_rtx x
, int verbose
)
769 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
770 print_value (pp
, x
, verbose
);
774 /* Emit a slim dump of X (an insn) to the file F, including any register
775 note attached to the instruction. */
777 dump_insn_slim (FILE *f
, const_rtx x
)
779 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
780 print_insn_with_notes (pp
, x
);
784 /* Same as above, but stop at LAST or when COUNT == 0.
785 If COUNT < 0 it will stop only at LAST or NULL rtx. */
788 dump_rtl_slim (FILE *f
, const_rtx first
, const_rtx last
,
789 int count
, int flags ATTRIBUTE_UNUSED
)
791 const_rtx insn
, tail
;
792 pretty_printer
*pp
= init_rtl_slim_pretty_print (f
);
794 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
796 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
797 insn
= NEXT_INSN (insn
))
799 print_insn_with_notes (pp
, insn
);
807 /* Dumps basic block BB to pretty-printer PP in slim form and without and
808 no indentation, for use as a label of a DOT graph record-node. */
811 rtl_dump_bb_for_graph (pretty_printer
*pp
, basic_block bb
)
816 /* TODO: inter-bb stuff. */
817 FOR_BB_INSNS (bb
, insn
)
821 pp_character (pp
, '|');
822 pp_write_text_to_stream (pp
);
825 print_insn_with_notes (pp
, insn
);
826 pp_write_text_as_dot_label_to_stream (pp
, /*for_record=*/true);
830 /* Pretty-print pattern X of some insn in non-verbose mode.
831 Return a string pointer to the pretty-printer buffer.
833 This function is only exported exists only to accommodate some older users
834 of the slim RTL pretty printers. Please do not use it for new code. */
837 str_pattern_slim (const_rtx x
)
839 pretty_printer
*pp
= init_rtl_slim_pretty_print (NULL
);
840 print_pattern (pp
, x
, 0);
841 return pp_base_formatted_text (pp
);
844 /* Emit a slim dump of X (an insn) to stderr. */
845 extern void debug_insn_slim (const_rtx
);
847 debug_insn_slim (const_rtx x
)
849 dump_insn_slim (stderr
, x
);
852 /* Same as above, but using dump_rtl_slim. */
853 extern void debug_rtl_slim (FILE *, const_rtx
, const_rtx
, int, int);
855 debug_rtl_slim (const_rtx first
, const_rtx last
, int count
, int flags
)
857 dump_rtl_slim (stderr
, first
, last
, count
, flags
);
860 extern void debug_bb_slim (basic_block
);
862 debug_bb_slim (basic_block bb
)
864 dump_bb (stderr
, bb
, 0, TDF_SLIM
| TDF_BLOCKS
);
867 extern void debug_bb_n_slim (int);
869 debug_bb_n_slim (int n
)
871 basic_block bb
= BASIC_BLOCK (n
);