1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
4 Free Software Foundation, Inc.
5 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
6 and currently maintained by, Jim Wilson (wilson@cygnus.com)
8 This file is part of GCC.
10 GCC is free software; you can redistribute it and/or modify it under
11 the terms of the GNU General Public License as published by the Free
12 Software Foundation; either version 3, or (at your option) any later
15 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16 WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 You should have received a copy of the GNU General Public License
21 along with GCC; see the file COPYING3. If not see
22 <http://www.gnu.org/licenses/>. */
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "insn-attr.h"
33 #include "sched-int.h"
34 #include "tree-pass.h"
36 static char *safe_concat (char *, char *, const char *);
41 safe_concat (char *buf
, char *cur
, const char *str
)
43 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
52 while (cur
< end
&& (c
= *str
++) != '\0')
59 /* This recognizes rtx, I classified as expressions. These are always
60 represent some action on values or results of other expression, that
61 may be stored in objects representing values. */
64 print_exp (char *buf
, const_rtx x
, int verbose
)
69 const char *fun
= (char *) 0;
74 for (i
= 0; i
< 4; i
++)
84 if (CONST_INT_P (XEXP (x
, 1))
85 && INTVAL (XEXP (x
, 1)) < 0)
88 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
268 fun
= (verbose
) ? "sign_extract" : "sxt";
274 fun
= (verbose
) ? "zero_extract" : "zxt";
280 fun
= (verbose
) ? "sign_extend" : "sxn";
284 fun
= (verbose
) ? "zero_extend" : "zxn";
288 fun
= (verbose
) ? "float_extend" : "fxn";
292 fun
= (verbose
) ? "trunc" : "trn";
296 fun
= (verbose
) ? "float_trunc" : "ftr";
300 fun
= (verbose
) ? "float" : "flt";
304 fun
= (verbose
) ? "uns_float" : "ufl";
312 fun
= (verbose
) ? "uns_fix" : "ufx";
333 op
[0] = XEXP (XEXP (x
, 1), 0);
335 op
[1] = XEXP (XEXP (x
, 1), 1);
339 op
[0] = XEXP (XEXP (x
, 1), 0);
341 op
[1] = XEXP (XEXP (x
, 1), 1);
363 op
[0] = TRAP_CONDITION (x
);
372 case UNSPEC_VOLATILE
:
374 cur
= safe_concat (buf
, cur
, "unspec");
375 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
376 cur
= safe_concat (buf
, cur
, "/v");
377 cur
= safe_concat (buf
, cur
, "[");
379 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
381 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
382 cur
= safe_concat (buf
, cur
, sep
);
383 cur
= safe_concat (buf
, cur
, tmp
);
386 cur
= safe_concat (buf
, cur
, "] ");
387 sprintf (tmp
, "%d", XINT (x
, 1));
388 cur
= safe_concat (buf
, cur
, tmp
);
392 /* If (verbose) debug_rtx (x); */
393 st
[0] = GET_RTX_NAME (GET_CODE (x
));
397 /* Print this as a function? */
400 cur
= safe_concat (buf
, cur
, fun
);
401 cur
= safe_concat (buf
, cur
, "(");
404 for (i
= 0; i
< 4; i
++)
407 cur
= safe_concat (buf
, cur
, st
[i
]);
412 cur
= safe_concat (buf
, cur
, ",");
414 print_value (tmp
, op
[i
], verbose
);
415 cur
= safe_concat (buf
, cur
, tmp
);
420 cur
= safe_concat (buf
, cur
, ")");
423 /* Prints rtxes, I customarily classified as values. They're constants,
424 registers, labels, symbols and memory accesses. */
427 print_value (char *buf
, const_rtx x
, int verbose
)
434 safe_concat (buf
, buf
, "(nil)");
437 switch (GET_CODE (x
))
440 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
,
441 (unsigned HOST_WIDE_INT
) INTVAL (x
));
442 cur
= safe_concat (buf
, cur
, t
);
445 if (FLOAT_MODE_P (GET_MODE (x
)))
446 real_to_decimal (t
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (t
), 0, 1);
449 "<" HOST_WIDE_INT_PRINT_HEX
"," HOST_WIDE_INT_PRINT_HEX
">",
450 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_LOW (x
),
451 (unsigned HOST_WIDE_INT
) CONST_DOUBLE_HIGH (x
));
452 cur
= safe_concat (buf
, cur
, t
);
455 fixed_to_decimal (t
, CONST_FIXED_VALUE (x
), sizeof (t
));
456 cur
= safe_concat (buf
, cur
, t
);
459 cur
= safe_concat (buf
, cur
, "\"");
460 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
461 cur
= safe_concat (buf
, cur
, "\"");
464 cur
= safe_concat (buf
, cur
, "`");
465 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
466 cur
= safe_concat (buf
, cur
, "'");
469 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
470 cur
= safe_concat (buf
, cur
, t
);
473 print_value (t
, XEXP (x
, 0), verbose
);
474 cur
= safe_concat (buf
, cur
, "const(");
475 cur
= safe_concat (buf
, cur
, t
);
476 cur
= safe_concat (buf
, cur
, ")");
479 print_value (t
, XEXP (x
, 0), verbose
);
480 cur
= safe_concat (buf
, cur
, "high(");
481 cur
= safe_concat (buf
, cur
, t
);
482 cur
= safe_concat (buf
, cur
, ")");
485 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
487 int c
= reg_names
[REGNO (x
)][0];
489 cur
= safe_concat (buf
, cur
, "%");
491 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
495 sprintf (t
, "r%d", REGNO (x
));
496 cur
= safe_concat (buf
, cur
, t
);
499 #ifdef INSN_SCHEDULING
500 && !current_sched_info
504 sprintf (t
, ":%s", GET_MODE_NAME (GET_MODE (x
)));
505 cur
= safe_concat (buf
, cur
, t
);
509 print_value (t
, SUBREG_REG (x
), verbose
);
510 cur
= safe_concat (buf
, cur
, t
);
511 sprintf (t
, "#%d", SUBREG_BYTE (x
));
512 cur
= safe_concat (buf
, cur
, t
);
515 cur
= safe_concat (buf
, cur
, "scratch");
518 cur
= safe_concat (buf
, cur
, "cc0");
521 cur
= safe_concat (buf
, cur
, "pc");
524 print_value (t
, XEXP (x
, 0), verbose
);
525 cur
= safe_concat (buf
, cur
, "[");
526 cur
= safe_concat (buf
, cur
, t
);
527 cur
= safe_concat (buf
, cur
, "]");
530 sprintf (t
, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x
)));
531 cur
= safe_concat (buf
, cur
, t
);
534 print_exp (t
, x
, verbose
);
535 cur
= safe_concat (buf
, cur
, t
);
540 /* The next step in insn detalization, its pattern recognition. */
543 print_pattern (char *buf
, const_rtx x
, int verbose
)
545 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
547 switch (GET_CODE (x
))
550 print_value (t1
, SET_DEST (x
), verbose
);
551 print_value (t2
, SET_SRC (x
), verbose
);
552 sprintf (buf
, "%s=%s", t1
, t2
);
555 sprintf (buf
, "return");
558 print_exp (buf
, x
, verbose
);
561 print_value (t1
, XEXP (x
, 0), verbose
);
562 sprintf (buf
, "clobber %s", t1
);
565 print_value (t1
, XEXP (x
, 0), verbose
);
566 sprintf (buf
, "use %s", t1
);
569 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
570 sprintf (buf
, "loc %s", t1
);
573 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
574 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
575 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
576 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
577 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
580 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
583 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
584 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
585 sprintf (buf
, "(%s) %s", t1
, t2
);
592 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
594 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
595 sprintf (t3
, "%s%s;", t1
, t2
);
598 sprintf (buf
, "%s}", t1
);
602 /* Should never see SEQUENCE codes until after reorg. */
605 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
610 print_value (buf
, XEXP (x
, 0), verbose
);
613 print_value (t1
, TRAP_CONDITION (x
), verbose
);
614 sprintf (buf
, "trap_if %s", t1
);
620 sprintf (t1
, "unspec{");
621 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
623 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
624 sprintf (t3
, "%s%s;", t1
, t2
);
627 sprintf (buf
, "%s}", t1
);
630 case UNSPEC_VOLATILE
:
634 sprintf (t1
, "unspec/v{");
635 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
637 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
638 sprintf (t3
, "%s%s;", t1
, t2
);
641 sprintf (buf
, "%s}", t1
);
645 print_value (buf
, x
, verbose
);
647 } /* print_pattern */
649 /* This is the main function in rtl visualization mechanism. It
650 accepts an rtx and tries to recognize it as an insn, then prints it
651 properly in human readable form, resembling assembler mnemonics.
652 For every insn it prints its UID and BB the insn belongs too.
653 (Probably the last "option" should be extended somehow, since it
654 depends now on sched.c inner variables ...) */
657 print_insn (char *buf
, const_rtx x
, int verbose
)
662 switch (GET_CODE (x
))
665 print_pattern (t
, PATTERN (x
), verbose
);
666 #ifdef INSN_SCHEDULING
667 if (verbose
&& current_sched_info
)
668 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
672 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
677 const char *name
= "?";
679 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
681 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
684 name
= IDENTIFIER_POINTER (id
);
685 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
688 sprintf (idbuf
, "D#%i",
689 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
694 sprintf (idbuf
, "D.%i",
695 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
699 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
700 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
703 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
704 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
710 print_pattern (t
, PATTERN (x
), verbose
);
711 #ifdef INSN_SCHEDULING
712 if (verbose
&& current_sched_info
)
713 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
717 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
721 if (GET_CODE (x
) == PARALLEL
)
723 x
= XVECEXP (x
, 0, 0);
724 print_pattern (t
, x
, verbose
);
727 strcpy (t
, "call <...>");
728 #ifdef INSN_SCHEDULING
729 if (verbose
&& current_sched_info
)
730 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (insn
, 1), t
);
733 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
736 sprintf (buf
, "L%d:", INSN_UID (x
));
739 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
742 sprintf (buf
, " %4d %s", INSN_UID (x
),
743 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
746 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
747 GET_RTX_NAME (GET_CODE (x
)));
751 /* Emit a slim dump of X (an insn) to the file F, including any register
752 note attached to the instruction. */
754 dump_insn_slim (FILE *f
, rtx x
)
756 char t
[BUF_LEN
+ 32];
759 print_insn (t
, x
, 1);
762 if (INSN_P (x
) && REG_NOTES (x
))
763 for (note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
765 print_value (t
, XEXP (note
, 0), 1);
766 fprintf (f
, " %s: %s\n",
767 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)), t
);
771 /* Emit a slim dump of X (an insn) to stderr. */
773 debug_insn_slim (rtx x
)
775 dump_insn_slim (stderr
, x
);
778 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
779 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
780 include more information on the basic blocks. */
782 print_rtl_slim_with_bb (FILE *f
, rtx first
, int flags
)
784 print_rtl_slim (f
, first
, NULL
, -1, flags
);
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. */
790 print_rtl_slim (FILE *f
, rtx first
, rtx last
, int count
, int flags
)
792 basic_block current_bb
= NULL
;
795 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
797 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
798 insn
= NEXT_INSN (insn
))
800 if ((flags
& TDF_BLOCKS
)
801 && (INSN_P (insn
) || NOTE_P (insn
))
802 && BLOCK_FOR_INSN (insn
)
805 current_bb
= BLOCK_FOR_INSN (insn
);
806 dump_bb_info (current_bb
, true, false, flags
, ";; ", f
);
809 dump_insn_slim (f
, insn
);
811 if ((flags
& TDF_BLOCKS
)
813 && insn
== BB_END (current_bb
))
815 dump_bb_info (current_bb
, false, true, flags
, ";; ", f
);
824 debug_bb_slim (struct basic_block_def
*bb
)
826 print_rtl_slim (stderr
, BB_HEAD (bb
), BB_END (bb
), -1, 32);
830 debug_bb_n_slim (int n
)
832 struct basic_block_def
*bb
= BASIC_BLOCK (n
);