2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / sched-vis.c
blob9174c8bf2ff5100822beb8ed9867f478e3728bd0
1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003 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 (char *, char *, const char *);
51 static int get_visual_tbl_length (void);
52 static void print_exp (char *, rtx, int);
53 static void print_value (char *, rtx, int);
54 static void print_pattern (char *, rtx, int);
56 /* Print names of units on which insn can/should execute, for debugging. */
58 void
59 insn_print_units (rtx insn)
61 int i;
62 int unit = insn_unit (insn);
64 if (unit == -1)
65 fprintf (sched_dump, "none");
66 else if (unit >= 0)
67 fprintf (sched_dump, "%s", function_units[unit].name);
68 else
70 fprintf (sched_dump, "[");
71 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
72 if (unit & 1)
74 fprintf (sched_dump, "%s", function_units[i].name);
75 if (unit != 1)
76 fprintf (sched_dump, " ");
78 fprintf (sched_dump, "]");
82 /* MAX_VISUAL_LINES is the maximum number of lines in visualization table
83 of a basic block. If more lines are needed, table is split to two.
84 n_visual_lines is the number of lines printed so far for a block.
85 visual_tbl contains the block visualization info.
86 vis_no_unit holds insns in a cycle that are not mapped to any unit. */
87 #define MAX_VISUAL_LINES 100
88 #define INSN_LEN 30
89 int n_visual_lines;
90 static unsigned visual_tbl_line_length;
91 char *visual_tbl;
92 int n_vis_no_unit;
93 #define MAX_VISUAL_NO_UNIT 20
94 rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
96 /* Finds units that are in use in this function. Required only
97 for visualization. */
99 void
100 init_target_units (void)
102 rtx insn;
103 int unit;
105 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
107 if (! INSN_P (insn))
108 continue;
110 unit = insn_unit (insn);
112 if (unit < 0)
113 target_units |= ~unit;
114 else
115 target_units |= (1 << unit);
119 /* Return the length of the visualization table. */
121 static int
122 get_visual_tbl_length (void)
124 int unit, i;
125 int n, n1;
126 char *s;
128 if (targetm.sched.use_dfa_pipeline_interface
129 && (*targetm.sched.use_dfa_pipeline_interface) ())
131 visual_tbl_line_length = 1;
132 return 1; /* Can't return 0 because that will cause problems
133 with alloca. */
136 /* Compute length of one field in line. */
137 s = alloca (INSN_LEN + 6);
138 sprintf (s, " %33s", "uname");
139 n1 = strlen (s);
141 /* Compute length of one line. */
142 n = strlen (";; ");
143 n += n1;
144 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
145 if (function_units[unit].bitmask & target_units)
146 for (i = 0; i < function_units[unit].multiplicity; i++)
147 n += n1;
148 n += n1;
149 n += strlen ("\n") + 2;
151 visual_tbl_line_length = n;
153 /* Compute length of visualization string. */
154 return (MAX_VISUAL_LINES * n);
157 /* Init block visualization debugging info. */
159 void
160 init_block_visualization (void)
162 strcpy (visual_tbl, "");
163 n_visual_lines = 0;
164 n_vis_no_unit = 0;
167 #define BUF_LEN 2048
169 static char *
170 safe_concat (char *buf, char *cur, const char *str)
172 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
173 int c;
175 if (cur > end)
177 *end = '\0';
178 return end;
181 while (cur < end && (c = *str++) != '\0')
182 *cur++ = c;
184 *cur = '\0';
185 return cur;
188 /* This recognizes rtx, I classified as expressions. These are always
189 represent some action on values or results of other expression, that
190 may be stored in objects representing values. */
192 static void
193 print_exp (char *buf, rtx x, int verbose)
195 char tmp[BUF_LEN];
196 const char *st[4];
197 char *cur = buf;
198 const char *fun = (char *) 0;
199 const char *sep;
200 rtx op[4];
201 int i;
203 for (i = 0; i < 4; i++)
205 st[i] = (char *) 0;
206 op[i] = NULL_RTX;
209 switch (GET_CODE (x))
211 case PLUS:
212 op[0] = XEXP (x, 0);
213 if (GET_CODE (XEXP (x, 1)) == CONST_INT
214 && INTVAL (XEXP (x, 1)) < 0)
216 st[1] = "-";
217 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
219 else
221 st[1] = "+";
222 op[1] = XEXP (x, 1);
224 break;
225 case LO_SUM:
226 op[0] = XEXP (x, 0);
227 st[1] = "+low(";
228 op[1] = XEXP (x, 1);
229 st[2] = ")";
230 break;
231 case MINUS:
232 op[0] = XEXP (x, 0);
233 st[1] = "-";
234 op[1] = XEXP (x, 1);
235 break;
236 case COMPARE:
237 fun = "cmp";
238 op[0] = XEXP (x, 0);
239 op[1] = XEXP (x, 1);
240 break;
241 case NEG:
242 st[0] = "-";
243 op[0] = XEXP (x, 0);
244 break;
245 case MULT:
246 op[0] = XEXP (x, 0);
247 st[1] = "*";
248 op[1] = XEXP (x, 1);
249 break;
250 case DIV:
251 op[0] = XEXP (x, 0);
252 st[1] = "/";
253 op[1] = XEXP (x, 1);
254 break;
255 case UDIV:
256 fun = "udiv";
257 op[0] = XEXP (x, 0);
258 op[1] = XEXP (x, 1);
259 break;
260 case MOD:
261 op[0] = XEXP (x, 0);
262 st[1] = "%";
263 op[1] = XEXP (x, 1);
264 break;
265 case UMOD:
266 fun = "umod";
267 op[0] = XEXP (x, 0);
268 op[1] = XEXP (x, 1);
269 break;
270 case SMIN:
271 fun = "smin";
272 op[0] = XEXP (x, 0);
273 op[1] = XEXP (x, 1);
274 break;
275 case SMAX:
276 fun = "smax";
277 op[0] = XEXP (x, 0);
278 op[1] = XEXP (x, 1);
279 break;
280 case UMIN:
281 fun = "umin";
282 op[0] = XEXP (x, 0);
283 op[1] = XEXP (x, 1);
284 break;
285 case UMAX:
286 fun = "umax";
287 op[0] = XEXP (x, 0);
288 op[1] = XEXP (x, 1);
289 break;
290 case NOT:
291 st[0] = "!";
292 op[0] = XEXP (x, 0);
293 break;
294 case AND:
295 op[0] = XEXP (x, 0);
296 st[1] = "&";
297 op[1] = XEXP (x, 1);
298 break;
299 case IOR:
300 op[0] = XEXP (x, 0);
301 st[1] = "|";
302 op[1] = XEXP (x, 1);
303 break;
304 case XOR:
305 op[0] = XEXP (x, 0);
306 st[1] = "^";
307 op[1] = XEXP (x, 1);
308 break;
309 case ASHIFT:
310 op[0] = XEXP (x, 0);
311 st[1] = "<<";
312 op[1] = XEXP (x, 1);
313 break;
314 case LSHIFTRT:
315 op[0] = XEXP (x, 0);
316 st[1] = " 0>>";
317 op[1] = XEXP (x, 1);
318 break;
319 case ASHIFTRT:
320 op[0] = XEXP (x, 0);
321 st[1] = ">>";
322 op[1] = XEXP (x, 1);
323 break;
324 case ROTATE:
325 op[0] = XEXP (x, 0);
326 st[1] = "<-<";
327 op[1] = XEXP (x, 1);
328 break;
329 case ROTATERT:
330 op[0] = XEXP (x, 0);
331 st[1] = ">->";
332 op[1] = XEXP (x, 1);
333 break;
334 case ABS:
335 fun = "abs";
336 op[0] = XEXP (x, 0);
337 break;
338 case SQRT:
339 fun = "sqrt";
340 op[0] = XEXP (x, 0);
341 break;
342 case FFS:
343 fun = "ffs";
344 op[0] = XEXP (x, 0);
345 break;
346 case EQ:
347 op[0] = XEXP (x, 0);
348 st[1] = "==";
349 op[1] = XEXP (x, 1);
350 break;
351 case NE:
352 op[0] = XEXP (x, 0);
353 st[1] = "!=";
354 op[1] = XEXP (x, 1);
355 break;
356 case GT:
357 op[0] = XEXP (x, 0);
358 st[1] = ">";
359 op[1] = XEXP (x, 1);
360 break;
361 case GTU:
362 fun = "gtu";
363 op[0] = XEXP (x, 0);
364 op[1] = XEXP (x, 1);
365 break;
366 case LT:
367 op[0] = XEXP (x, 0);
368 st[1] = "<";
369 op[1] = XEXP (x, 1);
370 break;
371 case LTU:
372 fun = "ltu";
373 op[0] = XEXP (x, 0);
374 op[1] = XEXP (x, 1);
375 break;
376 case GE:
377 op[0] = XEXP (x, 0);
378 st[1] = ">=";
379 op[1] = XEXP (x, 1);
380 break;
381 case GEU:
382 fun = "geu";
383 op[0] = XEXP (x, 0);
384 op[1] = XEXP (x, 1);
385 break;
386 case LE:
387 op[0] = XEXP (x, 0);
388 st[1] = "<=";
389 op[1] = XEXP (x, 1);
390 break;
391 case LEU:
392 fun = "leu";
393 op[0] = XEXP (x, 0);
394 op[1] = XEXP (x, 1);
395 break;
396 case SIGN_EXTRACT:
397 fun = (verbose) ? "sign_extract" : "sxt";
398 op[0] = XEXP (x, 0);
399 op[1] = XEXP (x, 1);
400 op[2] = XEXP (x, 2);
401 break;
402 case ZERO_EXTRACT:
403 fun = (verbose) ? "zero_extract" : "zxt";
404 op[0] = XEXP (x, 0);
405 op[1] = XEXP (x, 1);
406 op[2] = XEXP (x, 2);
407 break;
408 case SIGN_EXTEND:
409 fun = (verbose) ? "sign_extend" : "sxn";
410 op[0] = XEXP (x, 0);
411 break;
412 case ZERO_EXTEND:
413 fun = (verbose) ? "zero_extend" : "zxn";
414 op[0] = XEXP (x, 0);
415 break;
416 case FLOAT_EXTEND:
417 fun = (verbose) ? "float_extend" : "fxn";
418 op[0] = XEXP (x, 0);
419 break;
420 case TRUNCATE:
421 fun = (verbose) ? "trunc" : "trn";
422 op[0] = XEXP (x, 0);
423 break;
424 case FLOAT_TRUNCATE:
425 fun = (verbose) ? "float_trunc" : "ftr";
426 op[0] = XEXP (x, 0);
427 break;
428 case FLOAT:
429 fun = (verbose) ? "float" : "flt";
430 op[0] = XEXP (x, 0);
431 break;
432 case UNSIGNED_FLOAT:
433 fun = (verbose) ? "uns_float" : "ufl";
434 op[0] = XEXP (x, 0);
435 break;
436 case FIX:
437 fun = "fix";
438 op[0] = XEXP (x, 0);
439 break;
440 case UNSIGNED_FIX:
441 fun = (verbose) ? "uns_fix" : "ufx";
442 op[0] = XEXP (x, 0);
443 break;
444 case PRE_DEC:
445 st[0] = "--";
446 op[0] = XEXP (x, 0);
447 break;
448 case PRE_INC:
449 st[0] = "++";
450 op[0] = XEXP (x, 0);
451 break;
452 case POST_DEC:
453 op[0] = XEXP (x, 0);
454 st[1] = "--";
455 break;
456 case POST_INC:
457 op[0] = XEXP (x, 0);
458 st[1] = "++";
459 break;
460 case CALL:
461 st[0] = "call ";
462 op[0] = XEXP (x, 0);
463 if (verbose)
465 st[1] = " argc:";
466 op[1] = XEXP (x, 1);
468 break;
469 case IF_THEN_ELSE:
470 st[0] = "{(";
471 op[0] = XEXP (x, 0);
472 st[1] = ")?";
473 op[1] = XEXP (x, 1);
474 st[2] = ":";
475 op[2] = XEXP (x, 2);
476 st[3] = "}";
477 break;
478 case TRAP_IF:
479 fun = "trap_if";
480 op[0] = TRAP_CONDITION (x);
481 break;
482 case PREFETCH:
483 fun = "prefetch";
484 op[0] = XEXP (x, 0);
485 op[1] = XEXP (x, 1);
486 op[2] = XEXP (x, 2);
487 break;
488 case UNSPEC:
489 case UNSPEC_VOLATILE:
491 cur = safe_concat (buf, cur, "unspec");
492 if (GET_CODE (x) == UNSPEC_VOLATILE)
493 cur = safe_concat (buf, cur, "/v");
494 cur = safe_concat (buf, cur, "[");
495 sep = "";
496 for (i = 0; i < XVECLEN (x, 0); i++)
498 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
499 cur = safe_concat (buf, cur, sep);
500 cur = safe_concat (buf, cur, tmp);
501 sep = ",";
503 cur = safe_concat (buf, cur, "] ");
504 sprintf (tmp, "%d", XINT (x, 1));
505 cur = safe_concat (buf, cur, tmp);
507 break;
508 default:
509 /* If (verbose) debug_rtx (x); */
510 st[0] = GET_RTX_NAME (GET_CODE (x));
511 break;
514 /* Print this as a function? */
515 if (fun)
517 cur = safe_concat (buf, cur, fun);
518 cur = safe_concat (buf, cur, "(");
521 for (i = 0; i < 4; i++)
523 if (st[i])
524 cur = safe_concat (buf, cur, st[i]);
526 if (op[i])
528 if (fun && i != 0)
529 cur = safe_concat (buf, cur, ",");
531 print_value (tmp, op[i], verbose);
532 cur = safe_concat (buf, cur, tmp);
536 if (fun)
537 cur = safe_concat (buf, cur, ")");
538 } /* print_exp */
540 /* Prints rtxes, I customarily classified as values. They're constants,
541 registers, labels, symbols and memory accesses. */
543 static void
544 print_value (char *buf, rtx x, int verbose)
546 char t[BUF_LEN];
547 char *cur = buf;
549 switch (GET_CODE (x))
551 case CONST_INT:
552 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
553 cur = safe_concat (buf, cur, t);
554 break;
555 case CONST_DOUBLE:
556 if (FLOAT_MODE_P (GET_MODE (x)))
557 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
558 else
559 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
560 cur = safe_concat (buf, cur, t);
561 break;
562 case CONST_STRING:
563 cur = safe_concat (buf, cur, "\"");
564 cur = safe_concat (buf, cur, XSTR (x, 0));
565 cur = safe_concat (buf, cur, "\"");
566 break;
567 case SYMBOL_REF:
568 cur = safe_concat (buf, cur, "`");
569 cur = safe_concat (buf, cur, XSTR (x, 0));
570 cur = safe_concat (buf, cur, "'");
571 break;
572 case LABEL_REF:
573 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
574 cur = safe_concat (buf, cur, t);
575 break;
576 case CONST:
577 print_value (t, XEXP (x, 0), verbose);
578 cur = safe_concat (buf, cur, "const(");
579 cur = safe_concat (buf, cur, t);
580 cur = safe_concat (buf, cur, ")");
581 break;
582 case HIGH:
583 print_value (t, XEXP (x, 0), verbose);
584 cur = safe_concat (buf, cur, "high(");
585 cur = safe_concat (buf, cur, t);
586 cur = safe_concat (buf, cur, ")");
587 break;
588 case REG:
589 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
591 int c = reg_names[REGNO (x)][0];
592 if (ISDIGIT (c))
593 cur = safe_concat (buf, cur, "%");
595 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
597 else
599 sprintf (t, "r%d", REGNO (x));
600 cur = safe_concat (buf, cur, t);
602 break;
603 case SUBREG:
604 print_value (t, SUBREG_REG (x), verbose);
605 cur = safe_concat (buf, cur, t);
606 sprintf (t, "#%d", SUBREG_BYTE (x));
607 cur = safe_concat (buf, cur, t);
608 break;
609 case SCRATCH:
610 cur = safe_concat (buf, cur, "scratch");
611 break;
612 case CC0:
613 cur = safe_concat (buf, cur, "cc0");
614 break;
615 case PC:
616 cur = safe_concat (buf, cur, "pc");
617 break;
618 case MEM:
619 print_value (t, XEXP (x, 0), verbose);
620 cur = safe_concat (buf, cur, "[");
621 cur = safe_concat (buf, cur, t);
622 cur = safe_concat (buf, cur, "]");
623 break;
624 default:
625 print_exp (t, x, verbose);
626 cur = safe_concat (buf, cur, t);
627 break;
629 } /* print_value */
631 /* The next step in insn detalization, its pattern recognition. */
633 static void
634 print_pattern (char *buf, rtx x, int verbose)
636 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
638 switch (GET_CODE (x))
640 case SET:
641 print_value (t1, SET_DEST (x), verbose);
642 print_value (t2, SET_SRC (x), verbose);
643 sprintf (buf, "%s=%s", t1, t2);
644 break;
645 case RETURN:
646 sprintf (buf, "return");
647 break;
648 case CALL:
649 print_exp (buf, x, verbose);
650 break;
651 case CLOBBER:
652 print_value (t1, XEXP (x, 0), verbose);
653 sprintf (buf, "clobber %s", t1);
654 break;
655 case USE:
656 print_value (t1, XEXP (x, 0), verbose);
657 sprintf (buf, "use %s", t1);
658 break;
659 case COND_EXEC:
660 if (GET_CODE (COND_EXEC_TEST (x)) == NE
661 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
662 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
663 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
664 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
666 t1[0] = '!';
667 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
669 else
670 print_value (t1, COND_EXEC_TEST (x), verbose);
671 print_pattern (t2, COND_EXEC_CODE (x), verbose);
672 sprintf (buf, "(%s) %s", t1, t2);
673 break;
674 case PARALLEL:
676 int i;
678 sprintf (t1, "{");
679 for (i = 0; i < XVECLEN (x, 0); i++)
681 print_pattern (t2, XVECEXP (x, 0, i), verbose);
682 sprintf (t3, "%s%s;", t1, t2);
683 strcpy (t1, t3);
685 sprintf (buf, "%s}", t1);
687 break;
688 case SEQUENCE:
689 /* Should never see SEQUENCE codes until after reorg. */
690 abort ();
691 break;
692 case ASM_INPUT:
693 sprintf (buf, "asm {%s}", XSTR (x, 0));
694 break;
695 case ADDR_VEC:
696 break;
697 case ADDR_DIFF_VEC:
698 print_value (buf, XEXP (x, 0), verbose);
699 break;
700 case TRAP_IF:
701 print_value (t1, TRAP_CONDITION (x), verbose);
702 sprintf (buf, "trap_if %s", t1);
703 break;
704 case UNSPEC:
706 int i;
708 sprintf (t1, "unspec{");
709 for (i = 0; i < XVECLEN (x, 0); i++)
711 print_pattern (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 UNSPEC_VOLATILE:
720 int i;
722 sprintf (t1, "unspec/v{");
723 for (i = 0; i < XVECLEN (x, 0); i++)
725 print_pattern (t2, XVECEXP (x, 0, i), verbose);
726 sprintf (t3, "%s%s;", t1, t2);
727 strcpy (t1, t3);
729 sprintf (buf, "%s}", t1);
731 break;
732 default:
733 print_value (buf, x, verbose);
735 } /* print_pattern */
737 /* This is the main function in rtl visualization mechanism. It
738 accepts an rtx and tries to recognize it as an insn, then prints it
739 properly in human readable form, resembling assembler mnemonics.
740 For every insn it prints its UID and BB the insn belongs too.
741 (Probably the last "option" should be extended somehow, since it
742 depends now on sched.c inner variables ...) */
744 void
745 print_insn (char *buf, rtx x, int verbose)
747 char t[BUF_LEN];
748 rtx insn = x;
750 switch (GET_CODE (x))
752 case INSN:
753 print_pattern (t, PATTERN (x), verbose);
754 if (verbose)
755 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
757 else
758 sprintf (buf, "%-4d %s", INSN_UID (x), t);
759 break;
760 case JUMP_INSN:
761 print_pattern (t, PATTERN (x), verbose);
762 if (verbose)
763 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
765 else
766 sprintf (buf, "%-4d %s", INSN_UID (x), t);
767 break;
768 case CALL_INSN:
769 x = PATTERN (insn);
770 if (GET_CODE (x) == PARALLEL)
772 x = XVECEXP (x, 0, 0);
773 print_pattern (t, x, verbose);
775 else
776 strcpy (t, "call <...>");
777 if (verbose)
778 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
779 else
780 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
781 break;
782 case CODE_LABEL:
783 sprintf (buf, "L%d:", INSN_UID (x));
784 break;
785 case BARRIER:
786 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
787 break;
788 case NOTE:
789 if (NOTE_LINE_NUMBER (x) > 0)
790 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
791 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
792 else
793 sprintf (buf, "%4d %s", INSN_UID (x),
794 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
795 break;
796 default:
797 if (verbose)
799 sprintf (buf, "Not an INSN at all\n");
800 debug_rtx (x);
802 else
803 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
805 } /* print_insn */
807 /* Print visualization debugging info. The scheduler using only DFA
808 description should never use the following function. */
810 void
811 print_block_visualization (const char *s)
813 int unit, i;
815 /* Print header. */
816 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
818 /* Print names of units. */
819 fprintf (sched_dump, ";; %-8s", "clock");
820 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
821 if (function_units[unit].bitmask & target_units)
822 for (i = 0; i < function_units[unit].multiplicity; i++)
823 fprintf (sched_dump, " %-33s", function_units[unit].name);
824 fprintf (sched_dump, " %-8s\n", "no-unit");
826 fprintf (sched_dump, ";; %-8s", "=====");
827 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
828 if (function_units[unit].bitmask & target_units)
829 for (i = 0; i < function_units[unit].multiplicity; i++)
830 fprintf (sched_dump, " %-33s", "==============================");
831 fprintf (sched_dump, " %-8s\n", "=======");
833 /* Print insns in each cycle. */
834 fprintf (sched_dump, "%s\n", visual_tbl);
837 /* Print insns in the 'no_unit' column of visualization. */
839 void
840 visualize_no_unit (rtx insn)
842 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
844 vis_no_unit[n_vis_no_unit] = insn;
845 n_vis_no_unit++;
849 /* Print insns scheduled in clock, for visualization. */
851 void
852 visualize_scheduled_insns (int clock)
854 int i, unit;
856 /* If no more room, split table into two. */
857 if (n_visual_lines >= MAX_VISUAL_LINES)
859 print_block_visualization ("(incomplete)");
860 init_block_visualization ();
863 n_visual_lines++;
865 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
866 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
867 if (function_units[unit].bitmask & target_units)
868 for (i = 0; i < function_units[unit].multiplicity; i++)
870 int instance = unit + i * FUNCTION_UNITS_SIZE;
871 rtx insn = get_unit_last_insn (instance);
873 /* Print insns that still keep the unit busy. */
874 if (insn
875 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
877 char str[BUF_LEN];
878 print_insn (str, insn, 0);
879 str[INSN_LEN] = '\0';
880 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
882 else
883 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
886 /* Print insns that are not assigned to any unit. */
887 for (i = 0; i < n_vis_no_unit; i++)
888 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
889 INSN_UID (vis_no_unit[i]));
890 n_vis_no_unit = 0;
892 sprintf (visual_tbl + strlen (visual_tbl), "\n");
895 /* Print stalled cycles. */
897 void
898 visualize_stall_cycles (int stalls)
900 static const char *const prefix = ";; ";
901 const char *suffix = "\n";
902 char *p;
904 /* If no more room, split table into two. */
905 if (n_visual_lines >= MAX_VISUAL_LINES)
907 print_block_visualization ("(incomplete)");
908 init_block_visualization ();
911 n_visual_lines++;
913 p = visual_tbl + strlen (visual_tbl);
914 strcpy (p, prefix);
915 p += strlen (prefix);
917 if ((unsigned) stalls >
918 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
920 suffix = "[...]\n";
921 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
924 memset (p, '.', stalls);
925 p += stalls;
927 strcpy (p, suffix);
930 /* Allocate data used for visualization during scheduling. */
932 void
933 visualize_alloc (void)
935 visual_tbl = xmalloc (get_visual_tbl_length ());
938 /* Free data used for visualization. */
940 void
941 visualize_free (void)
943 free (visual_tbl);
945 #endif