* c-pretty-print.c (pp_c_semicolon): Fix formatting.
[official-gcc.git] / gcc / ra-debug.c
blob4936898ae8b06b9cfdf4625ed94de25208d56dc4
1 /* Graph coloring register allocator
2 Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
3 Contributed by Michael Matz <matz@suse.de>
4 and Daniel Berlin <dan@cgsoftware.com>.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2, or (at your option) any later version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 details.
17 You should have received a copy of the GNU General Public License along
18 with GCC; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "rtl.h"
26 #include "insn-config.h"
27 #include "recog.h"
28 #include "function.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "df.h"
32 #include "output.h"
33 #include "ra.h"
34 #include "tm_p.h"
35 #include "regs.h"
37 /* This file contains various dumping and debug functions for
38 the graph coloring register allocator. */
40 static void ra_print_rtx_1op (FILE *, rtx);
41 static void ra_print_rtx_2op (FILE *, rtx);
42 static void ra_print_rtx_3op (FILE *, rtx);
43 static void ra_print_rtx_object (FILE *, rtx);
45 /* The hardregs as names, for debugging. */
46 static const char *const reg_class_names[] = REG_CLASS_NAMES;
48 /* Print a message to the dump file, if debug_new_regalloc and LEVEL
49 have any bits in common. */
51 void
52 ra_debug_msg (unsigned int level, const char *format, ...)
54 va_list ap;
56 va_start (ap, format);
57 if ((debug_new_regalloc & level) != 0 && dump_file != NULL)
58 vfprintf (dump_file, format, ap);
59 va_end (ap);
63 /* The following ra_print_xxx() functions print RTL expressions
64 in concise infix form. If the mode can be seen from context it's
65 left out. Most operators are represented by their graphical
66 characters, e.g. LE as "<=". Unknown constructs are currently
67 printed with print_inline_rtx(), which disrupts the nice layout.
68 Currently only the inline asm things are written this way. */
70 /* Print rtx X, which is a one operand rtx (op:mode (Y)), as
71 "op(Y)" to FILE. */
73 static void
74 ra_print_rtx_1op (FILE *file, rtx x)
76 enum rtx_code code = GET_CODE (x);
77 rtx op0 = XEXP (x, 0);
78 switch (code)
80 case NEG:
81 case NOT:
82 fputs ((code == NEG) ? "-(" : "~(", file);
83 ra_print_rtx (file, op0, 0);
84 fputs (")", file);
85 break;
86 case HIGH:
87 fputs ("hi(", file);
88 ra_print_rtx (file, op0, 0);
89 fputs (")", file);
90 break;
91 default:
92 fprintf (file, "%s", GET_RTX_NAME (code));
93 if (GET_MODE (x) != VOIDmode)
94 fprintf (file, ":%s(", GET_MODE_NAME (GET_MODE (x)));
95 else
96 fputs ("(", file);
97 ra_print_rtx (file, op0, 0);
98 fputs (")", file);
99 break;
103 /* Print rtx X, which is a two operand rtx (op:mode (Y) (Z))
104 as "(Y op Z)", if the operand is know, or as "op(Y, Z)", if not,
105 to FILE. */
107 static void
108 ra_print_rtx_2op (FILE *file, rtx x)
110 int infix = 1;
111 const char *opname = "shitop";
112 enum rtx_code code = GET_CODE (x);
113 rtx op0 = XEXP (x, 0);
114 rtx op1 = XEXP (x, 1);
115 switch (code)
117 /* class '2' */
118 case COMPARE: opname = "?"; break;
119 case MINUS: opname = "-"; break;
120 case DIV: opname = "/"; break;
121 case UDIV: opname = "u/"; break;
122 case MOD: opname = "%"; break;
123 case UMOD: opname = "u%"; break;
124 case ASHIFT: opname = "<<"; break;
125 case ASHIFTRT: opname = "a>>"; break;
126 case LSHIFTRT: opname = "l>>"; break;
127 /* class 'c' */
128 case PLUS: opname = "+"; break;
129 case MULT: opname = "*"; break;
130 case AND: opname = "&"; break;
131 case IOR: opname = "|"; break;
132 case XOR: opname = "^"; break;
133 /* class '=' */
134 case NE: opname = "!="; break;
135 case EQ: opname = "=="; break;
136 case LTGT: opname = "<>"; break;
137 /* class '<' */
138 case GE: opname = "s>="; break;
139 case GT: opname = "s>"; break;
140 case LE: opname = "s<="; break;
141 case LT: opname = "s<"; break;
142 case GEU: opname = "u>="; break;
143 case GTU: opname = "u>"; break;
144 case LEU: opname = "u<="; break;
145 case LTU: opname = "u<"; break;
146 default:
147 infix = 0;
148 opname = GET_RTX_NAME (code);
149 break;
151 if (infix)
153 fputs ("(", file);
154 ra_print_rtx (file, op0, 0);
155 fprintf (file, " %s ", opname);
156 ra_print_rtx (file, op1, 0);
157 fputs (")", file);
159 else
161 fprintf (file, "%s(", opname);
162 ra_print_rtx (file, op0, 0);
163 fputs (", ", file);
164 ra_print_rtx (file, op1, 0);
165 fputs (")", file);
169 /* Print rtx X, which a three operand rtx to FILE.
170 I.e. X is either an IF_THEN_ELSE, or a bitmap operation. */
172 static void
173 ra_print_rtx_3op (FILE *file, rtx x)
175 enum rtx_code code = GET_CODE (x);
176 rtx op0 = XEXP (x, 0);
177 rtx op1 = XEXP (x, 1);
178 rtx op2 = XEXP (x, 2);
179 if (code == IF_THEN_ELSE)
181 ra_print_rtx (file, op0, 0);
182 fputs (" ? ", file);
183 ra_print_rtx (file, op1, 0);
184 fputs (" : ", file);
185 ra_print_rtx (file, op2, 0);
187 else
189 /* Bitmap-operation */
190 fprintf (file, "%s:%s(", GET_RTX_NAME (code),
191 GET_MODE_NAME (GET_MODE (x)));
192 ra_print_rtx (file, op0, 0);
193 fputs (", ", file);
194 ra_print_rtx (file, op1, 0);
195 fputs (", ", file);
196 ra_print_rtx (file, op2, 0);
197 fputs (")", file);
201 /* Print rtx X, which represents an object (class 'o', 'C', or some constructs
202 of class 'x' (e.g. subreg)), to FILE.
203 (reg XX) rtl is represented as "pXX", of XX was a pseudo,
204 as "name" it name is the nonnull hardreg name, or as "hXX", if XX
205 is a hardreg, whose name is NULL, or empty. */
207 static void
208 ra_print_rtx_object (FILE *file, rtx x)
210 enum rtx_code code = GET_CODE (x);
211 enum machine_mode mode = GET_MODE (x);
212 switch (code)
214 case CONST_INT:
215 fprintf (file, HOST_WIDE_INT_PRINT_DEC, XWINT (x, 0));
216 break;
217 case CONST_DOUBLE:
219 int i, num = 0;
220 const char *fmt = GET_RTX_FORMAT (code);
221 fputs ("dbl(", file);
222 for (i = 0; i < GET_RTX_LENGTH (code); i++)
224 if (num)
225 fputs (", ", file);
226 if (fmt[i] == 'e' && XEXP (x, i))
227 /* The MEM or other stuff */
229 ra_print_rtx (file, XEXP (x, i), 0);
230 num++;
232 else if (fmt[i] == 'w')
234 fprintf (file, HOST_WIDE_INT_PRINT_HEX, XWINT (x, i));
235 num++;
238 break;
240 case CONST_STRING: fprintf (file, "\"%s\"", XSTR (x, 0)); break;
241 case CONST: fputs ("const(", file);
242 ra_print_rtx (file, XEXP (x, 0), 0);
243 fputs (")", file);
244 break;
245 case PC: fputs ("pc", file); break;
246 case REG:
248 int regno = REGNO (x);
249 if (regno < FIRST_PSEUDO_REGISTER)
251 int i, nregs = hard_regno_nregs[regno][mode];
252 if (nregs > 1)
253 fputs ("[", file);
254 for (i = 0; i < nregs; i++)
256 if (i)
257 fputs (", ", file);
258 if (reg_names[regno+i] && *reg_names[regno + i])
259 fprintf (file, "%s", reg_names[regno + i]);
260 else
261 fprintf (file, "h%d", regno + i);
263 if (nregs > 1)
264 fputs ("]", file);
266 else
267 fprintf (file, "p%d", regno);
268 break;
270 case SUBREG:
272 rtx sub = SUBREG_REG (x);
273 int ofs = SUBREG_BYTE (x);
274 if (GET_CODE (sub) == REG
275 && REGNO (sub) < FIRST_PSEUDO_REGISTER)
277 int regno = REGNO (sub);
278 int i, nregs = hard_regno_nregs[regno][mode];
279 regno += subreg_regno_offset (regno, GET_MODE (sub),
280 ofs, mode);
281 if (nregs > 1)
282 fputs ("[", file);
283 for (i = 0; i < nregs; i++)
285 if (i)
286 fputs (", ", file);
287 if (reg_names[regno+i])
288 fprintf (file, "%s", reg_names[regno + i]);
289 else
290 fprintf (file, "h%d", regno + i);
292 if (nregs > 1)
293 fputs ("]", file);
295 else
297 ra_print_rtx (file, sub, 0);
298 fprintf (file, ":[%s+%d]", GET_MODE_NAME (mode), ofs);
300 break;
302 case SCRATCH: fputs ("scratch", file); break;
303 case CONCAT: ra_print_rtx_2op (file, x); break;
304 case HIGH: ra_print_rtx_1op (file, x); break;
305 case LO_SUM:
306 fputs ("(", file);
307 ra_print_rtx (file, XEXP (x, 0), 0);
308 fputs (" + lo(", file);
309 ra_print_rtx (file, XEXP (x, 1), 0);
310 fputs ("))", file);
311 break;
312 case MEM: fputs ("[", file);
313 ra_print_rtx (file, XEXP (x, 0), 0);
314 fprintf (file, "]:%s", GET_MODE_NAME (GET_MODE (x)));
315 /* XXX print alias set too ?? */
316 break;
317 case LABEL_REF:
319 rtx sub = XEXP (x, 0);
320 if (GET_CODE (sub) == NOTE
321 && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
322 fprintf (file, "(deleted uid=%d)", INSN_UID (sub));
323 else if (GET_CODE (sub) == CODE_LABEL)
324 fprintf (file, "L%d", CODE_LABEL_NUMBER (sub));
325 else
326 fprintf (file, "(nonlabel uid=%d)", INSN_UID (sub));
328 break;
329 case SYMBOL_REF:
330 fprintf (file, "sym(\"%s\")", XSTR (x, 0)); break;
331 case CC0: fputs ("cc0", file); break;
332 default: print_inline_rtx (file, x, 0); break;
336 /* Print a general rtx X to FILE in nice infix form.
337 If WITH_PN is set, and X is one of the toplevel constructs
338 (insns, notes, labels or barriers), then print also the UIDs of
339 the preceding and following insn. */
341 void
342 ra_print_rtx (FILE *file, rtx x, int with_pn)
344 enum rtx_code code;
345 int unhandled = 0;
346 if (!x)
347 return;
348 code = GET_CODE (x);
350 /* First handle the insn like constructs. */
351 if (INSN_P (x) || code == NOTE || code == CODE_LABEL || code == BARRIER)
353 if (INSN_P (x))
354 fputs (" ", file);
355 /* Non-insns are prefixed by a ';'. */
356 if (code == BARRIER)
357 fputs ("; ", file);
358 else if (code == NOTE)
359 /* But notes are indented very far right. */
360 fprintf (file, "\t\t\t\t\t; ");
361 else if (code == CODE_LABEL)
362 /* And labels have their Lxx name first, before the actual UID. */
364 fprintf (file, "L%d:\t; ", CODE_LABEL_NUMBER (x));
365 if (LABEL_NAME (x))
366 fprintf (file, "(%s) ", LABEL_NAME (x));
367 switch (LABEL_KIND (x))
369 case LABEL_NORMAL: break;
370 case LABEL_STATIC_ENTRY: fputs (" (entry)", file); break;
371 case LABEL_GLOBAL_ENTRY: fputs (" (global entry)", file); break;
372 case LABEL_WEAK_ENTRY: fputs (" (weak entry)", file); break;
373 default: abort();
375 fprintf (file, " [%d uses] uid=(", LABEL_NUSES (x));
377 fprintf (file, "%d", INSN_UID (x));
378 if (with_pn)
379 fprintf (file, " %d %d", PREV_INSN (x) ? INSN_UID (PREV_INSN (x)) : 0,
380 NEXT_INSN (x) ? INSN_UID (NEXT_INSN (x)) : 0);
381 if (code == BARRIER)
382 fputs (" -------- barrier ---------", file);
383 else if (code == CODE_LABEL)
384 fputs (")", file);
385 else if (code == NOTE)
387 int ln = NOTE_LINE_NUMBER (x);
388 if (ln >= (int) NOTE_INSN_BIAS && ln < (int) NOTE_INSN_MAX)
389 fprintf (file, " %s", GET_NOTE_INSN_NAME (ln));
390 else
392 fprintf (file, " line %d", ln);
393 if (NOTE_SOURCE_FILE (x))
394 fprintf (file, ":%s", NOTE_SOURCE_FILE (x));
397 else
399 fprintf (file, "\t");
400 ra_print_rtx (file, PATTERN (x), 0);
402 return;
404 switch (code)
406 /* Top-level stuff. */
407 case PARALLEL:
409 int j;
410 for (j = 0; j < XVECLEN (x, 0); j++)
412 if (j)
413 fputs ("\t;; ", file);
414 ra_print_rtx (file, XVECEXP (x, 0, j), 0);
416 break;
418 case UNSPEC: case UNSPEC_VOLATILE:
420 int j;
421 fprintf (file, "unspec%s(%d",
422 (code == UNSPEC) ? "" : "_vol", XINT (x, 1));
423 for (j = 0; j < XVECLEN (x, 0); j++)
425 fputs (", ", file);
426 ra_print_rtx (file, XVECEXP (x, 0, j), 0);
428 fputs (")", file);
429 break;
431 case SET:
432 if (GET_CODE (SET_DEST (x)) == PC)
434 if (GET_CODE (SET_SRC (x)) == IF_THEN_ELSE
435 && GET_CODE (XEXP (SET_SRC(x), 2)) == PC)
437 fputs ("if ", file);
438 ra_print_rtx (file, XEXP (SET_SRC (x), 0), 0);
439 fputs (" jump ", file);
440 ra_print_rtx (file, XEXP (SET_SRC (x), 1), 0);
442 else
444 fputs ("jump ", file);
445 ra_print_rtx (file, SET_SRC (x), 0);
448 else
450 ra_print_rtx (file, SET_DEST (x), 0);
451 fputs (" <= ", file);
452 ra_print_rtx (file, SET_SRC (x), 0);
454 break;
455 case USE:
456 fputs ("use <= ", file);
457 ra_print_rtx (file, XEXP (x, 0), 0);
458 break;
459 case CLOBBER:
460 ra_print_rtx (file, XEXP (x, 0), 0);
461 fputs (" <= clobber", file);
462 break;
463 case CALL:
464 fputs ("call ", file);
465 ra_print_rtx (file, XEXP (x, 0), 0); /* Address */
466 fputs (" numargs=", file);
467 ra_print_rtx (file, XEXP (x, 1), 0); /* Num arguments */
468 break;
469 case RETURN:
470 fputs ("return", file);
471 break;
472 case TRAP_IF:
473 fputs ("if (", file);
474 ra_print_rtx (file, XEXP (x, 0), 0);
475 fputs (") trap ", file);
476 ra_print_rtx (file, XEXP (x, 1), 0);
477 break;
478 case RESX:
479 fprintf (file, "resx from region %d", XINT (x, 0));
480 break;
482 /* Different things of class 'x' */
483 case SUBREG: ra_print_rtx_object (file, x); break;
484 case STRICT_LOW_PART:
485 fputs ("low(", file);
486 ra_print_rtx (file, XEXP (x, 0), 0);
487 fputs (")", file);
488 break;
489 default:
490 unhandled = 1;
491 break;
493 if (!unhandled)
494 return;
495 switch (GET_RTX_CLASS (code))
497 case RTX_UNARY:
498 ra_print_rtx_1op (file, x);
499 case RTX_BIN_ARITH:
500 case RTX_COMM_ARITH:
501 case RTX_COMPARE:
502 case RTX_COMM_COMPARE:
503 ra_print_rtx_2op (file, x);
504 case RTX_TERNARY:
505 case RTX_BITFIELD_OPS:
506 ra_print_rtx_3op (file, x);
507 case RTX_OBJ:
508 case RTX_CONST_OBJ:
509 ra_print_rtx_object (file, x);
510 default:
511 print_inline_rtx (file, x, 0);
515 /* This only calls ra_print_rtx(), but emits a final newline. */
517 void
518 ra_print_rtx_top (FILE *file, rtx x, int with_pn)
520 ra_print_rtx (file, x, with_pn);
521 fprintf (file, "\n");
524 /* Callable from gdb. This prints rtx X onto stderr. */
526 void
527 ra_debug_rtx (rtx x)
529 ra_print_rtx_top (stderr, x, 1);
532 /* This prints the content of basic block with index BBI.
533 The first and last insn are emitted with UIDs of prev and next insns. */
535 void
536 ra_debug_bbi (int bbi)
538 basic_block bb = BASIC_BLOCK (bbi);
539 rtx insn;
540 for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
542 ra_print_rtx_top (stderr, insn,
543 (insn == BB_HEAD (bb) || insn == BB_END (bb)));
544 fprintf (stderr, "\n");
545 if (insn == BB_END (bb))
546 break;
550 /* Beginning from INSN, emit NUM insns (if NUM is non-negative)
551 or emit a window of NUM insns around INSN, to stderr. */
553 void
554 ra_debug_insns (rtx insn, int num)
556 int i, count = (num == 0 ? 1 : num < 0 ? -num : num);
557 if (num < 0)
558 for (i = count / 2; i > 0 && PREV_INSN (insn); i--)
559 insn = PREV_INSN (insn);
560 for (i = count; i > 0 && insn; insn = NEXT_INSN (insn), i--)
562 if (GET_CODE (insn) == CODE_LABEL)
563 fprintf (stderr, "\n");
564 ra_print_rtx_top (stderr, insn, (i == count || i == 1));
568 /* Beginning with INSN, emit the whole insn chain into FILE.
569 This also outputs comments when basic blocks start or end and omits
570 some notes, if flag_ra_dump_notes is zero. */
572 void
573 ra_print_rtl_with_bb (FILE *file, rtx insn)
575 basic_block last_bb, bb;
576 unsigned int num = 0;
577 if (!insn)
578 fputs ("nil", file);
579 last_bb = NULL;
580 for (; insn; insn = NEXT_INSN (insn))
582 if (GET_CODE (insn) == BARRIER)
583 bb = NULL;
584 else
585 bb = BLOCK_FOR_INSN (insn);
586 if (bb != last_bb)
588 if (last_bb)
589 fprintf (file, ";; End of basic block %d\n", last_bb->index);
590 if (bb)
591 fprintf (file, ";; Begin of basic block %d\n", bb->index);
592 last_bb = bb;
594 if (GET_CODE (insn) == CODE_LABEL)
595 fputc ('\n', file);
596 if (GET_CODE (insn) == NOTE)
598 /* Ignore basic block and maybe other notes not referencing
599 deleted things. */
600 if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
601 && (flag_ra_dump_notes
602 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
603 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
605 ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn)));
606 num++;
609 else
611 ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn)));
612 num++;
617 /* Count how many insns were seen how often, while building the interference
618 graph, and prints the findings. */
620 void
621 dump_number_seen (void)
623 #define N 17
624 int num[N];
625 int i;
627 for (i = 0; i < N; i++)
628 num[i] = 0;
629 for (i = 0; i < get_max_uid (); i++)
630 if (number_seen[i] < N - 1)
631 num[number_seen[i]]++;
632 else
633 num[N - 1]++;
634 for (i = 0; i < N - 1; i++)
635 if (num[i])
636 ra_debug_msg (DUMP_PROCESS, "%d insns seen %d times\n", num[i], i);
637 if (num[N - 1])
638 ra_debug_msg (DUMP_PROCESS, "%d insns seen %d and more times\n", num[i],
639 N - 1);
640 ra_debug_msg (DUMP_PROCESS, "from overall %d insns\n", get_max_uid ());
641 #undef N
644 /* Dump the interference graph, the move list and the webs. */
646 void
647 dump_igraph (struct df *df ATTRIBUTE_UNUSED)
649 struct move_list *ml;
650 unsigned int def1, def2;
651 int num = 0;
652 int num2;
653 unsigned int i;
654 if (!dump_file || (debug_new_regalloc & (DUMP_IGRAPH | DUMP_WEBS)) == 0)
655 return;
656 ra_debug_msg (DUMP_IGRAPH, "conflicts:\n ");
657 for (def1 = 0; def1 < num_webs; def1++)
659 int num1 = num;
660 num2 = 0;
661 for (def2 = 0; def2 < num_webs; def2++)
662 if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2)))
664 if (num1 == num)
666 if (SUBWEB_P (ID2WEB (def1)))
667 ra_debug_msg (DUMP_IGRAPH, "%d (SUBREG %d, %d) with ", def1,
668 ID2WEB (def1)->regno,
669 SUBREG_BYTE (ID2WEB (def1)->orig_x));
670 else
671 ra_debug_msg (DUMP_IGRAPH, "%d (REG %d) with ", def1,
672 ID2WEB (def1)->regno);
674 if ((num2 % 9) == 8)
675 ra_debug_msg (DUMP_IGRAPH, "\n ");
676 num++;
677 num2++;
678 if (SUBWEB_P (ID2WEB (def2)))
679 ra_debug_msg (DUMP_IGRAPH, "%d(%d,%d) ", def2, ID2WEB (def2)->regno,
680 SUBREG_BYTE (ID2WEB (def2)->orig_x));
681 else
682 ra_debug_msg (DUMP_IGRAPH, "%d(%d) ", def2, ID2WEB (def2)->regno);
684 if (num1 != num)
685 ra_debug_msg (DUMP_IGRAPH, "\n ");
687 ra_debug_msg (DUMP_IGRAPH, "\n");
688 for (ml = wl_moves; ml; ml = ml->next)
689 if (ml->move)
691 ra_debug_msg (DUMP_IGRAPH, "move: insn %d: Web %d <-- Web %d\n",
692 INSN_UID (ml->move->insn), ml->move->target_web->id,
693 ml->move->source_web->id);
695 ra_debug_msg (DUMP_WEBS, "\nWebs:\n");
696 for (i = 0; i < num_webs; i++)
698 struct web *web = ID2WEB (i);
700 ra_debug_msg (DUMP_WEBS, " %4d : regno %3d", i, web->regno);
701 if (SUBWEB_P (web))
703 ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x));
704 ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id);
706 ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost "
707 HOST_WIDE_INT_PRINT_DEC ") (%s)",
708 web->add_hardregs, web->span_deaths, web->spill_cost,
709 reg_class_names[web->regclass]);
710 if (web->spill_temp == 1)
711 ra_debug_msg (DUMP_WEBS, " (spilltemp)");
712 else if (web->spill_temp == 2)
713 ra_debug_msg (DUMP_WEBS, " (spilltem2)");
714 else if (web->spill_temp == 3)
715 ra_debug_msg (DUMP_WEBS, " (short)");
716 if (web->type == PRECOLORED)
717 ra_debug_msg (DUMP_WEBS, " (precolored, color=%d)", web->color);
718 else if (find_web_for_subweb (web)->num_uses == 0)
719 ra_debug_msg (DUMP_WEBS, " dead");
720 if (web->crosses_call)
721 ra_debug_msg (DUMP_WEBS, " xcall");
722 if (web->regno >= max_normal_pseudo)
723 ra_debug_msg (DUMP_WEBS, " stack");
724 ra_debug_msg (DUMP_WEBS, "\n");
728 /* Dump the interference graph and webs in a format easily
729 parsable by programs. Used to emit real world interference graph
730 to my custom graph colorizer. */
732 void
733 dump_igraph_machine (void)
735 unsigned int i;
737 if (!dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0)
738 return;
739 ra_debug_msg (DUMP_IGRAPH_M, "g %d %d\n", num_webs - num_subwebs,
740 FIRST_PSEUDO_REGISTER);
741 for (i = 0; i < num_webs - num_subwebs; i++)
743 struct web *web = ID2WEB (i);
744 struct conflict_link *cl;
745 int flags = 0;
746 int numc = 0;
747 int col = 0;
748 flags = web->spill_temp & 0xF;
749 flags |= ((web->type == PRECOLORED) ? 1 : 0) << 4;
750 flags |= (web->add_hardregs & 0xF) << 5;
751 for (cl = web->conflict_list; cl; cl = cl->next)
752 if (cl->t->id < web->id)
753 numc++;
754 ra_debug_msg (DUMP_IGRAPH_M, "n %d %d %d %d %d %d %d\n",
755 web->id, web->color, flags,
756 (unsigned int)web->spill_cost, web->num_defs, web->num_uses,
757 numc);
758 if (web->type != PRECOLORED)
760 ra_debug_msg (DUMP_IGRAPH_M, "s %d", web->id);
761 while (1)
763 unsigned int u = 0;
764 int n;
765 for (n = 0; n < 32 && col < FIRST_PSEUDO_REGISTER; n++, col++)
766 if (TEST_HARD_REG_BIT (web->usable_regs, col))
767 u |= 1 << n;
768 ra_debug_msg (DUMP_IGRAPH_M, " %u", u);
769 if (col >= FIRST_PSEUDO_REGISTER)
770 break;
772 ra_debug_msg (DUMP_IGRAPH_M, "\n");
774 if (numc)
776 ra_debug_msg (DUMP_IGRAPH_M, "c %d", web->id);
777 for (cl = web->conflict_list; cl; cl = cl->next)
779 if (cl->t->id < web->id)
780 ra_debug_msg (DUMP_IGRAPH_M, " %d", cl->t->id);
782 ra_debug_msg (DUMP_IGRAPH_M, "\n");
785 ra_debug_msg (DUMP_IGRAPH_M, "e\n");
788 /* This runs after colorization and changing the insn stream.
789 It temporarily replaces all pseudo registers with their colors,
790 and emits information, if the resulting insns are strictly valid. */
792 void
793 dump_constraints (void)
795 rtx insn;
796 int i;
797 if (!dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0)
798 return;
799 for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++)
800 if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG)
801 REGNO (regno_reg_rtx[i])
802 = ra_reg_renumber[i] >= 0 ? ra_reg_renumber[i] : i;
803 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
804 if (INSN_P (insn))
806 int code;
807 int uid = INSN_UID (insn);
808 int o;
809 /* Don't simply force rerecognition, as combine might left us
810 with some unrecognizable ones, which later leads to aborts
811 in regclass, if we now destroy the remembered INSN_CODE(). */
812 /*INSN_CODE (insn) = -1;*/
813 code = recog_memoized (insn);
814 if (code < 0)
816 ra_debug_msg (DUMP_CONSTRAINTS,
817 "%d: asm insn or not recognizable.\n", uid);
818 continue;
820 ra_debug_msg (DUMP_CONSTRAINTS,
821 "%d: code %d {%s}, %d operands, constraints: ",
822 uid, code, insn_data[code].name, recog_data.n_operands);
823 extract_insn (insn);
824 /*preprocess_constraints ();*/
825 for (o = 0; o < recog_data.n_operands; o++)
827 ra_debug_msg (DUMP_CONSTRAINTS,
828 "%d:%s ", o, recog_data.constraints[o]);
830 if (constrain_operands (1))
831 ra_debug_msg (DUMP_CONSTRAINTS, "matches strictly alternative %d",
832 which_alternative);
833 else
834 ra_debug_msg (DUMP_CONSTRAINTS, "doesn't match strictly");
835 ra_debug_msg (DUMP_CONSTRAINTS, "\n");
837 for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++)
838 if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG)
839 REGNO (regno_reg_rtx[i]) = i;
842 /* This counts and emits the cumulated cost of all spilled webs,
843 preceded by a custom message MSG, with debug level LEVEL. */
845 void
846 dump_graph_cost (unsigned int level, const char *msg)
848 unsigned int i;
849 unsigned HOST_WIDE_INT cost;
850 if (!dump_file || (debug_new_regalloc & level) == 0)
851 return;
853 cost = 0;
854 for (i = 0; i < num_webs; i++)
856 struct web *web = id2web[i];
857 if (alias (web)->type == SPILLED)
858 cost += web->orig_spill_cost;
860 ra_debug_msg (level, " spill cost of graph (%s) = "
861 HOST_WIDE_INT_PRINT_UNSIGNED "\n",
862 msg ? msg : "", cost);
865 /* Dump the color assignment per web, the coalesced and spilled webs. */
867 void
868 dump_ra (struct df *df ATTRIBUTE_UNUSED)
870 struct web *web;
871 struct dlist *d;
872 if (!dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0)
873 return;
875 ra_debug_msg (DUMP_RESULTS, "\nColored:\n");
876 for (d = WEBS(COLORED); d; d = d->next)
878 web = DLIST_WEB (d);
879 ra_debug_msg (DUMP_RESULTS, " %4d : color %d\n", web->id, web->color);
881 ra_debug_msg (DUMP_RESULTS, "\nCoalesced:\n");
882 for (d = WEBS(COALESCED); d; d = d->next)
884 web = DLIST_WEB (d);
885 ra_debug_msg (DUMP_RESULTS, " %4d : to web %d, color %d\n", web->id,
886 alias (web)->id, web->color);
888 ra_debug_msg (DUMP_RESULTS, "\nSpilled:\n");
889 for (d = WEBS(SPILLED); d; d = d->next)
891 web = DLIST_WEB (d);
892 ra_debug_msg (DUMP_RESULTS, " %4d\n", web->id);
894 ra_debug_msg (DUMP_RESULTS, "\n");
895 dump_cost (DUMP_RESULTS);
898 /* Calculate and dump the cumulated costs of certain types of insns
899 (loads, stores and copies). */
901 void
902 dump_static_insn_cost (FILE *file, const char *message, const char *prefix)
904 struct cost
906 unsigned HOST_WIDE_INT cost;
907 unsigned int count;
909 basic_block bb;
910 struct cost load, store, regcopy, selfcopy, overall;
911 memset (&load, 0, sizeof(load));
912 memset (&store, 0, sizeof(store));
913 memset (&regcopy, 0, sizeof(regcopy));
914 memset (&selfcopy, 0, sizeof(selfcopy));
915 memset (&overall, 0, sizeof(overall));
917 if (!file)
918 return;
920 FOR_EACH_BB (bb)
922 unsigned HOST_WIDE_INT block_cost = bb->frequency;
923 rtx insn, set;
924 for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn))
926 /* Yes, yes. We don't calculate the costs precisely.
927 Only for "simple enough" insns. Those containing single
928 sets only. */
929 if (INSN_P (insn) && ((set = single_set (insn)) != NULL))
931 rtx src = SET_SRC (set);
932 rtx dest = SET_DEST (set);
933 struct cost *pcost = NULL;
934 overall.cost += block_cost;
935 overall.count++;
936 if (rtx_equal_p (src, dest))
937 pcost = &selfcopy;
938 else if (GET_CODE (src) == GET_CODE (dest)
939 && ((GET_CODE (src) == REG)
940 || (GET_CODE (src) == SUBREG
941 && GET_CODE (SUBREG_REG (src)) == REG
942 && GET_CODE (SUBREG_REG (dest)) == REG)))
943 pcost = &regcopy;
944 else
946 if (GET_CODE (src) == SUBREG)
947 src = SUBREG_REG (src);
948 if (GET_CODE (dest) == SUBREG)
949 dest = SUBREG_REG (dest);
950 if (GET_CODE (src) == MEM && GET_CODE (dest) != MEM
951 && memref_is_stack_slot (src))
952 pcost = &load;
953 else if (GET_CODE (src) != MEM && GET_CODE (dest) == MEM
954 && memref_is_stack_slot (dest))
955 pcost = &store;
957 if (pcost)
959 pcost->cost += block_cost;
960 pcost->count++;
963 if (insn == BB_END (bb))
964 break;
968 if (!prefix)
969 prefix = "";
970 fprintf (file, "static insn cost %s\n", message ? message : "");
971 fprintf (file, " %soverall:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
972 prefix, overall.count, overall.cost);
973 fprintf (file, " %sloads:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
974 prefix, load.count, load.cost);
975 fprintf (file, " %sstores:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
976 prefix, store.count, store.cost);
977 fprintf (file, " %sregcopy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
978 prefix, regcopy.count, regcopy.cost);
979 fprintf (file, " %sselfcpy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n",
980 prefix, selfcopy.count, selfcopy.cost);
983 /* Returns nonzero, if WEB1 and WEB2 have some possible
984 hardregs in common. */
987 web_conflicts_p (struct web *web1, struct web *web2)
989 if (web1->type == PRECOLORED && web2->type == PRECOLORED)
990 return 0;
992 if (web1->type == PRECOLORED)
993 return TEST_HARD_REG_BIT (web2->usable_regs, web1->regno);
995 if (web2->type == PRECOLORED)
996 return TEST_HARD_REG_BIT (web1->usable_regs, web2->regno);
998 return hard_regs_intersect_p (&web1->usable_regs, &web2->usable_regs);
1001 /* Dump all uids of insns in which WEB is mentioned. */
1003 void
1004 dump_web_insns (struct web *web)
1006 unsigned int i;
1008 ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
1009 web->id, web->regno, web->add_hardregs,
1010 reg_class_names[web->regclass],
1011 web->num_freedom, web->num_conflicts);
1012 ra_debug_msg (DUMP_EVER, " def insns:");
1014 for (i = 0; i < web->num_defs; ++i)
1016 ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn));
1019 ra_debug_msg (DUMP_EVER, "\n use insns:");
1020 for (i = 0; i < web->num_uses; ++i)
1022 ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn));
1024 ra_debug_msg (DUMP_EVER, "\n");
1027 /* Dump conflicts for web WEB. */
1029 void
1030 dump_web_conflicts (struct web *web)
1032 int num = 0;
1033 unsigned int def2;
1035 ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
1036 web->id, web->regno, web->add_hardregs,
1037 reg_class_names[web->regclass],
1038 web->num_freedom, web->num_conflicts);
1040 for (def2 = 0; def2 < num_webs; def2++)
1041 if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2)
1043 if ((num % 9) == 5)
1044 ra_debug_msg (DUMP_EVER, "\n ");
1045 num++;
1047 ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno);
1048 if (id2web[def2]->add_hardregs)
1049 ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs);
1051 if (web_conflicts_p (web, id2web[def2]))
1052 ra_debug_msg (DUMP_EVER, "/x");
1054 if (id2web[def2]->type == SELECT)
1055 ra_debug_msg (DUMP_EVER, "/s");
1057 if (id2web[def2]->type == COALESCED)
1058 ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id);
1060 ra_debug_msg (DUMP_EVER, "\n");
1062 struct conflict_link *wl;
1063 num = 0;
1064 ra_debug_msg (DUMP_EVER, "By conflicts: ");
1065 for (wl = web->conflict_list; wl; wl = wl->next)
1067 struct web* w = wl->t;
1068 if ((num % 9) == 8)
1069 ra_debug_msg (DUMP_EVER, "\n ");
1070 num++;
1071 ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno,
1072 web_conflicts_p (web, w) ? "+" : "");
1074 ra_debug_msg (DUMP_EVER, "\n");
1078 /* Output HARD_REG_SET to stderr. */
1080 void
1081 debug_hard_reg_set (HARD_REG_SET set)
1083 int i;
1084 for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i)
1086 if (TEST_HARD_REG_BIT (set, i))
1088 fprintf (stderr, "%s ", reg_names[i]);
1091 fprintf (stderr, "\n");
1095 vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: