OSDN Git Service

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