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
89 /* Finds units that are in use in this fuction. Required only
98 for (insn
= get_last_insn (); insn
; insn
= PREV_INSN (insn
))
103 unit
= insn_unit (insn
);
106 target_units
|= ~unit
;
108 target_units
|= (1 << unit
);
112 /* Return the length of the visualization table. */
115 get_visual_tbl_length ()
121 /* Compute length of one field in line. */
122 s
= (char *) alloca (INSN_LEN
+ 6);
123 sprintf (s
, " %33s", "uname");
126 /* Compute length of one line. */
129 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
130 if (function_units
[unit
].bitmask
& target_units
)
131 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
134 n
+= strlen ("\n") + 2;
136 /* Compute length of visualization string. */
137 return (MAX_VISUAL_LINES
* n
);
140 /* Init block visualization debugging info. */
143 init_block_visualization ()
145 strcpy (visual_tbl
, "");
153 safe_concat (buf
, cur
, str
)
158 char *end
= buf
+ BUF_LEN
- 2; /* Leave room for null. */
167 while (cur
< end
&& (c
= *str
++) != '\0')
174 /* This recognizes rtx, I classified as expressions. These are always
175 represent some action on values or results of other expression, that
176 may be stored in objects representing values. */
179 print_exp (buf
, x
, verbose
)
187 const char *fun
= (char *) 0;
192 for (i
= 0; i
< 4; i
++)
198 switch (GET_CODE (x
))
202 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
203 && INTVAL (XEXP (x
, 1)) < 0)
206 op
[1] = GEN_INT (-INTVAL (XEXP (x
, 1)));
386 fun
= (verbose
) ? "sign_extract" : "sxt";
392 fun
= (verbose
) ? "zero_extract" : "zxt";
398 fun
= (verbose
) ? "sign_extend" : "sxn";
402 fun
= (verbose
) ? "zero_extend" : "zxn";
406 fun
= (verbose
) ? "float_extend" : "fxn";
410 fun
= (verbose
) ? "trunc" : "trn";
414 fun
= (verbose
) ? "float_trunc" : "ftr";
418 fun
= (verbose
) ? "float" : "flt";
422 fun
= (verbose
) ? "uns_float" : "ufl";
430 fun
= (verbose
) ? "uns_fix" : "ufx";
469 op
[0] = TRAP_CONDITION (x
);
472 case UNSPEC_VOLATILE
:
474 cur
= safe_concat (buf
, cur
, "unspec");
475 if (GET_CODE (x
) == UNSPEC_VOLATILE
)
476 cur
= safe_concat (buf
, cur
, "/v");
477 cur
= safe_concat (buf
, cur
, "[");
479 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
481 print_pattern (tmp
, XVECEXP (x
, 0, i
), verbose
);
482 cur
= safe_concat (buf
, cur
, sep
);
483 cur
= safe_concat (buf
, cur
, tmp
);
486 cur
= safe_concat (buf
, cur
, "] ");
487 sprintf (tmp
, "%d", XINT (x
, 1));
488 cur
= safe_concat (buf
, cur
, tmp
);
492 /* If (verbose) debug_rtx (x); */
493 st
[0] = GET_RTX_NAME (GET_CODE (x
));
497 /* Print this as a function? */
500 cur
= safe_concat (buf
, cur
, fun
);
501 cur
= safe_concat (buf
, cur
, "(");
504 for (i
= 0; i
< 4; i
++)
507 cur
= safe_concat (buf
, cur
, st
[i
]);
512 cur
= safe_concat (buf
, cur
, ",");
514 print_value (tmp
, op
[i
], verbose
);
515 cur
= safe_concat (buf
, cur
, tmp
);
520 cur
= safe_concat (buf
, cur
, ")");
523 /* Prints rtxes, I customly classified as values. They're constants,
524 registers, labels, symbols and memory accesses. */
527 print_value (buf
, x
, verbose
)
535 switch (GET_CODE (x
))
538 sprintf (t
, HOST_WIDE_INT_PRINT_HEX
, INTVAL (x
));
539 cur
= safe_concat (buf
, cur
, t
);
542 sprintf (t
, "<0x%lx,0x%lx>", (long) XWINT (x
, 2), (long) XWINT (x
, 3));
543 cur
= safe_concat (buf
, cur
, t
);
546 cur
= safe_concat (buf
, cur
, "\"");
547 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
548 cur
= safe_concat (buf
, cur
, "\"");
551 cur
= safe_concat (buf
, cur
, "`");
552 cur
= safe_concat (buf
, cur
, XSTR (x
, 0));
553 cur
= safe_concat (buf
, cur
, "'");
556 sprintf (t
, "L%d", INSN_UID (XEXP (x
, 0)));
557 cur
= safe_concat (buf
, cur
, t
);
560 print_value (t
, XEXP (x
, 0), verbose
);
561 cur
= safe_concat (buf
, cur
, "const(");
562 cur
= safe_concat (buf
, cur
, t
);
563 cur
= safe_concat (buf
, cur
, ")");
566 print_value (t
, XEXP (x
, 0), verbose
);
567 cur
= safe_concat (buf
, cur
, "high(");
568 cur
= safe_concat (buf
, cur
, t
);
569 cur
= safe_concat (buf
, cur
, ")");
572 if (REGNO (x
) < FIRST_PSEUDO_REGISTER
)
574 int c
= reg_names
[REGNO (x
)][0];
575 if (c
>= '0' && c
<= '9')
576 cur
= safe_concat (buf
, cur
, "%");
578 cur
= safe_concat (buf
, cur
, reg_names
[REGNO (x
)]);
582 sprintf (t
, "r%d", REGNO (x
));
583 cur
= safe_concat (buf
, cur
, t
);
587 print_value (t
, SUBREG_REG (x
), verbose
);
588 cur
= safe_concat (buf
, cur
, t
);
589 sprintf (t
, "#%d", SUBREG_WORD (x
));
590 cur
= safe_concat (buf
, cur
, t
);
593 cur
= safe_concat (buf
, cur
, "scratch");
596 cur
= safe_concat (buf
, cur
, "cc0");
599 cur
= safe_concat (buf
, cur
, "pc");
602 print_value (t
, XEXP (x
, 0), verbose
);
603 cur
= safe_concat (buf
, cur
, "[");
604 cur
= safe_concat (buf
, cur
, t
);
605 cur
= safe_concat (buf
, cur
, "]");
608 print_exp (t
, x
, verbose
);
609 cur
= safe_concat (buf
, cur
, t
);
614 /* The next step in insn detalization, its pattern recognition. */
617 print_pattern (buf
, x
, verbose
)
622 char t1
[BUF_LEN
], t2
[BUF_LEN
], t3
[BUF_LEN
];
624 switch (GET_CODE (x
))
627 print_value (t1
, SET_DEST (x
), verbose
);
628 print_value (t2
, SET_SRC (x
), verbose
);
629 sprintf (buf
, "%s=%s", t1
, t2
);
632 sprintf (buf
, "return");
635 print_exp (buf
, x
, verbose
);
638 print_value (t1
, XEXP (x
, 0), verbose
);
639 sprintf (buf
, "clobber %s", t1
);
642 print_value (t1
, XEXP (x
, 0), verbose
);
643 sprintf (buf
, "use %s", t1
);
646 if (GET_CODE (COND_EXEC_TEST (x
)) == NE
647 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
648 print_value (t1
, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
649 else if (GET_CODE (COND_EXEC_TEST (x
)) == EQ
650 && XEXP (COND_EXEC_TEST (x
), 1) == const0_rtx
)
653 print_value (t1
+ 1, XEXP (COND_EXEC_TEST (x
), 0), verbose
);
656 print_value (t1
, COND_EXEC_TEST (x
), verbose
);
657 print_pattern (t2
, COND_EXEC_CODE (x
), verbose
);
658 sprintf (buf
, "(%s) %s", t1
, t2
);
665 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
667 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
668 sprintf (t3
, "%s%s;", t1
, t2
);
671 sprintf (buf
, "%s}", t1
);
679 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
681 print_insn (t2
, XVECEXP (x
, 0, i
), verbose
);
682 sprintf (t3
, "%s%s;", t1
, t2
);
685 sprintf (buf
, "%s%%}", t1
);
689 sprintf (buf
, "asm {%s}", XSTR (x
, 0));
694 print_value (buf
, XEXP (x
, 0), verbose
);
697 print_value (t1
, TRAP_CONDITION (x
), verbose
);
698 sprintf (buf
, "trap_if %s", t1
);
704 sprintf (t1
, "unspec{");
705 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
707 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
708 sprintf (t3
, "%s%s;", t1
, t2
);
711 sprintf (buf
, "%s}", t1
);
714 case UNSPEC_VOLATILE
:
718 sprintf (t1
, "unspec/v{");
719 for (i
= 0; i
< XVECLEN (x
, 0); i
++)
721 print_pattern (t2
, XVECEXP (x
, 0, i
), verbose
);
722 sprintf (t3
, "%s%s;", t1
, t2
);
725 sprintf (buf
, "%s}", t1
);
729 print_value (buf
, x
, verbose
);
731 } /* print_pattern */
733 /* This is the main function in rtl visualization mechanism. It
734 accepts an rtx and tries to recognize it as an insn, then prints it
735 properly in human readable form, resembling assembler mnemonics.
736 For every insn it prints its UID and BB the insn belongs too.
737 (Probably the last "option" should be extended somehow, since it
738 depends now on sched.c inner variables ...) */
741 print_insn (buf
, x
, verbose
)
749 switch (GET_CODE (x
))
752 print_pattern (t
, PATTERN (x
), verbose
);
754 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1),
757 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
760 print_pattern (t
, PATTERN (x
), verbose
);
762 sprintf (buf
, "%s: jump %s", (*current_sched_info
->print_insn
) (x
, 1),
765 sprintf (buf
, "%-4d %s", INSN_UID (x
), t
);
769 if (GET_CODE (x
) == PARALLEL
)
771 x
= XVECEXP (x
, 0, 0);
772 print_pattern (t
, x
, verbose
);
775 strcpy (t
, "call <...>");
777 sprintf (buf
, "%s: %s", (*current_sched_info
->print_insn
) (x
, 1), t
);
779 sprintf (buf
, "%-4d %s", INSN_UID (insn
), t
);
782 sprintf (buf
, "L%d:", INSN_UID (x
));
785 sprintf (buf
, "i% 4d: barrier", INSN_UID (x
));
788 if (NOTE_LINE_NUMBER (x
) > 0)
789 sprintf (buf
, "%4d note \"%s\" %d", INSN_UID (x
),
790 NOTE_SOURCE_FILE (x
), NOTE_LINE_NUMBER (x
));
792 sprintf (buf
, "%4d %s", INSN_UID (x
),
793 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x
)));
798 sprintf (buf
, "Not an INSN at all\n");
802 sprintf (buf
, "i%-4d <What?>", INSN_UID (x
));
806 /* Print visualization debugging info. */
809 print_block_visualization (s
)
815 fprintf (sched_dump
, "\n;; ==================== scheduling visualization %s \n", s
);
817 /* Print names of units. */
818 fprintf (sched_dump
, ";; %-8s", "clock");
819 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
820 if (function_units
[unit
].bitmask
& target_units
)
821 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
822 fprintf (sched_dump
, " %-33s", function_units
[unit
].name
);
823 fprintf (sched_dump
, " %-8s\n", "no-unit");
825 fprintf (sched_dump
, ";; %-8s", "=====");
826 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
827 if (function_units
[unit
].bitmask
& target_units
)
828 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
829 fprintf (sched_dump
, " %-33s", "==============================");
830 fprintf (sched_dump
, " %-8s\n", "=======");
832 /* Print insns in each cycle. */
833 fprintf (sched_dump
, "%s\n", visual_tbl
);
836 /* Print insns in the 'no_unit' column of visualization. */
839 visualize_no_unit (insn
)
842 vis_no_unit
[n_vis_no_unit
] = insn
;
846 /* Print insns scheduled in clock, for visualization. */
849 visualize_scheduled_insns (clock
)
854 /* If no more room, split table into two. */
855 if (n_visual_lines
>= MAX_VISUAL_LINES
)
857 print_block_visualization ("(incomplete)");
858 init_block_visualization ();
863 sprintf (visual_tbl
+ strlen (visual_tbl
), ";; %-8d", clock
);
864 for (unit
= 0; unit
< FUNCTION_UNITS_SIZE
; unit
++)
865 if (function_units
[unit
].bitmask
& target_units
)
866 for (i
= 0; i
< function_units
[unit
].multiplicity
; i
++)
868 int instance
= unit
+ i
* FUNCTION_UNITS_SIZE
;
869 rtx insn
= get_unit_last_insn (instance
);
871 /* Print insns that still keep the unit busy. */
873 && actual_hazard_this_instance (unit
, instance
, insn
, clock
, 0))
876 print_insn (str
, insn
, 0);
877 str
[INSN_LEN
] = '\0';
878 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", str
);
881 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-33s", "------------------------------");
884 /* Print insns that are not assigned to any unit. */
885 for (i
= 0; i
< n_vis_no_unit
; i
++)
886 sprintf (visual_tbl
+ strlen (visual_tbl
), " %-8d",
887 INSN_UID (vis_no_unit
[i
]));
890 sprintf (visual_tbl
+ strlen (visual_tbl
), "\n");
893 /* Print stalled cycles. */
896 visualize_stall_cycles (stalls
)
901 /* If no more room, split table into two. */
902 if (n_visual_lines
>= MAX_VISUAL_LINES
)
904 print_block_visualization ("(incomplete)");
905 init_block_visualization ();
910 sprintf (visual_tbl
+ strlen (visual_tbl
), ";; ");
911 for (i
= 0; i
< stalls
; i
++)
912 sprintf (visual_tbl
+ strlen (visual_tbl
), ".");
913 sprintf (visual_tbl
+ strlen (visual_tbl
), "\n");
916 /* Allocate data used for visualization during scheduling. */
921 visual_tbl
= xmalloc (get_visual_tbl_length ());
924 /* Free data used for visualization. */