1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 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 GNU CC.
9 GNU CC is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License as published by the
11 Free Software Foundation; either version 2, or (at your option) any
14 GNU CC is distributed in the hope that it will be useful, but WITHOUT
15 ANY 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 GNU CC; see the file COPYING. If not, write to the Free
21 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "insn-attr.h"
33 #include "sched-int.h"
35 #ifdef INSN_SCHEDULING
36 /* target_units bitmask has 1 for each unit in the cpu. It should be
37 possible to compute this variable from the machine description.
38 But currently it is computed by examining the insn list. Since
39 this is only needed for visualization, it seems an acceptable
40 solution. (For understanding the mapping of bits to units, see
41 definition of function_units[] in "insn-attrtab.c".) */
43 static int target_units
= 0;
45 static char *safe_concat
PARAMS ((char *, char *, const char *));
46 static int get_visual_tbl_length
PARAMS ((void));
47 static void print_exp
PARAMS ((char *, rtx
, int));
48 static void print_value
PARAMS ((char *, rtx
, int));
49 static void print_pattern
PARAMS ((char *, rtx
, int));
50 static void print_insn
PARAMS ((char *, rtx
, int));
52 /* Print names of units on which insn can/should execute, for debugging. */
55 insn_print_units (insn
)
59 int unit
= insn_unit (insn
);
62 fprintf (sched_dump
, "none");
64 fprintf (sched_dump
, "%s", function_units
[unit
].name
);
67 fprintf (sched_dump
, "[");
68 for (i
= 0, unit
= ~unit
; unit
; i
++, unit
>>= 1)
71 fprintf (sched_dump
, "%s", function_units
[i
].name
);
73 fprintf (sched_dump
, " ");
75 fprintf (sched_dump
, "]");
79 /* MAX_VISUAL_LINES is the maximum number of lines in visualization table
80 of a basic block. If more lines are needed, table is splitted to two.
81 n_visual_lines is the number of lines printed so far for a block.
82 visual_tbl contains the block visualization info.
83 vis_no_unit holds insns in a cycle that are not mapped to any unit. */
84 #define MAX_VISUAL_LINES 100
87 static unsigned visual_tbl_line_length
;
92 /* Finds units that are in use in this fuction. Required only
101 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
106 unit
= insn_unit (insn
);
109 target_units
|= ~unit
;
111 target_units
|= (1 << unit
);
115 /* Return the length of the visualization table. */
118 get_visual_tbl_length ()
124 /* Compute length of one field in line. */
125 s
= (char *) alloca (INSN_LEN
+ 6);
126 sprintf (s
, " %33s", "uname");
129 /* Compute length of one line. */
132 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
133 if (function_units
[unit
].bitmask
& target_units
)
134 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
137 n
+= strlen ("\n") + 2;
139 visual_tbl_line_length
= n
;
141 /* Compute length of visualization string. */
142 return (MAX_VISUAL_LINES
* n
);
145 /* Init block visualization debugging info. */
148 init_block_visualization ()
150 strcpy (visual_tbl
, "");
158 safe_concat (buf
, cur
, str
)
163 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
172 while (cur
< end
&& (c
= *str
++) != '\0')
179 /* This recognizes rtx, I classified as expressions. These are always
180 represent some action on values or results of other expression, that
181 may be stored in objects representing values. */
184 print_exp (buf
, x
, verbose
)
192 const char *fun
= (char *) 0;
197 for (i
= 0; i
< 4; i
++)
203 switch (GET_CODE (x
))
207 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
208 && INTVAL (XEXP (x
, 1)) < 0)
211 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
391 fun
= (verbose
) ? "sign_extract" : "sxt";
397 fun
= (verbose
) ? "zero_extract" : "zxt";
403 fun
= (verbose
) ? "sign_extend" : "sxn";
407 fun
= (verbose
) ? "zero_extend" : "zxn";
411 fun
= (verbose
) ? "float_extend" : "fxn";
415 fun
= (verbose
) ? "trunc" : "trn";
419 fun
= (verbose
) ? "float_trunc" : "ftr";
423 fun
= (verbose
) ? "float" : "flt";
427 fun
= (verbose
) ? "uns_float" : "ufl";
435 fun
= (verbose
) ? "uns_fix" : "ufx";
474 op
[0] = TRAP_CONDITION (x
);
477 case UNSPEC_VOLATILE
:
479 cur
= safe_concat (buf
, cur
, "unspec");
480 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
481 cur
= safe_concat (buf
, cur
, "/v");
482 cur
= safe_concat (buf
, cur
, "[");
484 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
486 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
487 cur
= safe_concat (buf
, cur
, sep
);
488 cur
= safe_concat (buf
, cur
, tmp
);
491 cur
= safe_concat (buf
, cur
, "] ");
492 sprintf (tmp
, "%d", XINT (x
, 1));
493 cur
= safe_concat (buf
, cur
, tmp
);
497 /* If (verbose) debug_rtx (x); */
498 st
[0] = GET_RTX_NAME (GET_CODE (x
));
502 /* Print this as a function? */
505 cur
= safe_concat (buf
, cur
, fun
);
506 cur
= safe_concat (buf
, cur
, "(");
509 for (i
= 0; i
< 4; i
++)
512 cur
= safe_concat (buf
, cur
, st
[i
]);
517 cur
= safe_concat (buf
, cur
, ",");
519 print_value (tmp
, op
[i
], verbose
);
520 cur
= safe_concat (buf
, cur
, tmp
);
525 cur
= safe_concat (buf
, cur
, ")");
528 /* Prints rtxes, I customly classified as values. They're constants,
529 registers, labels, symbols and memory accesses. */
532 print_value (buf
, x
, verbose
)
540 switch (GET_CODE (x
))
543 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
544 cur
= safe_concat (buf
, cur
, t
);
547 sprintf (t
, "<0x%lx,0x%lx>", (long) XWINT (x
, 2), (long) XWINT (x
, 3));
548 cur
= safe_concat (buf
, cur
, t
);
551 cur
= safe_concat (buf
, cur
, "\"");
552 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
553 cur
= safe_concat (buf
, cur
, "\"");
556 cur
= safe_concat (buf
, cur
, "`");
557 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
558 cur
= safe_concat (buf
, cur
, "'");
561 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
562 cur
= safe_concat (buf
, cur
, t
);
565 print_value (t
, XEXP (x
, 0), verbose
);
566 cur
= safe_concat (buf
, cur
, "const(");
567 cur
= safe_concat (buf
, cur
, t
);
568 cur
= safe_concat (buf
, cur
, ")");
571 print_value (t
, XEXP (x
, 0), verbose
);
572 cur
= safe_concat (buf
, cur
, "high(");
573 cur
= safe_concat (buf
, cur
, t
);
574 cur
= safe_concat (buf
, cur
, ")");
577 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
579 int c
= reg_names
[REGNO (x
)][0];
580 if (c
>= '0' && c
<= '9')
581 cur
= safe_concat (buf
, cur
, "%");
583 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
587 sprintf (t
, "r%d", REGNO (x
));
588 cur
= safe_concat (buf
, cur
, t
);
592 print_value (t
, SUBREG_REG (x
), verbose
);
593 cur
= safe_concat (buf
, cur
, t
);
594 sprintf (t
, "#%d", SUBREG_WORD (x
));
595 cur
= safe_concat (buf
, cur
, t
);
598 cur
= safe_concat (buf
, cur
, "scratch");
601 cur
= safe_concat (buf
, cur
, "cc0");
604 cur
= safe_concat (buf
, cur
, "pc");
607 print_value (t
, XEXP (x
, 0), verbose
);
608 cur
= safe_concat (buf
, cur
, "[");
609 cur
= safe_concat (buf
, cur
, t
);
610 cur
= safe_concat (buf
, cur
, "]");
613 print_exp (t
, x
, verbose
);
614 cur
= safe_concat (buf
, cur
, t
);
619 /* The next step in insn detalization, its pattern recognition. */
622 print_pattern (buf
, x
, verbose
)
627 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
629 switch (GET_CODE (x
))
632 print_value (t1
, SET_DEST (x
), verbose
);
633 print_value (t2
, SET_SRC (x
), verbose
);
634 sprintf (buf
, "%s=%s", t1
, t2
);
637 sprintf (buf
, "return");
640 print_exp (buf
, x
, verbose
);
643 print_value (t1
, XEXP (x
, 0), verbose
);
644 sprintf (buf
, "clobber %s", t1
);
647 print_value (t1
, XEXP (x
, 0), verbose
);
648 sprintf (buf
, "use %s", t1
);
651 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
652 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
653 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
654 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
655 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
658 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
661 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
662 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
663 sprintf (buf
, "(%s) %s", t1
, t2
);
670 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
672 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
673 sprintf (t3
, "%s%s;", t1
, t2
);
676 sprintf (buf
, "%s}", t1
);
684 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
686 print_insn (t2
, XVECEXP (x
, 0, i
), verbose
);
687 sprintf (t3
, "%s%s;", t1
, t2
);
690 sprintf (buf
, "%s%%}", t1
);
694 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
699 print_value (buf
, XEXP (x
, 0), verbose
);
702 print_value (t1
, TRAP_CONDITION (x
), verbose
);
703 sprintf (buf
, "trap_if %s", t1
);
709 sprintf (t1
, "unspec{");
710 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
712 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
713 sprintf (t3
, "%s%s;", t1
, t2
);
716 sprintf (buf
, "%s}", t1
);
719 case UNSPEC_VOLATILE
:
723 sprintf (t1
, "unspec/v{");
724 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
726 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
727 sprintf (t3
, "%s%s;", t1
, t2
);
730 sprintf (buf
, "%s}", t1
);
734 print_value (buf
, x
, verbose
);
736 } /* print_pattern */
738 /* This is the main function in rtl visualization mechanism. It
739 accepts an rtx and tries to recognize it as an insn, then prints it
740 properly in human readable form, resembling assembler mnemonics.
741 For every insn it prints its UID and BB the insn belongs too.
742 (Probably the last "option" should be extended somehow, since it
743 depends now on sched.c inner variables ...) */
746 print_insn (buf
, x
, verbose
)
754 switch (GET_CODE (x
))
757 print_pattern (t
, PATTERN (x
), verbose
);
759 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
762 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
765 print_pattern (t
, PATTERN (x
), verbose
);
767 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
770 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
774 if (GET_CODE (x
) == PARALLEL
)
776 x
= XVECEXP (x
, 0, 0);
777 print_pattern (t
, x
, verbose
);
780 strcpy (t
, "call <...>");
782 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
784 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
787 sprintf (buf
, "L%d:", INSN_UID (x
));
790 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
793 if (NOTE_LINE_NUMBER (x
) > 0)
794 sprintf (buf
, "%4d note \"%s\" %d", INSN_UID (x
),
795 NOTE_SOURCE_FILE (x
), NOTE_LINE_NUMBER (x
));
797 sprintf (buf
, "%4d %s", INSN_UID (x
),
798 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
803 sprintf (buf
, "Not an INSN at all\n");
807 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));
811 /* Print visualization debugging info. */
814 print_block_visualization (s
)
820 fprintf (sched_dump
, "\n;; ==================== scheduling visualization %s \n", s
);
822 /* Print names of units. */
823 fprintf (sched_dump
, ";; %-8s", "clock");
824 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
825 if (function_units
[unit
].bitmask
& target_units
)
826 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
827 fprintf (sched_dump
, " %-33s", function_units
[unit
].name
);
828 fprintf (sched_dump
, " %-8s\n", "no-unit");
830 fprintf (sched_dump
, ";; %-8s", "=====");
831 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
832 if (function_units
[unit
].bitmask
& target_units
)
833 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
834 fprintf (sched_dump
, " %-33s", "==============================");
835 fprintf (sched_dump
, " %-8s\n", "=======");
837 /* Print insns in each cycle. */
838 fprintf (sched_dump
, "%s\n", visual_tbl
);
841 /* Print insns in the 'no_unit' column of visualization. */
844 visualize_no_unit (insn
)
847 vis_no_unit
[n_vis_no_unit
] = insn
;
851 /* Print insns scheduled in clock, for visualization. */
854 visualize_scheduled_insns (clock
)
859 /* If no more room, split table into two. */
860 if (n_visual_lines
>= MAX_VISUAL_LINES
)
862 print_block_visualization ("(incomplete)");
863 init_block_visualization ();
868 sprintf (visual_tbl
+ strlen (visual_tbl
), ";; %-8d", clock
);
869 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
870 if (function_units
[unit
].bitmask
& target_units
)
871 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
873 int instance
= unit
+ i
* FUNCTION_UNITS_SIZE
;
874 rtx insn
= get_unit_last_insn (instance
);
876 /* Print insns that still keep the unit busy. */
878 && actual_hazard_this_instance (unit
, instance
, insn
, clock
, 0))
881 print_insn (str
, insn
, 0);
882 str
[INSN_LEN
] = '\0';
883 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", str
);
886 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", "------------------------------");
889 /* Print insns that are not assigned to any unit. */
890 for (i
= 0; i
< n_vis_no_unit
; i
++)
891 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-8d",
892 INSN_UID (vis_no_unit
[i
]));
895 sprintf (visual_tbl
+ strlen (visual_tbl
), "\n");
898 /* Print stalled cycles. */
901 visualize_stall_cycles (stalls
)
904 const char *prefix
= ";; ";
905 const char *suffix
= "\n";
908 /* If no more room, split table into two. */
909 if (n_visual_lines
>= MAX_VISUAL_LINES
)
911 print_block_visualization ("(incomplete)");
912 init_block_visualization ();
917 p
= visual_tbl
+ strlen (visual_tbl
);
919 p
+= strlen (prefix
);
921 if ((unsigned)stalls
>
922 visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
))
925 stalls
= visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
);
928 memset (p
, '.', stalls
);
934 /* Allocate data used for visualization during scheduling. */
939 visual_tbl
= xmalloc (get_visual_tbl_length ());
942 /* Free data used for visualization. */