2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / sched-vis.c
blob242791ba9e14d745aca11912ff52a8c7f0177ac4
1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007 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 3, 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 COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "obstack.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "real.h"
32 #include "sched-int.h"
33 #include "tree-pass.h"
35 static char *safe_concat (char *, char *, const char *);
36 static void print_exp (char *, const_rtx, int);
37 static void print_value (char *, const_rtx, int);
38 static void print_pattern (char *, const_rtx, int);
40 #define BUF_LEN 2048
42 static char *
43 safe_concat (char *buf, char *cur, const char *str)
45 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
46 int c;
48 if (cur > end)
50 *end = '\0';
51 return end;
54 while (cur < end && (c = *str++) != '\0')
55 *cur++ = c;
57 *cur = '\0';
58 return cur;
61 /* This recognizes rtx, I classified as expressions. These are always
62 represent some action on values or results of other expression, that
63 may be stored in objects representing values. */
65 static void
66 print_exp (char *buf, const_rtx x, int verbose)
68 char tmp[BUF_LEN];
69 const char *st[4];
70 char *cur = buf;
71 const char *fun = (char *) 0;
72 const char *sep;
73 rtx op[4];
74 int i;
76 for (i = 0; i < 4; i++)
78 st[i] = (char *) 0;
79 op[i] = NULL_RTX;
82 switch (GET_CODE (x))
84 case PLUS:
85 op[0] = XEXP (x, 0);
86 if (GET_CODE (XEXP (x, 1)) == CONST_INT
87 && INTVAL (XEXP (x, 1)) < 0)
89 st[1] = "-";
90 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
92 else
94 st[1] = "+";
95 op[1] = XEXP (x, 1);
97 break;
98 case LO_SUM:
99 op[0] = XEXP (x, 0);
100 st[1] = "+low(";
101 op[1] = XEXP (x, 1);
102 st[2] = ")";
103 break;
104 case MINUS:
105 op[0] = XEXP (x, 0);
106 st[1] = "-";
107 op[1] = XEXP (x, 1);
108 break;
109 case COMPARE:
110 fun = "cmp";
111 op[0] = XEXP (x, 0);
112 op[1] = XEXP (x, 1);
113 break;
114 case NEG:
115 st[0] = "-";
116 op[0] = XEXP (x, 0);
117 break;
118 case MULT:
119 op[0] = XEXP (x, 0);
120 st[1] = "*";
121 op[1] = XEXP (x, 1);
122 break;
123 case DIV:
124 op[0] = XEXP (x, 0);
125 st[1] = "/";
126 op[1] = XEXP (x, 1);
127 break;
128 case UDIV:
129 fun = "udiv";
130 op[0] = XEXP (x, 0);
131 op[1] = XEXP (x, 1);
132 break;
133 case MOD:
134 op[0] = XEXP (x, 0);
135 st[1] = "%";
136 op[1] = XEXP (x, 1);
137 break;
138 case UMOD:
139 fun = "umod";
140 op[0] = XEXP (x, 0);
141 op[1] = XEXP (x, 1);
142 break;
143 case SMIN:
144 fun = "smin";
145 op[0] = XEXP (x, 0);
146 op[1] = XEXP (x, 1);
147 break;
148 case SMAX:
149 fun = "smax";
150 op[0] = XEXP (x, 0);
151 op[1] = XEXP (x, 1);
152 break;
153 case UMIN:
154 fun = "umin";
155 op[0] = XEXP (x, 0);
156 op[1] = XEXP (x, 1);
157 break;
158 case UMAX:
159 fun = "umax";
160 op[0] = XEXP (x, 0);
161 op[1] = XEXP (x, 1);
162 break;
163 case NOT:
164 st[0] = "!";
165 op[0] = XEXP (x, 0);
166 break;
167 case AND:
168 op[0] = XEXP (x, 0);
169 st[1] = "&";
170 op[1] = XEXP (x, 1);
171 break;
172 case IOR:
173 op[0] = XEXP (x, 0);
174 st[1] = "|";
175 op[1] = XEXP (x, 1);
176 break;
177 case XOR:
178 op[0] = XEXP (x, 0);
179 st[1] = "^";
180 op[1] = XEXP (x, 1);
181 break;
182 case ASHIFT:
183 op[0] = XEXP (x, 0);
184 st[1] = "<<";
185 op[1] = XEXP (x, 1);
186 break;
187 case LSHIFTRT:
188 op[0] = XEXP (x, 0);
189 st[1] = " 0>>";
190 op[1] = XEXP (x, 1);
191 break;
192 case ASHIFTRT:
193 op[0] = XEXP (x, 0);
194 st[1] = ">>";
195 op[1] = XEXP (x, 1);
196 break;
197 case ROTATE:
198 op[0] = XEXP (x, 0);
199 st[1] = "<-<";
200 op[1] = XEXP (x, 1);
201 break;
202 case ROTATERT:
203 op[0] = XEXP (x, 0);
204 st[1] = ">->";
205 op[1] = XEXP (x, 1);
206 break;
207 case ABS:
208 fun = "abs";
209 op[0] = XEXP (x, 0);
210 break;
211 case SQRT:
212 fun = "sqrt";
213 op[0] = XEXP (x, 0);
214 break;
215 case FFS:
216 fun = "ffs";
217 op[0] = XEXP (x, 0);
218 break;
219 case EQ:
220 op[0] = XEXP (x, 0);
221 st[1] = "==";
222 op[1] = XEXP (x, 1);
223 break;
224 case NE:
225 op[0] = XEXP (x, 0);
226 st[1] = "!=";
227 op[1] = XEXP (x, 1);
228 break;
229 case GT:
230 op[0] = XEXP (x, 0);
231 st[1] = ">";
232 op[1] = XEXP (x, 1);
233 break;
234 case GTU:
235 fun = "gtu";
236 op[0] = XEXP (x, 0);
237 op[1] = XEXP (x, 1);
238 break;
239 case LT:
240 op[0] = XEXP (x, 0);
241 st[1] = "<";
242 op[1] = XEXP (x, 1);
243 break;
244 case LTU:
245 fun = "ltu";
246 op[0] = XEXP (x, 0);
247 op[1] = XEXP (x, 1);
248 break;
249 case GE:
250 op[0] = XEXP (x, 0);
251 st[1] = ">=";
252 op[1] = XEXP (x, 1);
253 break;
254 case GEU:
255 fun = "geu";
256 op[0] = XEXP (x, 0);
257 op[1] = XEXP (x, 1);
258 break;
259 case LE:
260 op[0] = XEXP (x, 0);
261 st[1] = "<=";
262 op[1] = XEXP (x, 1);
263 break;
264 case LEU:
265 fun = "leu";
266 op[0] = XEXP (x, 0);
267 op[1] = XEXP (x, 1);
268 break;
269 case SIGN_EXTRACT:
270 fun = (verbose) ? "sign_extract" : "sxt";
271 op[0] = XEXP (x, 0);
272 op[1] = XEXP (x, 1);
273 op[2] = XEXP (x, 2);
274 break;
275 case ZERO_EXTRACT:
276 fun = (verbose) ? "zero_extract" : "zxt";
277 op[0] = XEXP (x, 0);
278 op[1] = XEXP (x, 1);
279 op[2] = XEXP (x, 2);
280 break;
281 case SIGN_EXTEND:
282 fun = (verbose) ? "sign_extend" : "sxn";
283 op[0] = XEXP (x, 0);
284 break;
285 case ZERO_EXTEND:
286 fun = (verbose) ? "zero_extend" : "zxn";
287 op[0] = XEXP (x, 0);
288 break;
289 case FLOAT_EXTEND:
290 fun = (verbose) ? "float_extend" : "fxn";
291 op[0] = XEXP (x, 0);
292 break;
293 case TRUNCATE:
294 fun = (verbose) ? "trunc" : "trn";
295 op[0] = XEXP (x, 0);
296 break;
297 case FLOAT_TRUNCATE:
298 fun = (verbose) ? "float_trunc" : "ftr";
299 op[0] = XEXP (x, 0);
300 break;
301 case FLOAT:
302 fun = (verbose) ? "float" : "flt";
303 op[0] = XEXP (x, 0);
304 break;
305 case UNSIGNED_FLOAT:
306 fun = (verbose) ? "uns_float" : "ufl";
307 op[0] = XEXP (x, 0);
308 break;
309 case FIX:
310 fun = "fix";
311 op[0] = XEXP (x, 0);
312 break;
313 case UNSIGNED_FIX:
314 fun = (verbose) ? "uns_fix" : "ufx";
315 op[0] = XEXP (x, 0);
316 break;
317 case PRE_DEC:
318 st[0] = "--";
319 op[0] = XEXP (x, 0);
320 break;
321 case PRE_INC:
322 st[0] = "++";
323 op[0] = XEXP (x, 0);
324 break;
325 case POST_DEC:
326 op[0] = XEXP (x, 0);
327 st[1] = "--";
328 break;
329 case POST_INC:
330 op[0] = XEXP (x, 0);
331 st[1] = "++";
332 break;
333 case PRE_MODIFY:
334 st[0] = "pre ";
335 op[0] = XEXP (XEXP (x, 1), 0);
336 st[1] = "+=";
337 op[1] = XEXP (XEXP (x, 1), 1);
338 break;
339 case POST_MODIFY:
340 st[0] = "post ";
341 op[0] = XEXP (XEXP (x, 1), 0);
342 st[1] = "+=";
343 op[1] = XEXP (XEXP (x, 1), 1);
344 break;
345 case CALL:
346 st[0] = "call ";
347 op[0] = XEXP (x, 0);
348 if (verbose)
350 st[1] = " argc:";
351 op[1] = XEXP (x, 1);
353 break;
354 case IF_THEN_ELSE:
355 st[0] = "{(";
356 op[0] = XEXP (x, 0);
357 st[1] = ")?";
358 op[1] = XEXP (x, 1);
359 st[2] = ":";
360 op[2] = XEXP (x, 2);
361 st[3] = "}";
362 break;
363 case TRAP_IF:
364 fun = "trap_if";
365 op[0] = TRAP_CONDITION (x);
366 break;
367 case PREFETCH:
368 fun = "prefetch";
369 op[0] = XEXP (x, 0);
370 op[1] = XEXP (x, 1);
371 op[2] = XEXP (x, 2);
372 break;
373 case UNSPEC:
374 case UNSPEC_VOLATILE:
376 cur = safe_concat (buf, cur, "unspec");
377 if (GET_CODE (x) == UNSPEC_VOLATILE)
378 cur = safe_concat (buf, cur, "/v");
379 cur = safe_concat (buf, cur, "[");
380 sep = "";
381 for (i = 0; i < XVECLEN (x, 0); i++)
383 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
384 cur = safe_concat (buf, cur, sep);
385 cur = safe_concat (buf, cur, tmp);
386 sep = ",";
388 cur = safe_concat (buf, cur, "] ");
389 sprintf (tmp, "%d", XINT (x, 1));
390 cur = safe_concat (buf, cur, tmp);
392 break;
393 default:
394 /* If (verbose) debug_rtx (x); */
395 st[0] = GET_RTX_NAME (GET_CODE (x));
396 break;
399 /* Print this as a function? */
400 if (fun)
402 cur = safe_concat (buf, cur, fun);
403 cur = safe_concat (buf, cur, "(");
406 for (i = 0; i < 4; i++)
408 if (st[i])
409 cur = safe_concat (buf, cur, st[i]);
411 if (op[i])
413 if (fun && i != 0)
414 cur = safe_concat (buf, cur, ",");
416 print_value (tmp, op[i], verbose);
417 cur = safe_concat (buf, cur, tmp);
421 if (fun)
422 cur = safe_concat (buf, cur, ")");
423 } /* print_exp */
425 /* Prints rtxes, I customarily classified as values. They're constants,
426 registers, labels, symbols and memory accesses. */
428 static void
429 print_value (char *buf, const_rtx x, int verbose)
431 char t[BUF_LEN];
432 char *cur = buf;
434 switch (GET_CODE (x))
436 case CONST_INT:
437 sprintf (t, HOST_WIDE_INT_PRINT_HEX,
438 (unsigned HOST_WIDE_INT) INTVAL (x));
439 cur = safe_concat (buf, cur, t);
440 break;
441 case CONST_DOUBLE:
442 if (FLOAT_MODE_P (GET_MODE (x)))
443 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
444 else
445 sprintf (t,
446 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
447 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
448 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
449 cur = safe_concat (buf, cur, t);
450 break;
451 case CONST_FIXED:
452 fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
453 cur = safe_concat (buf, cur, t);
454 break;
455 case CONST_STRING:
456 cur = safe_concat (buf, cur, "\"");
457 cur = safe_concat (buf, cur, XSTR (x, 0));
458 cur = safe_concat (buf, cur, "\"");
459 break;
460 case SYMBOL_REF:
461 cur = safe_concat (buf, cur, "`");
462 cur = safe_concat (buf, cur, XSTR (x, 0));
463 cur = safe_concat (buf, cur, "'");
464 break;
465 case LABEL_REF:
466 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
467 cur = safe_concat (buf, cur, t);
468 break;
469 case CONST:
470 print_value (t, XEXP (x, 0), verbose);
471 cur = safe_concat (buf, cur, "const(");
472 cur = safe_concat (buf, cur, t);
473 cur = safe_concat (buf, cur, ")");
474 break;
475 case HIGH:
476 print_value (t, XEXP (x, 0), verbose);
477 cur = safe_concat (buf, cur, "high(");
478 cur = safe_concat (buf, cur, t);
479 cur = safe_concat (buf, cur, ")");
480 break;
481 case REG:
482 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
484 int c = reg_names[REGNO (x)][0];
485 if (ISDIGIT (c))
486 cur = safe_concat (buf, cur, "%");
488 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
490 else
492 sprintf (t, "r%d", REGNO (x));
493 cur = safe_concat (buf, cur, t);
495 if (verbose
496 #ifdef INSN_SCHEDULING
497 && !current_sched_info
498 #endif
501 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
502 cur = safe_concat (buf, cur, t);
504 break;
505 case SUBREG:
506 print_value (t, SUBREG_REG (x), verbose);
507 cur = safe_concat (buf, cur, t);
508 sprintf (t, "#%d", SUBREG_BYTE (x));
509 cur = safe_concat (buf, cur, t);
510 break;
511 case SCRATCH:
512 cur = safe_concat (buf, cur, "scratch");
513 break;
514 case CC0:
515 cur = safe_concat (buf, cur, "cc0");
516 break;
517 case PC:
518 cur = safe_concat (buf, cur, "pc");
519 break;
520 case MEM:
521 print_value (t, XEXP (x, 0), verbose);
522 cur = safe_concat (buf, cur, "[");
523 cur = safe_concat (buf, cur, t);
524 cur = safe_concat (buf, cur, "]");
525 break;
526 default:
527 print_exp (t, x, verbose);
528 cur = safe_concat (buf, cur, t);
529 break;
531 } /* print_value */
533 /* The next step in insn detalization, its pattern recognition. */
535 static void
536 print_pattern (char *buf, const_rtx x, int verbose)
538 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
540 switch (GET_CODE (x))
542 case SET:
543 print_value (t1, SET_DEST (x), verbose);
544 print_value (t2, SET_SRC (x), verbose);
545 sprintf (buf, "%s=%s", t1, t2);
546 break;
547 case RETURN:
548 sprintf (buf, "return");
549 break;
550 case CALL:
551 print_exp (buf, x, verbose);
552 break;
553 case CLOBBER:
554 print_value (t1, XEXP (x, 0), verbose);
555 sprintf (buf, "clobber %s", t1);
556 break;
557 case USE:
558 print_value (t1, XEXP (x, 0), verbose);
559 sprintf (buf, "use %s", t1);
560 break;
561 case COND_EXEC:
562 if (GET_CODE (COND_EXEC_TEST (x)) == NE
563 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
564 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
565 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
566 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
568 t1[0] = '!';
569 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
571 else
572 print_value (t1, COND_EXEC_TEST (x), verbose);
573 print_pattern (t2, COND_EXEC_CODE (x), verbose);
574 sprintf (buf, "(%s) %s", t1, t2);
575 break;
576 case PARALLEL:
578 int i;
580 sprintf (t1, "{");
581 for (i = 0; i < XVECLEN (x, 0); i++)
583 print_pattern (t2, XVECEXP (x, 0, i), verbose);
584 sprintf (t3, "%s%s;", t1, t2);
585 strcpy (t1, t3);
587 sprintf (buf, "%s}", t1);
589 break;
590 case SEQUENCE:
591 /* Should never see SEQUENCE codes until after reorg. */
592 gcc_unreachable ();
593 case ASM_INPUT:
594 sprintf (buf, "asm {%s}", XSTR (x, 0));
595 break;
596 case ADDR_VEC:
597 break;
598 case ADDR_DIFF_VEC:
599 print_value (buf, XEXP (x, 0), verbose);
600 break;
601 case TRAP_IF:
602 print_value (t1, TRAP_CONDITION (x), verbose);
603 sprintf (buf, "trap_if %s", t1);
604 break;
605 case UNSPEC:
607 int i;
609 sprintf (t1, "unspec{");
610 for (i = 0; i < XVECLEN (x, 0); i++)
612 print_pattern (t2, XVECEXP (x, 0, i), verbose);
613 sprintf (t3, "%s%s;", t1, t2);
614 strcpy (t1, t3);
616 sprintf (buf, "%s}", t1);
618 break;
619 case UNSPEC_VOLATILE:
621 int i;
623 sprintf (t1, "unspec/v{");
624 for (i = 0; i < XVECLEN (x, 0); i++)
626 print_pattern (t2, XVECEXP (x, 0, i), verbose);
627 sprintf (t3, "%s%s;", t1, t2);
628 strcpy (t1, t3);
630 sprintf (buf, "%s}", t1);
632 break;
633 default:
634 print_value (buf, x, verbose);
636 } /* print_pattern */
638 /* This is the main function in rtl visualization mechanism. It
639 accepts an rtx and tries to recognize it as an insn, then prints it
640 properly in human readable form, resembling assembler mnemonics.
641 For every insn it prints its UID and BB the insn belongs too.
642 (Probably the last "option" should be extended somehow, since it
643 depends now on sched.c inner variables ...) */
645 void
646 print_insn (char *buf, rtx x, int verbose)
648 char t[BUF_LEN];
649 rtx insn = x;
651 switch (GET_CODE (x))
653 case INSN:
654 print_pattern (t, PATTERN (x), verbose);
655 #ifdef INSN_SCHEDULING
656 if (verbose && current_sched_info)
657 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
659 else
660 #endif
661 sprintf (buf, " %4d %s", INSN_UID (x), t);
662 break;
663 case JUMP_INSN:
664 print_pattern (t, PATTERN (x), verbose);
665 #ifdef INSN_SCHEDULING
666 if (verbose && current_sched_info)
667 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
669 else
670 #endif
671 sprintf (buf, " %4d %s", INSN_UID (x), t);
672 break;
673 case CALL_INSN:
674 x = PATTERN (insn);
675 if (GET_CODE (x) == PARALLEL)
677 x = XVECEXP (x, 0, 0);
678 print_pattern (t, x, verbose);
680 else
681 strcpy (t, "call <...>");
682 #ifdef INSN_SCHEDULING
683 if (verbose && current_sched_info)
684 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
685 else
686 #endif
687 sprintf (buf, " %4d %s", INSN_UID (insn), t);
688 break;
689 case CODE_LABEL:
690 sprintf (buf, "L%d:", INSN_UID (x));
691 break;
692 case BARRIER:
693 sprintf (buf, "i%4d: barrier", INSN_UID (x));
694 break;
695 case NOTE:
696 sprintf (buf, " %4d %s", INSN_UID (x),
697 GET_NOTE_INSN_NAME (NOTE_KIND (x)));
698 break;
699 default:
700 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
701 GET_RTX_NAME (GET_CODE (x)));
703 } /* print_insn */
706 /* Emit a slim dump of X (an insn) to the file F, including any register
707 note attached to the instruction. */
708 void
709 dump_insn_slim (FILE *f, rtx x)
711 char t[BUF_LEN + 32];
712 rtx note;
714 print_insn (t, x, 1);
715 fputs (t, f);
716 putc ('\n', f);
717 if (INSN_P (x) && REG_NOTES (x))
718 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
720 print_value (t, XEXP (note, 0), 1);
721 fprintf (f, " %s: %s\n",
722 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
726 /* Emit a slim dump of X (an insn) to stderr. */
727 void
728 debug_insn_slim (rtx x)
730 dump_insn_slim (stderr, x);
733 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
734 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
735 include more information on the basic blocks. */
736 void
737 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
739 basic_block current_bb = NULL;
740 rtx insn;
742 for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
744 if ((flags & TDF_BLOCKS)
745 && (INSN_P (insn) || GET_CODE (insn) == NOTE)
746 && BLOCK_FOR_INSN (insn)
747 && !current_bb)
749 current_bb = BLOCK_FOR_INSN (insn);
750 dump_bb_info (current_bb, true, false, flags, ";; ", f);
753 dump_insn_slim (f, insn);
755 if ((flags & TDF_BLOCKS)
756 && current_bb
757 && insn == BB_END (current_bb))
759 dump_bb_info (current_bb, false, true, flags, ";; ", f);
760 current_bb = NULL;