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 "insn-attr.h"
31 #include "sched-int.h"
33 #ifdef INSN_SCHEDULING
34 /* target_units bitmask has 1 for each unit in the cpu. It should be
35 possible to compute this variable from the machine description.
36 But currently it is computed by examining the insn list. Since
37 this is only needed for visualization, it seems an acceptable
38 solution. (For understanding the mapping of bits to units, see
39 definition of function_units[] in "insn-attrtab.c".) */
41 static int target_units
= 0;
43 static char *safe_concat
PARAMS ((char *, char *, const char *));
44 static int get_visual_tbl_length
PARAMS ((void));
45 static void print_exp
PARAMS ((char *, rtx
, int));
46 static void print_value
PARAMS ((char *, rtx
, int));
47 static void print_pattern
PARAMS ((char *, rtx
, int));
48 static void print_insn
PARAMS ((char *, rtx
, int));
50 /* Print names of units on which insn can/should execute, for debugging. */
53 insn_print_units (insn
)
57 int unit
= insn_unit (insn
);
60 fprintf (sched_dump
, "none");
62 fprintf (sched_dump
, "%s", function_units
[unit
].name
);
65 fprintf (sched_dump
, "[");
66 for (i
= 0, unit
= ~unit
; unit
; i
++, unit
>>= 1)
69 fprintf (sched_dump
, "%s", function_units
[i
].name
);
71 fprintf (sched_dump
, " ");
73 fprintf (sched_dump
, "]");
77 /* MAX_VISUAL_LINES is the maximum number of lines in visualization table
78 of a basic block. If more lines are needed, table is splitted to two.
79 n_visual_lines is the number of lines printed so far for a block.
80 visual_tbl contains the block visualization info.
81 vis_no_unit holds insns in a cycle that are not mapped to any unit. */
82 #define MAX_VISUAL_LINES 100
85 static unsigned visual_tbl_line_length
;
90 /* Finds units that are in use in this fuction. Required only
99 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
104 unit
= insn_unit (insn
);
107 target_units
|= ~unit
;
109 target_units
|= (1 << unit
);
113 /* Return the length of the visualization table. */
116 get_visual_tbl_length ()
122 /* Compute length of one field in line. */
123 s
= (char *) alloca (INSN_LEN
+ 6);
124 sprintf (s
, " %33s", "uname");
127 /* Compute length of one line. */
130 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
131 if (function_units
[unit
].bitmask
& target_units
)
132 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
135 n
+= strlen ("\n") + 2;
137 visual_tbl_line_length
= n
;
139 /* Compute length of visualization string. */
140 return (MAX_VISUAL_LINES
* n
);
143 /* Init block visualization debugging info. */
146 init_block_visualization ()
148 strcpy (visual_tbl
, "");
156 safe_concat (buf
, cur
, str
)
161 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
170 while (cur
< end
&& (c
= *str
++) != '\0')
177 /* This recognizes rtx, I classified as expressions. These are always
178 represent some action on values or results of other expression, that
179 may be stored in objects representing values. */
182 print_exp (buf
, x
, verbose
)
190 const char *fun
= (char *) 0;
195 for (i
= 0; i
< 4; i
++)
201 switch (GET_CODE (x
))
205 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
206 && INTVAL (XEXP (x
, 1)) < 0)
209 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
389 fun
= (verbose
) ? "sign_extract" : "sxt";
395 fun
= (verbose
) ? "zero_extract" : "zxt";
401 fun
= (verbose
) ? "sign_extend" : "sxn";
405 fun
= (verbose
) ? "zero_extend" : "zxn";
409 fun
= (verbose
) ? "float_extend" : "fxn";
413 fun
= (verbose
) ? "trunc" : "trn";
417 fun
= (verbose
) ? "float_trunc" : "ftr";
421 fun
= (verbose
) ? "float" : "flt";
425 fun
= (verbose
) ? "uns_float" : "ufl";
433 fun
= (verbose
) ? "uns_fix" : "ufx";
472 op
[0] = TRAP_CONDITION (x
);
475 case UNSPEC_VOLATILE
:
477 cur
= safe_concat (buf
, cur
, "unspec");
478 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
479 cur
= safe_concat (buf
, cur
, "/v");
480 cur
= safe_concat (buf
, cur
, "[");
482 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
484 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
485 cur
= safe_concat (buf
, cur
, sep
);
486 cur
= safe_concat (buf
, cur
, tmp
);
489 cur
= safe_concat (buf
, cur
, "] ");
490 sprintf (tmp
, "%d", XINT (x
, 1));
491 cur
= safe_concat (buf
, cur
, tmp
);
495 /* If (verbose) debug_rtx (x); */
496 st
[0] = GET_RTX_NAME (GET_CODE (x
));
500 /* Print this as a function? */
503 cur
= safe_concat (buf
, cur
, fun
);
504 cur
= safe_concat (buf
, cur
, "(");
507 for (i
= 0; i
< 4; i
++)
510 cur
= safe_concat (buf
, cur
, st
[i
]);
515 cur
= safe_concat (buf
, cur
, ",");
517 print_value (tmp
, op
[i
], verbose
);
518 cur
= safe_concat (buf
, cur
, tmp
);
523 cur
= safe_concat (buf
, cur
, ")");
526 /* Prints rtxes, I customly classified as values. They're constants,
527 registers, labels, symbols and memory accesses. */
530 print_value (buf
, x
, verbose
)
538 switch (GET_CODE (x
))
541 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
542 cur
= safe_concat (buf
, cur
, t
);
545 sprintf (t
, "<0x%lx,0x%lx>", (long) XWINT (x
, 2), (long) XWINT (x
, 3));
546 cur
= safe_concat (buf
, cur
, t
);
549 cur
= safe_concat (buf
, cur
, "\"");
550 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
551 cur
= safe_concat (buf
, cur
, "\"");
554 cur
= safe_concat (buf
, cur
, "`");
555 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
556 cur
= safe_concat (buf
, cur
, "'");
559 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
560 cur
= safe_concat (buf
, cur
, t
);
563 print_value (t
, XEXP (x
, 0), verbose
);
564 cur
= safe_concat (buf
, cur
, "const(");
565 cur
= safe_concat (buf
, cur
, t
);
566 cur
= safe_concat (buf
, cur
, ")");
569 print_value (t
, XEXP (x
, 0), verbose
);
570 cur
= safe_concat (buf
, cur
, "high(");
571 cur
= safe_concat (buf
, cur
, t
);
572 cur
= safe_concat (buf
, cur
, ")");
575 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
577 int c
= reg_names
[REGNO (x
)][0];
578 if (c
>= '0' && c
<= '9')
579 cur
= safe_concat (buf
, cur
, "%");
581 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
585 sprintf (t
, "r%d", REGNO (x
));
586 cur
= safe_concat (buf
, cur
, t
);
590 print_value (t
, SUBREG_REG (x
), verbose
);
591 cur
= safe_concat (buf
, cur
, t
);
592 sprintf (t
, "#%d", SUBREG_WORD (x
));
593 cur
= safe_concat (buf
, cur
, t
);
596 cur
= safe_concat (buf
, cur
, "scratch");
599 cur
= safe_concat (buf
, cur
, "cc0");
602 cur
= safe_concat (buf
, cur
, "pc");
605 print_value (t
, XEXP (x
, 0), verbose
);
606 cur
= safe_concat (buf
, cur
, "[");
607 cur
= safe_concat (buf
, cur
, t
);
608 cur
= safe_concat (buf
, cur
, "]");
611 print_exp (t
, x
, verbose
);
612 cur
= safe_concat (buf
, cur
, t
);
617 /* The next step in insn detalization, its pattern recognition. */
620 print_pattern (buf
, x
, verbose
)
625 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
627 switch (GET_CODE (x
))
630 print_value (t1
, SET_DEST (x
), verbose
);
631 print_value (t2
, SET_SRC (x
), verbose
);
632 sprintf (buf
, "%s=%s", t1
, t2
);
635 sprintf (buf
, "return");
638 print_exp (buf
, x
, verbose
);
641 print_value (t1
, XEXP (x
, 0), verbose
);
642 sprintf (buf
, "clobber %s", t1
);
645 print_value (t1
, XEXP (x
, 0), verbose
);
646 sprintf (buf
, "use %s", t1
);
649 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
650 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
651 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
652 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
653 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
656 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
659 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
660 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
661 sprintf (buf
, "(%s) %s", t1
, t2
);
668 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
670 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
671 sprintf (t3
, "%s%s;", t1
, t2
);
674 sprintf (buf
, "%s}", t1
);
682 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
684 print_insn (t2
, XVECEXP (x
, 0, i
), verbose
);
685 sprintf (t3
, "%s%s;", t1
, t2
);
688 sprintf (buf
, "%s%%}", t1
);
692 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
697 print_value (buf
, XEXP (x
, 0), verbose
);
700 print_value (t1
, TRAP_CONDITION (x
), verbose
);
701 sprintf (buf
, "trap_if %s", t1
);
707 sprintf (t1
, "unspec{");
708 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
710 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
711 sprintf (t3
, "%s%s;", t1
, t2
);
714 sprintf (buf
, "%s}", t1
);
717 case UNSPEC_VOLATILE
:
721 sprintf (t1
, "unspec/v{");
722 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
724 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
725 sprintf (t3
, "%s%s;", t1
, t2
);
728 sprintf (buf
, "%s}", t1
);
732 print_value (buf
, x
, verbose
);
734 } /* print_pattern */
736 /* This is the main function in rtl visualization mechanism. It
737 accepts an rtx and tries to recognize it as an insn, then prints it
738 properly in human readable form, resembling assembler mnemonics.
739 For every insn it prints its UID and BB the insn belongs too.
740 (Probably the last "option" should be extended somehow, since it
741 depends now on sched.c inner variables ...) */
744 print_insn (buf
, x
, verbose
)
752 switch (GET_CODE (x
))
755 print_pattern (t
, PATTERN (x
), verbose
);
757 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
760 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
763 print_pattern (t
, PATTERN (x
), verbose
);
765 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
768 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
772 if (GET_CODE (x
) == PARALLEL
)
774 x
= XVECEXP (x
, 0, 0);
775 print_pattern (t
, x
, verbose
);
778 strcpy (t
, "call <...>");
780 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
782 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
785 sprintf (buf
, "L%d:", INSN_UID (x
));
788 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
791 if (NOTE_LINE_NUMBER (x
) > 0)
792 sprintf (buf
, "%4d note \"%s\" %d", INSN_UID (x
),
793 NOTE_SOURCE_FILE (x
), NOTE_LINE_NUMBER (x
));
795 sprintf (buf
, "%4d %s", INSN_UID (x
),
796 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
801 sprintf (buf
, "Not an INSN at all\n");
805 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));
809 /* Print visualization debugging info. */
812 print_block_visualization (s
)
818 fprintf (sched_dump
, "\n;; ==================== scheduling visualization %s \n", s
);
820 /* Print names of units. */
821 fprintf (sched_dump
, ";; %-8s", "clock");
822 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
823 if (function_units
[unit
].bitmask
& target_units
)
824 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
825 fprintf (sched_dump
, " %-33s", function_units
[unit
].name
);
826 fprintf (sched_dump
, " %-8s\n", "no-unit");
828 fprintf (sched_dump
, ";; %-8s", "=====");
829 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
830 if (function_units
[unit
].bitmask
& target_units
)
831 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
832 fprintf (sched_dump
, " %-33s", "==============================");
833 fprintf (sched_dump
, " %-8s\n", "=======");
835 /* Print insns in each cycle. */
836 fprintf (sched_dump
, "%s\n", visual_tbl
);
839 /* Print insns in the 'no_unit' column of visualization. */
842 visualize_no_unit (insn
)
845 vis_no_unit
[n_vis_no_unit
] = insn
;
849 /* Print insns scheduled in clock, for visualization. */
852 visualize_scheduled_insns (clock
)
857 /* If no more room, split table into two. */
858 if (n_visual_lines
>= MAX_VISUAL_LINES
)
860 print_block_visualization ("(incomplete)");
861 init_block_visualization ();
866 sprintf (visual_tbl
+ strlen (visual_tbl
), ";; %-8d", clock
);
867 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
868 if (function_units
[unit
].bitmask
& target_units
)
869 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
871 int instance
= unit
+ i
* FUNCTION_UNITS_SIZE
;
872 rtx insn
= get_unit_last_insn (instance
);
874 /* Print insns that still keep the unit busy. */
876 && actual_hazard_this_instance (unit
, instance
, insn
, clock
, 0))
879 print_insn (str
, insn
, 0);
880 str
[INSN_LEN
] = '\0';
881 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", str
);
884 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", "------------------------------");
887 /* Print insns that are not assigned to any unit. */
888 for (i
= 0; i
< n_vis_no_unit
; i
++)
889 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-8d",
890 INSN_UID (vis_no_unit
[i
]));
893 sprintf (visual_tbl
+ strlen (visual_tbl
), "\n");
896 /* Print stalled cycles. */
899 visualize_stall_cycles (stalls
)
903 const char *prefix
= ";; ";
904 const char *suffix
= "\n";
907 /* If no more room, split table into two. */
908 if (n_visual_lines
>= MAX_VISUAL_LINES
)
910 print_block_visualization ("(incomplete)");
911 init_block_visualization ();
916 p
= visual_tbl
+ strlen (visual_tbl
);
918 p
+= strlen (prefix
);
920 if ((unsigned)stalls
>
921 visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
))
924 stalls
= visual_tbl_line_length
- strlen (prefix
) - strlen (suffix
);
927 memset (p
, '.', stalls
);
933 /* Allocate data used for visualization during scheduling. */
938 visual_tbl
= xmalloc (get_visual_tbl_length ());
941 /* Free data used for visualization. */