decl.c (gnat_to_gnu_entity): For a constant object whose type has self-referential...
[official-gcc.git] / gcc / sched-vis.c
blob8f4597247e5fe625c745496d2085022ac5c8120a
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, INTVAL (x));
438 cur = safe_concat (buf, cur, t);
439 break;
440 case CONST_DOUBLE:
441 if (FLOAT_MODE_P (GET_MODE (x)))
442 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
443 else
444 sprintf (t,
445 "<" HOST_WIDE_INT_PRINT_HEX "," HOST_WIDE_INT_PRINT_HEX ">",
446 (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x),
447 (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x));
448 cur = safe_concat (buf, cur, t);
449 break;
450 case CONST_FIXED:
451 fixed_to_decimal (t, CONST_FIXED_VALUE (x), sizeof (t));
452 cur = safe_concat (buf, cur, t);
453 break;
454 case CONST_STRING:
455 cur = safe_concat (buf, cur, "\"");
456 cur = safe_concat (buf, cur, XSTR (x, 0));
457 cur = safe_concat (buf, cur, "\"");
458 break;
459 case SYMBOL_REF:
460 cur = safe_concat (buf, cur, "`");
461 cur = safe_concat (buf, cur, XSTR (x, 0));
462 cur = safe_concat (buf, cur, "'");
463 break;
464 case LABEL_REF:
465 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
466 cur = safe_concat (buf, cur, t);
467 break;
468 case CONST:
469 print_value (t, XEXP (x, 0), verbose);
470 cur = safe_concat (buf, cur, "const(");
471 cur = safe_concat (buf, cur, t);
472 cur = safe_concat (buf, cur, ")");
473 break;
474 case HIGH:
475 print_value (t, XEXP (x, 0), verbose);
476 cur = safe_concat (buf, cur, "high(");
477 cur = safe_concat (buf, cur, t);
478 cur = safe_concat (buf, cur, ")");
479 break;
480 case REG:
481 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
483 int c = reg_names[REGNO (x)][0];
484 if (ISDIGIT (c))
485 cur = safe_concat (buf, cur, "%");
487 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
489 else
491 sprintf (t, "r%d", REGNO (x));
492 cur = safe_concat (buf, cur, t);
494 if (verbose
495 #ifdef INSN_SCHEDULING
496 && !current_sched_info
497 #endif
500 sprintf (t, ":%s", GET_MODE_NAME (GET_MODE (x)));
501 cur = safe_concat (buf, cur, t);
503 break;
504 case SUBREG:
505 print_value (t, SUBREG_REG (x), verbose);
506 cur = safe_concat (buf, cur, t);
507 sprintf (t, "#%d", SUBREG_BYTE (x));
508 cur = safe_concat (buf, cur, t);
509 break;
510 case SCRATCH:
511 cur = safe_concat (buf, cur, "scratch");
512 break;
513 case CC0:
514 cur = safe_concat (buf, cur, "cc0");
515 break;
516 case PC:
517 cur = safe_concat (buf, cur, "pc");
518 break;
519 case MEM:
520 print_value (t, XEXP (x, 0), verbose);
521 cur = safe_concat (buf, cur, "[");
522 cur = safe_concat (buf, cur, t);
523 cur = safe_concat (buf, cur, "]");
524 break;
525 default:
526 print_exp (t, x, verbose);
527 cur = safe_concat (buf, cur, t);
528 break;
530 } /* print_value */
532 /* The next step in insn detalization, its pattern recognition. */
534 static void
535 print_pattern (char *buf, const_rtx x, int verbose)
537 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
539 switch (GET_CODE (x))
541 case SET:
542 print_value (t1, SET_DEST (x), verbose);
543 print_value (t2, SET_SRC (x), verbose);
544 sprintf (buf, "%s=%s", t1, t2);
545 break;
546 case RETURN:
547 sprintf (buf, "return");
548 break;
549 case CALL:
550 print_exp (buf, x, verbose);
551 break;
552 case CLOBBER:
553 print_value (t1, XEXP (x, 0), verbose);
554 sprintf (buf, "clobber %s", t1);
555 break;
556 case USE:
557 print_value (t1, XEXP (x, 0), verbose);
558 sprintf (buf, "use %s", t1);
559 break;
560 case COND_EXEC:
561 if (GET_CODE (COND_EXEC_TEST (x)) == NE
562 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
563 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
564 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
565 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
567 t1[0] = '!';
568 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
570 else
571 print_value (t1, COND_EXEC_TEST (x), verbose);
572 print_pattern (t2, COND_EXEC_CODE (x), verbose);
573 sprintf (buf, "(%s) %s", t1, t2);
574 break;
575 case PARALLEL:
577 int i;
579 sprintf (t1, "{");
580 for (i = 0; i < XVECLEN (x, 0); i++)
582 print_pattern (t2, XVECEXP (x, 0, i), verbose);
583 sprintf (t3, "%s%s;", t1, t2);
584 strcpy (t1, t3);
586 sprintf (buf, "%s}", t1);
588 break;
589 case SEQUENCE:
590 /* Should never see SEQUENCE codes until after reorg. */
591 gcc_unreachable ();
592 case ASM_INPUT:
593 sprintf (buf, "asm {%s}", XSTR (x, 0));
594 break;
595 case ADDR_VEC:
596 break;
597 case ADDR_DIFF_VEC:
598 print_value (buf, XEXP (x, 0), verbose);
599 break;
600 case TRAP_IF:
601 print_value (t1, TRAP_CONDITION (x), verbose);
602 sprintf (buf, "trap_if %s", t1);
603 break;
604 case UNSPEC:
606 int i;
608 sprintf (t1, "unspec{");
609 for (i = 0; i < XVECLEN (x, 0); i++)
611 print_pattern (t2, XVECEXP (x, 0, i), verbose);
612 sprintf (t3, "%s%s;", t1, t2);
613 strcpy (t1, t3);
615 sprintf (buf, "%s}", t1);
617 break;
618 case UNSPEC_VOLATILE:
620 int i;
622 sprintf (t1, "unspec/v{");
623 for (i = 0; i < XVECLEN (x, 0); i++)
625 print_pattern (t2, XVECEXP (x, 0, i), verbose);
626 sprintf (t3, "%s%s;", t1, t2);
627 strcpy (t1, t3);
629 sprintf (buf, "%s}", t1);
631 break;
632 default:
633 print_value (buf, x, verbose);
635 } /* print_pattern */
637 /* This is the main function in rtl visualization mechanism. It
638 accepts an rtx and tries to recognize it as an insn, then prints it
639 properly in human readable form, resembling assembler mnemonics.
640 For every insn it prints its UID and BB the insn belongs too.
641 (Probably the last "option" should be extended somehow, since it
642 depends now on sched.c inner variables ...) */
644 void
645 print_insn (char *buf, rtx x, int verbose)
647 char t[BUF_LEN];
648 rtx insn = x;
650 switch (GET_CODE (x))
652 case INSN:
653 print_pattern (t, PATTERN (x), verbose);
654 #ifdef INSN_SCHEDULING
655 if (verbose && current_sched_info)
656 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
658 else
659 #endif
660 sprintf (buf, " %4d %s", INSN_UID (x), t);
661 break;
662 case JUMP_INSN:
663 print_pattern (t, PATTERN (x), verbose);
664 #ifdef INSN_SCHEDULING
665 if (verbose && current_sched_info)
666 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
668 else
669 #endif
670 sprintf (buf, " %4d %s", INSN_UID (x), t);
671 break;
672 case CALL_INSN:
673 x = PATTERN (insn);
674 if (GET_CODE (x) == PARALLEL)
676 x = XVECEXP (x, 0, 0);
677 print_pattern (t, x, verbose);
679 else
680 strcpy (t, "call <...>");
681 #ifdef INSN_SCHEDULING
682 if (verbose && current_sched_info)
683 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
684 else
685 #endif
686 sprintf (buf, " %4d %s", INSN_UID (insn), t);
687 break;
688 case CODE_LABEL:
689 sprintf (buf, "L%d:", INSN_UID (x));
690 break;
691 case BARRIER:
692 sprintf (buf, "i%4d: barrier", INSN_UID (x));
693 break;
694 case NOTE:
695 sprintf (buf, " %4d %s", INSN_UID (x),
696 GET_NOTE_INSN_NAME (NOTE_KIND (x)));
697 break;
698 default:
699 sprintf (buf, "i%4d <What %s?>", INSN_UID (x),
700 GET_RTX_NAME (GET_CODE (x)));
702 } /* print_insn */
705 /* Emit a slim dump of X (an insn) to the file F, including any register
706 note attached to the instruction. */
707 void
708 dump_insn_slim (FILE *f, rtx x)
710 char t[BUF_LEN + 32];
711 rtx note;
713 print_insn (t, x, 1);
714 fputs (t, f);
715 putc ('\n', f);
716 if (INSN_P (x) && REG_NOTES (x))
717 for (note = REG_NOTES (x); note; note = XEXP (note, 1))
719 print_value (t, XEXP (note, 0), 1);
720 fprintf (f, " %s: %s\n",
721 GET_REG_NOTE_NAME (REG_NOTE_KIND (note)), t);
725 /* Emit a slim dump of X (an insn) to stderr. */
726 void
727 debug_insn_slim (rtx x)
729 dump_insn_slim (stderr, x);
732 /* Provide a slim dump the instruction chain starting at FIRST to F, honoring
733 the dump flags given in FLAGS. Currently, TDF_BLOCKS and TDF_DETAILS
734 include more information on the basic blocks. */
735 void
736 print_rtl_slim_with_bb (FILE *f, rtx first, int flags)
738 basic_block current_bb = NULL;
739 rtx insn;
741 for (insn = first; NULL != insn; insn = NEXT_INSN (insn))
743 if ((flags & TDF_BLOCKS)
744 && (INSN_P (insn) || GET_CODE (insn) == NOTE)
745 && BLOCK_FOR_INSN (insn)
746 && !current_bb)
748 current_bb = BLOCK_FOR_INSN (insn);
749 dump_bb_info (current_bb, true, false, flags, ";; ", f);
752 dump_insn_slim (f, insn);
754 if ((flags & TDF_BLOCKS)
755 && current_bb
756 && insn == BB_END (current_bb))
758 dump_bb_info (current_bb, false, true, flags, ";; ", f);
759 current_bb = NULL;