1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007 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 2, 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 COPYING. If not, write to the Free
21 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
26 #include "coretypes.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
33 #include "sched-int.h"
34 #include "tree-pass.h"
36 static char *safe_concat (char *, char *, const char *);
37 static void print_exp (char *, rtx, int);
38 static void print_value (char *, rtx, int);
39 static void print_pattern (char *, rtx, int);
44 safe_concat (char *buf, char *cur, const char *str)
46 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
55 while (cur < end && (c = *str++) != '\0')
62 /* This recognizes rtx, I classified as expressions. These are always
63 represent some action on values or results of other expression, that
64 may be stored in objects representing values. */
67 print_exp (char *buf, rtx x, int verbose)
72 const char *fun = (char *) 0;
77 for (i = 0; i < 4; i++)
87 if (GET_CODE (XEXP (x, 1)) == CONST_INT
88 && INTVAL (XEXP (x, 1)) < 0)
91 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
271 fun = (verbose) ? "sign_extract" : "sxt";
277 fun = (verbose) ? "zero_extract" : "zxt";
283 fun = (verbose) ? "sign_extend" : "sxn";
287 fun = (verbose) ? "zero_extend" : "zxn";
291 fun = (verbose) ? "float_extend" : "fxn";
295 fun = (verbose) ? "trunc" : "trn";
299 fun = (verbose) ? "float_trunc" : "ftr";
303 fun = (verbose) ? "float" : "flt";
307 fun = (verbose) ? "uns_float" : "ufl";
315 fun = (verbose) ? "uns_fix" : "ufx";
336 op[0] = XEXP (XEXP (x, 1), 0);
338 op[1] = XEXP (XEXP (x, 1), 1);
342 op[0] = XEXP (XEXP (x, 1), 0);
344 op[1] = XEXP (XEXP (x, 1), 1);
366 op[0] = TRAP_CONDITION (x);
375 case UNSPEC_VOLATILE:
377 cur = safe_concat (buf, cur, "unspec");
378 if (GET_CODE (x) == UNSPEC_VOLATILE)
379 cur = safe_concat (buf, cur, "/v");
380 cur = safe_concat (buf, cur, "[");
382 for (i = 0; i < XVECLEN (x, 0); i++)
384 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
385 cur = safe_concat (buf, cur, sep);
386 cur = safe_concat (buf, cur, tmp);
389 cur = safe_concat (buf, cur, "] ");
390 sprintf (tmp, "%d", XINT (x, 1));
391 cur = safe_concat (buf, cur, tmp);
395 /* If (verbose) debug_rtx (x); */
396 st[0] = GET_RTX_NAME (GET_CODE (x));
400 /* Print this as a function? */
403 cur = safe_concat (buf, cur, fun);
404 cur = safe_concat (buf, cur, "(");
407 for (i = 0; i < 4; i++)
410 cur = safe_concat (buf, cur, st[i]);
415 cur = safe_concat (buf, cur, ",");
417 print_value (tmp, op[i], verbose);
418 cur = safe_concat (buf, cur, tmp);
423 cur = safe_concat (buf, cur, ")");
426 /* Prints rtxes, I customarily classified as values. They're constants,
427 registers, labels, symbols and memory accesses. */
430 print_value (char *buf, rtx x, int verbose)
435 switch (GET_CODE (x))
438 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
439 cur = safe_concat (buf, cur, t);
442 if (FLOAT_MODE_P (GET_MODE (x)))
443 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
446 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
447 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
448 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
449 cur = safe_concat (buf, cur, t);
452 cur = safe_concat (buf, cur, "\"");
453 cur = safe_concat (buf, cur, XSTR (x, 0));
454 cur = safe_concat (buf, cur, "\"");
457 cur = safe_concat (buf, cur, "`");
458 cur = safe_concat (buf, cur, XSTR (x, 0));
459 cur = safe_concat (buf, cur, "'");
462 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
463 cur = safe_concat (buf, cur, t);
466 print_value (t, XEXP (x, 0), verbose);
467 cur = safe_concat (buf, cur, "const(");
468 cur = safe_concat (buf, cur, t);
469 cur = safe_concat (buf, cur, ")");
472 print_value (t, XEXP (x, 0), verbose);
473 cur = safe_concat (buf, cur, "high(");
474 cur = safe_concat (buf, cur, t);
475 cur = safe_concat (buf, cur, ")");
478 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
480 int c = reg_names[REGNO (x)][0];
482 cur = safe_concat (buf, cur, "%");
484 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
488 sprintf (t, "r%d", REGNO (x));
489 cur = safe_concat (buf, cur, t);
492 #ifdef INSN_SCHEDULING
493 && !current_sched_info
497 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
498 cur = safe_concat (buf, cur, t);
502 print_value (t, SUBREG_REG (x), verbose);
503 cur = safe_concat (buf, cur, t);
504 sprintf (t, "#%d", SUBREG_BYTE (x));
505 cur = safe_concat (buf, cur, t);
508 cur = safe_concat (buf, cur, "scratch");
511 cur = safe_concat (buf, cur, "cc0");
514 cur = safe_concat (buf, cur, "pc");
517 print_value (t, XEXP (x, 0), verbose);
518 cur = safe_concat (buf, cur, "[");
519 cur = safe_concat (buf, cur, t);
520 cur = safe_concat (buf, cur, "]");
523 print_exp (t, x, verbose);
524 cur = safe_concat (buf, cur, t);
529 /* The next step in insn detalization, its pattern recognition. */
532 print_pattern (char *buf, rtx x, int verbose)
534 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
536 switch (GET_CODE (x))
539 print_value (t1, SET_DEST (x), verbose);
540 print_value (t2, SET_SRC (x), verbose);
541 sprintf (buf, "%s=%s", t1, t2);
544 sprintf (buf, "return");
547 print_exp (buf, x, verbose);
550 print_value (t1, XEXP (x, 0), verbose);
551 sprintf (buf, "clobber %s", t1);
554 print_value (t1, XEXP (x, 0), verbose);
555 sprintf (buf, "use %s", t1);
558 if (GET_CODE (COND_EXEC_TEST (x)) == NE
559 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
560 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
561 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
562 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
565 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
568 print_value (t1, COND_EXEC_TEST (x), verbose);
569 print_pattern (t2, COND_EXEC_CODE (x), verbose);
570 sprintf (buf, "(%s) %s", t1, t2);
577 for (i = 0; i < XVECLEN (x, 0); i++)
579 print_pattern (t2, XVECEXP (x, 0, i), verbose);
580 sprintf (t3, "%s%s;", t1, t2);
583 sprintf (buf, "%s}", t1);
587 /* Should never see SEQUENCE codes until after reorg. */
590 sprintf (buf, "asm {%s}", XSTR (x, 0));
595 print_value (buf, XEXP (x, 0), verbose);
598 print_value (t1, TRAP_CONDITION (x), verbose);
599 sprintf (buf, "trap_if %s", t1);
605 sprintf (t1, "unspec{");
606 for (i = 0; i < XVECLEN (x, 0); i++)
608 print_pattern (t2, XVECEXP (x, 0, i), verbose);
609 sprintf (t3, "%s%s;", t1, t2);
612 sprintf (buf, "%s}", t1);
615 case UNSPEC_VOLATILE:
619 sprintf (t1, "unspec/v{");
620 for (i = 0; i < XVECLEN (x, 0); i++)
622 print_pattern (t2, XVECEXP (x, 0, i), verbose);
623 sprintf (t3, "%s%s;", t1, t2);
626 sprintf (buf, "%s}", t1);
630 print_value (buf, x, verbose);
632 } /* print_pattern */
634 /* This is the main function in rtl visualization mechanism. It
635 accepts an rtx and tries to recognize it as an insn, then prints it
636 properly in human readable form, resembling assembler mnemonics.
637 For every insn it prints its UID and BB the insn belongs too.
638 (Probably the last "option" should be extended somehow, since it
639 depends now on sched.c inner variables ...) */
642 print_insn (char *buf, rtx x, int verbose)
647 switch (GET_CODE (x))
650 print_pattern (t, PATTERN (x), verbose);
651 #ifdef INSN_SCHEDULING
652 if (verbose && current_sched_info)
653 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
657 sprintf (buf, " %4d %s", INSN_UID (x), t);
660 print_pattern (t, PATTERN (x), verbose);
661 #ifdef INSN_SCHEDULING
662 if (verbose && current_sched_info)
663 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
667 sprintf (buf, " %4d %s", INSN_UID (x), t);
671 if (GET_CODE (x) == PARALLEL)
673 x = XVECEXP (x, 0, 0);
674 print_pattern (t, x, verbose);
677 strcpy (t, "call <...>");
678 #ifdef INSN_SCHEDULING
679 if (verbose && current_sched_info)
680 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
683 sprintf (buf, " %4d %s", INSN_UID (insn), t);
686 sprintf (buf, "L%d:", INSN_UID (x));
689 sprintf (buf, "i%4d: barrier", INSN_UID (x));
692 sprintf (buf, " %4d %s", INSN_UID (x),
693 GET_NOTE_INSN_NAME (NOTE_KIND (x)));
696 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
697 GET_RTX_NAME (GET_CODE (x)));
702 /* Emit a slim dump of X (an insn) to the file F, including any register
703 note attached to the instruction. */
705 dump_insn_slim (FILE *f, rtx x)
707 char t[BUF_LEN + 32];
710 print_insn (t, x, 1);
713 if (INSN_P (x) && REG_NOTES (x))
714 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
716 print_value (t, XEXP (note, 0), 1);
717 fprintf (f, " %s: %s\n",
718 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
722 /* Emit a slim dump of X (an insn) to stderr. */
724 debug_insn_slim (rtx x)
726 dump_insn_slim (stderr, x);
729 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
730 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
731 include more information on the basic blocks. */
733 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
735 basic_block current_bb = NULL;
738 for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
740 if ((flags & TDF_BLOCKS)
741 && (INSN_P (insn) || GET_CODE (insn) == NOTE)
742 && BLOCK_FOR_INSN (insn)
745 current_bb = BLOCK_FOR_INSN (insn);
746 dump_bb_info (current_bb, true, false, flags, ";; ", f);
749 dump_insn_slim (f, insn);
751 if ((flags & TDF_BLOCKS)
753 && insn == BB_END (current_bb))
755 dump_bb_info (current_bb, false, true, flags, ";; ", f);