* cfg.c (remove_edge): Don't use FOR_EACH_EDGE for loops that
[official-gcc.git] / gcc / sched-vis.c
blobc7c5427b86328b65ec4f9b15c1cece15aab10d25
1 /* Instruction scheduling pass.
2 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004 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
41 static char *safe_concat (char *, char *, const char *);
42 static void print_exp (char *, rtx, int);
43 static void print_value (char *, rtx, int);
44 static void print_pattern (char *, rtx, int);
46 #define BUF_LEN 2048
48 static char *
49 safe_concat (char *buf, char *cur, const char *str)
51 char *end = buf + BUF_LEN - 2; /* Leave room for null. */
52 int c;
54 if (cur > end)
56 *end = '\0';
57 return end;
60 while (cur < end && (c = *str++) != '\0')
61 *cur++ = c;
63 *cur = '\0';
64 return cur;
67 /* This recognizes rtx, I classified as expressions. These are always
68 represent some action on values or results of other expression, that
69 may be stored in objects representing values. */
71 static void
72 print_exp (char *buf, rtx x, int verbose)
74 char tmp[BUF_LEN];
75 const char *st[4];
76 char *cur = buf;
77 const char *fun = (char *) 0;
78 const char *sep;
79 rtx op[4];
80 int i;
82 for (i = 0; i < 4; i++)
84 st[i] = (char *) 0;
85 op[i] = NULL_RTX;
88 switch (GET_CODE (x))
90 case PLUS:
91 op[0] = XEXP (x, 0);
92 if (GET_CODE (XEXP (x, 1)) == CONST_INT
93 && INTVAL (XEXP (x, 1)) < 0)
95 st[1] = "-";
96 op[1] = GEN_INT (-INTVAL (XEXP (x, 1)));
98 else
100 st[1] = "+";
101 op[1] = XEXP (x, 1);
103 break;
104 case LO_SUM:
105 op[0] = XEXP (x, 0);
106 st[1] = "+low(";
107 op[1] = XEXP (x, 1);
108 st[2] = ")";
109 break;
110 case MINUS:
111 op[0] = XEXP (x, 0);
112 st[1] = "-";
113 op[1] = XEXP (x, 1);
114 break;
115 case COMPARE:
116 fun = "cmp";
117 op[0] = XEXP (x, 0);
118 op[1] = XEXP (x, 1);
119 break;
120 case NEG:
121 st[0] = "-";
122 op[0] = XEXP (x, 0);
123 break;
124 case MULT:
125 op[0] = XEXP (x, 0);
126 st[1] = "*";
127 op[1] = XEXP (x, 1);
128 break;
129 case DIV:
130 op[0] = XEXP (x, 0);
131 st[1] = "/";
132 op[1] = XEXP (x, 1);
133 break;
134 case UDIV:
135 fun = "udiv";
136 op[0] = XEXP (x, 0);
137 op[1] = XEXP (x, 1);
138 break;
139 case MOD:
140 op[0] = XEXP (x, 0);
141 st[1] = "%";
142 op[1] = XEXP (x, 1);
143 break;
144 case UMOD:
145 fun = "umod";
146 op[0] = XEXP (x, 0);
147 op[1] = XEXP (x, 1);
148 break;
149 case SMIN:
150 fun = "smin";
151 op[0] = XEXP (x, 0);
152 op[1] = XEXP (x, 1);
153 break;
154 case SMAX:
155 fun = "smax";
156 op[0] = XEXP (x, 0);
157 op[1] = XEXP (x, 1);
158 break;
159 case UMIN:
160 fun = "umin";
161 op[0] = XEXP (x, 0);
162 op[1] = XEXP (x, 1);
163 break;
164 case UMAX:
165 fun = "umax";
166 op[0] = XEXP (x, 0);
167 op[1] = XEXP (x, 1);
168 break;
169 case NOT:
170 st[0] = "!";
171 op[0] = XEXP (x, 0);
172 break;
173 case AND:
174 op[0] = XEXP (x, 0);
175 st[1] = "&";
176 op[1] = XEXP (x, 1);
177 break;
178 case IOR:
179 op[0] = XEXP (x, 0);
180 st[1] = "|";
181 op[1] = XEXP (x, 1);
182 break;
183 case XOR:
184 op[0] = XEXP (x, 0);
185 st[1] = "^";
186 op[1] = XEXP (x, 1);
187 break;
188 case ASHIFT:
189 op[0] = XEXP (x, 0);
190 st[1] = "<<";
191 op[1] = XEXP (x, 1);
192 break;
193 case LSHIFTRT:
194 op[0] = XEXP (x, 0);
195 st[1] = " 0>>";
196 op[1] = XEXP (x, 1);
197 break;
198 case ASHIFTRT:
199 op[0] = XEXP (x, 0);
200 st[1] = ">>";
201 op[1] = XEXP (x, 1);
202 break;
203 case ROTATE:
204 op[0] = XEXP (x, 0);
205 st[1] = "<-<";
206 op[1] = XEXP (x, 1);
207 break;
208 case ROTATERT:
209 op[0] = XEXP (x, 0);
210 st[1] = ">->";
211 op[1] = XEXP (x, 1);
212 break;
213 case ABS:
214 fun = "abs";
215 op[0] = XEXP (x, 0);
216 break;
217 case SQRT:
218 fun = "sqrt";
219 op[0] = XEXP (x, 0);
220 break;
221 case FFS:
222 fun = "ffs";
223 op[0] = XEXP (x, 0);
224 break;
225 case EQ:
226 op[0] = XEXP (x, 0);
227 st[1] = "==";
228 op[1] = XEXP (x, 1);
229 break;
230 case NE:
231 op[0] = XEXP (x, 0);
232 st[1] = "!=";
233 op[1] = XEXP (x, 1);
234 break;
235 case GT:
236 op[0] = XEXP (x, 0);
237 st[1] = ">";
238 op[1] = XEXP (x, 1);
239 break;
240 case GTU:
241 fun = "gtu";
242 op[0] = XEXP (x, 0);
243 op[1] = XEXP (x, 1);
244 break;
245 case LT:
246 op[0] = XEXP (x, 0);
247 st[1] = "<";
248 op[1] = XEXP (x, 1);
249 break;
250 case LTU:
251 fun = "ltu";
252 op[0] = XEXP (x, 0);
253 op[1] = XEXP (x, 1);
254 break;
255 case GE:
256 op[0] = XEXP (x, 0);
257 st[1] = ">=";
258 op[1] = XEXP (x, 1);
259 break;
260 case GEU:
261 fun = "geu";
262 op[0] = XEXP (x, 0);
263 op[1] = XEXP (x, 1);
264 break;
265 case LE:
266 op[0] = XEXP (x, 0);
267 st[1] = "<=";
268 op[1] = XEXP (x, 1);
269 break;
270 case LEU:
271 fun = "leu";
272 op[0] = XEXP (x, 0);
273 op[1] = XEXP (x, 1);
274 break;
275 case SIGN_EXTRACT:
276 fun = (verbose) ? "sign_extract" : "sxt";
277 op[0] = XEXP (x, 0);
278 op[1] = XEXP (x, 1);
279 op[2] = XEXP (x, 2);
280 break;
281 case ZERO_EXTRACT:
282 fun = (verbose) ? "zero_extract" : "zxt";
283 op[0] = XEXP (x, 0);
284 op[1] = XEXP (x, 1);
285 op[2] = XEXP (x, 2);
286 break;
287 case SIGN_EXTEND:
288 fun = (verbose) ? "sign_extend" : "sxn";
289 op[0] = XEXP (x, 0);
290 break;
291 case ZERO_EXTEND:
292 fun = (verbose) ? "zero_extend" : "zxn";
293 op[0] = XEXP (x, 0);
294 break;
295 case FLOAT_EXTEND:
296 fun = (verbose) ? "float_extend" : "fxn";
297 op[0] = XEXP (x, 0);
298 break;
299 case TRUNCATE:
300 fun = (verbose) ? "trunc" : "trn";
301 op[0] = XEXP (x, 0);
302 break;
303 case FLOAT_TRUNCATE:
304 fun = (verbose) ? "float_trunc" : "ftr";
305 op[0] = XEXP (x, 0);
306 break;
307 case FLOAT:
308 fun = (verbose) ? "float" : "flt";
309 op[0] = XEXP (x, 0);
310 break;
311 case UNSIGNED_FLOAT:
312 fun = (verbose) ? "uns_float" : "ufl";
313 op[0] = XEXP (x, 0);
314 break;
315 case FIX:
316 fun = "fix";
317 op[0] = XEXP (x, 0);
318 break;
319 case UNSIGNED_FIX:
320 fun = (verbose) ? "uns_fix" : "ufx";
321 op[0] = XEXP (x, 0);
322 break;
323 case PRE_DEC:
324 st[0] = "--";
325 op[0] = XEXP (x, 0);
326 break;
327 case PRE_INC:
328 st[0] = "++";
329 op[0] = XEXP (x, 0);
330 break;
331 case POST_DEC:
332 op[0] = XEXP (x, 0);
333 st[1] = "--";
334 break;
335 case POST_INC:
336 op[0] = XEXP (x, 0);
337 st[1] = "++";
338 break;
339 case CALL:
340 st[0] = "call ";
341 op[0] = XEXP (x, 0);
342 if (verbose)
344 st[1] = " argc:";
345 op[1] = XEXP (x, 1);
347 break;
348 case IF_THEN_ELSE:
349 st[0] = "{(";
350 op[0] = XEXP (x, 0);
351 st[1] = ")?";
352 op[1] = XEXP (x, 1);
353 st[2] = ":";
354 op[2] = XEXP (x, 2);
355 st[3] = "}";
356 break;
357 case TRAP_IF:
358 fun = "trap_if";
359 op[0] = TRAP_CONDITION (x);
360 break;
361 case PREFETCH:
362 fun = "prefetch";
363 op[0] = XEXP (x, 0);
364 op[1] = XEXP (x, 1);
365 op[2] = XEXP (x, 2);
366 break;
367 case UNSPEC:
368 case UNSPEC_VOLATILE:
370 cur = safe_concat (buf, cur, "unspec");
371 if (GET_CODE (x) == UNSPEC_VOLATILE)
372 cur = safe_concat (buf, cur, "/v");
373 cur = safe_concat (buf, cur, "[");
374 sep = "";
375 for (i = 0; i < XVECLEN (x, 0); i++)
377 print_pattern (tmp, XVECEXP (x, 0, i), verbose);
378 cur = safe_concat (buf, cur, sep);
379 cur = safe_concat (buf, cur, tmp);
380 sep = ",";
382 cur = safe_concat (buf, cur, "] ");
383 sprintf (tmp, "%d", XINT (x, 1));
384 cur = safe_concat (buf, cur, tmp);
386 break;
387 default:
388 /* If (verbose) debug_rtx (x); */
389 st[0] = GET_RTX_NAME (GET_CODE (x));
390 break;
393 /* Print this as a function? */
394 if (fun)
396 cur = safe_concat (buf, cur, fun);
397 cur = safe_concat (buf, cur, "(");
400 for (i = 0; i < 4; i++)
402 if (st[i])
403 cur = safe_concat (buf, cur, st[i]);
405 if (op[i])
407 if (fun && i != 0)
408 cur = safe_concat (buf, cur, ",");
410 print_value (tmp, op[i], verbose);
411 cur = safe_concat (buf, cur, tmp);
415 if (fun)
416 cur = safe_concat (buf, cur, ")");
417 } /* print_exp */
419 /* Prints rtxes, I customarily classified as values. They're constants,
420 registers, labels, symbols and memory accesses. */
422 static void
423 print_value (char *buf, rtx x, int verbose)
425 char t[BUF_LEN];
426 char *cur = buf;
428 switch (GET_CODE (x))
430 case CONST_INT:
431 sprintf (t, HOST_WIDE_INT_PRINT_HEX, INTVAL (x));
432 cur = safe_concat (buf, cur, t);
433 break;
434 case CONST_DOUBLE:
435 if (FLOAT_MODE_P (GET_MODE (x)))
436 real_to_decimal (t, CONST_DOUBLE_REAL_VALUE (x), sizeof (t), 0, 1);
437 else
438 sprintf (t, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
439 cur = safe_concat (buf, cur, t);
440 break;
441 case CONST_STRING:
442 cur = safe_concat (buf, cur, "\"");
443 cur = safe_concat (buf, cur, XSTR (x, 0));
444 cur = safe_concat (buf, cur, "\"");
445 break;
446 case SYMBOL_REF:
447 cur = safe_concat (buf, cur, "`");
448 cur = safe_concat (buf, cur, XSTR (x, 0));
449 cur = safe_concat (buf, cur, "'");
450 break;
451 case LABEL_REF:
452 sprintf (t, "L%d", INSN_UID (XEXP (x, 0)));
453 cur = safe_concat (buf, cur, t);
454 break;
455 case CONST:
456 print_value (t, XEXP (x, 0), verbose);
457 cur = safe_concat (buf, cur, "const(");
458 cur = safe_concat (buf, cur, t);
459 cur = safe_concat (buf, cur, ")");
460 break;
461 case HIGH:
462 print_value (t, XEXP (x, 0), verbose);
463 cur = safe_concat (buf, cur, "high(");
464 cur = safe_concat (buf, cur, t);
465 cur = safe_concat (buf, cur, ")");
466 break;
467 case REG:
468 if (REGNO (x) < FIRST_PSEUDO_REGISTER)
470 int c = reg_names[REGNO (x)][0];
471 if (ISDIGIT (c))
472 cur = safe_concat (buf, cur, "%");
474 cur = safe_concat (buf, cur, reg_names[REGNO (x)]);
476 else
478 sprintf (t, "r%d", REGNO (x));
479 cur = safe_concat (buf, cur, t);
481 break;
482 case SUBREG:
483 print_value (t, SUBREG_REG (x), verbose);
484 cur = safe_concat (buf, cur, t);
485 sprintf (t, "#%d", SUBREG_BYTE (x));
486 cur = safe_concat (buf, cur, t);
487 break;
488 case SCRATCH:
489 cur = safe_concat (buf, cur, "scratch");
490 break;
491 case CC0:
492 cur = safe_concat (buf, cur, "cc0");
493 break;
494 case PC:
495 cur = safe_concat (buf, cur, "pc");
496 break;
497 case MEM:
498 print_value (t, XEXP (x, 0), verbose);
499 cur = safe_concat (buf, cur, "[");
500 cur = safe_concat (buf, cur, t);
501 cur = safe_concat (buf, cur, "]");
502 break;
503 default:
504 print_exp (t, x, verbose);
505 cur = safe_concat (buf, cur, t);
506 break;
508 } /* print_value */
510 /* The next step in insn detalization, its pattern recognition. */
512 static void
513 print_pattern (char *buf, rtx x, int verbose)
515 char t1[BUF_LEN], t2[BUF_LEN], t3[BUF_LEN];
517 switch (GET_CODE (x))
519 case SET:
520 print_value (t1, SET_DEST (x), verbose);
521 print_value (t2, SET_SRC (x), verbose);
522 sprintf (buf, "%s=%s", t1, t2);
523 break;
524 case RETURN:
525 sprintf (buf, "return");
526 break;
527 case CALL:
528 print_exp (buf, x, verbose);
529 break;
530 case CLOBBER:
531 print_value (t1, XEXP (x, 0), verbose);
532 sprintf (buf, "clobber %s", t1);
533 break;
534 case USE:
535 print_value (t1, XEXP (x, 0), verbose);
536 sprintf (buf, "use %s", t1);
537 break;
538 case COND_EXEC:
539 if (GET_CODE (COND_EXEC_TEST (x)) == NE
540 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
541 print_value (t1, XEXP (COND_EXEC_TEST (x), 0), verbose);
542 else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
543 && XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
545 t1[0] = '!';
546 print_value (t1 + 1, XEXP (COND_EXEC_TEST (x), 0), verbose);
548 else
549 print_value (t1, COND_EXEC_TEST (x), verbose);
550 print_pattern (t2, COND_EXEC_CODE (x), verbose);
551 sprintf (buf, "(%s) %s", t1, t2);
552 break;
553 case PARALLEL:
555 int i;
557 sprintf (t1, "{");
558 for (i = 0; i < XVECLEN (x, 0); i++)
560 print_pattern (t2, XVECEXP (x, 0, i), verbose);
561 sprintf (t3, "%s%s;", t1, t2);
562 strcpy (t1, t3);
564 sprintf (buf, "%s}", t1);
566 break;
567 case SEQUENCE:
568 /* Should never see SEQUENCE codes until after reorg. */
569 abort ();
570 break;
571 case ASM_INPUT:
572 sprintf (buf, "asm {%s}", XSTR (x, 0));
573 break;
574 case ADDR_VEC:
575 break;
576 case ADDR_DIFF_VEC:
577 print_value (buf, XEXP (x, 0), verbose);
578 break;
579 case TRAP_IF:
580 print_value (t1, TRAP_CONDITION (x), verbose);
581 sprintf (buf, "trap_if %s", t1);
582 break;
583 case UNSPEC:
585 int i;
587 sprintf (t1, "unspec{");
588 for (i = 0; i < XVECLEN (x, 0); i++)
590 print_pattern (t2, XVECEXP (x, 0, i), verbose);
591 sprintf (t3, "%s%s;", t1, t2);
592 strcpy (t1, t3);
594 sprintf (buf, "%s}", t1);
596 break;
597 case UNSPEC_VOLATILE:
599 int i;
601 sprintf (t1, "unspec/v{");
602 for (i = 0; i < XVECLEN (x, 0); i++)
604 print_pattern (t2, XVECEXP (x, 0, i), verbose);
605 sprintf (t3, "%s%s;", t1, t2);
606 strcpy (t1, t3);
608 sprintf (buf, "%s}", t1);
610 break;
611 default:
612 print_value (buf, x, verbose);
614 } /* print_pattern */
616 /* This is the main function in rtl visualization mechanism. It
617 accepts an rtx and tries to recognize it as an insn, then prints it
618 properly in human readable form, resembling assembler mnemonics.
619 For every insn it prints its UID and BB the insn belongs too.
620 (Probably the last "option" should be extended somehow, since it
621 depends now on sched.c inner variables ...) */
623 void
624 print_insn (char *buf, rtx x, int verbose)
626 char t[BUF_LEN];
627 rtx insn = x;
629 switch (GET_CODE (x))
631 case INSN:
632 print_pattern (t, PATTERN (x), verbose);
633 if (verbose)
634 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
636 else
637 sprintf (buf, "%-4d %s", INSN_UID (x), t);
638 break;
639 case JUMP_INSN:
640 print_pattern (t, PATTERN (x), verbose);
641 if (verbose)
642 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
644 else
645 sprintf (buf, "%-4d %s", INSN_UID (x), t);
646 break;
647 case CALL_INSN:
648 x = PATTERN (insn);
649 if (GET_CODE (x) == PARALLEL)
651 x = XVECEXP (x, 0, 0);
652 print_pattern (t, x, verbose);
654 else
655 strcpy (t, "call <...>");
656 if (verbose)
657 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
658 else
659 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
660 break;
661 case CODE_LABEL:
662 sprintf (buf, "L%d:", INSN_UID (x));
663 break;
664 case BARRIER:
665 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
666 break;
667 case NOTE:
668 if (NOTE_LINE_NUMBER (x) > 0)
670 expanded_location xloc;
671 NOTE_EXPANDED_LOCATION (xloc, x);
672 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
673 xloc.file, xloc.line);
675 else
676 sprintf (buf, "%4d %s", INSN_UID (x),
677 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
678 break;
679 default:
680 if (verbose)
682 sprintf (buf, "Not an INSN at all\n");
683 debug_rtx (x);
685 else
686 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
688 } /* print_insn */
690 #endif