Mark ChangeLog
[official-gcc.git] / gcc / sched-vis.c
blob4cd07790130aef6d88718e607d7e716454fb25ad
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 GNU CC.
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.
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.
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. */
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 rtx vis_no_unit[10];
92 /* Finds units that are in use in this fuction. Required only
93 for visualization. */
95 void
96 init_target_units ()
98 rtx insn;
99 int unit;
101 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
103 if (! INSN_P (insn))
104 continue;
106 unit = insn_unit (insn);
108 if (unit < 0)
109 target_units |= ~unit;
110 else
111 target_units |= (1 << unit);
115 /* Return the length of the visualization table. */
117 static int
118 get_visual_tbl_length ()
120 int unit, i;
121 int n, n1;
122 char *s;
124 /* Compute length of one field in line. */
125 s = (char *) alloca (INSN_LEN + 6);
126 sprintf (s, " %33s", "uname");
127 n1 = strlen (s);
129 /* Compute length of one line. */
130 n = strlen (";; ");
131 n += n1;
132 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
133 if (function_units[unit].bitmask & target_units)
134 for (i = 0; i < function_units[unit].multiplicity; i++)
135 n += n1;
136 n += n1;
137 n += strlen ("\n") + 2;
139 visual_tbl_line_length = n;
141 /* Compute length of visualization string. */
142 return (MAX_VISUAL_LINES * n);
145 /* Init block visualization debugging info. */
147 void
148 init_block_visualization ()
150 strcpy (visual_tbl, "");
151 n_visual_lines = 0;
152 n_vis_no_unit = 0;
155 #define BUF_LEN 2048
157 static char *
158 safe_concat (buf, cur, str)
159 char *buf;
160 char *cur;
161 const char *str;
163 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
164 int c;
166 if (cur > end)
168 *end = '\0';
169 return end;
172 while (cur < end && (c = *str++) != '\0')
173 *cur++ = c;
175 *cur = '\0';
176 return cur;
179 /* This recognizes rtx, I classified as expressions. These are always
180 represent some action on values or results of other expression, that
181 may be stored in objects representing values. */
183 static void
184 print_exp (buf, x, verbose)
185 char *buf;
186 rtx x;
187 int verbose;
189 char tmp[BUF_LEN];
190 const char *st[4];
191 char *cur = buf;
192 const char *fun = (char *) 0;
193 const char *sep;
194 rtx op[4];
195 int i;
197 for (i = 0; i < 4; i++)
199 st[i] = (char *) 0;
200 op[i] = NULL_RTX;
203 switch (GET_CODE (x))
205 case PLUS:
206 op[0] = XEXP (x, 0);
207 if (GET_CODE (XEXP (x, 1)) == CONST_INT
208 && INTVAL (XEXP (x, 1)) < 0)
210 st[1] = "-";
211 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
213 else
215 st[1] = "+";
216 op[1] = XEXP (x, 1);
218 break;
219 case LO_SUM:
220 op[0] = XEXP (x, 0);
221 st[1] = "+low(";
222 op[1] = XEXP (x, 1);
223 st[2] = ")";
224 break;
225 case MINUS:
226 op[0] = XEXP (x, 0);
227 st[1] = "-";
228 op[1] = XEXP (x, 1);
229 break;
230 case COMPARE:
231 fun = "cmp";
232 op[0] = XEXP (x, 0);
233 op[1] = XEXP (x, 1);
234 break;
235 case NEG:
236 st[0] = "-";
237 op[0] = XEXP (x, 0);
238 break;
239 case MULT:
240 op[0] = XEXP (x, 0);
241 st[1] = "*";
242 op[1] = XEXP (x, 1);
243 break;
244 case DIV:
245 op[0] = XEXP (x, 0);
246 st[1] = "/";
247 op[1] = XEXP (x, 1);
248 break;
249 case UDIV:
250 fun = "udiv";
251 op[0] = XEXP (x, 0);
252 op[1] = XEXP (x, 1);
253 break;
254 case MOD:
255 op[0] = XEXP (x, 0);
256 st[1] = "%";
257 op[1] = XEXP (x, 1);
258 break;
259 case UMOD:
260 fun = "umod";
261 op[0] = XEXP (x, 0);
262 op[1] = XEXP (x, 1);
263 break;
264 case SMIN:
265 fun = "smin";
266 op[0] = XEXP (x, 0);
267 op[1] = XEXP (x, 1);
268 break;
269 case SMAX:
270 fun = "smax";
271 op[0] = XEXP (x, 0);
272 op[1] = XEXP (x, 1);
273 break;
274 case UMIN:
275 fun = "umin";
276 op[0] = XEXP (x, 0);
277 op[1] = XEXP (x, 1);
278 break;
279 case UMAX:
280 fun = "umax";
281 op[0] = XEXP (x, 0);
282 op[1] = XEXP (x, 1);
283 break;
284 case NOT:
285 st[0] = "!";
286 op[0] = XEXP (x, 0);
287 break;
288 case AND:
289 op[0] = XEXP (x, 0);
290 st[1] = "&";
291 op[1] = XEXP (x, 1);
292 break;
293 case IOR:
294 op[0] = XEXP (x, 0);
295 st[1] = "|";
296 op[1] = XEXP (x, 1);
297 break;
298 case XOR:
299 op[0] = XEXP (x, 0);
300 st[1] = "^";
301 op[1] = XEXP (x, 1);
302 break;
303 case ASHIFT:
304 op[0] = XEXP (x, 0);
305 st[1] = "<<";
306 op[1] = XEXP (x, 1);
307 break;
308 case LSHIFTRT:
309 op[0] = XEXP (x, 0);
310 st[1] = " 0>>";
311 op[1] = XEXP (x, 1);
312 break;
313 case ASHIFTRT:
314 op[0] = XEXP (x, 0);
315 st[1] = ">>";
316 op[1] = XEXP (x, 1);
317 break;
318 case ROTATE:
319 op[0] = XEXP (x, 0);
320 st[1] = "<-<";
321 op[1] = XEXP (x, 1);
322 break;
323 case ROTATERT:
324 op[0] = XEXP (x, 0);
325 st[1] = ">->";
326 op[1] = XEXP (x, 1);
327 break;
328 case ABS:
329 fun = "abs";
330 op[0] = XEXP (x, 0);
331 break;
332 case SQRT:
333 fun = "sqrt";
334 op[0] = XEXP (x, 0);
335 break;
336 case FFS:
337 fun = "ffs";
338 op[0] = XEXP (x, 0);
339 break;
340 case EQ:
341 op[0] = XEXP (x, 0);
342 st[1] = "==";
343 op[1] = XEXP (x, 1);
344 break;
345 case NE:
346 op[0] = XEXP (x, 0);
347 st[1] = "!=";
348 op[1] = XEXP (x, 1);
349 break;
350 case GT:
351 op[0] = XEXP (x, 0);
352 st[1] = ">";
353 op[1] = XEXP (x, 1);
354 break;
355 case GTU:
356 fun = "gtu";
357 op[0] = XEXP (x, 0);
358 op[1] = XEXP (x, 1);
359 break;
360 case LT:
361 op[0] = XEXP (x, 0);
362 st[1] = "<";
363 op[1] = XEXP (x, 1);
364 break;
365 case LTU:
366 fun = "ltu";
367 op[0] = XEXP (x, 0);
368 op[1] = XEXP (x, 1);
369 break;
370 case GE:
371 op[0] = XEXP (x, 0);
372 st[1] = ">=";
373 op[1] = XEXP (x, 1);
374 break;
375 case GEU:
376 fun = "geu";
377 op[0] = XEXP (x, 0);
378 op[1] = XEXP (x, 1);
379 break;
380 case LE:
381 op[0] = XEXP (x, 0);
382 st[1] = "<=";
383 op[1] = XEXP (x, 1);
384 break;
385 case LEU:
386 fun = "leu";
387 op[0] = XEXP (x, 0);
388 op[1] = XEXP (x, 1);
389 break;
390 case SIGN_EXTRACT:
391 fun = (verbose) ? "sign_extract" : "sxt";
392 op[0] = XEXP (x, 0);
393 op[1] = XEXP (x, 1);
394 op[2] = XEXP (x, 2);
395 break;
396 case ZERO_EXTRACT:
397 fun = (verbose) ? "zero_extract" : "zxt";
398 op[0] = XEXP (x, 0);
399 op[1] = XEXP (x, 1);
400 op[2] = XEXP (x, 2);
401 break;
402 case SIGN_EXTEND:
403 fun = (verbose) ? "sign_extend" : "sxn";
404 op[0] = XEXP (x, 0);
405 break;
406 case ZERO_EXTEND:
407 fun = (verbose) ? "zero_extend" : "zxn";
408 op[0] = XEXP (x, 0);
409 break;
410 case FLOAT_EXTEND:
411 fun = (verbose) ? "float_extend" : "fxn";
412 op[0] = XEXP (x, 0);
413 break;
414 case TRUNCATE:
415 fun = (verbose) ? "trunc" : "trn";
416 op[0] = XEXP (x, 0);
417 break;
418 case FLOAT_TRUNCATE:
419 fun = (verbose) ? "float_trunc" : "ftr";
420 op[0] = XEXP (x, 0);
421 break;
422 case FLOAT:
423 fun = (verbose) ? "float" : "flt";
424 op[0] = XEXP (x, 0);
425 break;
426 case UNSIGNED_FLOAT:
427 fun = (verbose) ? "uns_float" : "ufl";
428 op[0] = XEXP (x, 0);
429 break;
430 case FIX:
431 fun = "fix";
432 op[0] = XEXP (x, 0);
433 break;
434 case UNSIGNED_FIX:
435 fun = (verbose) ? "uns_fix" : "ufx";
436 op[0] = XEXP (x, 0);
437 break;
438 case PRE_DEC:
439 st[0] = "--";
440 op[0] = XEXP (x, 0);
441 break;
442 case PRE_INC:
443 st[0] = "++";
444 op[0] = XEXP (x, 0);
445 break;
446 case POST_DEC:
447 op[0] = XEXP (x, 0);
448 st[1] = "--";
449 break;
450 case POST_INC:
451 op[0] = XEXP (x, 0);
452 st[1] = "++";
453 break;
454 case CALL:
455 st[0] = "call ";
456 op[0] = XEXP (x, 0);
457 if (verbose)
459 st[1] = " argc:";
460 op[1] = XEXP (x, 1);
462 break;
463 case IF_THEN_ELSE:
464 st[0] = "{(";
465 op[0] = XEXP (x, 0);
466 st[1] = ")?";
467 op[1] = XEXP (x, 1);
468 st[2] = ":";
469 op[2] = XEXP (x, 2);
470 st[3] = "}";
471 break;
472 case TRAP_IF:
473 fun = "trap_if";
474 op[0] = TRAP_CONDITION (x);
475 break;
476 case UNSPEC:
477 case UNSPEC_VOLATILE:
479 cur = safe_concat (buf, cur, "unspec");
480 if (GET_CODE (x) == UNSPEC_VOLATILE)
481 cur = safe_concat (buf, cur, "/v");
482 cur = safe_concat (buf, cur, "[");
483 sep = "";
484 for (i = 0; i < XVECLEN (x, 0); i++)
486 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
487 cur = safe_concat (buf, cur, sep);
488 cur = safe_concat (buf, cur, tmp);
489 sep = ",";
491 cur = safe_concat (buf, cur, "] ");
492 sprintf (tmp, "%d", XINT (x, 1));
493 cur = safe_concat (buf, cur, tmp);
495 break;
496 default:
497 /* If (verbose) debug_rtx (x); */
498 st[0] = GET_RTX_NAME (GET_CODE (x));
499 break;
502 /* Print this as a function? */
503 if (fun)
505 cur = safe_concat (buf, cur, fun);
506 cur = safe_concat (buf, cur, "(");
509 for (i = 0; i < 4; i++)
511 if (st[i])
512 cur = safe_concat (buf, cur, st[i]);
514 if (op[i])
516 if (fun && i != 0)
517 cur = safe_concat (buf, cur, ",");
519 print_value (tmp, op[i], verbose);
520 cur = safe_concat (buf, cur, tmp);
524 if (fun)
525 cur = safe_concat (buf, cur, ")");
526 } /* print_exp */
528 /* Prints rtxes, I customly classified as values. They're constants,
529 registers, labels, symbols and memory accesses. */
531 static void
532 print_value (buf, x, verbose)
533 char *buf;
534 rtx x;
535 int verbose;
537 char t[BUF_LEN];
538 char *cur = buf;
540 switch (GET_CODE (x))
542 case CONST_INT:
543 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
544 cur = safe_concat (buf, cur, t);
545 break;
546 case CONST_DOUBLE:
547 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
548 cur = safe_concat (buf, cur, t);
549 break;
550 case CONST_STRING:
551 cur = safe_concat (buf, cur, "\"");
552 cur = safe_concat (buf, cur, XSTR (x, 0));
553 cur = safe_concat (buf, cur, "\"");
554 break;
555 case SYMBOL_REF:
556 cur = safe_concat (buf, cur, "`");
557 cur = safe_concat (buf, cur, XSTR (x, 0));
558 cur = safe_concat (buf, cur, "'");
559 break;
560 case LABEL_REF:
561 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
562 cur = safe_concat (buf, cur, t);
563 break;
564 case CONST:
565 print_value (t, XEXP (x, 0), verbose);
566 cur = safe_concat (buf, cur, "const(");
567 cur = safe_concat (buf, cur, t);
568 cur = safe_concat (buf, cur, ")");
569 break;
570 case HIGH:
571 print_value (t, XEXP (x, 0), verbose);
572 cur = safe_concat (buf, cur, "high(");
573 cur = safe_concat (buf, cur, t);
574 cur = safe_concat (buf, cur, ")");
575 break;
576 case REG:
577 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
579 int c = reg_names[REGNO (x)][0];
580 if (c >= '0' && c <= '9')
581 cur = safe_concat (buf, cur, "%");
583 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
585 else
587 sprintf (t, "r%d", REGNO (x));
588 cur = safe_concat (buf, cur, t);
590 break;
591 case SUBREG:
592 print_value (t, SUBREG_REG (x), verbose);
593 cur = safe_concat (buf, cur, t);
594 sprintf (t, "#%d", SUBREG_WORD (x));
595 cur = safe_concat (buf, cur, t);
596 break;
597 case SCRATCH:
598 cur = safe_concat (buf, cur, "scratch");
599 break;
600 case CC0:
601 cur = safe_concat (buf, cur, "cc0");
602 break;
603 case PC:
604 cur = safe_concat (buf, cur, "pc");
605 break;
606 case MEM:
607 print_value (t, XEXP (x, 0), verbose);
608 cur = safe_concat (buf, cur, "[");
609 cur = safe_concat (buf, cur, t);
610 cur = safe_concat (buf, cur, "]");
611 break;
612 default:
613 print_exp (t, x, verbose);
614 cur = safe_concat (buf, cur, t);
615 break;
617 } /* print_value */
619 /* The next step in insn detalization, its pattern recognition. */
621 static void
622 print_pattern (buf, x, verbose)
623 char *buf;
624 rtx x;
625 int verbose;
627 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
629 switch (GET_CODE (x))
631 case SET:
632 print_value (t1, SET_DEST (x), verbose);
633 print_value (t2, SET_SRC (x), verbose);
634 sprintf (buf, "%s=%s", t1, t2);
635 break;
636 case RETURN:
637 sprintf (buf, "return");
638 break;
639 case CALL:
640 print_exp (buf, x, verbose);
641 break;
642 case CLOBBER:
643 print_value (t1, XEXP (x, 0), verbose);
644 sprintf (buf, "clobber %s", t1);
645 break;
646 case USE:
647 print_value (t1, XEXP (x, 0), verbose);
648 sprintf (buf, "use %s", t1);
649 break;
650 case COND_EXEC:
651 if (GET_CODE (COND_EXEC_TEST (x)) == NE
652 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
653 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
654 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
655 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
657 t1[0] = '!';
658 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
660 else
661 print_value (t1, COND_EXEC_TEST (x), verbose);
662 print_pattern (t2, COND_EXEC_CODE (x), verbose);
663 sprintf (buf, "(%s) %s", t1, t2);
664 break;
665 case PARALLEL:
667 int i;
669 sprintf (t1, "{");
670 for (i = 0; i < XVECLEN (x, 0); i++)
672 print_pattern (t2, XVECEXP (x, 0, i), verbose);
673 sprintf (t3, "%s%s;", t1, t2);
674 strcpy (t1, t3);
676 sprintf (buf, "%s}", t1);
678 break;
679 case SEQUENCE:
681 int i;
683 sprintf (t1, "%%{");
684 for (i = 0; i < XVECLEN (x, 0); i++)
686 print_insn (t2, XVECEXP (x, 0, i), verbose);
687 sprintf (t3, "%s%s;", t1, t2);
688 strcpy (t1, t3);
690 sprintf (buf, "%s%%}", t1);
692 break;
693 case ASM_INPUT:
694 sprintf (buf, "asm {%s}", XSTR (x, 0));
695 break;
696 case ADDR_VEC:
697 break;
698 case ADDR_DIFF_VEC:
699 print_value (buf, XEXP (x, 0), verbose);
700 break;
701 case TRAP_IF:
702 print_value (t1, TRAP_CONDITION (x), verbose);
703 sprintf (buf, "trap_if %s", t1);
704 break;
705 case UNSPEC:
707 int i;
709 sprintf (t1, "unspec{");
710 for (i = 0; i < XVECLEN (x, 0); i++)
712 print_pattern (t2, XVECEXP (x, 0, i), verbose);
713 sprintf (t3, "%s%s;", t1, t2);
714 strcpy (t1, t3);
716 sprintf (buf, "%s}", t1);
718 break;
719 case UNSPEC_VOLATILE:
721 int i;
723 sprintf (t1, "unspec/v{");
724 for (i = 0; i < XVECLEN (x, 0); i++)
726 print_pattern (t2, XVECEXP (x, 0, i), verbose);
727 sprintf (t3, "%s%s;", t1, t2);
728 strcpy (t1, t3);
730 sprintf (buf, "%s}", t1);
732 break;
733 default:
734 print_value (buf, x, verbose);
736 } /* print_pattern */
738 /* This is the main function in rtl visualization mechanism. It
739 accepts an rtx and tries to recognize it as an insn, then prints it
740 properly in human readable form, resembling assembler mnemonics.
741 For every insn it prints its UID and BB the insn belongs too.
742 (Probably the last "option" should be extended somehow, since it
743 depends now on sched.c inner variables ...) */
745 static void
746 print_insn (buf, x, verbose)
747 char *buf;
748 rtx x;
749 int verbose;
751 char t[BUF_LEN];
752 rtx insn = x;
754 switch (GET_CODE (x))
756 case INSN:
757 print_pattern (t, PATTERN (x), verbose);
758 if (verbose)
759 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
761 else
762 sprintf (buf, "%-4d %s", INSN_UID (x), t);
763 break;
764 case JUMP_INSN:
765 print_pattern (t, PATTERN (x), verbose);
766 if (verbose)
767 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
769 else
770 sprintf (buf, "%-4d %s", INSN_UID (x), t);
771 break;
772 case CALL_INSN:
773 x = PATTERN (insn);
774 if (GET_CODE (x) == PARALLEL)
776 x = XVECEXP (x, 0, 0);
777 print_pattern (t, x, verbose);
779 else
780 strcpy (t, "call <...>");
781 if (verbose)
782 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
783 else
784 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
785 break;
786 case CODE_LABEL:
787 sprintf (buf, "L%d:", INSN_UID (x));
788 break;
789 case BARRIER:
790 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
791 break;
792 case NOTE:
793 if (NOTE_LINE_NUMBER (x) > 0)
794 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
795 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
796 else
797 sprintf (buf, "%4d %s", INSN_UID (x),
798 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
799 break;
800 default:
801 if (verbose)
803 sprintf (buf, "Not an INSN at all\n");
804 debug_rtx (x);
806 else
807 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
809 } /* print_insn */
811 /* Print visualization debugging info. */
813 void
814 print_block_visualization (s)
815 const char *s;
817 int unit, i;
819 /* Print header. */
820 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
822 /* Print names of units. */
823 fprintf (sched_dump, ";; %-8s", "clock");
824 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
825 if (function_units[unit].bitmask & target_units)
826 for (i = 0; i < function_units[unit].multiplicity; i++)
827 fprintf (sched_dump, " %-33s", function_units[unit].name);
828 fprintf (sched_dump, " %-8s\n", "no-unit");
830 fprintf (sched_dump, ";; %-8s", "=====");
831 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
832 if (function_units[unit].bitmask & target_units)
833 for (i = 0; i < function_units[unit].multiplicity; i++)
834 fprintf (sched_dump, " %-33s", "==============================");
835 fprintf (sched_dump, " %-8s\n", "=======");
837 /* Print insns in each cycle. */
838 fprintf (sched_dump, "%s\n", visual_tbl);
841 /* Print insns in the 'no_unit' column of visualization. */
843 void
844 visualize_no_unit (insn)
845 rtx insn;
847 vis_no_unit[n_vis_no_unit] = insn;
848 n_vis_no_unit++;
851 /* Print insns scheduled in clock, for visualization. */
853 void
854 visualize_scheduled_insns (clock)
855 int clock;
857 int i, unit;
859 /* If no more room, split table into two. */
860 if (n_visual_lines >= MAX_VISUAL_LINES)
862 print_block_visualization ("(incomplete)");
863 init_block_visualization ();
866 n_visual_lines++;
868 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
869 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
870 if (function_units[unit].bitmask & target_units)
871 for (i = 0; i < function_units[unit].multiplicity; i++)
873 int instance = unit + i * FUNCTION_UNITS_SIZE;
874 rtx insn = get_unit_last_insn (instance);
876 /* Print insns that still keep the unit busy. */
877 if (insn
878 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
880 char str[BUF_LEN];
881 print_insn (str, insn, 0);
882 str[INSN_LEN] = '\0';
883 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
885 else
886 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
889 /* Print insns that are not assigned to any unit. */
890 for (i = 0; i < n_vis_no_unit; i++)
891 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
892 INSN_UID (vis_no_unit[i]));
893 n_vis_no_unit = 0;
895 sprintf (visual_tbl + strlen (visual_tbl), "\n");
898 /* Print stalled cycles. */
900 void
901 visualize_stall_cycles (stalls)
902 int stalls;
904 const char *prefix = ";; ";
905 const char *suffix = "\n";
906 char *p;
908 /* If no more room, split table into two. */
909 if (n_visual_lines >= MAX_VISUAL_LINES)
911 print_block_visualization ("(incomplete)");
912 init_block_visualization ();
915 n_visual_lines++;
917 p = visual_tbl + strlen (visual_tbl);
918 strcpy (p, prefix);
919 p += strlen (prefix);
921 if ((unsigned)stalls >
922 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
924 suffix = "[...]\n";
925 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
928 memset (p, '.', stalls);
929 p += stalls;
931 strcpy (p, suffix);
934 /* Allocate data used for visualization during scheduling. */
936 void
937 visualize_alloc ()
939 visual_tbl = xmalloc (get_visual_tbl_length ());
942 /* Free data used for visualization. */
944 void
945 visualize_free ()
947 free (visual_tbl);
949 #endif