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

Last change on this file since 2 was 2, checked in by bird, 23 years ago

Initial revision

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