PR libstdc++/3584
[official-gcc.git] / gcc / sched-vis.c
blob571c4ce13058843154d7ad0b5e02fdc435ad0b97
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, t, 6);
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:
705 /* Should never see SEQUENCE codes until after reorg. */
706 abort ();
707 break;
708 case ASM_INPUT:
709 sprintf (buf, "asm {%s}", XSTR (x, 0));
710 break;
711 case ADDR_VEC:
712 break;
713 case ADDR_DIFF_VEC:
714 print_value (buf, XEXP (x, 0), verbose);
715 break;
716 case TRAP_IF:
717 print_value (t1, TRAP_CONDITION (x), verbose);
718 sprintf (buf, "trap_if %s", t1);
719 break;
720 case UNSPEC:
722 int i;
724 sprintf (t1, "unspec{");
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 case UNSPEC_VOLATILE:
736 int i;
738 sprintf (t1, "unspec/v{");
739 for (i = 0; i < XVECLEN (x, 0); i++)
741 print_pattern (t2, XVECEXP (x, 0, i), verbose);
742 sprintf (t3, "%s%s;", t1, t2);
743 strcpy (t1, t3);
745 sprintf (buf, "%s}", t1);
747 break;
748 default:
749 print_value (buf, x, verbose);
751 } /* print_pattern */
753 /* This is the main function in rtl visualization mechanism. It
754 accepts an rtx and tries to recognize it as an insn, then prints it
755 properly in human readable form, resembling assembler mnemonics.
756 For every insn it prints its UID and BB the insn belongs too.
757 (Probably the last "option" should be extended somehow, since it
758 depends now on sched.c inner variables ...) */
760 void
761 print_insn (buf, x, verbose)
762 char *buf;
763 rtx x;
764 int verbose;
766 char t[BUF_LEN];
767 rtx insn = x;
769 switch (GET_CODE (x))
771 case INSN:
772 print_pattern (t, PATTERN (x), verbose);
773 if (verbose)
774 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
776 else
777 sprintf (buf, "%-4d %s", INSN_UID (x), t);
778 break;
779 case JUMP_INSN:
780 print_pattern (t, PATTERN (x), verbose);
781 if (verbose)
782 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
784 else
785 sprintf (buf, "%-4d %s", INSN_UID (x), t);
786 break;
787 case CALL_INSN:
788 x = PATTERN (insn);
789 if (GET_CODE (x) == PARALLEL)
791 x = XVECEXP (x, 0, 0);
792 print_pattern (t, x, verbose);
794 else
795 strcpy (t, "call <...>");
796 if (verbose)
797 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
798 else
799 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
800 break;
801 case CODE_LABEL:
802 sprintf (buf, "L%d:", INSN_UID (x));
803 break;
804 case BARRIER:
805 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
806 break;
807 case NOTE:
808 if (NOTE_LINE_NUMBER (x) > 0)
809 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
810 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
811 else
812 sprintf (buf, "%4d %s", INSN_UID (x),
813 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
814 break;
815 default:
816 if (verbose)
818 sprintf (buf, "Not an INSN at all\n");
819 debug_rtx (x);
821 else
822 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
824 } /* print_insn */
826 /* Print visualization debugging info. The scheduler using only DFA
827 description should never use the following function. */
829 void
830 print_block_visualization (s)
831 const char *s;
833 int unit, i;
835 /* Print header. */
836 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
838 /* Print names of units. */
839 fprintf (sched_dump, ";; %-8s", "clock");
840 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
841 if (function_units[unit].bitmask & target_units)
842 for (i = 0; i < function_units[unit].multiplicity; i++)
843 fprintf (sched_dump, " %-33s", function_units[unit].name);
844 fprintf (sched_dump, " %-8s\n", "no-unit");
846 fprintf (sched_dump, ";; %-8s", "=====");
847 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
848 if (function_units[unit].bitmask & target_units)
849 for (i = 0; i < function_units[unit].multiplicity; i++)
850 fprintf (sched_dump, " %-33s", "==============================");
851 fprintf (sched_dump, " %-8s\n", "=======");
853 /* Print insns in each cycle. */
854 fprintf (sched_dump, "%s\n", visual_tbl);
857 /* Print insns in the 'no_unit' column of visualization. */
859 void
860 visualize_no_unit (insn)
861 rtx insn;
863 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
865 vis_no_unit[n_vis_no_unit] = insn;
866 n_vis_no_unit++;
870 /* Print insns scheduled in clock, for visualization. */
872 void
873 visualize_scheduled_insns (clock)
874 int clock;
876 int i, unit;
878 /* If no more room, split table into two. */
879 if (n_visual_lines >= MAX_VISUAL_LINES)
881 print_block_visualization ("(incomplete)");
882 init_block_visualization ();
885 n_visual_lines++;
887 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
888 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
889 if (function_units[unit].bitmask & target_units)
890 for (i = 0; i < function_units[unit].multiplicity; i++)
892 int instance = unit + i * FUNCTION_UNITS_SIZE;
893 rtx insn = get_unit_last_insn (instance);
895 /* Print insns that still keep the unit busy. */
896 if (insn
897 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
899 char str[BUF_LEN];
900 print_insn (str, insn, 0);
901 str[INSN_LEN] = '\0';
902 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
904 else
905 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
908 /* Print insns that are not assigned to any unit. */
909 for (i = 0; i < n_vis_no_unit; i++)
910 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
911 INSN_UID (vis_no_unit[i]));
912 n_vis_no_unit = 0;
914 sprintf (visual_tbl + strlen (visual_tbl), "\n");
917 /* Print stalled cycles. */
919 void
920 visualize_stall_cycles (stalls)
921 int stalls;
923 static const char *const prefix = ";; ";
924 const char *suffix = "\n";
925 char *p;
927 /* If no more room, split table into two. */
928 if (n_visual_lines >= MAX_VISUAL_LINES)
930 print_block_visualization ("(incomplete)");
931 init_block_visualization ();
934 n_visual_lines++;
936 p = visual_tbl + strlen (visual_tbl);
937 strcpy (p, prefix);
938 p += strlen (prefix);
940 if ((unsigned) stalls >
941 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
943 suffix = "[...]\n";
944 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
947 memset (p, '.', stalls);
948 p += stalls;
950 strcpy (p, suffix);
953 /* Allocate data used for visualization during scheduling. */
955 void
956 visualize_alloc ()
958 visual_tbl = xmalloc (get_visual_tbl_length ());
961 /* Free data used for visualization. */
963 void
964 visualize_free ()
966 free (visual_tbl);
968 #endif