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 sprintf (buf
, "simple_return");
561 print_exp (buf
, x
, verbose
);
564 print_value (t1
, XEXP (x
, 0), verbose
);
565 sprintf (buf
, "clobber %s", t1
);
568 print_value (t1
, XEXP (x
, 0), verbose
);
569 sprintf (buf
, "use %s", t1
);
572 print_value (t1
, PAT_VAR_LOCATION_LOC (x
), verbose
);
573 sprintf (buf
, "loc %s", t1
);
576 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
577 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
578 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
579 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
580 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
583 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
586 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
587 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
588 sprintf (buf
, "(%s) %s", t1
, t2
);
595 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
597 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
598 sprintf (t3
, "%s%s;", t1
, t2
);
601 sprintf (buf
, "%s}", t1
);
605 /* Should never see SEQUENCE codes until after reorg. */
608 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
613 print_value (buf
, XEXP (x
, 0), verbose
);
616 print_value (t1
, TRAP_CONDITION (x
), verbose
);
617 sprintf (buf
, "trap_if %s", t1
);
623 sprintf (t1
, "unspec{");
624 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
626 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
627 sprintf (t3
, "%s%s;", t1
, t2
);
630 sprintf (buf
, "%s}", t1
);
633 case UNSPEC_VOLATILE
:
637 sprintf (t1
, "unspec/v{");
638 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
640 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
641 sprintf (t3
, "%s%s;", t1
, t2
);
644 sprintf (buf
, "%s}", t1
);
648 print_value (buf
, x
, verbose
);
650 } /* print_pattern */
652 /* This is the main function in rtl visualization mechanism. It
653 accepts an rtx and tries to recognize it as an insn, then prints it
654 properly in human readable form, resembling assembler mnemonics.
655 For every insn it prints its UID and BB the insn belongs too.
656 (Probably the last "option" should be extended somehow, since it
657 depends now on sched.c inner variables ...) */
660 print_insn (char *buf
, const_rtx x
, int verbose
)
665 switch (GET_CODE (x
))
668 print_pattern (t
, PATTERN (x
), verbose
);
669 #ifdef INSN_SCHEDULING
670 if (verbose
&& current_sched_info
)
671 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
675 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
680 const char *name
= "?";
682 if (DECL_P (INSN_VAR_LOCATION_DECL (insn
)))
684 tree id
= DECL_NAME (INSN_VAR_LOCATION_DECL (insn
));
687 name
= IDENTIFIER_POINTER (id
);
688 else if (TREE_CODE (INSN_VAR_LOCATION_DECL (insn
))
691 sprintf (idbuf
, "D#%i",
692 DEBUG_TEMP_UID (INSN_VAR_LOCATION_DECL (insn
)));
697 sprintf (idbuf
, "D.%i",
698 DECL_UID (INSN_VAR_LOCATION_DECL (insn
)));
702 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn
)))
703 sprintf (buf
, " %4d: debug %s optimized away", INSN_UID (insn
), name
);
706 print_pattern (t
, INSN_VAR_LOCATION_LOC (insn
), verbose
);
707 sprintf (buf
, " %4d: debug %s => %s", INSN_UID (insn
), name
, t
);
713 print_pattern (t
, PATTERN (x
), verbose
);
714 #ifdef INSN_SCHEDULING
715 if (verbose
&& current_sched_info
)
716 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
720 sprintf (buf
, " %4d %s", INSN_UID (x
), t
);
724 if (GET_CODE (x
) == PARALLEL
)
726 x
= XVECEXP (x
, 0, 0);
727 print_pattern (t
, x
, verbose
);
730 strcpy (t
, "call <...>");
731 #ifdef INSN_SCHEDULING
732 if (verbose
&& current_sched_info
)
733 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (insn
, 1), t
);
736 sprintf (buf
, " %4d %s", INSN_UID (insn
), t
);
739 sprintf (buf
, "L%d:", INSN_UID (x
));
742 sprintf (buf
, "i%4d: barrier", INSN_UID (x
));
745 sprintf (buf
, " %4d %s", INSN_UID (x
),
746 GET_NOTE_INSN_NAME (NOTE_KIND (x
)));
749 sprintf (buf
, "i%4d <What %s?>", INSN_UID (x
),
750 GET_RTX_NAME (GET_CODE (x
)));
754 /* Emit a slim dump of X (an insn) to the file F, including any register
755 note attached to the instruction. */
757 dump_insn_slim (FILE *f
, rtx x
)
759 char t
[BUF_LEN
+ 32];
762 print_insn (t
, x
, 1);
765 if (INSN_P (x
) && REG_NOTES (x
))
766 for (note
= REG_NOTES (x
); note
; note
= XEXP (note
, 1))
768 print_value (t
, XEXP (note
, 0), 1);
769 fprintf (f
, " %s: %s\n",
770 GET_REG_NOTE_NAME (REG_NOTE_KIND (note
)), t
);
774 /* Emit a slim dump of X (an insn) to stderr. */
776 debug_insn_slim (rtx x
)
778 dump_insn_slim (stderr
, x
);
781 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
782 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
783 include more information on the basic blocks. */
785 print_rtl_slim_with_bb (FILE *f
, rtx first
, int flags
)
787 print_rtl_slim (f
, first
, NULL
, -1, flags
);
790 /* Same as above, but stop at LAST or when COUNT == 0.
791 If COUNT < 0 it will stop only at LAST or NULL rtx. */
793 print_rtl_slim (FILE *f
, rtx first
, rtx last
, int count
, int flags
)
795 basic_block current_bb
= NULL
;
798 tail
= last
? NEXT_INSN (last
) : NULL_RTX
;
800 (insn
!= NULL
) && (insn
!= tail
) && (count
!= 0);
801 insn
= NEXT_INSN (insn
))
803 if ((flags
& TDF_BLOCKS
)
804 && (INSN_P (insn
) || NOTE_P (insn
))
805 && BLOCK_FOR_INSN (insn
)
808 current_bb
= BLOCK_FOR_INSN (insn
);
809 dump_bb_info (current_bb
, true, false, flags
, ";; ", f
);
812 dump_insn_slim (f
, insn
);
814 if ((flags
& TDF_BLOCKS
)
816 && insn
== BB_END (current_bb
))
818 dump_bb_info (current_bb
, false, true, flags
, ";; ", f
);
827 debug_bb_slim (struct basic_block_def
*bb
)
829 print_rtl_slim (stderr
, BB_HEAD (bb
), BB_END (bb
), -1, 32);
833 debug_bb_n_slim (int n
)
835 struct basic_block_def
*bb
= BASIC_BLOCK (n
);