OSDN Git Service

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