1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5 and currently maintained by, Jim Wilson (wilson@cygnus.com)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #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)
432 switch (GET_CODE (x))
435 sprintf (t, HOST_WIDE_INT_PRINT_HEX,
436 (unsigned HOST_WIDE_INT) INTVAL (x));
437 cur = safe_concat (buf, cur, t);
440 if (FLOAT_MODE_P (GET_MODE (x)))
441 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
444 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
445 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
446 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
447 cur = safe_concat (buf, cur, t);
450 fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
451 cur = safe_concat (buf, cur, t);
454 cur = safe_concat (buf, cur, "\"");
455 cur = safe_concat (buf, cur, XSTR (x, 0));
456 cur = safe_concat (buf, cur, "\"");
459 cur = safe_concat (buf, cur, "`");
460 cur = safe_concat (buf, cur, XSTR (x, 0));
461 cur = safe_concat (buf, cur, "'");
464 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
465 cur = safe_concat (buf, cur, t);
468 print_value (t, XEXP (x, 0), verbose);
469 cur = safe_concat (buf, cur, "const(");
470 cur = safe_concat (buf, cur, t);
471 cur = safe_concat (buf, cur, ")");
474 print_value (t, XEXP (x, 0), verbose);
475 cur = safe_concat (buf, cur, "high(");
476 cur = safe_concat (buf, cur, t);
477 cur = safe_concat (buf, cur, ")");
480 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
482 int c = reg_names[REGNO (x)][0];
484 cur = safe_concat (buf, cur, "%");
486 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
490 sprintf (t, "r%d", REGNO (x));
491 cur = safe_concat (buf, cur, t);
494 #ifdef INSN_SCHEDULING
495 && !current_sched_info
499 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
500 cur = safe_concat (buf, cur, t);
504 print_value (t, SUBREG_REG (x), verbose);
505 cur = safe_concat (buf, cur, t);
506 sprintf (t, "#%d", SUBREG_BYTE (x));
507 cur = safe_concat (buf, cur, t);
510 cur = safe_concat (buf, cur, "scratch");
513 cur = safe_concat (buf, cur, "cc0");
516 cur = safe_concat (buf, cur, "pc");
519 print_value (t, XEXP (x, 0), verbose);
520 cur = safe_concat (buf, cur, "[");
521 cur = safe_concat (buf, cur, t);
522 cur = safe_concat (buf, cur, "]");
525 print_exp (t, x, verbose);
526 cur = safe_concat (buf, cur, t);
531 /* The next step in insn detalization, its pattern recognition. */
534 print_pattern (char *buf, const_rtx x, int verbose)
536 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
538 switch (GET_CODE (x))
541 print_value (t1, SET_DEST (x), verbose);
542 print_value (t2, SET_SRC (x), verbose);
543 sprintf (buf, "%s=%s", t1, t2);
546 sprintf (buf, "return");
549 print_exp (buf, x, verbose);
552 print_value (t1, XEXP (x, 0), verbose);
553 sprintf (buf, "clobber %s", t1);
556 print_value (t1, XEXP (x, 0), verbose);
557 sprintf (buf, "use %s", t1);
560 print_value (t1, PAT_VAR_LOCATION_LOC (x), verbose);
561 sprintf (buf, "loc %s", t1);
564 if (GET_CODE (COND_EXEC_TEST (x)) == NE
565 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
566 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
567 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
568 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
571 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
574 print_value (t1, COND_EXEC_TEST (x), verbose);
575 print_pattern (t2, COND_EXEC_CODE (x), verbose);
576 sprintf (buf, "(%s) %s", t1, t2);
583 for (i = 0; i < XVECLEN (x, 0); i++)
585 print_pattern (t2, XVECEXP (x, 0, i), verbose);
586 sprintf (t3, "%s%s;", t1, t2);
589 sprintf (buf, "%s}", t1);
593 /* Should never see SEQUENCE codes until after reorg. */
596 sprintf (buf, "asm {%s}", XSTR (x, 0));
601 print_value (buf, XEXP (x, 0), verbose);
604 print_value (t1, TRAP_CONDITION (x), verbose);
605 sprintf (buf, "trap_if %s", t1);
611 sprintf (t1, "unspec{");
612 for (i = 0; i < XVECLEN (x, 0); i++)
614 print_pattern (t2, XVECEXP (x, 0, i), verbose);
615 sprintf (t3, "%s%s;", t1, t2);
618 sprintf (buf, "%s}", t1);
621 case UNSPEC_VOLATILE:
625 sprintf (t1, "unspec/v{");
626 for (i = 0; i < XVECLEN (x, 0); i++)
628 print_pattern (t2, XVECEXP (x, 0, i), verbose);
629 sprintf (t3, "%s%s;", t1, t2);
632 sprintf (buf, "%s}", t1);
636 print_value (buf, x, verbose);
638 } /* print_pattern */
640 /* This is the main function in rtl visualization mechanism. It
641 accepts an rtx and tries to recognize it as an insn, then prints it
642 properly in human readable form, resembling assembler mnemonics.
643 For every insn it prints its UID and BB the insn belongs too.
644 (Probably the last "option" should be extended somehow, since it
645 depends now on sched.c inner variables ...) */
648 print_insn (char *buf, const_rtx x, int verbose)
653 switch (GET_CODE (x))
656 print_pattern (t, PATTERN (x), verbose);
657 #ifdef INSN_SCHEDULING
658 if (verbose && current_sched_info)
659 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
663 sprintf (buf, " %4d %s", INSN_UID (x), t);
668 const char *name = "?";
670 if (DECL_P (INSN_VAR_LOCATION_DECL (insn)))
672 tree id = DECL_NAME (INSN_VAR_LOCATION_DECL (insn));
674 name = IDENTIFIER_POINTER (id);
678 sprintf (idbuf, "D.%i",
679 DECL_UID (INSN_VAR_LOCATION_DECL (insn)));
683 if (VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)))
684 sprintf (buf, " %4d: debug %s optimized away", INSN_UID (insn), name);
687 print_pattern (t, INSN_VAR_LOCATION_LOC (insn), verbose);
688 sprintf (buf, " %4d: debug %s => %s", INSN_UID (insn), name, t);
694 print_pattern (t, PATTERN (x), verbose);
695 #ifdef INSN_SCHEDULING
696 if (verbose && current_sched_info)
697 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
701 sprintf (buf, " %4d %s", INSN_UID (x), t);
705 if (GET_CODE (x) == PARALLEL)
707 x = XVECEXP (x, 0, 0);
708 print_pattern (t, x, verbose);
711 strcpy (t, "call <...>");
712 #ifdef INSN_SCHEDULING
713 if (verbose && current_sched_info)
714 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (insn, 1), t);
717 sprintf (buf, " %4d %s", INSN_UID (insn), t);
720 sprintf (buf, "L%d:", INSN_UID (x));
723 sprintf (buf, "i%4d: barrier", INSN_UID (x));
726 sprintf (buf, " %4d %s", INSN_UID (x),
727 GET_NOTE_INSN_NAME (NOTE_KIND (x)));
730 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
731 GET_RTX_NAME (GET_CODE (x)));
735 /* Emit a slim dump of X (an insn) to the file F, including any register
736 note attached to the instruction. */
738 dump_insn_slim (FILE *f, rtx x)
740 char t[BUF_LEN + 32];
743 print_insn (t, x, 1);
746 if (INSN_P (x) && REG_NOTES (x))
747 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
749 print_value (t, XEXP (note, 0), 1);
750 fprintf (f, " %s: %s\n",
751 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
755 /* Emit a slim dump of X (an insn) to stderr. */
757 debug_insn_slim (rtx x)
759 dump_insn_slim (stderr, x);
762 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
763 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
764 include more information on the basic blocks. */
766 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
768 print_rtl_slim (f, first, NULL, -1, flags);
771 /* Same as above, but stop at LAST or when COUNT == 0.
772 If COUNT < 0 it will stop only at LAST or NULL rtx. */
774 print_rtl_slim (FILE *f, rtx first, rtx last, int count, int flags)
776 basic_block current_bb = NULL;
779 tail = last ? NEXT_INSN (last) : NULL_RTX;
781 (insn != NULL) && (insn != tail) && (count != 0);
782 insn = NEXT_INSN (insn))
784 if ((flags & TDF_BLOCKS)
785 && (INSN_P (insn) || NOTE_P (insn))
786 && BLOCK_FOR_INSN (insn)
789 current_bb = BLOCK_FOR_INSN (insn);
790 dump_bb_info (current_bb, true, false, flags, ";; ", f);
793 dump_insn_slim (f, insn);
795 if ((flags & TDF_BLOCKS)
797 && insn == BB_END (current_bb))
799 dump_bb_info (current_bb, false, true, flags, ";; ", f);
808 debug_bb_slim (struct basic_block_def *bb)
810 print_rtl_slim (stderr, BB_HEAD (bb), BB_END (bb), -1, 32);
814 debug_bb_n_slim (int n)
816 struct basic_block_def *bb = BASIC_BLOCK (n);