OSDN Git Service

* parse.y (nomods_initdcl0): Do not move stack entries
[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 #include "target.h"
35
36 #ifdef INSN_SCHEDULING
37 /* target_units bitmask has 1 for each unit in the cpu.  It should be
38    possible to compute this variable from the machine description.
39    But currently it is computed by examining the insn list.  Since
40    this is only needed for visualization, it seems an acceptable
41    solution.  (For understanding the mapping of bits to units, see
42    definition of function_units[] in "insn-attrtab.c".)  The scheduler
43    using only DFA description should never use the following variable.  */
44
45 static int target_units = 0;
46
47 static char *safe_concat PARAMS ((char *, char *, const char *));
48 static int get_visual_tbl_length PARAMS ((void));
49 static void print_exp PARAMS ((char *, rtx, int));
50 static void print_value PARAMS ((char *, rtx, int));
51 static void print_pattern PARAMS ((char *, rtx, int));
52 static void print_insn 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       sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
565       cur = safe_concat (buf, cur, t);
566       break;
567     case CONST_STRING:
568       cur = safe_concat (buf, cur, "\"");
569       cur = safe_concat (buf, cur, XSTR (x, 0));
570       cur = safe_concat (buf, cur, "\"");
571       break;
572     case SYMBOL_REF:
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 LABEL_REF:
578       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
579       cur = safe_concat (buf, cur, t);
580       break;
581     case CONST:
582       print_value (t, XEXP (x, 0), verbose);
583       cur = safe_concat (buf, cur, "const(");
584       cur = safe_concat (buf, cur, t);
585       cur = safe_concat (buf, cur, ")");
586       break;
587     case HIGH:
588       print_value (t, XEXP (x, 0), verbose);
589       cur = safe_concat (buf, cur, "high(");
590       cur = safe_concat (buf, cur, t);
591       cur = safe_concat (buf, cur, ")");
592       break;
593     case REG:
594       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
595         {
596           int c = reg_names[REGNO (x)][0];
597           if (ISDIGIT (c))
598             cur = safe_concat (buf, cur, "%");
599
600           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
601         }
602       else
603         {
604           sprintf (t, "r%d", REGNO (x));
605           cur = safe_concat (buf, cur, t);
606         }
607       break;
608     case SUBREG:
609       print_value (t, SUBREG_REG (x), verbose);
610       cur = safe_concat (buf, cur, t);
611       sprintf (t, "#%d", SUBREG_BYTE (x));
612       cur = safe_concat (buf, cur, t);
613       break;
614     case SCRATCH:
615       cur = safe_concat (buf, cur, "scratch");
616       break;
617     case CC0:
618       cur = safe_concat (buf, cur, "cc0");
619       break;
620     case PC:
621       cur = safe_concat (buf, cur, "pc");
622       break;
623     case MEM:
624       print_value (t, XEXP (x, 0), verbose);
625       cur = safe_concat (buf, cur, "[");
626       cur = safe_concat (buf, cur, t);
627       cur = safe_concat (buf, cur, "]");
628       break;
629     default:
630       print_exp (t, x, verbose);
631       cur = safe_concat (buf, cur, t);
632       break;
633     }
634 }                               /* print_value */
635
636 /* The next step in insn detalization, its pattern recognition.  */
637
638 static void
639 print_pattern (buf, x, verbose)
640      char *buf;
641      rtx x;
642      int verbose;
643 {
644   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
645
646   switch (GET_CODE (x))
647     {
648     case SET:
649       print_value (t1, SET_DEST (x), verbose);
650       print_value (t2, SET_SRC (x), verbose);
651       sprintf (buf, "%s=%s", t1, t2);
652       break;
653     case RETURN:
654       sprintf (buf, "return");
655       break;
656     case CALL:
657       print_exp (buf, x, verbose);
658       break;
659     case CLOBBER:
660       print_value (t1, XEXP (x, 0), verbose);
661       sprintf (buf, "clobber %s", t1);
662       break;
663     case USE:
664       print_value (t1, XEXP (x, 0), verbose);
665       sprintf (buf, "use %s", t1);
666       break;
667     case COND_EXEC:
668       if (GET_CODE (COND_EXEC_TEST (x)) == NE
669           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
670         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
671       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
672                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
673         {
674           t1[0] = '!';
675           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
676         }
677       else
678         print_value (t1, COND_EXEC_TEST (x), verbose);
679       print_pattern (t2, COND_EXEC_CODE (x), verbose);
680       sprintf (buf, "(%s) %s", t1, t2);
681       break;
682     case PARALLEL:
683       {
684         int i;
685
686         sprintf (t1, "{");
687         for (i = 0; i < XVECLEN (x, 0); i++)
688           {
689             print_pattern (t2, XVECEXP (x, 0, i), verbose);
690             sprintf (t3, "%s%s;", t1, t2);
691             strcpy (t1, t3);
692           }
693         sprintf (buf, "%s}", t1);
694       }
695       break;
696     case SEQUENCE:
697       {
698         int i;
699
700         sprintf (t1, "%%{");
701         for (i = 0; i < XVECLEN (x, 0); i++)
702           {
703             print_insn (t2, XVECEXP (x, 0, i), verbose);
704             sprintf (t3, "%s%s;", t1, t2);
705             strcpy (t1, t3);
706           }
707         sprintf (buf, "%s%%}", t1);
708       }
709       break;
710     case ASM_INPUT:
711       sprintf (buf, "asm {%s}", XSTR (x, 0));
712       break;
713     case ADDR_VEC:
714       break;
715     case ADDR_DIFF_VEC:
716       print_value (buf, XEXP (x, 0), verbose);
717       break;
718     case TRAP_IF:
719       print_value (t1, TRAP_CONDITION (x), verbose);
720       sprintf (buf, "trap_if %s", t1);
721       break;
722     case UNSPEC:
723       {
724         int i;
725
726         sprintf (t1, "unspec{");
727         for (i = 0; i < XVECLEN (x, 0); i++)
728           {
729             print_pattern (t2, XVECEXP (x, 0, i), verbose);
730             sprintf (t3, "%s%s;", t1, t2);
731             strcpy (t1, t3);
732           }
733         sprintf (buf, "%s}", t1);
734       }
735       break;
736     case UNSPEC_VOLATILE:
737       {
738         int i;
739
740         sprintf (t1, "unspec/v{");
741         for (i = 0; i < XVECLEN (x, 0); i++)
742           {
743             print_pattern (t2, XVECEXP (x, 0, i), verbose);
744             sprintf (t3, "%s%s;", t1, t2);
745             strcpy (t1, t3);
746           }
747         sprintf (buf, "%s}", t1);
748       }
749       break;
750     default:
751       print_value (buf, x, verbose);
752     }
753 }                               /* print_pattern */
754
755 /* This is the main function in rtl visualization mechanism. It
756    accepts an rtx and tries to recognize it as an insn, then prints it
757    properly in human readable form, resembling assembler mnemonics.
758    For every insn it prints its UID and BB the insn belongs too.
759    (Probably the last "option" should be extended somehow, since it
760    depends now on sched.c inner variables ...)  */
761
762 static void
763 print_insn (buf, x, verbose)
764      char *buf;
765      rtx x;
766      int verbose;
767 {
768   char t[BUF_LEN];
769   rtx insn = x;
770
771   switch (GET_CODE (x))
772     {
773     case INSN:
774       print_pattern (t, PATTERN (x), verbose);
775       if (verbose)
776         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
777                  t);
778       else
779         sprintf (buf, "%-4d %s", INSN_UID (x), t);
780       break;
781     case JUMP_INSN:
782       print_pattern (t, PATTERN (x), verbose);
783       if (verbose)
784         sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
785                  t);
786       else
787         sprintf (buf, "%-4d %s", INSN_UID (x), t);
788       break;
789     case CALL_INSN:
790       x = PATTERN (insn);
791       if (GET_CODE (x) == PARALLEL)
792         {
793           x = XVECEXP (x, 0, 0);
794           print_pattern (t, x, verbose);
795         }
796       else
797         strcpy (t, "call <...>");
798       if (verbose)
799         sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
800       else
801         sprintf (buf, "%-4d %s", INSN_UID (insn), t);
802       break;
803     case CODE_LABEL:
804       sprintf (buf, "L%d:", INSN_UID (x));
805       break;
806     case BARRIER:
807       sprintf (buf, "i% 4d: barrier", INSN_UID (x));
808       break;
809     case NOTE:
810       if (NOTE_LINE_NUMBER (x) > 0)
811         sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
812                  NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
813       else
814         sprintf (buf, "%4d %s", INSN_UID (x),
815                  GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
816       break;
817     default:
818       if (verbose)
819         {
820           sprintf (buf, "Not an INSN at all\n");
821           debug_rtx (x);
822         }
823       else
824         sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
825     }
826 }                               /* print_insn */
827
828 /* Print visualization debugging info.  The scheduler using only DFA
829    description should never use the following function.  */
830
831 void
832 print_block_visualization (s)
833      const char *s;
834 {
835   int unit, i;
836
837   /* Print header.  */
838   fprintf (sched_dump, "\n;;   ==================== scheduling visualization %s \n", s);
839
840   /* Print names of units.  */
841   fprintf (sched_dump, ";;   %-8s", "clock");
842   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
843     if (function_units[unit].bitmask & target_units)
844       for (i = 0; i < function_units[unit].multiplicity; i++)
845         fprintf (sched_dump, "  %-33s", function_units[unit].name);
846   fprintf (sched_dump, "  %-8s\n", "no-unit");
847
848   fprintf (sched_dump, ";;   %-8s", "=====");
849   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
850     if (function_units[unit].bitmask & target_units)
851       for (i = 0; i < function_units[unit].multiplicity; i++)
852         fprintf (sched_dump, "  %-33s", "==============================");
853   fprintf (sched_dump, "  %-8s\n", "=======");
854
855   /* Print insns in each cycle.  */
856   fprintf (sched_dump, "%s\n", visual_tbl);
857 }
858
859 /* Print insns in the 'no_unit' column of visualization.  */
860
861 void
862 visualize_no_unit (insn)
863      rtx insn;
864 {
865   if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
866     {
867       vis_no_unit[n_vis_no_unit] = insn;
868       n_vis_no_unit++;
869     }
870 }
871
872 /* Print insns scheduled in clock, for visualization.  */
873
874 void
875 visualize_scheduled_insns (clock)
876      int clock;
877 {
878   int i, unit;
879
880   /* If no more room, split table into two.  */
881   if (n_visual_lines >= MAX_VISUAL_LINES)
882     {
883       print_block_visualization ("(incomplete)");
884       init_block_visualization ();
885     }
886
887   n_visual_lines++;
888
889   sprintf (visual_tbl + strlen (visual_tbl), ";;   %-8d", clock);
890   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
891     if (function_units[unit].bitmask & target_units)
892       for (i = 0; i < function_units[unit].multiplicity; i++)
893         {
894           int instance = unit + i * FUNCTION_UNITS_SIZE;
895           rtx insn = get_unit_last_insn (instance);
896
897           /* Print insns that still keep the unit busy.  */
898           if (insn
899               && actual_hazard_this_instance (unit, instance, insn, clock, 0))
900             {
901               char str[BUF_LEN];
902               print_insn (str, insn, 0);
903               str[INSN_LEN] = '\0';
904               sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", str);
905             }
906           else
907             sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", "------------------------------");
908         }
909
910   /* Print insns that are not assigned to any unit.  */
911   for (i = 0; i < n_vis_no_unit; i++)
912     sprintf (visual_tbl + strlen (visual_tbl), "  %-8d",
913              INSN_UID (vis_no_unit[i]));
914   n_vis_no_unit = 0;
915
916   sprintf (visual_tbl + strlen (visual_tbl), "\n");
917 }
918
919 /* Print stalled cycles.  */
920
921 void
922 visualize_stall_cycles (stalls)
923      int stalls;
924 {
925   static const char *const prefix = ";;       ";
926   const char *suffix = "\n";
927   char *p;
928
929   /* If no more room, split table into two.  */
930   if (n_visual_lines >= MAX_VISUAL_LINES)
931     {
932       print_block_visualization ("(incomplete)");
933       init_block_visualization ();
934     }
935
936   n_visual_lines++;
937
938   p = visual_tbl + strlen (visual_tbl);
939   strcpy (p, prefix);
940   p += strlen (prefix);
941
942   if ((unsigned) stalls >
943       visual_tbl_line_length - strlen (prefix) - strlen (suffix))
944     {
945       suffix = "[...]\n";
946       stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
947     }
948
949   memset (p, '.', stalls);
950   p += stalls;
951
952   strcpy (p, suffix);
953 }
954
955 /* Allocate data used for visualization during scheduling.  */
956
957 void
958 visualize_alloc ()
959 {
960   visual_tbl = xmalloc (get_visual_tbl_length ());
961 }
962
963 /* Free data used for visualization.  */
964
965 void
966 visualize_free ()
967 {
968   free (visual_tbl);
969 }
970 #endif