OSDN Git Service

* config/s390/s390.c (s390_emit_epilogue): Always restore registers
[pf3gnuchains/gcc-fork.git] / gcc / sched-vis.c
1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2002 Free Software Foundation, Inc.
4    Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5    and currently maintained by, Jim Wilson (wilson@cygnus.com)
6
7 This file is part of GCC.
8
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
12 version.
13
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
17 for more details.
18
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, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA.  */
23 \f
24 #include "config.h"
25 #include "system.h"
26 #include "toplev.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "regs.h"
30 #include "hard-reg-set.h"
31 #include "basic-block.h"
32 #include "insn-attr.h"
33 #include "sched-int.h"
34
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".)  */
42
43 static int target_units = 0;
44
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));
51
52 /* Print names of units on which insn can/should execute, for debugging.  */
53
54 void
55 insn_print_units (insn)
56      rtx insn;
57 {
58   int i;
59   int unit = insn_unit (insn);
60
61   if (unit == -1)
62     fprintf (sched_dump, "none");
63   else if (unit >= 0)
64     fprintf (sched_dump, "%s", function_units[unit].name);
65   else
66     {
67       fprintf (sched_dump, "[");
68       for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
69         if (unit & 1)
70           {
71             fprintf (sched_dump, "%s", function_units[i].name);
72             if (unit != 1)
73               fprintf (sched_dump, " ");
74           }
75       fprintf (sched_dump, "]");
76     }
77 }
78
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
85 #define INSN_LEN 30
86 int n_visual_lines;
87 static unsigned visual_tbl_line_length;
88 char *visual_tbl;
89 int n_vis_no_unit;
90 #define MAX_VISUAL_NO_UNIT 20
91 rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
92
93 /* Finds units that are in use in this function.  Required only
94    for visualization.  */
95
96 void
97 init_target_units ()
98 {
99   rtx insn;
100   int unit;
101
102   for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
103     {
104       if (! INSN_P (insn))
105         continue;
106
107       unit = insn_unit (insn);
108
109       if (unit < 0)
110         target_units |= ~unit;
111       else
112         target_units |= (1 << unit);
113     }
114 }
115
116 /* Return the length of the visualization table.  */
117
118 static int
119 get_visual_tbl_length ()
120 {
121   int unit, i;
122   int n, n1;
123   char *s;
124
125   /* Compute length of one field in line.  */
126   s = (char *) alloca (INSN_LEN + 6);
127   sprintf (s, "  %33s", "uname");
128   n1 = strlen (s);
129
130   /* Compute length of one line.  */
131   n = strlen (";; ");
132   n += n1;
133   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
134     if (function_units[unit].bitmask & target_units)
135       for (i = 0; i < function_units[unit].multiplicity; i++)
136         n += n1;
137   n += n1;
138   n += strlen ("\n") + 2;
139
140   visual_tbl_line_length = n;
141
142   /* Compute length of visualization string.  */
143   return (MAX_VISUAL_LINES * n);
144 }
145
146 /* Init block visualization debugging info.  */
147
148 void
149 init_block_visualization ()
150 {
151   strcpy (visual_tbl, "");
152   n_visual_lines = 0;
153   n_vis_no_unit = 0;
154 }
155
156 #define BUF_LEN 2048
157
158 static char *
159 safe_concat (buf, cur, str)
160      char *buf;
161      char *cur;
162      const char *str;
163 {
164   char *end = buf + BUF_LEN - 2;        /* Leave room for null.  */
165   int c;
166
167   if (cur > end)
168     {
169       *end = '\0';
170       return end;
171     }
172
173   while (cur < end && (c = *str++) != '\0')
174     *cur++ = c;
175
176   *cur = '\0';
177   return cur;
178 }
179
180 /* This recognizes rtx, I classified as expressions.  These are always
181    represent some action on values or results of other expression, that
182    may be stored in objects representing values.  */
183
184 static void
185 print_exp (buf, x, verbose)
186      char *buf;
187      rtx x;
188      int verbose;
189 {
190   char tmp[BUF_LEN];
191   const char *st[4];
192   char *cur = buf;
193   const char *fun = (char *) 0;
194   const char *sep;
195   rtx op[4];
196   int i;
197
198   for (i = 0; i < 4; i++)
199     {
200       st[i] = (char *) 0;
201       op[i] = NULL_RTX;
202     }
203
204   switch (GET_CODE (x))
205     {
206     case PLUS:
207       op[0] = XEXP (x, 0);
208       if (GET_CODE (XEXP (x, 1)) == CONST_INT
209           && INTVAL (XEXP (x, 1)) < 0)
210         {
211           st[1] = "-";
212           op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
213         }
214       else
215         {
216           st[1] = "+";
217           op[1] = XEXP (x, 1);
218         }
219       break;
220     case LO_SUM:
221       op[0] = XEXP (x, 0);
222       st[1] = "+low(";
223       op[1] = XEXP (x, 1);
224       st[2] = ")";
225       break;
226     case MINUS:
227       op[0] = XEXP (x, 0);
228       st[1] = "-";
229       op[1] = XEXP (x, 1);
230       break;
231     case COMPARE:
232       fun = "cmp";
233       op[0] = XEXP (x, 0);
234       op[1] = XEXP (x, 1);
235       break;
236     case NEG:
237       st[0] = "-";
238       op[0] = XEXP (x, 0);
239       break;
240     case MULT:
241       op[0] = XEXP (x, 0);
242       st[1] = "*";
243       op[1] = XEXP (x, 1);
244       break;
245     case DIV:
246       op[0] = XEXP (x, 0);
247       st[1] = "/";
248       op[1] = XEXP (x, 1);
249       break;
250     case UDIV:
251       fun = "udiv";
252       op[0] = XEXP (x, 0);
253       op[1] = XEXP (x, 1);
254       break;
255     case MOD:
256       op[0] = XEXP (x, 0);
257       st[1] = "%";
258       op[1] = XEXP (x, 1);
259       break;
260     case UMOD:
261       fun = "umod";
262       op[0] = XEXP (x, 0);
263       op[1] = XEXP (x, 1);
264       break;
265     case SMIN:
266       fun = "smin";
267       op[0] = XEXP (x, 0);
268       op[1] = XEXP (x, 1);
269       break;
270     case SMAX:
271       fun = "smax";
272       op[0] = XEXP (x, 0);
273       op[1] = XEXP (x, 1);
274       break;
275     case UMIN:
276       fun = "umin";
277       op[0] = XEXP (x, 0);
278       op[1] = XEXP (x, 1);
279       break;
280     case UMAX:
281       fun = "umax";
282       op[0] = XEXP (x, 0);
283       op[1] = XEXP (x, 1);
284       break;
285     case NOT:
286       st[0] = "!";
287       op[0] = XEXP (x, 0);
288       break;
289     case AND:
290       op[0] = XEXP (x, 0);
291       st[1] = "&";
292       op[1] = XEXP (x, 1);
293       break;
294     case IOR:
295       op[0] = XEXP (x, 0);
296       st[1] = "|";
297       op[1] = XEXP (x, 1);
298       break;
299     case XOR:
300       op[0] = XEXP (x, 0);
301       st[1] = "^";
302       op[1] = XEXP (x, 1);
303       break;
304     case ASHIFT:
305       op[0] = XEXP (x, 0);
306       st[1] = "<<";
307       op[1] = XEXP (x, 1);
308       break;
309     case LSHIFTRT:
310       op[0] = XEXP (x, 0);
311       st[1] = " 0>>";
312       op[1] = XEXP (x, 1);
313       break;
314     case ASHIFTRT:
315       op[0] = XEXP (x, 0);
316       st[1] = ">>";
317       op[1] = XEXP (x, 1);
318       break;
319     case ROTATE:
320       op[0] = XEXP (x, 0);
321       st[1] = "<-<";
322       op[1] = XEXP (x, 1);
323       break;
324     case ROTATERT:
325       op[0] = XEXP (x, 0);
326       st[1] = ">->";
327       op[1] = XEXP (x, 1);
328       break;
329     case ABS:
330       fun = "abs";
331       op[0] = XEXP (x, 0);
332       break;
333     case SQRT:
334       fun = "sqrt";
335       op[0] = XEXP (x, 0);
336       break;
337     case FFS:
338       fun = "ffs";
339       op[0] = XEXP (x, 0);
340       break;
341     case EQ:
342       op[0] = XEXP (x, 0);
343       st[1] = "==";
344       op[1] = XEXP (x, 1);
345       break;
346     case NE:
347       op[0] = XEXP (x, 0);
348       st[1] = "!=";
349       op[1] = XEXP (x, 1);
350       break;
351     case GT:
352       op[0] = XEXP (x, 0);
353       st[1] = ">";
354       op[1] = XEXP (x, 1);
355       break;
356     case GTU:
357       fun = "gtu";
358       op[0] = XEXP (x, 0);
359       op[1] = XEXP (x, 1);
360       break;
361     case LT:
362       op[0] = XEXP (x, 0);
363       st[1] = "<";
364       op[1] = XEXP (x, 1);
365       break;
366     case LTU:
367       fun = "ltu";
368       op[0] = XEXP (x, 0);
369       op[1] = XEXP (x, 1);
370       break;
371     case GE:
372       op[0] = XEXP (x, 0);
373       st[1] = ">=";
374       op[1] = XEXP (x, 1);
375       break;
376     case GEU:
377       fun = "geu";
378       op[0] = XEXP (x, 0);
379       op[1] = XEXP (x, 1);
380       break;
381     case LE:
382       op[0] = XEXP (x, 0);
383       st[1] = "<=";
384       op[1] = XEXP (x, 1);
385       break;
386     case LEU:
387       fun = "leu";
388       op[0] = XEXP (x, 0);
389       op[1] = XEXP (x, 1);
390       break;
391     case SIGN_EXTRACT:
392       fun = (verbose) ? "sign_extract" : "sxt";
393       op[0] = XEXP (x, 0);
394       op[1] = XEXP (x, 1);
395       op[2] = XEXP (x, 2);
396       break;
397     case ZERO_EXTRACT:
398       fun = (verbose) ? "zero_extract" : "zxt";
399       op[0] = XEXP (x, 0);
400       op[1] = XEXP (x, 1);
401       op[2] = XEXP (x, 2);
402       break;
403     case SIGN_EXTEND:
404       fun = (verbose) ? "sign_extend" : "sxn";
405       op[0] = XEXP (x, 0);
406       break;
407     case ZERO_EXTEND:
408       fun = (verbose) ? "zero_extend" : "zxn";
409       op[0] = XEXP (x, 0);
410       break;
411     case FLOAT_EXTEND:
412       fun = (verbose) ? "float_extend" : "fxn";
413       op[0] = XEXP (x, 0);
414       break;
415     case TRUNCATE:
416       fun = (verbose) ? "trunc" : "trn";
417       op[0] = XEXP (x, 0);
418       break;
419     case FLOAT_TRUNCATE:
420       fun = (verbose) ? "float_trunc" : "ftr";
421       op[0] = XEXP (x, 0);
422       break;
423     case FLOAT:
424       fun = (verbose) ? "float" : "flt";
425       op[0] = XEXP (x, 0);
426       break;
427     case UNSIGNED_FLOAT:
428       fun = (verbose) ? "uns_float" : "ufl";
429       op[0] = XEXP (x, 0);
430       break;
431     case FIX:
432       fun = "fix";
433       op[0] = XEXP (x, 0);
434       break;
435     case UNSIGNED_FIX:
436       fun = (verbose) ? "uns_fix" : "ufx";
437       op[0] = XEXP (x, 0);
438       break;
439     case PRE_DEC:
440       st[0] = "--";
441       op[0] = XEXP (x, 0);
442       break;
443     case PRE_INC:
444       st[0] = "++";
445       op[0] = XEXP (x, 0);
446       break;
447     case POST_DEC:
448       op[0] = XEXP (x, 0);
449       st[1] = "--";
450       break;
451     case POST_INC:
452       op[0] = XEXP (x, 0);
453       st[1] = "++";
454       break;
455     case CALL:
456       st[0] = "call ";
457       op[0] = XEXP (x, 0);
458       if (verbose)
459         {
460           st[1] = " argc:";
461           op[1] = XEXP (x, 1);
462         }
463       break;
464     case IF_THEN_ELSE:
465       st[0] = "{(";
466       op[0] = XEXP (x, 0);
467       st[1] = ")?";
468       op[1] = XEXP (x, 1);
469       st[2] = ":";
470       op[2] = XEXP (x, 2);
471       st[3] = "}";
472       break;
473     case TRAP_IF:
474       fun = "trap_if";
475       op[0] = TRAP_CONDITION (x);
476       break;
477     case PREFETCH:
478       fun = "prefetch";
479       op[0] = XEXP (x, 0);
480       op[1] = XEXP (x, 1);
481       op[2] = XEXP (x, 2);
482       break;
483     case UNSPEC:
484     case UNSPEC_VOLATILE:
485       {
486         cur = safe_concat (buf, cur, "unspec");
487         if (GET_CODE (x) == UNSPEC_VOLATILE)
488           cur = safe_concat (buf, cur, "/v");
489         cur = safe_concat (buf, cur, "[");
490         sep = "";
491         for (i = 0; i < XVECLEN (x, 0); i++)
492           {
493             print_pattern (tmp, XVECEXP (x, 0, i), verbose);
494             cur = safe_concat (buf, cur, sep);
495             cur = safe_concat (buf, cur, tmp);
496             sep = ",";
497           }
498         cur = safe_concat (buf, cur, "] ");
499         sprintf (tmp, "%d", XINT (x, 1));
500         cur = safe_concat (buf, cur, tmp);
501       }
502       break;
503     default:
504       /* If (verbose) debug_rtx (x);  */
505       st[0] = GET_RTX_NAME (GET_CODE (x));
506       break;
507     }
508
509   /* Print this as a function?  */
510   if (fun)
511     {
512       cur = safe_concat (buf, cur, fun);
513       cur = safe_concat (buf, cur, "(");
514     }
515
516   for (i = 0; i < 4; i++)
517     {
518       if (st[i])
519         cur = safe_concat (buf, cur, st[i]);
520
521       if (op[i])
522         {
523           if (fun && i != 0)
524             cur = safe_concat (buf, cur, ",");
525
526           print_value (tmp, op[i], verbose);
527           cur = safe_concat (buf, cur, tmp);
528         }
529     }
530
531   if (fun)
532     cur = safe_concat (buf, cur, ")");
533 }               /* print_exp */
534
535 /* Prints rtxes, I customly classified as values.  They're constants,
536    registers, labels, symbols and memory accesses.  */
537
538 static void
539 print_value (buf, x, verbose)
540      char *buf;
541      rtx x;
542      int verbose;
543 {
544   char t[BUF_LEN];
545   char *cur = buf;
546
547   switch (GET_CODE (x))
548     {
549     case CONST_INT:
550       sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
551       cur = safe_concat (buf, cur, t);
552       break;
553     case CONST_DOUBLE:
554       sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
555       cur = safe_concat (buf, cur, t);
556       break;
557     case CONST_STRING:
558       cur = safe_concat (buf, cur, "\"");
559       cur = safe_concat (buf, cur, XSTR (x, 0));
560       cur = safe_concat (buf, cur, "\"");
561       break;
562     case SYMBOL_REF:
563       cur = safe_concat (buf, cur, "`");
564       cur = safe_concat (buf, cur, XSTR (x, 0));
565       cur = safe_concat (buf, cur, "'");
566       break;
567     case LABEL_REF:
568       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
569       cur = safe_concat (buf, cur, t);
570       break;
571     case CONST:
572       print_value (t, XEXP (x, 0), verbose);
573       cur = safe_concat (buf, cur, "const(");
574       cur = safe_concat (buf, cur, t);
575       cur = safe_concat (buf, cur, ")");
576       break;
577     case HIGH:
578       print_value (t, XEXP (x, 0), verbose);
579       cur = safe_concat (buf, cur, "high(");
580       cur = safe_concat (buf, cur, t);
581       cur = safe_concat (buf, cur, ")");
582       break;
583     case REG:
584       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
585         {
586           int c = reg_names[REGNO (x)][0];
587           if (ISDIGIT (c))
588             cur = safe_concat (buf, cur, "%");
589
590           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
591         }
592       else
593         {
594           sprintf (t, "r%d", REGNO (x));
595           cur = safe_concat (buf, cur, t);
596         }
597       break;
598     case SUBREG:
599       print_value (t, SUBREG_REG (x), verbose);
600       cur = safe_concat (buf, cur, t);
601       sprintf (t, "#%d", SUBREG_BYTE (x));
602       cur = safe_concat (buf, cur, t);
603       break;
604     case SCRATCH:
605       cur = safe_concat (buf, cur, "scratch");
606       break;
607     case CC0:
608       cur = safe_concat (buf, cur, "cc0");
609       break;
610     case PC:
611       cur = safe_concat (buf, cur, "pc");
612       break;
613     case MEM:
614       print_value (t, XEXP (x, 0), verbose);
615       cur = safe_concat (buf, cur, "[");
616       cur = safe_concat (buf, cur, t);
617       cur = safe_concat (buf, cur, "]");
618       break;
619     default:
620       print_exp (t, x, verbose);
621       cur = safe_concat (buf, cur, t);
622       break;
623     }
624 }                               /* print_value */
625
626 /* The next step in insn detalization, its pattern recognition.  */
627
628 static void
629 print_pattern (buf, x, verbose)
630      char *buf;
631      rtx x;
632      int verbose;
633 {
634   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
635
636   switch (GET_CODE (x))
637     {
638     case SET:
639       print_value (t1, SET_DEST (x), verbose);
640       print_value (t2, SET_SRC (x), verbose);
641       sprintf (buf, "%s=%s", t1, t2);
642       break;
643     case RETURN:
644       sprintf (buf, "return");
645       break;
646     case CALL:
647       print_exp (buf, x, verbose);
648       break;
649     case CLOBBER:
650       print_value (t1, XEXP (x, 0), verbose);
651       sprintf (buf, "clobber %s", t1);
652       break;
653     case USE:
654       print_value (t1, XEXP (x, 0), verbose);
655       sprintf (buf, "use %s", t1);
656       break;
657     case COND_EXEC:
658       if (GET_CODE (COND_EXEC_TEST (x)) == NE
659           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
660         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
661       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
662                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
663         {
664           t1[0] = '!';
665           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
666         }
667       else
668         print_value (t1, COND_EXEC_TEST (x), verbose);
669       print_pattern (t2, COND_EXEC_CODE (x), verbose);
670       sprintf (buf, "(%s) %s", t1, t2);
671       break;
672     case PARALLEL:
673       {
674         int i;
675
676         sprintf (t1, "{");
677         for (i = 0; i < XVECLEN (x, 0); i++)
678           {
679             print_pattern (t2, XVECEXP (x, 0, i), verbose);
680             sprintf (t3, "%s%s;", t1, t2);
681             strcpy (t1, t3);
682           }
683         sprintf (buf, "%s}", t1);
684       }
685       break;
686     case SEQUENCE:
687       {
688         int i;
689
690         sprintf (t1, "%%{");
691         for (i = 0; i < XVECLEN (x, 0); i++)
692           {
693             print_insn (t2, XVECEXP (x, 0, i), verbose);
694             sprintf (t3, "%s%s;", t1, t2);
695             strcpy (t1, t3);
696           }
697         sprintf (buf, "%s%%}", t1);
698       }
699       break;
700     case ASM_INPUT:
701       sprintf (buf, "asm {%s}", XSTR (x, 0));
702       break;
703     case ADDR_VEC:
704       break;
705     case ADDR_DIFF_VEC:
706       print_value (buf, XEXP (x, 0), verbose);
707       break;
708     case TRAP_IF:
709       print_value (t1, TRAP_CONDITION (x), verbose);
710       sprintf (buf, "trap_if %s", t1);
711       break;
712     case UNSPEC:
713       {
714         int i;
715
716         sprintf (t1, "unspec{");
717         for (i = 0; i < XVECLEN (x, 0); i++)
718           {
719             print_pattern (t2, XVECEXP (x, 0, i), verbose);
720             sprintf (t3, "%s%s;", t1, t2);
721             strcpy (t1, t3);
722           }
723         sprintf (buf, "%s}", t1);
724       }
725       break;
726     case UNSPEC_VOLATILE:
727       {
728         int i;
729
730         sprintf (t1, "unspec/v{");
731         for (i = 0; i < XVECLEN (x, 0); i++)
732           {
733             print_pattern (t2, XVECEXP (x, 0, i), verbose);
734             sprintf (t3, "%s%s;", t1, t2);
735             strcpy (t1, t3);
736           }
737         sprintf (buf, "%s}", t1);
738       }
739       break;
740     default:
741       print_value (buf, x, verbose);
742     }
743 }                               /* print_pattern */
744
745 /* This is the main function in rtl visualization mechanism. It
746    accepts an rtx and tries to recognize it as an insn, then prints it
747    properly in human readable form, resembling assembler mnemonics.
748    For every insn it prints its UID and BB the insn belongs too.
749    (Probably the last "option" should be extended somehow, since it
750    depends now on sched.c inner variables ...)  */
751
752 static void
753 print_insn (buf, x, verbose)
754      char *buf;
755      rtx x;
756      int verbose;
757 {
758   char t[BUF_LEN];
759   rtx insn = x;
760
761   switch (GET_CODE (x))
762     {
763     case INSN:
764       print_pattern (t, PATTERN (x), verbose);
765       if (verbose)
766         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
767                  t);
768       else
769         sprintf (buf, "%-4d %s", INSN_UID (x), t);
770       break;
771     case JUMP_INSN:
772       print_pattern (t, PATTERN (x), verbose);
773       if (verbose)
774         sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
775                  t);
776       else
777         sprintf (buf, "%-4d %s", INSN_UID (x), t);
778       break;
779     case CALL_INSN:
780       x = PATTERN (insn);
781       if (GET_CODE (x) == PARALLEL)
782         {
783           x = XVECEXP (x, 0, 0);
784           print_pattern (t, x, verbose);
785         }
786       else
787         strcpy (t, "call <...>");
788       if (verbose)
789         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
790       else
791         sprintf (buf, "%-4d %s", INSN_UID (insn), t);
792       break;
793     case CODE_LABEL:
794       sprintf (buf, "L%d:", INSN_UID (x));
795       break;
796     case BARRIER:
797       sprintf (buf, "i% 4d: barrier", INSN_UID (x));
798       break;
799     case NOTE:
800       if (NOTE_LINE_NUMBER (x) > 0)
801         sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
802                  NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
803       else
804         sprintf (buf, "%4d %s", INSN_UID (x),
805                  GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
806       break;
807     default:
808       if (verbose)
809         {
810           sprintf (buf, "Not an INSN at all\n");
811           debug_rtx (x);
812         }
813       else
814         sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
815     }
816 }                               /* print_insn */
817
818 /* Print visualization debugging info.  */
819
820 void
821 print_block_visualization (s)
822      const char *s;
823 {
824   int unit, i;
825
826   /* Print header.  */
827   fprintf (sched_dump, "\n;;   ==================== scheduling visualization %s \n", s);
828
829   /* Print names of units.  */
830   fprintf (sched_dump, ";;   %-8s", "clock");
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", function_units[unit].name);
835   fprintf (sched_dump, "  %-8s\n", "no-unit");
836
837   fprintf (sched_dump, ";;   %-8s", "=====");
838   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
839     if (function_units[unit].bitmask & target_units)
840       for (i = 0; i < function_units[unit].multiplicity; i++)
841         fprintf (sched_dump, "  %-33s", "==============================");
842   fprintf (sched_dump, "  %-8s\n", "=======");
843
844   /* Print insns in each cycle.  */
845   fprintf (sched_dump, "%s\n", visual_tbl);
846 }
847
848 /* Print insns in the 'no_unit' column of visualization.  */
849
850 void
851 visualize_no_unit (insn)
852      rtx insn;
853 {
854   if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
855     {
856       vis_no_unit[n_vis_no_unit] = insn;
857       n_vis_no_unit++;
858     }
859 }
860
861 /* Print insns scheduled in clock, for visualization.  */
862
863 void
864 visualize_scheduled_insns (clock)
865      int clock;
866 {
867   int i, unit;
868
869   /* If no more room, split table into two.  */
870   if (n_visual_lines >= MAX_VISUAL_LINES)
871     {
872       print_block_visualization ("(incomplete)");
873       init_block_visualization ();
874     }
875
876   n_visual_lines++;
877
878   sprintf (visual_tbl + strlen (visual_tbl), ";;   %-8d", clock);
879   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
880     if (function_units[unit].bitmask & target_units)
881       for (i = 0; i < function_units[unit].multiplicity; i++)
882         {
883           int instance = unit + i * FUNCTION_UNITS_SIZE;
884           rtx insn = get_unit_last_insn (instance);
885
886           /* Print insns that still keep the unit busy.  */
887           if (insn
888               && actual_hazard_this_instance (unit, instance, insn, clock, 0))
889             {
890               char str[BUF_LEN];
891               print_insn (str, insn, 0);
892               str[INSN_LEN] = '\0';
893               sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", str);
894             }
895           else
896             sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", "------------------------------");
897         }
898
899   /* Print insns that are not assigned to any unit.  */
900   for (i = 0; i < n_vis_no_unit; i++)
901     sprintf (visual_tbl + strlen (visual_tbl), "  %-8d",
902              INSN_UID (vis_no_unit[i]));
903   n_vis_no_unit = 0;
904
905   sprintf (visual_tbl + strlen (visual_tbl), "\n");
906 }
907
908 /* Print stalled cycles.  */
909
910 void
911 visualize_stall_cycles (stalls)
912      int stalls;
913 {
914   static const char *const prefix = ";;       ";
915   const char *suffix = "\n";
916   char *p;
917
918   /* If no more room, split table into two.  */
919   if (n_visual_lines >= MAX_VISUAL_LINES)
920     {
921       print_block_visualization ("(incomplete)");
922       init_block_visualization ();
923     }
924
925   n_visual_lines++;
926
927   p = visual_tbl + strlen (visual_tbl);
928   strcpy (p, prefix);
929   p += strlen (prefix);
930
931   if ((unsigned) stalls >
932       visual_tbl_line_length - strlen (prefix) - strlen (suffix))
933     {
934       suffix = "[...]\n";
935       stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
936     }
937
938   memset (p, '.', stalls);
939   p += stalls;
940
941   strcpy (p, suffix);
942 }
943
944 /* Allocate data used for visualization during scheduling.  */
945
946 void
947 visualize_alloc ()
948 {
949   visual_tbl = xmalloc (get_visual_tbl_length ());
950 }
951
952 /* Free data used for visualization.  */
953
954 void
955 visualize_free ()
956 {
957   free (visual_tbl);
958 }
959 #endif