2002-04-24 Aldy Hernandez <aldyh@redhat.com>
[official-gcc.git] / gcc / sched-vis.c
blob2dd20d0cd506776193dd20fe882876895e71f75e
1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002 Free Software Foundation, Inc.
4 Contributed by Michael Tiemann (tiemann@cygnus.com) Enhanced by,
5 and currently maintained by, Jim Wilson (wilson@cygnus.com)
7 This file is part of GCC.
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.
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.
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. */
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"
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".) */
43 static int target_units = 0;
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));
52 /* Print names of units on which insn can/should execute, for debugging. */
54 void
55 insn_print_units (insn)
56 rtx insn;
58 int i;
59 int unit = insn_unit (insn);
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
67 fprintf (sched_dump, "[");
68 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
69 if (unit & 1)
71 fprintf (sched_dump, "%s", function_units[i].name);
72 if (unit != 1)
73 fprintf (sched_dump, " ");
75 fprintf (sched_dump, "]");
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 #define MAX_VISUAL_NO_UNIT 20
91 rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
93 /* Finds units that are in use in this function. Required only
94 for visualization. */
96 void
97 init_target_units ()
99 rtx insn;
100 int unit;
102 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
104 if (! INSN_P (insn))
105 continue;
107 unit = insn_unit (insn);
109 if (unit < 0)
110 target_units |= ~unit;
111 else
112 target_units |= (1 << unit);
116 /* Return the length of the visualization table. */
118 static int
119 get_visual_tbl_length ()
121 int unit, i;
122 int n, n1;
123 char *s;
125 /* Compute length of one field in line. */
126 s = (char *) alloca (INSN_LEN + 6);
127 sprintf (s, " %33s", "uname");
128 n1 = strlen (s);
130 /* Compute length of one line. */
131 n = strlen (";; ");
132 n += n1;
133 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
134 if (function_units[unit].bitmask & target_units)
135 for (i = 0; i < function_units[unit].multiplicity; i++)
136 n += n1;
137 n += n1;
138 n += strlen ("\n") + 2;
140 visual_tbl_line_length = n;
142 /* Compute length of visualization string. */
143 return (MAX_VISUAL_LINES * n);
146 /* Init block visualization debugging info. */
148 void
149 init_block_visualization ()
151 strcpy (visual_tbl, "");
152 n_visual_lines = 0;
153 n_vis_no_unit = 0;
156 #define BUF_LEN 2048
158 static char *
159 safe_concat (buf, cur, str)
160 char *buf;
161 char *cur;
162 const char *str;
164 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
165 int c;
167 if (cur > end)
169 *end = '\0';
170 return end;
173 while (cur < end && (c = *str++) != '\0')
174 *cur++ = c;
176 *cur = '\0';
177 return cur;
180 /* This recognizes rtx, I classified as expressions. These are always
181 represent some action on values or results of other expression, that
182 may be stored in objects representing values. */
184 static void
185 print_exp (buf, x, verbose)
186 char *buf;
187 rtx x;
188 int verbose;
190 char tmp[BUF_LEN];
191 const char *st[4];
192 char *cur = buf;
193 const char *fun = (char *) 0;
194 const char *sep;
195 rtx op[4];
196 int i;
198 for (i = 0; i < 4; i++)
200 st[i] = (char *) 0;
201 op[i] = NULL_RTX;
204 switch (GET_CODE (x))
206 case PLUS:
207 op[0] = XEXP (x, 0);
208 if (GET_CODE (XEXP (x, 1)) == CONST_INT
209 && INTVAL (XEXP (x, 1)) < 0)
211 st[1] = "-";
212 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
214 else
216 st[1] = "+";
217 op[1] = XEXP (x, 1);
219 break;
220 case LO_SUM:
221 op[0] = XEXP (x, 0);
222 st[1] = "+low(";
223 op[1] = XEXP (x, 1);
224 st[2] = ")";
225 break;
226 case MINUS:
227 op[0] = XEXP (x, 0);
228 st[1] = "-";
229 op[1] = XEXP (x, 1);
230 break;
231 case COMPARE:
232 fun = "cmp";
233 op[0] = XEXP (x, 0);
234 op[1] = XEXP (x, 1);
235 break;
236 case NEG:
237 st[0] = "-";
238 op[0] = XEXP (x, 0);
239 break;
240 case MULT:
241 op[0] = XEXP (x, 0);
242 st[1] = "*";
243 op[1] = XEXP (x, 1);
244 break;
245 case DIV:
246 op[0] = XEXP (x, 0);
247 st[1] = "/";
248 op[1] = XEXP (x, 1);
249 break;
250 case UDIV:
251 fun = "udiv";
252 op[0] = XEXP (x, 0);
253 op[1] = XEXP (x, 1);
254 break;
255 case MOD:
256 op[0] = XEXP (x, 0);
257 st[1] = "%";
258 op[1] = XEXP (x, 1);
259 break;
260 case UMOD:
261 fun = "umod";
262 op[0] = XEXP (x, 0);
263 op[1] = XEXP (x, 1);
264 break;
265 case SMIN:
266 fun = "smin";
267 op[0] = XEXP (x, 0);
268 op[1] = XEXP (x, 1);
269 break;
270 case SMAX:
271 fun = "smax";
272 op[0] = XEXP (x, 0);
273 op[1] = XEXP (x, 1);
274 break;
275 case UMIN:
276 fun = "umin";
277 op[0] = XEXP (x, 0);
278 op[1] = XEXP (x, 1);
279 break;
280 case UMAX:
281 fun = "umax";
282 op[0] = XEXP (x, 0);
283 op[1] = XEXP (x, 1);
284 break;
285 case NOT:
286 st[0] = "!";
287 op[0] = XEXP (x, 0);
288 break;
289 case AND:
290 op[0] = XEXP (x, 0);
291 st[1] = "&";
292 op[1] = XEXP (x, 1);
293 break;
294 case IOR:
295 op[0] = XEXP (x, 0);
296 st[1] = "|";
297 op[1] = XEXP (x, 1);
298 break;
299 case XOR:
300 op[0] = XEXP (x, 0);
301 st[1] = "^";
302 op[1] = XEXP (x, 1);
303 break;
304 case ASHIFT:
305 op[0] = XEXP (x, 0);
306 st[1] = "<<";
307 op[1] = XEXP (x, 1);
308 break;
309 case LSHIFTRT:
310 op[0] = XEXP (x, 0);
311 st[1] = " 0>>";
312 op[1] = XEXP (x, 1);
313 break;
314 case ASHIFTRT:
315 op[0] = XEXP (x, 0);
316 st[1] = ">>";
317 op[1] = XEXP (x, 1);
318 break;
319 case ROTATE:
320 op[0] = XEXP (x, 0);
321 st[1] = "<-<";
322 op[1] = XEXP (x, 1);
323 break;
324 case ROTATERT:
325 op[0] = XEXP (x, 0);
326 st[1] = ">->";
327 op[1] = XEXP (x, 1);
328 break;
329 case ABS:
330 fun = "abs";
331 op[0] = XEXP (x, 0);
332 break;
333 case SQRT:
334 fun = "sqrt";
335 op[0] = XEXP (x, 0);
336 break;
337 case FFS:
338 fun = "ffs";
339 op[0] = XEXP (x, 0);
340 break;
341 case EQ:
342 op[0] = XEXP (x, 0);
343 st[1] = "==";
344 op[1] = XEXP (x, 1);
345 break;
346 case NE:
347 op[0] = XEXP (x, 0);
348 st[1] = "!=";
349 op[1] = XEXP (x, 1);
350 break;
351 case GT:
352 op[0] = XEXP (x, 0);
353 st[1] = ">";
354 op[1] = XEXP (x, 1);
355 break;
356 case GTU:
357 fun = "gtu";
358 op[0] = XEXP (x, 0);
359 op[1] = XEXP (x, 1);
360 break;
361 case LT:
362 op[0] = XEXP (x, 0);
363 st[1] = "<";
364 op[1] = XEXP (x, 1);
365 break;
366 case LTU:
367 fun = "ltu";
368 op[0] = XEXP (x, 0);
369 op[1] = XEXP (x, 1);
370 break;
371 case GE:
372 op[0] = XEXP (x, 0);
373 st[1] = ">=";
374 op[1] = XEXP (x, 1);
375 break;
376 case GEU:
377 fun = "geu";
378 op[0] = XEXP (x, 0);
379 op[1] = XEXP (x, 1);
380 break;
381 case LE:
382 op[0] = XEXP (x, 0);
383 st[1] = "<=";
384 op[1] = XEXP (x, 1);
385 break;
386 case LEU:
387 fun = "leu";
388 op[0] = XEXP (x, 0);
389 op[1] = XEXP (x, 1);
390 break;
391 case SIGN_EXTRACT:
392 fun = (verbose) ? "sign_extract" : "sxt";
393 op[0] = XEXP (x, 0);
394 op[1] = XEXP (x, 1);
395 op[2] = XEXP (x, 2);
396 break;
397 case ZERO_EXTRACT:
398 fun = (verbose) ? "zero_extract" : "zxt";
399 op[0] = XEXP (x, 0);
400 op[1] = XEXP (x, 1);
401 op[2] = XEXP (x, 2);
402 break;
403 case SIGN_EXTEND:
404 fun = (verbose) ? "sign_extend" : "sxn";
405 op[0] = XEXP (x, 0);
406 break;
407 case ZERO_EXTEND:
408 fun = (verbose) ? "zero_extend" : "zxn";
409 op[0] = XEXP (x, 0);
410 break;
411 case FLOAT_EXTEND:
412 fun = (verbose) ? "float_extend" : "fxn";
413 op[0] = XEXP (x, 0);
414 break;
415 case TRUNCATE:
416 fun = (verbose) ? "trunc" : "trn";
417 op[0] = XEXP (x, 0);
418 break;
419 case FLOAT_TRUNCATE:
420 fun = (verbose) ? "float_trunc" : "ftr";
421 op[0] = XEXP (x, 0);
422 break;
423 case FLOAT:
424 fun = (verbose) ? "float" : "flt";
425 op[0] = XEXP (x, 0);
426 break;
427 case UNSIGNED_FLOAT:
428 fun = (verbose) ? "uns_float" : "ufl";
429 op[0] = XEXP (x, 0);
430 break;
431 case FIX:
432 fun = "fix";
433 op[0] = XEXP (x, 0);
434 break;
435 case UNSIGNED_FIX:
436 fun = (verbose) ? "uns_fix" : "ufx";
437 op[0] = XEXP (x, 0);
438 break;
439 case PRE_DEC:
440 st[0] = "--";
441 op[0] = XEXP (x, 0);
442 break;
443 case PRE_INC:
444 st[0] = "++";
445 op[0] = XEXP (x, 0);
446 break;
447 case POST_DEC:
448 op[0] = XEXP (x, 0);
449 st[1] = "--";
450 break;
451 case POST_INC:
452 op[0] = XEXP (x, 0);
453 st[1] = "++";
454 break;
455 case CALL:
456 st[0] = "call ";
457 op[0] = XEXP (x, 0);
458 if (verbose)
460 st[1] = " argc:";
461 op[1] = XEXP (x, 1);
463 break;
464 case IF_THEN_ELSE:
465 st[0] = "{(";
466 op[0] = XEXP (x, 0);
467 st[1] = ")?";
468 op[1] = XEXP (x, 1);
469 st[2] = ":";
470 op[2] = XEXP (x, 2);
471 st[3] = "}";
472 break;
473 case TRAP_IF:
474 fun = "trap_if";
475 op[0] = TRAP_CONDITION (x);
476 break;
477 case PREFETCH:
478 fun = "prefetch";
479 op[0] = XEXP (x, 0);
480 op[1] = XEXP (x, 1);
481 op[2] = XEXP (x, 2);
482 break;
483 case UNSPEC:
484 case UNSPEC_VOLATILE:
486 cur = safe_concat (buf, cur, "unspec");
487 if (GET_CODE (x) == UNSPEC_VOLATILE)
488 cur = safe_concat (buf, cur, "/v");
489 cur = safe_concat (buf, cur, "[");
490 sep = "";
491 for (i = 0; i < XVECLEN (x, 0); i++)
493 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
494 cur = safe_concat (buf, cur, sep);
495 cur = safe_concat (buf, cur, tmp);
496 sep = ",";
498 cur = safe_concat (buf, cur, "] ");
499 sprintf (tmp, "%d", XINT (x, 1));
500 cur = safe_concat (buf, cur, tmp);
502 break;
503 default:
504 /* If (verbose) debug_rtx (x); */
505 st[0] = GET_RTX_NAME (GET_CODE (x));
506 break;
509 /* Print this as a function? */
510 if (fun)
512 cur = safe_concat (buf, cur, fun);
513 cur = safe_concat (buf, cur, "(");
516 for (i = 0; i < 4; i++)
518 if (st[i])
519 cur = safe_concat (buf, cur, st[i]);
521 if (op[i])
523 if (fun && i != 0)
524 cur = safe_concat (buf, cur, ",");
526 print_value (tmp, op[i], verbose);
527 cur = safe_concat (buf, cur, tmp);
531 if (fun)
532 cur = safe_concat (buf, cur, ")");
533 } /* print_exp */
535 /* Prints rtxes, I customly classified as values. They're constants,
536 registers, labels, symbols and memory accesses. */
538 static void
539 print_value (buf, x, verbose)
540 char *buf;
541 rtx x;
542 int verbose;
544 char t[BUF_LEN];
545 char *cur = buf;
547 switch (GET_CODE (x))
549 case CONST_INT:
550 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
551 cur = safe_concat (buf, cur, t);
552 break;
553 case CONST_DOUBLE:
554 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
555 cur = safe_concat (buf, cur, t);
556 break;
557 case CONST_STRING:
558 cur = safe_concat (buf, cur, "\"");
559 cur = safe_concat (buf, cur, XSTR (x, 0));
560 cur = safe_concat (buf, cur, "\"");
561 break;
562 case SYMBOL_REF:
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 LABEL_REF:
568 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
569 cur = safe_concat (buf, cur, t);
570 break;
571 case CONST:
572 print_value (t, XEXP (x, 0), verbose);
573 cur = safe_concat (buf, cur, "const(");
574 cur = safe_concat (buf, cur, t);
575 cur = safe_concat (buf, cur, ")");
576 break;
577 case HIGH:
578 print_value (t, XEXP (x, 0), verbose);
579 cur = safe_concat (buf, cur, "high(");
580 cur = safe_concat (buf, cur, t);
581 cur = safe_concat (buf, cur, ")");
582 break;
583 case REG:
584 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
586 int c = reg_names[REGNO (x)][0];
587 if (ISDIGIT (c))
588 cur = safe_concat (buf, cur, "%");
590 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
592 else
594 sprintf (t, "r%d", REGNO (x));
595 cur = safe_concat (buf, cur, t);
597 break;
598 case SUBREG:
599 print_value (t, SUBREG_REG (x), verbose);
600 cur = safe_concat (buf, cur, t);
601 sprintf (t, "#%d", SUBREG_BYTE (x));
602 cur = safe_concat (buf, cur, t);
603 break;
604 case SCRATCH:
605 cur = safe_concat (buf, cur, "scratch");
606 break;
607 case CC0:
608 cur = safe_concat (buf, cur, "cc0");
609 break;
610 case PC:
611 cur = safe_concat (buf, cur, "pc");
612 break;
613 case MEM:
614 print_value (t, XEXP (x, 0), verbose);
615 cur = safe_concat (buf, cur, "[");
616 cur = safe_concat (buf, cur, t);
617 cur = safe_concat (buf, cur, "]");
618 break;
619 default:
620 print_exp (t, x, verbose);
621 cur = safe_concat (buf, cur, t);
622 break;
624 } /* print_value */
626 /* The next step in insn detalization, its pattern recognition. */
628 static void
629 print_pattern (buf, x, verbose)
630 char *buf;
631 rtx x;
632 int verbose;
634 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
636 switch (GET_CODE (x))
638 case SET:
639 print_value (t1, SET_DEST (x), verbose);
640 print_value (t2, SET_SRC (x), verbose);
641 sprintf (buf, "%s=%s", t1, t2);
642 break;
643 case RETURN:
644 sprintf (buf, "return");
645 break;
646 case CALL:
647 print_exp (buf, x, verbose);
648 break;
649 case CLOBBER:
650 print_value (t1, XEXP (x, 0), verbose);
651 sprintf (buf, "clobber %s", t1);
652 break;
653 case USE:
654 print_value (t1, XEXP (x, 0), verbose);
655 sprintf (buf, "use %s", t1);
656 break;
657 case COND_EXEC:
658 if (GET_CODE (COND_EXEC_TEST (x)) == NE
659 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
660 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
661 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
662 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
664 t1[0] = '!';
665 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
667 else
668 print_value (t1, COND_EXEC_TEST (x), verbose);
669 print_pattern (t2, COND_EXEC_CODE (x), verbose);
670 sprintf (buf, "(%s) %s", t1, t2);
671 break;
672 case PARALLEL:
674 int i;
676 sprintf (t1, "{");
677 for (i = 0; i < XVECLEN (x, 0); i++)
679 print_pattern (t2, XVECEXP (x, 0, i), verbose);
680 sprintf (t3, "%s%s;", t1, t2);
681 strcpy (t1, t3);
683 sprintf (buf, "%s}", t1);
685 break;
686 case SEQUENCE:
688 int i;
690 sprintf (t1, "%%{");
691 for (i = 0; i < XVECLEN (x, 0); i++)
693 print_insn (t2, XVECEXP (x, 0, i), verbose);
694 sprintf (t3, "%s%s;", t1, t2);
695 strcpy (t1, t3);
697 sprintf (buf, "%s%%}", t1);
699 break;
700 case ASM_INPUT:
701 sprintf (buf, "asm {%s}", XSTR (x, 0));
702 break;
703 case ADDR_VEC:
704 break;
705 case ADDR_DIFF_VEC:
706 print_value (buf, XEXP (x, 0), verbose);
707 break;
708 case TRAP_IF:
709 print_value (t1, TRAP_CONDITION (x), verbose);
710 sprintf (buf, "trap_if %s", t1);
711 break;
712 case UNSPEC:
714 int i;
716 sprintf (t1, "unspec{");
717 for (i = 0; i < XVECLEN (x, 0); i++)
719 print_pattern (t2, XVECEXP (x, 0, i), verbose);
720 sprintf (t3, "%s%s;", t1, t2);
721 strcpy (t1, t3);
723 sprintf (buf, "%s}", t1);
725 break;
726 case UNSPEC_VOLATILE:
728 int i;
730 sprintf (t1, "unspec/v{");
731 for (i = 0; i < XVECLEN (x, 0); i++)
733 print_pattern (t2, XVECEXP (x, 0, i), verbose);
734 sprintf (t3, "%s%s;", t1, t2);
735 strcpy (t1, t3);
737 sprintf (buf, "%s}", t1);
739 break;
740 default:
741 print_value (buf, x, verbose);
743 } /* print_pattern */
745 /* This is the main function in rtl visualization mechanism. It
746 accepts an rtx and tries to recognize it as an insn, then prints it
747 properly in human readable form, resembling assembler mnemonics.
748 For every insn it prints its UID and BB the insn belongs too.
749 (Probably the last "option" should be extended somehow, since it
750 depends now on sched.c inner variables ...) */
752 static void
753 print_insn (buf, x, verbose)
754 char *buf;
755 rtx x;
756 int verbose;
758 char t[BUF_LEN];
759 rtx insn = x;
761 switch (GET_CODE (x))
763 case INSN:
764 print_pattern (t, PATTERN (x), verbose);
765 if (verbose)
766 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
768 else
769 sprintf (buf, "%-4d %s", INSN_UID (x), t);
770 break;
771 case JUMP_INSN:
772 print_pattern (t, PATTERN (x), verbose);
773 if (verbose)
774 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
776 else
777 sprintf (buf, "%-4d %s", INSN_UID (x), t);
778 break;
779 case CALL_INSN:
780 x = PATTERN (insn);
781 if (GET_CODE (x) == PARALLEL)
783 x = XVECEXP (x, 0, 0);
784 print_pattern (t, x, verbose);
786 else
787 strcpy (t, "call <...>");
788 if (verbose)
789 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
790 else
791 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
792 break;
793 case CODE_LABEL:
794 sprintf (buf, "L%d:", INSN_UID (x));
795 break;
796 case BARRIER:
797 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
798 break;
799 case NOTE:
800 if (NOTE_LINE_NUMBER (x) > 0)
801 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
802 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
803 else
804 sprintf (buf, "%4d %s", INSN_UID (x),
805 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
806 break;
807 default:
808 if (verbose)
810 sprintf (buf, "Not an INSN at all\n");
811 debug_rtx (x);
813 else
814 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
816 } /* print_insn */
818 /* Print visualization debugging info. */
820 void
821 print_block_visualization (s)
822 const char *s;
824 int unit, i;
826 /* Print header. */
827 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
829 /* Print names of units. */
830 fprintf (sched_dump, ";; %-8s", "clock");
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", function_units[unit].name);
835 fprintf (sched_dump, " %-8s\n", "no-unit");
837 fprintf (sched_dump, ";; %-8s", "=====");
838 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
839 if (function_units[unit].bitmask & target_units)
840 for (i = 0; i < function_units[unit].multiplicity; i++)
841 fprintf (sched_dump, " %-33s", "==============================");
842 fprintf (sched_dump, " %-8s\n", "=======");
844 /* Print insns in each cycle. */
845 fprintf (sched_dump, "%s\n", visual_tbl);
848 /* Print insns in the 'no_unit' column of visualization. */
850 void
851 visualize_no_unit (insn)
852 rtx insn;
854 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
856 vis_no_unit[n_vis_no_unit] = insn;
857 n_vis_no_unit++;
861 /* Print insns scheduled in clock, for visualization. */
863 void
864 visualize_scheduled_insns (clock)
865 int clock;
867 int i, unit;
869 /* If no more room, split table into two. */
870 if (n_visual_lines >= MAX_VISUAL_LINES)
872 print_block_visualization ("(incomplete)");
873 init_block_visualization ();
876 n_visual_lines++;
878 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
879 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
880 if (function_units[unit].bitmask & target_units)
881 for (i = 0; i < function_units[unit].multiplicity; i++)
883 int instance = unit + i * FUNCTION_UNITS_SIZE;
884 rtx insn = get_unit_last_insn (instance);
886 /* Print insns that still keep the unit busy. */
887 if (insn
888 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
890 char str[BUF_LEN];
891 print_insn (str, insn, 0);
892 str[INSN_LEN] = '\0';
893 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
895 else
896 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
899 /* Print insns that are not assigned to any unit. */
900 for (i = 0; i < n_vis_no_unit; i++)
901 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
902 INSN_UID (vis_no_unit[i]));
903 n_vis_no_unit = 0;
905 sprintf (visual_tbl + strlen (visual_tbl), "\n");
908 /* Print stalled cycles. */
910 void
911 visualize_stall_cycles (stalls)
912 int stalls;
914 static const char *const prefix = ";; ";
915 const char *suffix = "\n";
916 char *p;
918 /* If no more room, split table into two. */
919 if (n_visual_lines >= MAX_VISUAL_LINES)
921 print_block_visualization ("(incomplete)");
922 init_block_visualization ();
925 n_visual_lines++;
927 p = visual_tbl + strlen (visual_tbl);
928 strcpy (p, prefix);
929 p += strlen (prefix);
931 if ((unsigned) stalls >
932 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
934 suffix = "[...]\n";
935 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
938 memset (p, '.', stalls);
939 p += stalls;
941 strcpy (p, suffix);
944 /* Allocate data used for visualization during scheduling. */
946 void
947 visualize_alloc ()
949 visual_tbl = xmalloc (get_visual_tbl_length ());
952 /* Free data used for visualization. */
954 void
955 visualize_free ()
957 free (visual_tbl);
959 #endif