* Makefile.in (rtlanal.o): Depend on $(TM_P_H).
[official-gcc.git] / gcc / sched-vis.c
blob8949421c5aec9ac6fa4864ef08e5e9f17f6f7c1d
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)
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 fuction. 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 UNSPEC:
478 case UNSPEC_VOLATILE:
480 cur = safe_concat (buf, cur, "unspec");
481 if (GET_CODE (x) == UNSPEC_VOLATILE)
482 cur = safe_concat (buf, cur, "/v");
483 cur = safe_concat (buf, cur, "[");
484 sep = "";
485 for (i = 0; i < XVECLEN (x, 0); i++)
487 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
488 cur = safe_concat (buf, cur, sep);
489 cur = safe_concat (buf, cur, tmp);
490 sep = ",";
492 cur = safe_concat (buf, cur, "] ");
493 sprintf (tmp, "%d", XINT (x, 1));
494 cur = safe_concat (buf, cur, tmp);
496 break;
497 default:
498 /* If (verbose) debug_rtx (x); */
499 st[0] = GET_RTX_NAME (GET_CODE (x));
500 break;
503 /* Print this as a function? */
504 if (fun)
506 cur = safe_concat (buf, cur, fun);
507 cur = safe_concat (buf, cur, "(");
510 for (i = 0; i < 4; i++)
512 if (st[i])
513 cur = safe_concat (buf, cur, st[i]);
515 if (op[i])
517 if (fun && i != 0)
518 cur = safe_concat (buf, cur, ",");
520 print_value (tmp, op[i], verbose);
521 cur = safe_concat (buf, cur, tmp);
525 if (fun)
526 cur = safe_concat (buf, cur, ")");
527 } /* print_exp */
529 /* Prints rtxes, I customly classified as values. They're constants,
530 registers, labels, symbols and memory accesses. */
532 static void
533 print_value (buf, x, verbose)
534 char *buf;
535 rtx x;
536 int verbose;
538 char t[BUF_LEN];
539 char *cur = buf;
541 switch (GET_CODE (x))
543 case CONST_INT:
544 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
545 cur = safe_concat (buf, cur, t);
546 break;
547 case CONST_DOUBLE:
548 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
549 cur = safe_concat (buf, cur, t);
550 break;
551 case CONST_STRING:
552 cur = safe_concat (buf, cur, "\"");
553 cur = safe_concat (buf, cur, XSTR (x, 0));
554 cur = safe_concat (buf, cur, "\"");
555 break;
556 case SYMBOL_REF:
557 cur = safe_concat (buf, cur, "`");
558 cur = safe_concat (buf, cur, XSTR (x, 0));
559 cur = safe_concat (buf, cur, "'");
560 break;
561 case LABEL_REF:
562 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
563 cur = safe_concat (buf, cur, t);
564 break;
565 case CONST:
566 print_value (t, XEXP (x, 0), verbose);
567 cur = safe_concat (buf, cur, "const(");
568 cur = safe_concat (buf, cur, t);
569 cur = safe_concat (buf, cur, ")");
570 break;
571 case HIGH:
572 print_value (t, XEXP (x, 0), verbose);
573 cur = safe_concat (buf, cur, "high(");
574 cur = safe_concat (buf, cur, t);
575 cur = safe_concat (buf, cur, ")");
576 break;
577 case REG:
578 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
580 int c = reg_names[REGNO (x)][0];
581 if (c >= '0' && c <= '9')
582 cur = safe_concat (buf, cur, "%");
584 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
586 else
588 sprintf (t, "r%d", REGNO (x));
589 cur = safe_concat (buf, cur, t);
591 break;
592 case SUBREG:
593 print_value (t, SUBREG_REG (x), verbose);
594 cur = safe_concat (buf, cur, t);
595 sprintf (t, "#%d", SUBREG_BYTE (x));
596 cur = safe_concat (buf, cur, t);
597 break;
598 case SCRATCH:
599 cur = safe_concat (buf, cur, "scratch");
600 break;
601 case CC0:
602 cur = safe_concat (buf, cur, "cc0");
603 break;
604 case PC:
605 cur = safe_concat (buf, cur, "pc");
606 break;
607 case MEM:
608 print_value (t, XEXP (x, 0), verbose);
609 cur = safe_concat (buf, cur, "[");
610 cur = safe_concat (buf, cur, t);
611 cur = safe_concat (buf, cur, "]");
612 break;
613 default:
614 print_exp (t, x, verbose);
615 cur = safe_concat (buf, cur, t);
616 break;
618 } /* print_value */
620 /* The next step in insn detalization, its pattern recognition. */
622 static void
623 print_pattern (buf, x, verbose)
624 char *buf;
625 rtx x;
626 int verbose;
628 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
630 switch (GET_CODE (x))
632 case SET:
633 print_value (t1, SET_DEST (x), verbose);
634 print_value (t2, SET_SRC (x), verbose);
635 sprintf (buf, "%s=%s", t1, t2);
636 break;
637 case RETURN:
638 sprintf (buf, "return");
639 break;
640 case CALL:
641 print_exp (buf, x, verbose);
642 break;
643 case CLOBBER:
644 print_value (t1, XEXP (x, 0), verbose);
645 sprintf (buf, "clobber %s", t1);
646 break;
647 case USE:
648 print_value (t1, XEXP (x, 0), verbose);
649 sprintf (buf, "use %s", t1);
650 break;
651 case COND_EXEC:
652 if (GET_CODE (COND_EXEC_TEST (x)) == NE
653 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
654 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
655 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
656 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
658 t1[0] = '!';
659 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
661 else
662 print_value (t1, COND_EXEC_TEST (x), verbose);
663 print_pattern (t2, COND_EXEC_CODE (x), verbose);
664 sprintf (buf, "(%s) %s", t1, t2);
665 break;
666 case PARALLEL:
668 int i;
670 sprintf (t1, "{");
671 for (i = 0; i < XVECLEN (x, 0); i++)
673 print_pattern (t2, XVECEXP (x, 0, i), verbose);
674 sprintf (t3, "%s%s;", t1, t2);
675 strcpy (t1, t3);
677 sprintf (buf, "%s}", t1);
679 break;
680 case SEQUENCE:
682 int i;
684 sprintf (t1, "%%{");
685 for (i = 0; i < XVECLEN (x, 0); i++)
687 print_insn (t2, XVECEXP (x, 0, i), verbose);
688 sprintf (t3, "%s%s;", t1, t2);
689 strcpy (t1, t3);
691 sprintf (buf, "%s%%}", t1);
693 break;
694 case ASM_INPUT:
695 sprintf (buf, "asm {%s}", XSTR (x, 0));
696 break;
697 case ADDR_VEC:
698 break;
699 case ADDR_DIFF_VEC:
700 print_value (buf, XEXP (x, 0), verbose);
701 break;
702 case TRAP_IF:
703 print_value (t1, TRAP_CONDITION (x), verbose);
704 sprintf (buf, "trap_if %s", t1);
705 break;
706 case UNSPEC:
708 int i;
710 sprintf (t1, "unspec{");
711 for (i = 0; i < XVECLEN (x, 0); i++)
713 print_pattern (t2, XVECEXP (x, 0, i), verbose);
714 sprintf (t3, "%s%s;", t1, t2);
715 strcpy (t1, t3);
717 sprintf (buf, "%s}", t1);
719 break;
720 case UNSPEC_VOLATILE:
722 int i;
724 sprintf (t1, "unspec/v{");
725 for (i = 0; i < XVECLEN (x, 0); i++)
727 print_pattern (t2, XVECEXP (x, 0, i), verbose);
728 sprintf (t3, "%s%s;", t1, t2);
729 strcpy (t1, t3);
731 sprintf (buf, "%s}", t1);
733 break;
734 default:
735 print_value (buf, x, verbose);
737 } /* print_pattern */
739 /* This is the main function in rtl visualization mechanism. It
740 accepts an rtx and tries to recognize it as an insn, then prints it
741 properly in human readable form, resembling assembler mnemonics.
742 For every insn it prints its UID and BB the insn belongs too.
743 (Probably the last "option" should be extended somehow, since it
744 depends now on sched.c inner variables ...) */
746 static void
747 print_insn (buf, x, verbose)
748 char *buf;
749 rtx x;
750 int verbose;
752 char t[BUF_LEN];
753 rtx insn = x;
755 switch (GET_CODE (x))
757 case INSN:
758 print_pattern (t, PATTERN (x), verbose);
759 if (verbose)
760 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
762 else
763 sprintf (buf, "%-4d %s", INSN_UID (x), t);
764 break;
765 case JUMP_INSN:
766 print_pattern (t, PATTERN (x), verbose);
767 if (verbose)
768 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
770 else
771 sprintf (buf, "%-4d %s", INSN_UID (x), t);
772 break;
773 case CALL_INSN:
774 x = PATTERN (insn);
775 if (GET_CODE (x) == PARALLEL)
777 x = XVECEXP (x, 0, 0);
778 print_pattern (t, x, verbose);
780 else
781 strcpy (t, "call <...>");
782 if (verbose)
783 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
784 else
785 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
786 break;
787 case CODE_LABEL:
788 sprintf (buf, "L%d:", INSN_UID (x));
789 break;
790 case BARRIER:
791 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
792 break;
793 case NOTE:
794 if (NOTE_LINE_NUMBER (x) > 0)
795 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
796 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
797 else
798 sprintf (buf, "%4d %s", INSN_UID (x),
799 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
800 break;
801 default:
802 if (verbose)
804 sprintf (buf, "Not an INSN at all\n");
805 debug_rtx (x);
807 else
808 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
810 } /* print_insn */
812 /* Print visualization debugging info. */
814 void
815 print_block_visualization (s)
816 const char *s;
818 int unit, i;
820 /* Print header. */
821 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
823 /* Print names of units. */
824 fprintf (sched_dump, ";; %-8s", "clock");
825 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
826 if (function_units[unit].bitmask & target_units)
827 for (i = 0; i < function_units[unit].multiplicity; i++)
828 fprintf (sched_dump, " %-33s", function_units[unit].name);
829 fprintf (sched_dump, " %-8s\n", "no-unit");
831 fprintf (sched_dump, ";; %-8s", "=====");
832 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
833 if (function_units[unit].bitmask & target_units)
834 for (i = 0; i < function_units[unit].multiplicity; i++)
835 fprintf (sched_dump, " %-33s", "==============================");
836 fprintf (sched_dump, " %-8s\n", "=======");
838 /* Print insns in each cycle. */
839 fprintf (sched_dump, "%s\n", visual_tbl);
842 /* Print insns in the 'no_unit' column of visualization. */
844 void
845 visualize_no_unit (insn)
846 rtx insn;
848 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
850 vis_no_unit[n_vis_no_unit] = insn;
851 n_vis_no_unit++;
855 /* Print insns scheduled in clock, for visualization. */
857 void
858 visualize_scheduled_insns (clock)
859 int clock;
861 int i, unit;
863 /* If no more room, split table into two. */
864 if (n_visual_lines >= MAX_VISUAL_LINES)
866 print_block_visualization ("(incomplete)");
867 init_block_visualization ();
870 n_visual_lines++;
872 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
873 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
874 if (function_units[unit].bitmask & target_units)
875 for (i = 0; i < function_units[unit].multiplicity; i++)
877 int instance = unit + i * FUNCTION_UNITS_SIZE;
878 rtx insn = get_unit_last_insn (instance);
880 /* Print insns that still keep the unit busy. */
881 if (insn
882 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
884 char str[BUF_LEN];
885 print_insn (str, insn, 0);
886 str[INSN_LEN] = '\0';
887 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
889 else
890 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
893 /* Print insns that are not assigned to any unit. */
894 for (i = 0; i < n_vis_no_unit; i++)
895 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
896 INSN_UID (vis_no_unit[i]));
897 n_vis_no_unit = 0;
899 sprintf (visual_tbl + strlen (visual_tbl), "\n");
902 /* Print stalled cycles. */
904 void
905 visualize_stall_cycles (stalls)
906 int stalls;
908 static const char *const prefix = ";; ";
909 const char *suffix = "\n";
910 char *p;
912 /* If no more room, split table into two. */
913 if (n_visual_lines >= MAX_VISUAL_LINES)
915 print_block_visualization ("(incomplete)");
916 init_block_visualization ();
919 n_visual_lines++;
921 p = visual_tbl + strlen (visual_tbl);
922 strcpy (p, prefix);
923 p += strlen (prefix);
925 if ((unsigned)stalls >
926 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
928 suffix = "[...]\n";
929 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
932 memset (p, '.', stalls);
933 p += stalls;
935 strcpy (p, suffix);
938 /* Allocate data used for visualization during scheduling. */
940 void
941 visualize_alloc ()
943 visual_tbl = xmalloc (get_visual_tbl_length ());
946 /* Free data used for visualization. */
948 void
949 visualize_free ()
951 free (visual_tbl);
953 #endif