]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/sched-vis.c
237d4460d51a43a3d0080a2f64d168c23425cda1
[thirdparty/gcc.git] / gcc / sched-vis.c
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)
6
7 This file is part of GCC.
8
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.
13
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.
18
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. */
23 \f
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"
36
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. */
45
46 static int target_units = 0;
47
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));
53
54 /* Print names of units on which insn can/should execute, for debugging. */
55
56 void
57 insn_print_units (insn)
58 rtx insn;
59 {
60 int i;
61 int unit = insn_unit (insn);
62
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
68 {
69 fprintf (sched_dump, "[");
70 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
71 if (unit & 1)
72 {
73 fprintf (sched_dump, "%s", function_units[i].name);
74 if (unit != 1)
75 fprintf (sched_dump, " ");
76 }
77 fprintf (sched_dump, "]");
78 }
79 }
80
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];
94
95 /* Finds units that are in use in this function. Required only
96 for visualization. */
97
98 void
99 init_target_units ()
100 {
101 rtx insn;
102 int unit;
103
104 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
105 {
106 if (! INSN_P (insn))
107 continue;
108
109 unit = insn_unit (insn);
110
111 if (unit < 0)
112 target_units |= ~unit;
113 else
114 target_units |= (1 << unit);
115 }
116 }
117
118 /* Return the length of the visualization table. */
119
120 static int
121 get_visual_tbl_length ()
122 {
123 int unit, i;
124 int n, n1;
125 char *s;
126
127 if (targetm.sched.use_dfa_pipeline_interface
128 && (*targetm.sched.use_dfa_pipeline_interface) ())
129 {
130 visual_tbl_line_length = 1;
131 return 1; /* Can't return 0 because that will cause problems
132 with alloca. */
133 }
134
135 /* Compute length of one field in line. */
136 s = (char *) alloca (INSN_LEN + 6);
137 sprintf (s, " %33s", "uname");
138 n1 = strlen (s);
139
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;
149
150 visual_tbl_line_length = n;
151
152 /* Compute length of visualization string. */
153 return (MAX_VISUAL_LINES * n);
154 }
155
156 /* Init block visualization debugging info. */
157
158 void
159 init_block_visualization ()
160 {
161 strcpy (visual_tbl, "");
162 n_visual_lines = 0;
163 n_vis_no_unit = 0;
164 }
165
166 #define BUF_LEN 2048
167
168 static char *
169 safe_concat (buf, cur, str)
170 char *buf;
171 char *cur;
172 const char *str;
173 {
174 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
175 int c;
176
177 if (cur > end)
178 {
179 *end = '\0';
180 return end;
181 }
182
183 while (cur < end && (c = *str++) != '\0')
184 *cur++ = c;
185
186 *cur = '\0';
187 return cur;
188 }
189
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. */
193
194 static void
195 print_exp (buf, x, verbose)
196 char *buf;
197 rtx x;
198 int verbose;
199 {
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;
207
208 for (i = 0; i < 4; i++)
209 {
210 st[i] = (char *) 0;
211 op[i] = NULL_RTX;
212 }
213
214 switch (GET_CODE (x))
215 {
216 case PLUS:
217 op[0] = XEXP (x, 0);
218 if (GET_CODE (XEXP (x, 1)) == CONST_INT
219 && INTVAL (XEXP (x, 1)) < 0)
220 {
221 st[1] = "-";
222 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
223 }
224 else
225 {
226 st[1] = "+";
227 op[1] = XEXP (x, 1);
228 }
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)
469 {
470 st[1] = " argc:";
471 op[1] = XEXP (x, 1);
472 }
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:
495 {
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++)
502 {
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 = ",";
507 }
508 cur = safe_concat (buf, cur, "] ");
509 sprintf (tmp, "%d", XINT (x, 1));
510 cur = safe_concat (buf, cur, tmp);
511 }
512 break;
513 default:
514 /* If (verbose) debug_rtx (x); */
515 st[0] = GET_RTX_NAME (GET_CODE (x));
516 break;
517 }
518
519 /* Print this as a function? */
520 if (fun)
521 {
522 cur = safe_concat (buf, cur, fun);
523 cur = safe_concat (buf, cur, "(");
524 }
525
526 for (i = 0; i < 4; i++)
527 {
528 if (st[i])
529 cur = safe_concat (buf, cur, st[i]);
530
531 if (op[i])
532 {
533 if (fun && i != 0)
534 cur = safe_concat (buf, cur, ",");
535
536 print_value (tmp, op[i], verbose);
537 cur = safe_concat (buf, cur, tmp);
538 }
539 }
540
541 if (fun)
542 cur = safe_concat (buf, cur, ")");
543 } /* print_exp */
544
545 /* Prints rtxes, I customly classified as values. They're constants,
546 registers, labels, symbols and memory accesses. */
547
548 static void
549 print_value (buf, x, verbose)
550 char *buf;
551 rtx x;
552 int verbose;
553 {
554 char t[BUF_LEN];
555 char *cur = buf;
556
557 switch (GET_CODE (x))
558 {
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)))
565 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
566 else
567 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
568 cur = safe_concat (buf, cur, t);
569 break;
570 case CONST_STRING:
571 cur = safe_concat (buf, cur, "\"");
572 cur = safe_concat (buf, cur, XSTR (x, 0));
573 cur = safe_concat (buf, cur, "\"");
574 break;
575 case SYMBOL_REF:
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 LABEL_REF:
581 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
582 cur = safe_concat (buf, cur, t);
583 break;
584 case CONST:
585 print_value (t, XEXP (x, 0), verbose);
586 cur = safe_concat (buf, cur, "const(");
587 cur = safe_concat (buf, cur, t);
588 cur = safe_concat (buf, cur, ")");
589 break;
590 case HIGH:
591 print_value (t, XEXP (x, 0), verbose);
592 cur = safe_concat (buf, cur, "high(");
593 cur = safe_concat (buf, cur, t);
594 cur = safe_concat (buf, cur, ")");
595 break;
596 case REG:
597 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
598 {
599 int c = reg_names[REGNO (x)][0];
600 if (ISDIGIT (c))
601 cur = safe_concat (buf, cur, "%");
602
603 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
604 }
605 else
606 {
607 sprintf (t, "r%d", REGNO (x));
608 cur = safe_concat (buf, cur, t);
609 }
610 break;
611 case SUBREG:
612 print_value (t, SUBREG_REG (x), verbose);
613 cur = safe_concat (buf, cur, t);
614 sprintf (t, "#%d", SUBREG_BYTE (x));
615 cur = safe_concat (buf, cur, t);
616 break;
617 case SCRATCH:
618 cur = safe_concat (buf, cur, "scratch");
619 break;
620 case CC0:
621 cur = safe_concat (buf, cur, "cc0");
622 break;
623 case PC:
624 cur = safe_concat (buf, cur, "pc");
625 break;
626 case MEM:
627 print_value (t, XEXP (x, 0), verbose);
628 cur = safe_concat (buf, cur, "[");
629 cur = safe_concat (buf, cur, t);
630 cur = safe_concat (buf, cur, "]");
631 break;
632 default:
633 print_exp (t, x, verbose);
634 cur = safe_concat (buf, cur, t);
635 break;
636 }
637 } /* print_value */
638
639 /* The next step in insn detalization, its pattern recognition. */
640
641 static void
642 print_pattern (buf, x, verbose)
643 char *buf;
644 rtx x;
645 int verbose;
646 {
647 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
648
649 switch (GET_CODE (x))
650 {
651 case SET:
652 print_value (t1, SET_DEST (x), verbose);
653 print_value (t2, SET_SRC (x), verbose);
654 sprintf (buf, "%s=%s", t1, t2);
655 break;
656 case RETURN:
657 sprintf (buf, "return");
658 break;
659 case CALL:
660 print_exp (buf, x, verbose);
661 break;
662 case CLOBBER:
663 print_value (t1, XEXP (x, 0), verbose);
664 sprintf (buf, "clobber %s", t1);
665 break;
666 case USE:
667 print_value (t1, XEXP (x, 0), verbose);
668 sprintf (buf, "use %s", t1);
669 break;
670 case COND_EXEC:
671 if (GET_CODE (COND_EXEC_TEST (x)) == NE
672 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
673 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
674 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
675 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
676 {
677 t1[0] = '!';
678 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
679 }
680 else
681 print_value (t1, COND_EXEC_TEST (x), verbose);
682 print_pattern (t2, COND_EXEC_CODE (x), verbose);
683 sprintf (buf, "(%s) %s", t1, t2);
684 break;
685 case PARALLEL:
686 {
687 int i;
688
689 sprintf (t1, "{");
690 for (i = 0; i < XVECLEN (x, 0); i++)
691 {
692 print_pattern (t2, XVECEXP (x, 0, i), verbose);
693 sprintf (t3, "%s%s;", t1, t2);
694 strcpy (t1, t3);
695 }
696 sprintf (buf, "%s}", t1);
697 }
698 break;
699 case SEQUENCE:
700 /* Should never see SEQUENCE codes until after reorg. */
701 abort ();
702 break;
703 case ASM_INPUT:
704 sprintf (buf, "asm {%s}", XSTR (x, 0));
705 break;
706 case ADDR_VEC:
707 break;
708 case ADDR_DIFF_VEC:
709 print_value (buf, XEXP (x, 0), verbose);
710 break;
711 case TRAP_IF:
712 print_value (t1, TRAP_CONDITION (x), verbose);
713 sprintf (buf, "trap_if %s", t1);
714 break;
715 case UNSPEC:
716 {
717 int i;
718
719 sprintf (t1, "unspec{");
720 for (i = 0; i < XVECLEN (x, 0); i++)
721 {
722 print_pattern (t2, XVECEXP (x, 0, i), verbose);
723 sprintf (t3, "%s%s;", t1, t2);
724 strcpy (t1, t3);
725 }
726 sprintf (buf, "%s}", t1);
727 }
728 break;
729 case UNSPEC_VOLATILE:
730 {
731 int i;
732
733 sprintf (t1, "unspec/v{");
734 for (i = 0; i < XVECLEN (x, 0); i++)
735 {
736 print_pattern (t2, XVECEXP (x, 0, i), verbose);
737 sprintf (t3, "%s%s;", t1, t2);
738 strcpy (t1, t3);
739 }
740 sprintf (buf, "%s}", t1);
741 }
742 break;
743 default:
744 print_value (buf, x, verbose);
745 }
746 } /* print_pattern */
747
748 /* This is the main function in rtl visualization mechanism. It
749 accepts an rtx and tries to recognize it as an insn, then prints it
750 properly in human readable form, resembling assembler mnemonics.
751 For every insn it prints its UID and BB the insn belongs too.
752 (Probably the last "option" should be extended somehow, since it
753 depends now on sched.c inner variables ...) */
754
755 void
756 print_insn (buf, x, verbose)
757 char *buf;
758 rtx x;
759 int verbose;
760 {
761 char t[BUF_LEN];
762 rtx insn = x;
763
764 switch (GET_CODE (x))
765 {
766 case INSN:
767 print_pattern (t, PATTERN (x), verbose);
768 if (verbose)
769 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
770 t);
771 else
772 sprintf (buf, "%-4d %s", INSN_UID (x), t);
773 break;
774 case JUMP_INSN:
775 print_pattern (t, PATTERN (x), verbose);
776 if (verbose)
777 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
778 t);
779 else
780 sprintf (buf, "%-4d %s", INSN_UID (x), t);
781 break;
782 case CALL_INSN:
783 x = PATTERN (insn);
784 if (GET_CODE (x) == PARALLEL)
785 {
786 x = XVECEXP (x, 0, 0);
787 print_pattern (t, x, verbose);
788 }
789 else
790 strcpy (t, "call <...>");
791 if (verbose)
792 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
793 else
794 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
795 break;
796 case CODE_LABEL:
797 sprintf (buf, "L%d:", INSN_UID (x));
798 break;
799 case BARRIER:
800 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
801 break;
802 case NOTE:
803 if (NOTE_LINE_NUMBER (x) > 0)
804 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
805 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
806 else
807 sprintf (buf, "%4d %s", INSN_UID (x),
808 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
809 break;
810 default:
811 if (verbose)
812 {
813 sprintf (buf, "Not an INSN at all\n");
814 debug_rtx (x);
815 }
816 else
817 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
818 }
819 } /* print_insn */
820
821 /* Print visualization debugging info. The scheduler using only DFA
822 description should never use the following function. */
823
824 void
825 print_block_visualization (s)
826 const char *s;
827 {
828 int unit, i;
829
830 /* Print header. */
831 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
832
833 /* Print names of units. */
834 fprintf (sched_dump, ";; %-8s", "clock");
835 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
836 if (function_units[unit].bitmask & target_units)
837 for (i = 0; i < function_units[unit].multiplicity; i++)
838 fprintf (sched_dump, " %-33s", function_units[unit].name);
839 fprintf (sched_dump, " %-8s\n", "no-unit");
840
841 fprintf (sched_dump, ";; %-8s", "=====");
842 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
843 if (function_units[unit].bitmask & target_units)
844 for (i = 0; i < function_units[unit].multiplicity; i++)
845 fprintf (sched_dump, " %-33s", "==============================");
846 fprintf (sched_dump, " %-8s\n", "=======");
847
848 /* Print insns in each cycle. */
849 fprintf (sched_dump, "%s\n", visual_tbl);
850 }
851
852 /* Print insns in the 'no_unit' column of visualization. */
853
854 void
855 visualize_no_unit (insn)
856 rtx insn;
857 {
858 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
859 {
860 vis_no_unit[n_vis_no_unit] = insn;
861 n_vis_no_unit++;
862 }
863 }
864
865 /* Print insns scheduled in clock, for visualization. */
866
867 void
868 visualize_scheduled_insns (clock)
869 int clock;
870 {
871 int i, unit;
872
873 /* If no more room, split table into two. */
874 if (n_visual_lines >= MAX_VISUAL_LINES)
875 {
876 print_block_visualization ("(incomplete)");
877 init_block_visualization ();
878 }
879
880 n_visual_lines++;
881
882 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
883 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
884 if (function_units[unit].bitmask & target_units)
885 for (i = 0; i < function_units[unit].multiplicity; i++)
886 {
887 int instance = unit + i * FUNCTION_UNITS_SIZE;
888 rtx insn = get_unit_last_insn (instance);
889
890 /* Print insns that still keep the unit busy. */
891 if (insn
892 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
893 {
894 char str[BUF_LEN];
895 print_insn (str, insn, 0);
896 str[INSN_LEN] = '\0';
897 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
898 }
899 else
900 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
901 }
902
903 /* Print insns that are not assigned to any unit. */
904 for (i = 0; i < n_vis_no_unit; i++)
905 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
906 INSN_UID (vis_no_unit[i]));
907 n_vis_no_unit = 0;
908
909 sprintf (visual_tbl + strlen (visual_tbl), "\n");
910 }
911
912 /* Print stalled cycles. */
913
914 void
915 visualize_stall_cycles (stalls)
916 int stalls;
917 {
918 static const char *const prefix = ";; ";
919 const char *suffix = "\n";
920 char *p;
921
922 /* If no more room, split table into two. */
923 if (n_visual_lines >= MAX_VISUAL_LINES)
924 {
925 print_block_visualization ("(incomplete)");
926 init_block_visualization ();
927 }
928
929 n_visual_lines++;
930
931 p = visual_tbl + strlen (visual_tbl);
932 strcpy (p, prefix);
933 p += strlen (prefix);
934
935 if ((unsigned) stalls >
936 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
937 {
938 suffix = "[...]\n";
939 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
940 }
941
942 memset (p, '.', stalls);
943 p += stalls;
944
945 strcpy (p, suffix);
946 }
947
948 /* Allocate data used for visualization during scheduling. */
949
950 void
951 visualize_alloc ()
952 {
953 visual_tbl = xmalloc (get_visual_tbl_length ());
954 }
955
956 /* Free data used for visualization. */
957
958 void
959 visualize_free ()
960 {
961 free (visual_tbl);
962 }
963 #endif