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 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 the
21 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"
36 #ifdef INSN_SCHEDULING
37 /* target_units bitmask has 1 for each unit in the cpu. It should be
38 possible to compute this variable from the machine description.
39 But currently it is computed by examining the insn list. Since
40 this is only needed for visualization, it seems an acceptable
41 solution. (For understanding the mapping of bits to units, see
42 definition of function_units[] in "insn-attrtab.c".) The scheduler
43 using only DFA description should never use the following variable. */
45 static int target_units
= 0;
47 static char *safe_concat
PARAMS ((char *, char *, const char *));
48 static int get_visual_tbl_length
PARAMS ((void));
49 static void print_exp
PARAMS ((char *, rtx
, int));
50 static void print_value
PARAMS ((char *, rtx
, int));
51 static void print_pattern
PARAMS ((char *, rtx
, int));
52 static void print_insn
PARAMS ((char *, rtx
, int));
54 /* Print names of units on which insn can/should execute, for debugging. */
57 insn_print_units (insn
)
61 int unit
= insn_unit (insn
);
64 fprintf (sched_dump
, "none");
66 fprintf (sched_dump
, "%s", function_units
[unit
].name
);
69 fprintf (sched_dump
, "[");
70 for (i
= 0, unit
= ~unit
; unit
; i
++, unit
>>= 1)
73 fprintf (sched_dump
, "%s", function_units
[i
].name
);
75 fprintf (sched_dump
, " ");
77 fprintf (sched_dump
, "]");
81 /* MAX_VISUAL_LINES is the maximum number of lines in visualization table
82 of a basic block. If more lines are needed, table is splitted to two.
83 n_visual_lines is the number of lines printed so far for a block.
84 visual_tbl contains the block visualization info.
85 vis_no_unit holds insns in a cycle that are not mapped to any unit. */
86 #define MAX_VISUAL_LINES 100
89 static unsigned visual_tbl_line_length
;
92 #define MAX_VISUAL_NO_UNIT 20
93 rtx vis_no_unit
[MAX_VISUAL_NO_UNIT
];
95 /* Finds units that are in use in this fuction. Required only
104 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
109 unit
= insn_unit (insn
);
112 target_units
|= ~unit
;
114 target_units
|= (1 << unit
);
118 /* Return the length of the visualization table. */
121 get_visual_tbl_length ()
127 if (targetm
.sched
.use_dfa_pipeline_interface
)
129 visual_tbl_line_length
= 1;
130 return 1; /* Can't return 0 because that will cause problems
134 /* Compute length of one field in line. */
135 s
= (char *) alloca (INSN_LEN
+ 6);
136 sprintf (s
, " %33s", "uname");
139 /* Compute length of one line. */
142 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
143 if (function_units
[unit
].bitmask
& target_units
)
144 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
147 n
+= strlen ("\n") + 2;
149 visual_tbl_line_length
= n
;
151 /* Compute length of visualization string. */
152 return (MAX_VISUAL_LINES
* n
);
155 /* Init block visualization debugging info. */
158 init_block_visualization ()
160 strcpy (visual_tbl
, "");
168 safe_concat (buf
, cur
, str
)
173 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
182 while (cur
< end
&& (c
= *str
++) != '\0')
189 /* This recognizes rtx, I classified as expressions. These are always
190 represent some action on values or results of other expression, that
191 may be stored in objects representing values. */
194 print_exp (buf
, x
, verbose
)
202 const char *fun
= (char *) 0;
207 for (i
= 0; i
< 4; i
++)
213 switch (GET_CODE (x
))
217 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
218 && INTVAL (XEXP (x
, 1)) < 0)
221 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
401 fun
= (verbose
) ? "sign_extract" : "sxt";
407 fun
= (verbose
) ? "zero_extract" : "zxt";
413 fun
= (verbose
) ? "sign_extend" : "sxn";
417 fun
= (verbose
) ? "zero_extend" : "zxn";
421 fun
= (verbose
) ? "float_extend" : "fxn";
425 fun
= (verbose
) ? "trunc" : "trn";
429 fun
= (verbose
) ? "float_trunc" : "ftr";
433 fun
= (verbose
) ? "float" : "flt";
437 fun
= (verbose
) ? "uns_float" : "ufl";
445 fun
= (verbose
) ? "uns_fix" : "ufx";
484 op
[0] = TRAP_CONDITION (x
);
487 case UNSPEC_VOLATILE
:
489 cur
= safe_concat (buf
, cur
, "unspec");
490 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
491 cur
= safe_concat (buf
, cur
, "/v");
492 cur
= safe_concat (buf
, cur
, "[");
494 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
496 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
497 cur
= safe_concat (buf
, cur
, sep
);
498 cur
= safe_concat (buf
, cur
, tmp
);
501 cur
= safe_concat (buf
, cur
, "] ");
502 sprintf (tmp
, "%d", XINT (x
, 1));
503 cur
= safe_concat (buf
, cur
, tmp
);
507 /* If (verbose) debug_rtx (x); */
508 st
[0] = GET_RTX_NAME (GET_CODE (x
));
512 /* Print this as a function? */
515 cur
= safe_concat (buf
, cur
, fun
);
516 cur
= safe_concat (buf
, cur
, "(");
519 for (i
= 0; i
< 4; i
++)
522 cur
= safe_concat (buf
, cur
, st
[i
]);
527 cur
= safe_concat (buf
, cur
, ",");
529 print_value (tmp
, op
[i
], verbose
);
530 cur
= safe_concat (buf
, cur
, tmp
);
535 cur
= safe_concat (buf
, cur
, ")");
538 /* Prints rtxes, I customly classified as values. They're constants,
539 registers, labels, symbols and memory accesses. */
542 print_value (buf
, x
, verbose
)
550 switch (GET_CODE (x
))
553 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
554 cur
= safe_concat (buf
, cur
, t
);
557 sprintf (t
, "<0x%lx,0x%lx>", (long) XWINT (x
, 2), (long) XWINT (x
, 3));
558 cur
= safe_concat (buf
, cur
, t
);
561 cur
= safe_concat (buf
, cur
, "\"");
562 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
563 cur
= safe_concat (buf
, cur
, "\"");
566 cur
= safe_concat (buf
, cur
, "`");
567 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
568 cur
= safe_concat (buf
, cur
, "'");
571 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
572 cur
= safe_concat (buf
, cur
, t
);
575 print_value (t
, XEXP (x
, 0), verbose
);
576 cur
= safe_concat (buf
, cur
, "const(");
577 cur
= safe_concat (buf
, cur
, t
);
578 cur
= safe_concat (buf
, cur
, ")");
581 print_value (t
, XEXP (x
, 0), verbose
);
582 cur
= safe_concat (buf
, cur
, "high(");
583 cur
= safe_concat (buf
, cur
, t
);
584 cur
= safe_concat (buf
, cur
, ")");
587 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
589 int c
= reg_names
[REGNO (x
)][0];
590 if (c
>= '0' && c
<= '9')
591 cur
= safe_concat (buf
, cur
, "%");
593 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
597 sprintf (t
, "r%d", REGNO (x
));
598 cur
= safe_concat (buf
, cur
, t
);
602 print_value (t
, SUBREG_REG (x
), verbose
);
603 cur
= safe_concat (buf
, cur
, t
);
604 sprintf (t
, "#%d", SUBREG_BYTE (x
));
605 cur
= safe_concat (buf
, cur
, t
);
608 cur
= safe_concat (buf
, cur
, "scratch");
611 cur
= safe_concat (buf
, cur
, "cc0");
614 cur
= safe_concat (buf
, cur
, "pc");
617 print_value (t
, XEXP (x
, 0), verbose
);
618 cur
= safe_concat (buf
, cur
, "[");
619 cur
= safe_concat (buf
, cur
, t
);
620 cur
= safe_concat (buf
, cur
, "]");
623 print_exp (t
, x
, verbose
);
624 cur
= safe_concat (buf
, cur
, t
);
629 /* The next step in insn detalization, its pattern recognition. */
632 print_pattern (buf
, x
, verbose
)
637 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
639 switch (GET_CODE (x
))
642 print_value (t1
, SET_DEST (x
), verbose
);
643 print_value (t2
, SET_SRC (x
), verbose
);
644 sprintf (buf
, "%s=%s", t1
, t2
);
647 sprintf (buf
, "return");
650 print_exp (buf
, x
, verbose
);
653 print_value (t1
, XEXP (x
, 0), verbose
);
654 sprintf (buf
, "clobber %s", t1
);
657 print_value (t1
, XEXP (x
, 0), verbose
);
658 sprintf (buf
, "use %s", t1
);
661 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
662 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
663 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
664 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
665 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
668 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
671 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
672 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
673 sprintf (buf
, "(%s) %s", t1
, t2
);
680 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
682 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
683 sprintf (t3
, "%s%s;", t1
, t2
);
686 sprintf (buf
, "%s}", t1
);
694 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
696 print_insn (t2
, XVECEXP (x
, 0, i
), verbose
);
697 sprintf (t3
, "%s%s;", t1
, t2
);
700 sprintf (buf
, "%s%%}", t1
);
704 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
709 print_value (buf
, XEXP (x
, 0), verbose
);
712 print_value (t1
, TRAP_CONDITION (x
), verbose
);
713 sprintf (buf
, "trap_if %s", t1
);
719 sprintf (t1
, "unspec{");
720 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
722 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
723 sprintf (t3
, "%s%s;", t1
, t2
);
726 sprintf (buf
, "%s}", t1
);
729 case UNSPEC_VOLATILE
:
733 sprintf (t1
, "unspec/v{");
734 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
736 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
737 sprintf (t3
, "%s%s;", t1
, t2
);
740 sprintf (buf
, "%s}", t1
);
744 print_value (buf
, x
, verbose
);
746 } /* print_pattern */
748 /* This is the main function in rtl visualization mechanism. It
749 accepts an rtx and tries to recognize it as an insn, then prints it
750 properly in human readable form, resembling assembler mnemonics.
751 For every insn it prints its UID and BB the insn belongs too.
752 (Probably the last "option" should be extended somehow, since it
753 depends now on sched.c inner variables ...) */
756 print_insn (buf
, x
, verbose
)
764 switch (GET_CODE (x
))
767 print_pattern (t
, PATTERN (x
), verbose
);
769 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
772 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
775 print_pattern (t
, PATTERN (x
), verbose
);
777 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
780 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
784 if (GET_CODE (x
) == PARALLEL
)
786 x
= XVECEXP (x
, 0, 0);
787 print_pattern (t
, x
, verbose
);
790 strcpy (t
, "call <...>");
792 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
794 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
797 sprintf (buf
, "L%d:", INSN_UID (x
));
800 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
803 if (NOTE_LINE_NUMBER (x
) > 0)
804 sprintf (buf
, "%4d note \"%s\" %d", INSN_UID (x
),
805 NOTE_SOURCE_FILE (x
), NOTE_LINE_NUMBER (x
));
807 sprintf (buf
, "%4d %s", INSN_UID (x
),
808 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
813 sprintf (buf
, "Not an INSN at all\n");
817 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));
821 /* Print visualization debugging info. The scheduler using only DFA
822 description should never use the following function. */
825 print_block_visualization (s
)
831 fprintf (sched_dump
, "\n;; ==================== scheduling visualization %s \n", s
);
833 /* Print names of units. */
834 fprintf (sched_dump
, ";; %-8s", "clock");
835 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
836 if (function_units
[unit
].bitmask
& target_units
)
837 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
838 fprintf (sched_dump
, " %-33s", function_units
[unit
].name
);
839 fprintf (sched_dump
, " %-8s\n", "no-unit");
841 fprintf (sched_dump
, ";; %-8s", "=====");
842 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
843 if (function_units
[unit
].bitmask
& target_units
)
844 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
845 fprintf (sched_dump
, " %-33s", "==============================");
846 fprintf (sched_dump
, " %-8s\n", "=======");
848 /* Print insns in each cycle. */
849 fprintf (sched_dump
, "%s\n", visual_tbl
);
852 /* Print insns in the 'no_unit' column of visualization. */
855 visualize_no_unit (insn
)
858 if (n_vis_no_unit
< MAX_VISUAL_NO_UNIT
)
860 vis_no_unit
[n_vis_no_unit
] = insn
;
865 /* Print insns scheduled in clock, for visualization. */
868 visualize_scheduled_insns (clock
)
873 /* If no more room, split table into two. */
874 if (n_visual_lines
>= MAX_VISUAL_LINES
)
876 print_block_visualization ("(incomplete)");
877 init_block_visualization ();
882 sprintf (visual_tbl
+ strlen (visual_tbl
), ";; %-8d", clock
);
883 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
884 if (function_units
[unit
].bitmask
& target_units
)
885 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
887 int instance
= unit
+ i
* FUNCTION_UNITS_SIZE
;
888 rtx insn
= get_unit_last_insn (instance
);
890 /* Print insns that still keep the unit busy. */
892 && actual_hazard_this_instance (unit
, instance
, insn
, clock
, 0))
895 print_insn (str
, insn
, 0);
896 str
[INSN_LEN
] = '\0';
897 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", str
);
900 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", "------------------------------");
903 /* Print insns that are not assigned to any unit. */
904 for (i
= 0; i
< n_vis_no_unit
; i
++)
905 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-8d",
906 INSN_UID (vis_no_unit
[i
]));
909 sprintf (visual_tbl
+ strlen (visual_tbl
), "\n");
912 /* Print stalled cycles. */
915 visualize_stall_cycles (stalls
)
918 const char *prefix
= ";; ";
919 const char *suffix
= "\n";
922 /* If no more room, split table into two. */
923 if (n_visual_lines
>= MAX_VISUAL_LINES
)
925 print_block_visualization ("(incomplete)");
926 init_block_visualization ();
931 p
= visual_tbl
+ strlen (visual_tbl
);
933 p
+= strlen (prefix
);
935 if ((unsigned)stalls
>
936 visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
))
939 stalls
= visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
);
942 memset (p
, '.', stalls
);
948 /* Allocate data used for visualization during scheduling. */
953 visual_tbl
= xmalloc (get_visual_tbl_length ());
956 /* Free data used for visualization. */