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