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