source: trunk/src/gcc/gcc/sched-vis.c@ 1392

Last change on this file since 1392 was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 22.7 KB
Line 
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
7This file is part of GCC.
8
9GCC is free software; you can redistribute it and/or modify it under
10the terms of the GNU General Public License as published by the Free
11Software Foundation; either version 2, or (at your option) any later
12version.
13
14GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15WARRANTY; without even the implied warranty of MERCHANTABILITY or
16FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17for more details.
18
19You should have received a copy of the GNU General Public License
20along with GCC; see the file COPYING. If not, write to the Free
21Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2202111-1307, USA. */
23
24
25#include "config.h"
26#include "system.h"
27#include "toplev.h"
28#include "rtl.h"
29#include "tm_p.h"
30#include "regs.h"
31#include "hard-reg-set.h"
32#include "basic-block.h"
33#include "insn-attr.h"
34#include "real.h"
35#include "sched-int.h"
36#include "target.h"
37
38#ifdef INSN_SCHEDULING
39/* target_units bitmask has 1 for each unit in the cpu. It should be
40 possible to compute this variable from the machine description.
41 But currently it is computed by examining the insn list. Since
42 this is only needed for visualization, it seems an acceptable
43 solution. (For understanding the mapping of bits to units, see
44 definition of function_units[] in "insn-attrtab.c".) The scheduler
45 using only DFA description should never use the following variable. */
46
47static int target_units = 0;
48
49static char *safe_concat PARAMS ((char *, char *, const char *));
50static int get_visual_tbl_length PARAMS ((void));
51static void print_exp PARAMS ((char *, rtx, int));
52static void print_value PARAMS ((char *, rtx, int));
53static void print_pattern PARAMS ((char *, rtx, int));
54
55/* Print names of units on which insn can/should execute, for debugging. */
56
57void
58insn_print_units (insn)
59 rtx insn;
60{
61 int i;
62 int unit = insn_unit (insn);
63
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
69 {
70 fprintf (sched_dump, "[");
71 for (i = 0, unit = ~unit; unit; i++, unit >>= 1)
72 if (unit & 1)
73 {
74 fprintf (sched_dump, "%s", function_units[i].name);
75 if (unit != 1)
76 fprintf (sched_dump, " ");
77 }
78 fprintf (sched_dump, "]");
79 }
80}
81
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 splitted 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
89int n_visual_lines;
90static unsigned visual_tbl_line_length;
91char *visual_tbl;
92int n_vis_no_unit;
93#define MAX_VISUAL_NO_UNIT 20
94rtx vis_no_unit[MAX_VISUAL_NO_UNIT];
95
96/* Finds units that are in use in this function. Required only
97 for visualization. */
98
99void
100init_target_units ()
101{
102 rtx insn;
103 int unit;
104
105 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
106 {
107 if (! INSN_P (insn))
108 continue;
109
110 unit = insn_unit (insn);
111
112 if (unit < 0)
113 target_units |= ~unit;
114 else
115 target_units |= (1 << unit);
116 }
117}
118
119/* Return the length of the visualization table. */
120
121static int
122get_visual_tbl_length ()
123{
124 int unit, i;
125 int n, n1;
126 char *s;
127
128 if (targetm.sched.use_dfa_pipeline_interface
129 && (*targetm.sched.use_dfa_pipeline_interface) ())
130 {
131 visual_tbl_line_length = 1;
132 return 1; /* Can't return 0 because that will cause problems
133 with alloca. */
134 }
135
136 /* Compute length of one field in line. */
137 s = (char *) alloca (INSN_LEN + 6);
138 sprintf (s, " %33s", "uname");
139 n1 = strlen (s);
140
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;
150
151 visual_tbl_line_length = n;
152
153 /* Compute length of visualization string. */
154 return (MAX_VISUAL_LINES * n);
155}
156
157/* Init block visualization debugging info. */
158
159void
160init_block_visualization ()
161{
162 strcpy (visual_tbl, "");
163 n_visual_lines = 0;
164 n_vis_no_unit = 0;
165}
166
167#define BUF_LEN 2048
168
169static char *
170safe_concat (buf, cur, str)
171 char *buf;
172 char *cur;
173 const char *str;
174{
175 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
176 int c;
177
178 if (cur > end)
179 {
180 *end = '\0';
181 return end;
182 }
183
184 while (cur < end && (c = *str++) != '\0')
185 *cur++ = c;
186
187 *cur = '\0';
188 return cur;
189}
190
191/* This recognizes rtx, I classified as expressions. These are always
192 represent some action on values or results of other expression, that
193 may be stored in objects representing values. */
194
195static void
196print_exp (buf, x, verbose)
197 char *buf;
198 rtx x;
199 int verbose;
200{
201 char tmp[BUF_LEN];
202 const char *st[4];
203 char *cur = buf;
204 const char *fun = (char *) 0;
205 const char *sep;
206 rtx op[4];
207 int i;
208
209 for (i = 0; i < 4; i++)
210 {
211 st[i] = (char *) 0;
212 op[i] = NULL_RTX;
213 }
214
215 switch (GET_CODE (x))
216 {
217 case PLUS:
218 op[0] = XEXP (x, 0);
219 if (GET_CODE (XEXP (x, 1)) == CONST_INT
220 && INTVAL (XEXP (x, 1)) < 0)
221 {
222 st[1] = "-";
223 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
224 }
225 else
226 {
227 st[1] = "+";
228 op[1] = XEXP (x, 1);
229 }
230 break;
231 case LO_SUM:
232 op[0] = XEXP (x, 0);
233 st[1] = "+low(";
234 op[1] = XEXP (x, 1);
235 st[2] = ")";
236 break;
237 case MINUS:
238 op[0] = XEXP (x, 0);
239 st[1] = "-";
240 op[1] = XEXP (x, 1);
241 break;
242 case COMPARE:
243 fun = "cmp";
244 op[0] = XEXP (x, 0);
245 op[1] = XEXP (x, 1);
246 break;
247 case NEG:
248 st[0] = "-";
249 op[0] = XEXP (x, 0);
250 break;
251 case MULT:
252 op[0] = XEXP (x, 0);
253 st[1] = "*";
254 op[1] = XEXP (x, 1);
255 break;
256 case DIV:
257 op[0] = XEXP (x, 0);
258 st[1] = "/";
259 op[1] = XEXP (x, 1);
260 break;
261 case UDIV:
262 fun = "udiv";
263 op[0] = XEXP (x, 0);
264 op[1] = XEXP (x, 1);
265 break;
266 case MOD:
267 op[0] = XEXP (x, 0);
268 st[1] = "%";
269 op[1] = XEXP (x, 1);
270 break;
271 case UMOD:
272 fun = "umod";
273 op[0] = XEXP (x, 0);
274 op[1] = XEXP (x, 1);
275 break;
276 case SMIN:
277 fun = "smin";
278 op[0] = XEXP (x, 0);
279 op[1] = XEXP (x, 1);
280 break;
281 case SMAX:
282 fun = "smax";
283 op[0] = XEXP (x, 0);
284 op[1] = XEXP (x, 1);
285 break;
286 case UMIN:
287 fun = "umin";
288 op[0] = XEXP (x, 0);
289 op[1] = XEXP (x, 1);
290 break;
291 case UMAX:
292 fun = "umax";
293 op[0] = XEXP (x, 0);
294 op[1] = XEXP (x, 1);
295 break;
296 case NOT:
297 st[0] = "!";
298 op[0] = XEXP (x, 0);
299 break;
300 case AND:
301 op[0] = XEXP (x, 0);
302 st[1] = "&";
303 op[1] = XEXP (x, 1);
304 break;
305 case IOR:
306 op[0] = XEXP (x, 0);
307 st[1] = "|";
308 op[1] = XEXP (x, 1);
309 break;
310 case XOR:
311 op[0] = XEXP (x, 0);
312 st[1] = "^";
313 op[1] = XEXP (x, 1);
314 break;
315 case ASHIFT:
316 op[0] = XEXP (x, 0);
317 st[1] = "<<";
318 op[1] = XEXP (x, 1);
319 break;
320 case LSHIFTRT:
321 op[0] = XEXP (x, 0);
322 st[1] = " 0>>";
323 op[1] = XEXP (x, 1);
324 break;
325 case ASHIFTRT:
326 op[0] = XEXP (x, 0);
327 st[1] = ">>";
328 op[1] = XEXP (x, 1);
329 break;
330 case ROTATE:
331 op[0] = XEXP (x, 0);
332 st[1] = "<-<";
333 op[1] = XEXP (x, 1);
334 break;
335 case ROTATERT:
336 op[0] = XEXP (x, 0);
337 st[1] = ">->";
338 op[1] = XEXP (x, 1);
339 break;
340 case ABS:
341 fun = "abs";
342 op[0] = XEXP (x, 0);
343 break;
344 case SQRT:
345 fun = "sqrt";
346 op[0] = XEXP (x, 0);
347 break;
348 case FFS:
349 fun = "ffs";
350 op[0] = XEXP (x, 0);
351 break;
352 case EQ:
353 op[0] = XEXP (x, 0);
354 st[1] = "==";
355 op[1] = XEXP (x, 1);
356 break;
357 case NE:
358 op[0] = XEXP (x, 0);
359 st[1] = "!=";
360 op[1] = XEXP (x, 1);
361 break;
362 case GT:
363 op[0] = XEXP (x, 0);
364 st[1] = ">";
365 op[1] = XEXP (x, 1);
366 break;
367 case GTU:
368 fun = "gtu";
369 op[0] = XEXP (x, 0);
370 op[1] = XEXP (x, 1);
371 break;
372 case LT:
373 op[0] = XEXP (x, 0);
374 st[1] = "<";
375 op[1] = XEXP (x, 1);
376 break;
377 case LTU:
378 fun = "ltu";
379 op[0] = XEXP (x, 0);
380 op[1] = XEXP (x, 1);
381 break;
382 case GE:
383 op[0] = XEXP (x, 0);
384 st[1] = ">=";
385 op[1] = XEXP (x, 1);
386 break;
387 case GEU:
388 fun = "geu";
389 op[0] = XEXP (x, 0);
390 op[1] = XEXP (x, 1);
391 break;
392 case LE:
393 op[0] = XEXP (x, 0);
394 st[1] = "<=";
395 op[1] = XEXP (x, 1);
396 break;
397 case LEU:
398 fun = "leu";
399 op[0] = XEXP (x, 0);
400 op[1] = XEXP (x, 1);
401 break;
402 case SIGN_EXTRACT:
403 fun = (verbose) ? "sign_extract" : "sxt";
404 op[0] = XEXP (x, 0);
405 op[1] = XEXP (x, 1);
406 op[2] = XEXP (x, 2);
407 break;
408 case ZERO_EXTRACT:
409 fun = (verbose) ? "zero_extract" : "zxt";
410 op[0] = XEXP (x, 0);
411 op[1] = XEXP (x, 1);
412 op[2] = XEXP (x, 2);
413 break;
414 case SIGN_EXTEND:
415 fun = (verbose) ? "sign_extend" : "sxn";
416 op[0] = XEXP (x, 0);
417 break;
418 case ZERO_EXTEND:
419 fun = (verbose) ? "zero_extend" : "zxn";
420 op[0] = XEXP (x, 0);
421 break;
422 case FLOAT_EXTEND:
423 fun = (verbose) ? "float_extend" : "fxn";
424 op[0] = XEXP (x, 0);
425 break;
426 case TRUNCATE:
427 fun = (verbose) ? "trunc" : "trn";
428 op[0] = XEXP (x, 0);
429 break;
430 case FLOAT_TRUNCATE:
431 fun = (verbose) ? "float_trunc" : "ftr";
432 op[0] = XEXP (x, 0);
433 break;
434 case FLOAT:
435 fun = (verbose) ? "float" : "flt";
436 op[0] = XEXP (x, 0);
437 break;
438 case UNSIGNED_FLOAT:
439 fun = (verbose) ? "uns_float" : "ufl";
440 op[0] = XEXP (x, 0);
441 break;
442 case FIX:
443 fun = "fix";
444 op[0] = XEXP (x, 0);
445 break;
446 case UNSIGNED_FIX:
447 fun = (verbose) ? "uns_fix" : "ufx";
448 op[0] = XEXP (x, 0);
449 break;
450 case PRE_DEC:
451 st[0] = "--";
452 op[0] = XEXP (x, 0);
453 break;
454 case PRE_INC:
455 st[0] = "++";
456 op[0] = XEXP (x, 0);
457 break;
458 case POST_DEC:
459 op[0] = XEXP (x, 0);
460 st[1] = "--";
461 break;
462 case POST_INC:
463 op[0] = XEXP (x, 0);
464 st[1] = "++";
465 break;
466 case CALL:
467 st[0] = "call ";
468 op[0] = XEXP (x, 0);
469 if (verbose)
470 {
471 st[1] = " argc:";
472 op[1] = XEXP (x, 1);
473 }
474 break;
475 case IF_THEN_ELSE:
476 st[0] = "{(";
477 op[0] = XEXP (x, 0);
478 st[1] = ")?";
479 op[1] = XEXP (x, 1);
480 st[2] = ":";
481 op[2] = XEXP (x, 2);
482 st[3] = "}";
483 break;
484 case TRAP_IF:
485 fun = "trap_if";
486 op[0] = TRAP_CONDITION (x);
487 break;
488 case PREFETCH:
489 fun = "prefetch";
490 op[0] = XEXP (x, 0);
491 op[1] = XEXP (x, 1);
492 op[2] = XEXP (x, 2);
493 break;
494 case UNSPEC:
495 case UNSPEC_VOLATILE:
496 {
497 cur = safe_concat (buf, cur, "unspec");
498 if (GET_CODE (x) == UNSPEC_VOLATILE)
499 cur = safe_concat (buf, cur, "/v");
500 cur = safe_concat (buf, cur, "[");
501 sep = "";
502 for (i = 0; i < XVECLEN (x, 0); i++)
503 {
504 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
505 cur = safe_concat (buf, cur, sep);
506 cur = safe_concat (buf, cur, tmp);
507 sep = ",";
508 }
509 cur = safe_concat (buf, cur, "] ");
510 sprintf (tmp, "%d", XINT (x, 1));
511 cur = safe_concat (buf, cur, tmp);
512 }
513 break;
514 default:
515 /* If (verbose) debug_rtx (x); */
516 st[0] = GET_RTX_NAME (GET_CODE (x));
517 break;
518 }
519
520 /* Print this as a function? */
521 if (fun)
522 {
523 cur = safe_concat (buf, cur, fun);
524 cur = safe_concat (buf, cur, "(");
525 }
526
527 for (i = 0; i < 4; i++)
528 {
529 if (st[i])
530 cur = safe_concat (buf, cur, st[i]);
531
532 if (op[i])
533 {
534 if (fun && i != 0)
535 cur = safe_concat (buf, cur, ",");
536
537 print_value (tmp, op[i], verbose);
538 cur = safe_concat (buf, cur, tmp);
539 }
540 }
541
542 if (fun)
543 cur = safe_concat (buf, cur, ")");
544} /* print_exp */
545
546/* Prints rtxes, I customly classified as values. They're constants,
547 registers, labels, symbols and memory accesses. */
548
549static void
550print_value (buf, x, verbose)
551 char *buf;
552 rtx x;
553 int verbose;
554{
555 char t[BUF_LEN];
556 char *cur = buf;
557
558 switch (GET_CODE (x))
559 {
560 case CONST_INT:
561 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
562 cur = safe_concat (buf, cur, t);
563 break;
564 case CONST_DOUBLE:
565 if (FLOAT_MODE_P (GET_MODE (x)))
566 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
567 else
568 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
569 cur = safe_concat (buf, cur, t);
570 break;
571 case CONST_STRING:
572 cur = safe_concat (buf, cur, "\"");
573 cur = safe_concat (buf, cur, XSTR (x, 0));
574 cur = safe_concat (buf, cur, "\"");
575 break;
576 case SYMBOL_REF:
577 cur = safe_concat (buf, cur, "`");
578 cur = safe_concat (buf, cur, XSTR (x, 0));
579 cur = safe_concat (buf, cur, "'");
580 break;
581 case LABEL_REF:
582 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
583 cur = safe_concat (buf, cur, t);
584 break;
585 case CONST:
586 print_value (t, XEXP (x, 0), verbose);
587 cur = safe_concat (buf, cur, "const(");
588 cur = safe_concat (buf, cur, t);
589 cur = safe_concat (buf, cur, ")");
590 break;
591 case HIGH:
592 print_value (t, XEXP (x, 0), verbose);
593 cur = safe_concat (buf, cur, "high(");
594 cur = safe_concat (buf, cur, t);
595 cur = safe_concat (buf, cur, ")");
596 break;
597 case REG:
598 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
599 {
600 int c = reg_names[REGNO (x)][0];
601 if (ISDIGIT (c))
602 cur = safe_concat (buf, cur, "%");
603
604 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
605 }
606 else
607 {
608 sprintf (t, "r%d", REGNO (x));
609 cur = safe_concat (buf, cur, t);
610 }
611 break;
612 case SUBREG:
613 print_value (t, SUBREG_REG (x), verbose);
614 cur = safe_concat (buf, cur, t);
615 sprintf (t, "#%d", SUBREG_BYTE (x));
616 cur = safe_concat (buf, cur, t);
617 break;
618 case SCRATCH:
619 cur = safe_concat (buf, cur, "scratch");
620 break;
621 case CC0:
622 cur = safe_concat (buf, cur, "cc0");
623 break;
624 case PC:
625 cur = safe_concat (buf, cur, "pc");
626 break;
627 case MEM:
628 print_value (t, XEXP (x, 0), verbose);
629 cur = safe_concat (buf, cur, "[");
630 cur = safe_concat (buf, cur, t);
631 cur = safe_concat (buf, cur, "]");
632 break;
633 default:
634 print_exp (t, x, verbose);
635 cur = safe_concat (buf, cur, t);
636 break;
637 }
638} /* print_value */
639
640/* The next step in insn detalization, its pattern recognition. */
641
642static void
643print_pattern (buf, x, verbose)
644 char *buf;
645 rtx x;
646 int verbose;
647{
648 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
649
650 switch (GET_CODE (x))
651 {
652 case SET:
653 print_value (t1, SET_DEST (x), verbose);
654 print_value (t2, SET_SRC (x), verbose);
655 sprintf (buf, "%s=%s", t1, t2);
656 break;
657 case RETURN:
658 sprintf (buf, "return");
659 break;
660 case CALL:
661 print_exp (buf, x, verbose);
662 break;
663 case CLOBBER:
664 print_value (t1, XEXP (x, 0), verbose);
665 sprintf (buf, "clobber %s", t1);
666 break;
667 case USE:
668 print_value (t1, XEXP (x, 0), verbose);
669 sprintf (buf, "use %s", t1);
670 break;
671 case COND_EXEC:
672 if (GET_CODE (COND_EXEC_TEST (x)) == NE
673 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
674 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
675 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
676 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
677 {
678 t1[0] = '!';
679 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
680 }
681 else
682 print_value (t1, COND_EXEC_TEST (x), verbose);
683 print_pattern (t2, COND_EXEC_CODE (x), verbose);
684 sprintf (buf, "(%s) %s", t1, t2);
685 break;
686 case PARALLEL:
687 {
688 int i;
689
690 sprintf (t1, "{");
691 for (i = 0; i < XVECLEN (x, 0); i++)
692 {
693 print_pattern (t2, XVECEXP (x, 0, i), verbose);
694 sprintf (t3, "%s%s;", t1, t2);
695 strcpy (t1, t3);
696 }
697 sprintf (buf, "%s}", t1);
698 }
699 break;
700 case SEQUENCE:
701 /* Should never see SEQUENCE codes until after reorg. */
702 abort ();
703 break;
704 case ASM_INPUT:
705 sprintf (buf, "asm {%s}", XSTR (x, 0));
706 break;
707 case ADDR_VEC:
708 break;
709 case ADDR_DIFF_VEC:
710 print_value (buf, XEXP (x, 0), verbose);
711 break;
712 case TRAP_IF:
713 print_value (t1, TRAP_CONDITION (x), verbose);
714 sprintf (buf, "trap_if %s", t1);
715 break;
716 case UNSPEC:
717 {
718 int i;
719
720 sprintf (t1, "unspec{");
721 for (i = 0; i < XVECLEN (x, 0); i++)
722 {
723 print_pattern (t2, XVECEXP (x, 0, i), verbose);
724 sprintf (t3, "%s%s;", t1, t2);
725 strcpy (t1, t3);
726 }
727 sprintf (buf, "%s}", t1);
728 }
729 break;
730 case UNSPEC_VOLATILE:
731 {
732 int i;
733
734 sprintf (t1, "unspec/v{");
735 for (i = 0; i < XVECLEN (x, 0); i++)
736 {
737 print_pattern (t2, XVECEXP (x, 0, i), verbose);
738 sprintf (t3, "%s%s;", t1, t2);
739 strcpy (t1, t3);
740 }
741 sprintf (buf, "%s}", t1);
742 }
743 break;
744 default:
745 print_value (buf, x, verbose);
746 }
747} /* print_pattern */
748
749/* This is the main function in rtl visualization mechanism. It
750 accepts an rtx and tries to recognize it as an insn, then prints it
751 properly in human readable form, resembling assembler mnemonics.
752 For every insn it prints its UID and BB the insn belongs too.
753 (Probably the last "option" should be extended somehow, since it
754 depends now on sched.c inner variables ...) */
755
756void
757print_insn (buf, x, verbose)
758 char *buf;
759 rtx x;
760 int verbose;
761{
762 char t[BUF_LEN];
763 rtx insn = x;
764
765 switch (GET_CODE (x))
766 {
767 case INSN:
768 print_pattern (t, PATTERN (x), verbose);
769 if (verbose)
770 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
771 t);
772 else
773 sprintf (buf, "%-4d %s", INSN_UID (x), t);
774 break;
775 case JUMP_INSN:
776 print_pattern (t, PATTERN (x), verbose);
777 if (verbose)
778 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
779 t);
780 else
781 sprintf (buf, "%-4d %s", INSN_UID (x), t);
782 break;
783 case CALL_INSN:
784 x = PATTERN (insn);
785 if (GET_CODE (x) == PARALLEL)
786 {
787 x = XVECEXP (x, 0, 0);
788 print_pattern (t, x, verbose);
789 }
790 else
791 strcpy (t, "call <...>");
792 if (verbose)
793 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
794 else
795 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
796 break;
797 case CODE_LABEL:
798 sprintf (buf, "L%d:", INSN_UID (x));
799 break;
800 case BARRIER:
801 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
802 break;
803 case NOTE:
804 if (NOTE_LINE_NUMBER (x) > 0)
805 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
806 NOTE_SOURCE_FILE (x), NOTE_LINE_NUMBER (x));
807 else
808 sprintf (buf, "%4d %s", INSN_UID (x),
809 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
810 break;
811 default:
812 if (verbose)
813 {
814 sprintf (buf, "Not an INSN at all\n");
815 debug_rtx (x);
816 }
817 else
818 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
819 }
820} /* print_insn */
821
822/* Print visualization debugging info. The scheduler using only DFA
823 description should never use the following function. */
824
825void
826print_block_visualization (s)
827 const char *s;
828{
829 int unit, i;
830
831 /* Print header. */
832 fprintf (sched_dump, "\n;; ==================== scheduling visualization %s \n", s);
833
834 /* Print names of units. */
835 fprintf (sched_dump, ";; %-8s", "clock");
836 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
837 if (function_units[unit].bitmask & target_units)
838 for (i = 0; i < function_units[unit].multiplicity; i++)
839 fprintf (sched_dump, " %-33s", function_units[unit].name);
840 fprintf (sched_dump, " %-8s\n", "no-unit");
841
842 fprintf (sched_dump, ";; %-8s", "=====");
843 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
844 if (function_units[unit].bitmask & target_units)
845 for (i = 0; i < function_units[unit].multiplicity; i++)
846 fprintf (sched_dump, " %-33s", "==============================");
847 fprintf (sched_dump, " %-8s\n", "=======");
848
849 /* Print insns in each cycle. */
850 fprintf (sched_dump, "%s\n", visual_tbl);
851}
852
853/* Print insns in the 'no_unit' column of visualization. */
854
855void
856visualize_no_unit (insn)
857 rtx insn;
858{
859 if (n_vis_no_unit < MAX_VISUAL_NO_UNIT)
860 {
861 vis_no_unit[n_vis_no_unit] = insn;
862 n_vis_no_unit++;
863 }
864}
865
866/* Print insns scheduled in clock, for visualization. */
867
868void
869visualize_scheduled_insns (clock)
870 int clock;
871{
872 int i, unit;
873
874 /* If no more room, split table into two. */
875 if (n_visual_lines >= MAX_VISUAL_LINES)
876 {
877 print_block_visualization ("(incomplete)");
878 init_block_visualization ();
879 }
880
881 n_visual_lines++;
882
883 sprintf (visual_tbl + strlen (visual_tbl), ";; %-8d", clock);
884 for (unit = 0; unit < FUNCTION_UNITS_SIZE; unit++)
885 if (function_units[unit].bitmask & target_units)
886 for (i = 0; i < function_units[unit].multiplicity; i++)
887 {
888 int instance = unit + i * FUNCTION_UNITS_SIZE;
889 rtx insn = get_unit_last_insn (instance);
890
891 /* Print insns that still keep the unit busy. */
892 if (insn
893 && actual_hazard_this_instance (unit, instance, insn, clock, 0))
894 {
895 char str[BUF_LEN];
896 print_insn (str, insn, 0);
897 str[INSN_LEN] = '\0';
898 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", str);
899 }
900 else
901 sprintf (visual_tbl + strlen (visual_tbl), " %-33s", "------------------------------");
902 }
903
904 /* Print insns that are not assigned to any unit. */
905 for (i = 0; i < n_vis_no_unit; i++)
906 sprintf (visual_tbl + strlen (visual_tbl), " %-8d",
907 INSN_UID (vis_no_unit[i]));
908 n_vis_no_unit = 0;
909
910 sprintf (visual_tbl + strlen (visual_tbl), "\n");
911}
912
913/* Print stalled cycles. */
914
915void
916visualize_stall_cycles (stalls)
917 int stalls;
918{
919 static const char *const prefix = ";; ";
920 const char *suffix = "\n";
921 char *p;
922
923 /* If no more room, split table into two. */
924 if (n_visual_lines >= MAX_VISUAL_LINES)
925 {
926 print_block_visualization ("(incomplete)");
927 init_block_visualization ();
928 }
929
930 n_visual_lines++;
931
932 p = visual_tbl + strlen (visual_tbl);
933 strcpy (p, prefix);
934 p += strlen (prefix);
935
936 if ((unsigned) stalls >
937 visual_tbl_line_length - strlen (prefix) - strlen (suffix))
938 {
939 suffix = "[...]\n";
940 stalls = visual_tbl_line_length - strlen (prefix) - strlen (suffix);
941 }
942
943 memset (p, '.', stalls);
944 p += stalls;
945
946 strcpy (p, suffix);
947}
948
949/* Allocate data used for visualization during scheduling. */
950
951void
952visualize_alloc ()
953{
954 visual_tbl = xmalloc (get_visual_tbl_length ());
955}
956
957/* Free data used for visualization. */
958
959void
960visualize_free ()
961{
962 free (visual_tbl);
963}
964#endif
Note: See TracBrowser for help on using the repository browser.