1 /* Instruction scheduling pass.
2    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3    1999, 2000, 2002, 2003 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 
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
insn_print_units(rtx insn)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
init_target_units(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
get_visual_tbl_length(void)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
init_block_visualization(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 *
safe_concat(char * buf,char * cur,const char * str)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
print_exp(char * buf,rtx x,int verbose)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
print_value(char * buf,rtx x,int verbose)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
print_pattern(char * buf,rtx x,int verbose)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
print_insn(char * buf,rtx x,int verbose)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 	sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
791 		 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
792       else
793 	sprintf (buf, "%4d %s", INSN_UID (x),
794 		 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
795       break;
796     default:
797       if (verbose)
798 	{
799 	  sprintf (buf, "Not an INSN at all\n");
800 	  debug_rtx (x);
801 	}
802       else
803 	sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
804     }
805 }				/* print_insn */
806 
807 /* Print visualization debugging info.  The scheduler using only DFA
808    description should never use the following function.  */
809 
810 void
print_block_visualization(const char * s)811 print_block_visualization (const char *s)
812 {
813   int unit, i;
814 
815   /* Print header.  */
816   fprintf (sched_dump, "\n;;   ==================== scheduling visualization %s \n", s);
817 
818   /* Print names of units.  */
819   fprintf (sched_dump, ";;   %-8s", "clock");
820   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
821     if (function_units[unit].bitmask & target_units)
822       for (i = 0; i < function_units[unit].multiplicity; i++)
823 	fprintf (sched_dump, "  %-33s", function_units[unit].name);
824   fprintf (sched_dump, "  %-8s\n", "no-unit");
825 
826   fprintf (sched_dump, ";;   %-8s", "=====");
827   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
828     if (function_units[unit].bitmask & target_units)
829       for (i = 0; i < function_units[unit].multiplicity; i++)
830 	fprintf (sched_dump, "  %-33s", "==============================");
831   fprintf (sched_dump, "  %-8s\n", "=======");
832 
833   /* Print insns in each cycle.  */
834   fprintf (sched_dump, "%s\n", visual_tbl);
835 }
836 
837 /* Print insns in the 'no_unit' column of visualization.  */
838 
839 void
visualize_no_unit(rtx insn)840 visualize_no_unit (rtx insn)
841 {
842   if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
843     {
844       vis_no_unit[n_vis_no_unit] = insn;
845       n_vis_no_unit++;
846     }
847 }
848 
849 /* Print insns scheduled in clock, for visualization.  */
850 
851 void
visualize_scheduled_insns(int clock)852 visualize_scheduled_insns (int clock)
853 {
854   int i, unit;
855 
856   /* If no more room, split table into two.  */
857   if (n_visual_lines >= MAX_VISUAL_LINES)
858     {
859       print_block_visualization ("(incomplete)");
860       init_block_visualization ();
861     }
862 
863   n_visual_lines++;
864 
865   sprintf (visual_tbl + strlen (visual_tbl), ";;   %-8d", clock);
866   for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
867     if (function_units[unit].bitmask & target_units)
868       for (i = 0; i < function_units[unit].multiplicity; i++)
869 	{
870 	  int instance = unit + i * FUNCTION_UNITS_SIZE;
871 	  rtx insn = get_unit_last_insn (instance);
872 
873 	  /* Print insns that still keep the unit busy.  */
874 	  if (insn
875 	      && actual_hazard_this_instance (unit, instance, insn, clock, 0))
876 	    {
877 	      char str[BUF_LEN];
878 	      print_insn (str, insn, 0);
879 	      str[INSN_LEN] = '\0';
880 	      sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", str);
881 	    }
882 	  else
883 	    sprintf (visual_tbl + strlen (visual_tbl), "  %-33s", "------------------------------");
884 	}
885 
886   /* Print insns that are not assigned to any unit.  */
887   for (i = 0; i < n_vis_no_unit; i++)
888     sprintf (visual_tbl + strlen (visual_tbl), "  %-8d",
889 	     INSN_UID (vis_no_unit[i]));
890   n_vis_no_unit = 0;
891 
892   sprintf (visual_tbl + strlen (visual_tbl), "\n");
893 }
894 
895 /* Print stalled cycles.  */
896 
897 void
visualize_stall_cycles(int stalls)898 visualize_stall_cycles (int stalls)
899 {
900   static const char *const prefix = ";;       ";
901   const char *suffix = "\n";
902   char *p;
903 
904   /* If no more room, split table into two.  */
905   if (n_visual_lines >= MAX_VISUAL_LINES)
906     {
907       print_block_visualization ("(incomplete)");
908       init_block_visualization ();
909     }
910 
911   n_visual_lines++;
912 
913   p = visual_tbl + strlen (visual_tbl);
914   strcpy (p, prefix);
915   p += strlen (prefix);
916 
917   if ((unsigned) stalls >
918       visual_tbl_line_length - strlen (prefix) - strlen (suffix))
919     {
920       suffix = "[...]\n";
921       stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
922     }
923 
924   memset (p, '.', stalls);
925   p += stalls;
926 
927   strcpy (p, suffix);
928 }
929 
930 /* Allocate data used for visualization during scheduling.  */
931 
932 void
visualize_alloc(void)933 visualize_alloc (void)
934 {
935   visual_tbl = xmalloc (get_visual_tbl_length ());
936 }
937 
938 /* Free data used for visualization.  */
939 
940 void
visualize_free(void)941 visualize_free (void)
942 {
943   free (visual_tbl);
944 }
945 #endif
946