237d4460d51a43a3d0080a2f64d168c23425cda1
[platform/upstream/gcc.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         real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
566       else
567         sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
568       cur = safe_concat (buf, cur, t);
569       break;
570     case CONST_STRING:
571       cur = safe_concat (buf, cur, "\"");
572       cur = safe_concat (buf, cur, XSTR (x, 0));
573       cur = safe_concat (buf, cur, "\"");
574       break;
575     case SYMBOL_REF:
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 LABEL_REF:
581       sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
582       cur = safe_concat (buf, cur, t);
583       break;
584     case CONST:
585       print_value (t, XEXP (x, 0), verbose);
586       cur = safe_concat (buf, cur, "const(");
587       cur = safe_concat (buf, cur, t);
588       cur = safe_concat (buf, cur, ")");
589       break;
590     case HIGH:
591       print_value (t, XEXP (x, 0), verbose);
592       cur = safe_concat (buf, cur, "high(");
593       cur = safe_concat (buf, cur, t);
594       cur = safe_concat (buf, cur, ")");
595       break;
596     case REG:
597       if (REGNO (x) < FIRST_PSEUDO_REGISTER)
598         {
599           int c = reg_names[REGNO (x)][0];
600           if (ISDIGIT (c))
601             cur = safe_concat (buf, cur, "%");
602
603           cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
604         }
605       else
606         {
607           sprintf (t, "r%d", REGNO (x));
608           cur = safe_concat (buf, cur, t);
609         }
610       break;
611     case SUBREG:
612       print_value (t, SUBREG_REG (x), verbose);
613       cur = safe_concat (buf, cur, t);
614       sprintf (t, "#%d", SUBREG_BYTE (x));
615       cur = safe_concat (buf, cur, t);
616       break;
617     case SCRATCH:
618       cur = safe_concat (buf, cur, "scratch");
619       break;
620     case CC0:
621       cur = safe_concat (buf, cur, "cc0");
622       break;
623     case PC:
624       cur = safe_concat (buf, cur, "pc");
625       break;
626     case MEM:
627       print_value (t, XEXP (x, 0), verbose);
628       cur = safe_concat (buf, cur, "[");
629       cur = safe_concat (buf, cur, t);
630       cur = safe_concat (buf, cur, "]");
631       break;
632     default:
633       print_exp (t, x, verbose);
634       cur = safe_concat (buf, cur, t);
635       break;
636     }
637 }                               /* print_value */
638
639 /* The next step in insn detalization, its pattern recognition.  */
640
641 static void
642 print_pattern (buf, x, verbose)
643      char *buf;
644      rtx x;
645      int verbose;
646 {
647   char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
648
649   switch (GET_CODE (x))
650     {
651     case SET:
652       print_value (t1, SET_DEST (x), verbose);
653       print_value (t2, SET_SRC (x), verbose);
654       sprintf (buf, "%s=%s", t1, t2);
655       break;
656     case RETURN:
657       sprintf (buf, "return");
658       break;
659     case CALL:
660       print_exp (buf, x, verbose);
661       break;
662     case CLOBBER:
663       print_value (t1, XEXP (x, 0), verbose);
664       sprintf (buf, "clobber %s", t1);
665       break;
666     case USE:
667       print_value (t1, XEXP (x, 0), verbose);
668       sprintf (buf, "use %s", t1);
669       break;
670     case COND_EXEC:
671       if (GET_CODE (COND_EXEC_TEST (x)) == NE
672           && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
673         print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
674       else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
675                && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
676         {
677           t1[0] = '!';
678           print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
679         }
680       else
681         print_value (t1, COND_EXEC_TEST (x), verbose);
682       print_pattern (t2, COND_EXEC_CODE (x), verbose);
683       sprintf (buf, "(%s) %s", t1, t2);
684       break;
685     case PARALLEL:
686       {
687         int i;
688
689         sprintf (t1, "{");
690         for (i = 0; i < XVECLEN (x, 0); i++)
691           {
692             print_pattern (t2, XVECEXP (x, 0, i), verbose);
693             sprintf (t3, "%s%s;", t1, t2);
694             strcpy (t1, t3);
695           }
696         sprintf (buf, "%s}", t1);
697       }
698       break;
699     case SEQUENCE:
700       /* Should never see SEQUENCE codes until after reorg.  */
701       abort ();
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 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   static const char *const 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