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