OSDN Git Service

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