OSDN Git Service

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