Mark ChangeLog
[official-gcc.git] / gcc / sched-vis.c
blobaa228317ba08dfbe241e6a768226a34458eb875a
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 gcc_unreachable ();
570 case ASM_INPUT:
571 sprintf (buf, "asm {%s}", XSTR (x, 0));
572 break;
573 case ADDR_VEC:
574 break;
575 case ADDR_DIFF_VEC:
576 print_value (buf, XEXP (x, 0), verbose);
577 break;
578 case TRAP_IF:
579 print_value (t1, TRAP_CONDITION (x), verbose);
580 sprintf (buf, "trap_if %s", t1);
581 break;
582 case UNSPEC:
584 int i;
586 sprintf (t1, "unspec{");
587 for (i = 0; i < XVECLEN (x, 0); i++)
589 print_pattern (t2, XVECEXP (x, 0, i), verbose);
590 sprintf (t3, "%s%s;", t1, t2);
591 strcpy (t1, t3);
593 sprintf (buf, "%s}", t1);
595 break;
596 case UNSPEC_VOLATILE:
598 int i;
600 sprintf (t1, "unspec/v{");
601 for (i = 0; i < XVECLEN (x, 0); i++)
603 print_pattern (t2, XVECEXP (x, 0, i), verbose);
604 sprintf (t3, "%s%s;", t1, t2);
605 strcpy (t1, t3);
607 sprintf (buf, "%s}", t1);
609 break;
610 default:
611 print_value (buf, x, verbose);
613 } /* print_pattern */
615 /* This is the main function in rtl visualization mechanism. It
616 accepts an rtx and tries to recognize it as an insn, then prints it
617 properly in human readable form, resembling assembler mnemonics.
618 For every insn it prints its UID and BB the insn belongs too.
619 (Probably the last "option" should be extended somehow, since it
620 depends now on sched.c inner variables ...) */
622 void
623 print_insn (char *buf, rtx x, int verbose)
625 char t[BUF_LEN];
626 rtx insn = x;
628 switch (GET_CODE (x))
630 case INSN:
631 print_pattern (t, PATTERN (x), verbose);
632 if (verbose)
633 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
635 else
636 sprintf (buf, "%-4d %s", INSN_UID (x), t);
637 break;
638 case JUMP_INSN:
639 print_pattern (t, PATTERN (x), verbose);
640 if (verbose)
641 sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
643 else
644 sprintf (buf, "%-4d %s", INSN_UID (x), t);
645 break;
646 case CALL_INSN:
647 x = PATTERN (insn);
648 if (GET_CODE (x) == PARALLEL)
650 x = XVECEXP (x, 0, 0);
651 print_pattern (t, x, verbose);
653 else
654 strcpy (t, "call <...>");
655 if (verbose)
656 sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
657 else
658 sprintf (buf, "%-4d %s", INSN_UID (insn), t);
659 break;
660 case CODE_LABEL:
661 sprintf (buf, "L%d:", INSN_UID (x));
662 break;
663 case BARRIER:
664 sprintf (buf, "i% 4d: barrier", INSN_UID (x));
665 break;
666 case NOTE:
667 if (NOTE_LINE_NUMBER (x) > 0)
669 expanded_location xloc;
670 NOTE_EXPANDED_LOCATION (xloc, x);
671 sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
672 xloc.file, xloc.line);
674 else
675 sprintf (buf, "%4d %s", INSN_UID (x),
676 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
677 break;
678 default:
679 if (verbose)
681 sprintf (buf, "Not an INSN at all\n");
682 debug_rtx (x);
684 else
685 sprintf (buf, "i%-4d <What?>", INSN_UID (x));
687 } /* print_insn */
689 #endif