OSDN Git Service

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