]>
Commit | Line | Data |
---|---|---|
ed8d2920 | 1 | /* Graph coloring register allocator |
ec8e098d | 2 | Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc. |
ed8d2920 MM |
3 | Contributed by Michael Matz <matz@suse.de> |
4 | and Daniel Berlin <dan@cgsoftware.com>. | |
5 | ||
6 | This file is part of GCC. | |
7 | ||
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. | |
11 | ||
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. | |
16 | ||
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. */ | |
20 | ||
21 | #include "config.h" | |
22 | #include "system.h" | |
4977bab6 ZW |
23 | #include "coretypes.h" |
24 | #include "tm.h" | |
ed8d2920 MM |
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" | |
a6be5aee | 34 | #include "tm_p.h" |
66fd46b6 | 35 | #include "regs.h" |
ed8d2920 MM |
36 | |
37 | /* This file contains various dumping and debug functions for | |
38 | the graph coloring register allocator. */ | |
39 | ||
93bad80e SB |
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); | |
ed8d2920 MM |
44 | |
45 | /* The hardregs as names, for debugging. */ | |
46 | static const char *const reg_class_names[] = REG_CLASS_NAMES; | |
47 | ||
48 | /* Print a message to the dump file, if debug_new_regalloc and LEVEL | |
49 | have any bits in common. */ | |
50 | ||
51 | void | |
e34d07f2 | 52 | ra_debug_msg (unsigned int level, const char *format, ...) |
ed8d2920 | 53 | { |
e34d07f2 KG |
54 | va_list ap; |
55 | ||
56 | va_start (ap, format); | |
c263766c RH |
57 | if ((debug_new_regalloc & level) != 0 && dump_file != NULL) |
58 | vfprintf (dump_file, format, ap); | |
e34d07f2 | 59 | va_end (ap); |
ed8d2920 MM |
60 | } |
61 | ||
62 | ||
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. */ | |
69 | ||
70 | /* Print rtx X, which is a one operand rtx (op:mode (Y)), as | |
71 | "op(Y)" to FILE. */ | |
72 | ||
73 | static void | |
93bad80e | 74 | ra_print_rtx_1op (FILE *file, rtx x) |
ed8d2920 MM |
75 | { |
76 | enum rtx_code code = GET_CODE (x); | |
77 | rtx op0 = XEXP (x, 0); | |
78 | switch (code) | |
79 | { | |
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; | |
100 | } | |
101 | } | |
102 | ||
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. */ | |
106 | ||
107 | static void | |
93bad80e | 108 | ra_print_rtx_2op (FILE *file, rtx x) |
ed8d2920 MM |
109 | { |
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) | |
116 | { | |
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; | |
ec8e098d | 133 | /* class '=' */ |
ed8d2920 MM |
134 | case NE: opname = "!="; break; |
135 | case EQ: opname = "=="; break; | |
ec8e098d PB |
136 | case LTGT: opname = "<>"; break; |
137 | /* class '<' */ | |
ed8d2920 MM |
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; | |
150 | } | |
151 | if (infix) | |
152 | { | |
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); | |
158 | } | |
159 | else | |
160 | { | |
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); | |
166 | } | |
167 | } | |
168 | ||
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. */ | |
171 | ||
172 | static void | |
93bad80e | 173 | ra_print_rtx_3op (FILE *file, rtx x) |
ed8d2920 MM |
174 | { |
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) | |
180 | { | |
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); | |
186 | } | |
187 | else | |
188 | { | |
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); | |
198 | } | |
199 | } | |
200 | ||
ec8e098d | 201 | /* Print rtx X, which represents an object (class 'o', 'C', or some constructs |
ed8d2920 MM |
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. */ | |
206 | ||
207 | static void | |
93bad80e | 208 | ra_print_rtx_object (FILE *file, rtx x) |
ed8d2920 MM |
209 | { |
210 | enum rtx_code code = GET_CODE (x); | |
211 | enum machine_mode mode = GET_MODE (x); | |
212 | switch (code) | |
213 | { | |
214 | case CONST_INT: | |
215 | fprintf (file, HOST_WIDE_INT_PRINT_DEC, XWINT (x, 0)); | |
216 | break; | |
217 | case CONST_DOUBLE: | |
218 | { | |
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++) | |
223 | { | |
224 | if (num) | |
225 | fputs (", ", file); | |
226 | if (fmt[i] == 'e' && XEXP (x, i)) | |
227 | /* The MEM or other stuff */ | |
228 | { | |
229 | ra_print_rtx (file, XEXP (x, i), 0); | |
230 | num++; | |
231 | } | |
232 | else if (fmt[i] == 'w') | |
233 | { | |
234 | fprintf (file, HOST_WIDE_INT_PRINT_HEX, XWINT (x, i)); | |
235 | num++; | |
236 | } | |
237 | } | |
238 | break; | |
239 | } | |
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: | |
247 | { | |
248 | int regno = REGNO (x); | |
249 | if (regno < FIRST_PSEUDO_REGISTER) | |
250 | { | |
66fd46b6 | 251 | int i, nregs = hard_regno_nregs[regno][mode]; |
ed8d2920 MM |
252 | if (nregs > 1) |
253 | fputs ("[", file); | |
254 | for (i = 0; i < nregs; i++) | |
255 | { | |
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); | |
262 | } | |
263 | if (nregs > 1) | |
264 | fputs ("]", file); | |
265 | } | |
266 | else | |
267 | fprintf (file, "p%d", regno); | |
268 | break; | |
269 | } | |
270 | case SUBREG: | |
271 | { | |
272 | rtx sub = SUBREG_REG (x); | |
273 | int ofs = SUBREG_BYTE (x); | |
f8cfc6aa | 274 | if (REG_P (sub) |
ed8d2920 MM |
275 | && REGNO (sub) < FIRST_PSEUDO_REGISTER) |
276 | { | |
277 | int regno = REGNO (sub); | |
66fd46b6 | 278 | int i, nregs = hard_regno_nregs[regno][mode]; |
ed8d2920 MM |
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++) | |
284 | { | |
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); | |
291 | } | |
292 | if (nregs > 1) | |
293 | fputs ("]", file); | |
294 | } | |
295 | else | |
296 | { | |
297 | ra_print_rtx (file, sub, 0); | |
298 | fprintf (file, ":[%s+%d]", GET_MODE_NAME (mode), ofs); | |
299 | } | |
300 | break; | |
301 | } | |
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: | |
318 | { | |
319 | rtx sub = XEXP (x, 0); | |
4b4bf941 | 320 | if (NOTE_P (sub) |
ed8d2920 MM |
321 | && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL) |
322 | fprintf (file, "(deleted uid=%d)", INSN_UID (sub)); | |
4b4bf941 | 323 | else if (LABEL_P (sub)) |
ed8d2920 MM |
324 | fprintf (file, "L%d", CODE_LABEL_NUMBER (sub)); |
325 | else | |
326 | fprintf (file, "(nonlabel uid=%d)", INSN_UID (sub)); | |
327 | } | |
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; | |
333 | } | |
334 | } | |
335 | ||
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. */ | |
340 | ||
341 | void | |
93bad80e | 342 | ra_print_rtx (FILE *file, rtx x, int with_pn) |
ed8d2920 MM |
343 | { |
344 | enum rtx_code code; | |
ed8d2920 MM |
345 | int unhandled = 0; |
346 | if (!x) | |
347 | return; | |
348 | code = GET_CODE (x); | |
ed8d2920 MM |
349 | |
350 | /* First handle the insn like constructs. */ | |
351 | if (INSN_P (x) || code == NOTE || code == CODE_LABEL || code == BARRIER) | |
352 | { | |
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. */ | |
363 | { | |
364 | fprintf (file, "L%d:\t; ", CODE_LABEL_NUMBER (x)); | |
365 | if (LABEL_NAME (x)) | |
366 | fprintf (file, "(%s) ", LABEL_NAME (x)); | |
0dc36574 ZW |
367 | switch (LABEL_KIND (x)) |
368 | { | |
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(); | |
374 | } | |
ed8d2920 MM |
375 | fprintf (file, " [%d uses] uid=(", LABEL_NUSES (x)); |
376 | } | |
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) | |
386 | { | |
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 | |
391 | { | |
9506ac2b PB |
392 | expanded_location s; |
393 | NOTE_EXPANDED_LOCATION (s, x); | |
394 | fprintf (file, " line %d", s.line); | |
395 | if (s.file != NULL) | |
396 | fprintf (file, ":%s", s.file); | |
ed8d2920 MM |
397 | } |
398 | } | |
399 | else | |
400 | { | |
401 | fprintf (file, "\t"); | |
402 | ra_print_rtx (file, PATTERN (x), 0); | |
403 | } | |
404 | return; | |
405 | } | |
406 | switch (code) | |
407 | { | |
408 | /* Top-level stuff. */ | |
409 | case PARALLEL: | |
410 | { | |
411 | int j; | |
412 | for (j = 0; j < XVECLEN (x, 0); j++) | |
413 | { | |
414 | if (j) | |
415 | fputs ("\t;; ", file); | |
416 | ra_print_rtx (file, XVECEXP (x, 0, j), 0); | |
417 | } | |
418 | break; | |
419 | } | |
420 | case UNSPEC: case UNSPEC_VOLATILE: | |
421 | { | |
422 | int j; | |
423 | fprintf (file, "unspec%s(%d", | |
424 | (code == UNSPEC) ? "" : "_vol", XINT (x, 1)); | |
425 | for (j = 0; j < XVECLEN (x, 0); j++) | |
426 | { | |
427 | fputs (", ", file); | |
428 | ra_print_rtx (file, XVECEXP (x, 0, j), 0); | |
429 | } | |
430 | fputs (")", file); | |
431 | break; | |
432 | } | |
433 | case SET: | |
434 | if (GET_CODE (SET_DEST (x)) == PC) | |
435 | { | |
436 | if (GET_CODE (SET_SRC (x)) == IF_THEN_ELSE | |
437 | && GET_CODE (XEXP (SET_SRC(x), 2)) == PC) | |
438 | { | |
439 | fputs ("if ", file); | |
440 | ra_print_rtx (file, XEXP (SET_SRC (x), 0), 0); | |
441 | fputs (" jump ", file); | |
442 | ra_print_rtx (file, XEXP (SET_SRC (x), 1), 0); | |
443 | } | |
444 | else | |
445 | { | |
446 | fputs ("jump ", file); | |
447 | ra_print_rtx (file, SET_SRC (x), 0); | |
448 | } | |
449 | } | |
450 | else | |
451 | { | |
452 | ra_print_rtx (file, SET_DEST (x), 0); | |
453 | fputs (" <= ", file); | |
454 | ra_print_rtx (file, SET_SRC (x), 0); | |
455 | } | |
456 | break; | |
457 | case USE: | |
458 | fputs ("use <= ", file); | |
459 | ra_print_rtx (file, XEXP (x, 0), 0); | |
460 | break; | |
461 | case CLOBBER: | |
462 | ra_print_rtx (file, XEXP (x, 0), 0); | |
463 | fputs (" <= clobber", file); | |
464 | break; | |
465 | case CALL: | |
466 | fputs ("call ", file); | |
467 | ra_print_rtx (file, XEXP (x, 0), 0); /* Address */ | |
468 | fputs (" numargs=", file); | |
469 | ra_print_rtx (file, XEXP (x, 1), 0); /* Num arguments */ | |
470 | break; | |
471 | case RETURN: | |
472 | fputs ("return", file); | |
473 | break; | |
474 | case TRAP_IF: | |
475 | fputs ("if (", file); | |
476 | ra_print_rtx (file, XEXP (x, 0), 0); | |
477 | fputs (") trap ", file); | |
478 | ra_print_rtx (file, XEXP (x, 1), 0); | |
479 | break; | |
480 | case RESX: | |
481 | fprintf (file, "resx from region %d", XINT (x, 0)); | |
482 | break; | |
483 | ||
484 | /* Different things of class 'x' */ | |
485 | case SUBREG: ra_print_rtx_object (file, x); break; | |
486 | case STRICT_LOW_PART: | |
487 | fputs ("low(", file); | |
488 | ra_print_rtx (file, XEXP (x, 0), 0); | |
489 | fputs (")", file); | |
490 | break; | |
491 | default: | |
492 | unhandled = 1; | |
493 | break; | |
494 | } | |
495 | if (!unhandled) | |
496 | return; | |
ec8e098d PB |
497 | switch (GET_RTX_CLASS (code)) |
498 | { | |
499 | case RTX_UNARY: | |
c87fbb0a PH |
500 | ra_print_rtx_1op (file, x); |
501 | break; | |
ec8e098d PB |
502 | case RTX_BIN_ARITH: |
503 | case RTX_COMM_ARITH: | |
504 | case RTX_COMPARE: | |
505 | case RTX_COMM_COMPARE: | |
c87fbb0a PH |
506 | ra_print_rtx_2op (file, x); |
507 | break; | |
ec8e098d PB |
508 | case RTX_TERNARY: |
509 | case RTX_BITFIELD_OPS: | |
c87fbb0a PH |
510 | ra_print_rtx_3op (file, x); |
511 | break; | |
ec8e098d PB |
512 | case RTX_OBJ: |
513 | case RTX_CONST_OBJ: | |
c87fbb0a PH |
514 | ra_print_rtx_object (file, x); |
515 | break; | |
ec8e098d | 516 | default: |
c87fbb0a PH |
517 | print_inline_rtx (file, x, 0); |
518 | break; | |
ec8e098d | 519 | } |
ed8d2920 MM |
520 | } |
521 | ||
522 | /* This only calls ra_print_rtx(), but emits a final newline. */ | |
523 | ||
524 | void | |
93bad80e | 525 | ra_print_rtx_top (FILE *file, rtx x, int with_pn) |
ed8d2920 MM |
526 | { |
527 | ra_print_rtx (file, x, with_pn); | |
528 | fprintf (file, "\n"); | |
529 | } | |
530 | ||
531 | /* Callable from gdb. This prints rtx X onto stderr. */ | |
532 | ||
533 | void | |
93bad80e | 534 | ra_debug_rtx (rtx x) |
ed8d2920 MM |
535 | { |
536 | ra_print_rtx_top (stderr, x, 1); | |
537 | } | |
538 | ||
539 | /* This prints the content of basic block with index BBI. | |
540 | The first and last insn are emitted with UIDs of prev and next insns. */ | |
541 | ||
542 | void | |
93bad80e | 543 | ra_debug_bbi (int bbi) |
ed8d2920 MM |
544 | { |
545 | basic_block bb = BASIC_BLOCK (bbi); | |
546 | rtx insn; | |
a813c111 | 547 | for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn)) |
ed8d2920 | 548 | { |
a813c111 SB |
549 | ra_print_rtx_top (stderr, insn, |
550 | (insn == BB_HEAD (bb) || insn == BB_END (bb))); | |
ed8d2920 | 551 | fprintf (stderr, "\n"); |
a813c111 | 552 | if (insn == BB_END (bb)) |
ed8d2920 MM |
553 | break; |
554 | } | |
555 | } | |
556 | ||
557 | /* Beginning from INSN, emit NUM insns (if NUM is non-negative) | |
558 | or emit a window of NUM insns around INSN, to stderr. */ | |
559 | ||
560 | void | |
93bad80e | 561 | ra_debug_insns (rtx insn, int num) |
ed8d2920 MM |
562 | { |
563 | int i, count = (num == 0 ? 1 : num < 0 ? -num : num); | |
564 | if (num < 0) | |
565 | for (i = count / 2; i > 0 && PREV_INSN (insn); i--) | |
566 | insn = PREV_INSN (insn); | |
567 | for (i = count; i > 0 && insn; insn = NEXT_INSN (insn), i--) | |
568 | { | |
4b4bf941 | 569 | if (LABEL_P (insn)) |
ed8d2920 MM |
570 | fprintf (stderr, "\n"); |
571 | ra_print_rtx_top (stderr, insn, (i == count || i == 1)); | |
572 | } | |
573 | } | |
574 | ||
575 | /* Beginning with INSN, emit the whole insn chain into FILE. | |
576 | This also outputs comments when basic blocks start or end and omits | |
577 | some notes, if flag_ra_dump_notes is zero. */ | |
578 | ||
579 | void | |
93bad80e | 580 | ra_print_rtl_with_bb (FILE *file, rtx insn) |
ed8d2920 MM |
581 | { |
582 | basic_block last_bb, bb; | |
583 | unsigned int num = 0; | |
584 | if (!insn) | |
585 | fputs ("nil", file); | |
586 | last_bb = NULL; | |
587 | for (; insn; insn = NEXT_INSN (insn)) | |
588 | { | |
4b4bf941 | 589 | if (BARRIER_P (insn)) |
ed8d2920 MM |
590 | bb = NULL; |
591 | else | |
592 | bb = BLOCK_FOR_INSN (insn); | |
593 | if (bb != last_bb) | |
594 | { | |
595 | if (last_bb) | |
596 | fprintf (file, ";; End of basic block %d\n", last_bb->index); | |
597 | if (bb) | |
598 | fprintf (file, ";; Begin of basic block %d\n", bb->index); | |
599 | last_bb = bb; | |
600 | } | |
4b4bf941 | 601 | if (LABEL_P (insn)) |
ed8d2920 | 602 | fputc ('\n', file); |
4b4bf941 | 603 | if (NOTE_P (insn)) |
ed8d2920 MM |
604 | { |
605 | /* Ignore basic block and maybe other notes not referencing | |
606 | deleted things. */ | |
607 | if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK | |
608 | && (flag_ra_dump_notes | |
609 | || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED | |
610 | || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)) | |
611 | { | |
612 | ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); | |
613 | num++; | |
614 | } | |
615 | } | |
616 | else | |
617 | { | |
618 | ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); | |
619 | num++; | |
620 | } | |
621 | } | |
622 | } | |
623 | ||
624 | /* Count how many insns were seen how often, while building the interference | |
625 | graph, and prints the findings. */ | |
626 | ||
627 | void | |
93bad80e | 628 | dump_number_seen (void) |
ed8d2920 MM |
629 | { |
630 | #define N 17 | |
631 | int num[N]; | |
632 | int i; | |
633 | ||
634 | for (i = 0; i < N; i++) | |
635 | num[i] = 0; | |
636 | for (i = 0; i < get_max_uid (); i++) | |
637 | if (number_seen[i] < N - 1) | |
638 | num[number_seen[i]]++; | |
639 | else | |
640 | num[N - 1]++; | |
641 | for (i = 0; i < N - 1; i++) | |
642 | if (num[i]) | |
643 | ra_debug_msg (DUMP_PROCESS, "%d insns seen %d times\n", num[i], i); | |
644 | if (num[N - 1]) | |
645 | ra_debug_msg (DUMP_PROCESS, "%d insns seen %d and more times\n", num[i], | |
646 | N - 1); | |
647 | ra_debug_msg (DUMP_PROCESS, "from overall %d insns\n", get_max_uid ()); | |
648 | #undef N | |
649 | } | |
650 | ||
651 | /* Dump the interference graph, the move list and the webs. */ | |
652 | ||
653 | void | |
93bad80e | 654 | dump_igraph (struct df *df ATTRIBUTE_UNUSED) |
ed8d2920 MM |
655 | { |
656 | struct move_list *ml; | |
657 | unsigned int def1, def2; | |
658 | int num = 0; | |
659 | int num2; | |
660 | unsigned int i; | |
c263766c | 661 | if (!dump_file || (debug_new_regalloc & (DUMP_IGRAPH | DUMP_WEBS)) == 0) |
ed8d2920 MM |
662 | return; |
663 | ra_debug_msg (DUMP_IGRAPH, "conflicts:\n "); | |
664 | for (def1 = 0; def1 < num_webs; def1++) | |
665 | { | |
666 | int num1 = num; | |
6a87d634 RS |
667 | num2 = 0; |
668 | for (def2 = 0; def2 < num_webs; def2++) | |
ed8d2920 MM |
669 | if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2))) |
670 | { | |
671 | if (num1 == num) | |
672 | { | |
673 | if (SUBWEB_P (ID2WEB (def1))) | |
674 | ra_debug_msg (DUMP_IGRAPH, "%d (SUBREG %d, %d) with ", def1, | |
675 | ID2WEB (def1)->regno, | |
676 | SUBREG_BYTE (ID2WEB (def1)->orig_x)); | |
677 | else | |
678 | ra_debug_msg (DUMP_IGRAPH, "%d (REG %d) with ", def1, | |
679 | ID2WEB (def1)->regno); | |
680 | } | |
681 | if ((num2 % 9) == 8) | |
682 | ra_debug_msg (DUMP_IGRAPH, "\n "); | |
683 | num++; | |
684 | num2++; | |
685 | if (SUBWEB_P (ID2WEB (def2))) | |
686 | ra_debug_msg (DUMP_IGRAPH, "%d(%d,%d) ", def2, ID2WEB (def2)->regno, | |
687 | SUBREG_BYTE (ID2WEB (def2)->orig_x)); | |
688 | else | |
689 | ra_debug_msg (DUMP_IGRAPH, "%d(%d) ", def2, ID2WEB (def2)->regno); | |
690 | } | |
691 | if (num1 != num) | |
692 | ra_debug_msg (DUMP_IGRAPH, "\n "); | |
693 | } | |
694 | ra_debug_msg (DUMP_IGRAPH, "\n"); | |
695 | for (ml = wl_moves; ml; ml = ml->next) | |
696 | if (ml->move) | |
697 | { | |
698 | ra_debug_msg (DUMP_IGRAPH, "move: insn %d: Web %d <-- Web %d\n", | |
699 | INSN_UID (ml->move->insn), ml->move->target_web->id, | |
700 | ml->move->source_web->id); | |
701 | } | |
702 | ra_debug_msg (DUMP_WEBS, "\nWebs:\n"); | |
703 | for (i = 0; i < num_webs; i++) | |
704 | { | |
705 | struct web *web = ID2WEB (i); | |
706 | ||
707 | ra_debug_msg (DUMP_WEBS, " %4d : regno %3d", i, web->regno); | |
708 | if (SUBWEB_P (web)) | |
709 | { | |
710 | ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x)); | |
711 | ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id); | |
712 | } | |
90ff44cf KG |
713 | ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost " |
714 | HOST_WIDE_INT_PRINT_DEC ") (%s)", | |
715 | web->add_hardregs, web->span_deaths, web->spill_cost, | |
716 | reg_class_names[web->regclass]); | |
ed8d2920 MM |
717 | if (web->spill_temp == 1) |
718 | ra_debug_msg (DUMP_WEBS, " (spilltemp)"); | |
719 | else if (web->spill_temp == 2) | |
720 | ra_debug_msg (DUMP_WEBS, " (spilltem2)"); | |
721 | else if (web->spill_temp == 3) | |
722 | ra_debug_msg (DUMP_WEBS, " (short)"); | |
723 | if (web->type == PRECOLORED) | |
724 | ra_debug_msg (DUMP_WEBS, " (precolored, color=%d)", web->color); | |
725 | else if (find_web_for_subweb (web)->num_uses == 0) | |
726 | ra_debug_msg (DUMP_WEBS, " dead"); | |
727 | if (web->crosses_call) | |
728 | ra_debug_msg (DUMP_WEBS, " xcall"); | |
729 | if (web->regno >= max_normal_pseudo) | |
730 | ra_debug_msg (DUMP_WEBS, " stack"); | |
731 | ra_debug_msg (DUMP_WEBS, "\n"); | |
732 | } | |
733 | } | |
734 | ||
735 | /* Dump the interference graph and webs in a format easily | |
736 | parsable by programs. Used to emit real world interference graph | |
737 | to my custom graph colorizer. */ | |
738 | ||
739 | void | |
93bad80e | 740 | dump_igraph_machine (void) |
ed8d2920 MM |
741 | { |
742 | unsigned int i; | |
743 | ||
c263766c | 744 | if (!dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0) |
ed8d2920 MM |
745 | return; |
746 | ra_debug_msg (DUMP_IGRAPH_M, "g %d %d\n", num_webs - num_subwebs, | |
747 | FIRST_PSEUDO_REGISTER); | |
748 | for (i = 0; i < num_webs - num_subwebs; i++) | |
749 | { | |
750 | struct web *web = ID2WEB (i); | |
751 | struct conflict_link *cl; | |
752 | int flags = 0; | |
753 | int numc = 0; | |
754 | int col = 0; | |
755 | flags = web->spill_temp & 0xF; | |
756 | flags |= ((web->type == PRECOLORED) ? 1 : 0) << 4; | |
757 | flags |= (web->add_hardregs & 0xF) << 5; | |
758 | for (cl = web->conflict_list; cl; cl = cl->next) | |
759 | if (cl->t->id < web->id) | |
760 | numc++; | |
761 | ra_debug_msg (DUMP_IGRAPH_M, "n %d %d %d %d %d %d %d\n", | |
762 | web->id, web->color, flags, | |
763 | (unsigned int)web->spill_cost, web->num_defs, web->num_uses, | |
764 | numc); | |
765 | if (web->type != PRECOLORED) | |
766 | { | |
767 | ra_debug_msg (DUMP_IGRAPH_M, "s %d", web->id); | |
768 | while (1) | |
769 | { | |
770 | unsigned int u = 0; | |
771 | int n; | |
772 | for (n = 0; n < 32 && col < FIRST_PSEUDO_REGISTER; n++, col++) | |
773 | if (TEST_HARD_REG_BIT (web->usable_regs, col)) | |
774 | u |= 1 << n; | |
775 | ra_debug_msg (DUMP_IGRAPH_M, " %u", u); | |
776 | if (col >= FIRST_PSEUDO_REGISTER) | |
777 | break; | |
778 | } | |
779 | ra_debug_msg (DUMP_IGRAPH_M, "\n"); | |
780 | } | |
781 | if (numc) | |
782 | { | |
783 | ra_debug_msg (DUMP_IGRAPH_M, "c %d", web->id); | |
784 | for (cl = web->conflict_list; cl; cl = cl->next) | |
785 | { | |
786 | if (cl->t->id < web->id) | |
787 | ra_debug_msg (DUMP_IGRAPH_M, " %d", cl->t->id); | |
788 | } | |
789 | ra_debug_msg (DUMP_IGRAPH_M, "\n"); | |
790 | } | |
791 | } | |
792 | ra_debug_msg (DUMP_IGRAPH_M, "e\n"); | |
793 | } | |
794 | ||
795 | /* This runs after colorization and changing the insn stream. | |
796 | It temporarily replaces all pseudo registers with their colors, | |
797 | and emits information, if the resulting insns are strictly valid. */ | |
798 | ||
799 | void | |
93bad80e | 800 | dump_constraints (void) |
ed8d2920 MM |
801 | { |
802 | rtx insn; | |
803 | int i; | |
c263766c | 804 | if (!dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0) |
ed8d2920 MM |
805 | return; |
806 | for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) | |
f8cfc6aa | 807 | if (regno_reg_rtx[i] && REG_P (regno_reg_rtx[i])) |
ed8d2920 MM |
808 | REGNO (regno_reg_rtx[i]) |
809 | = ra_reg_renumber[i] >= 0 ? ra_reg_renumber[i] : i; | |
810 | for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | |
811 | if (INSN_P (insn)) | |
812 | { | |
813 | int code; | |
814 | int uid = INSN_UID (insn); | |
815 | int o; | |
816 | /* Don't simply force rerecognition, as combine might left us | |
d55d8fc7 | 817 | with some unrecognizable ones, which later leads to aborts |
ed8d2920 MM |
818 | in regclass, if we now destroy the remembered INSN_CODE(). */ |
819 | /*INSN_CODE (insn) = -1;*/ | |
820 | code = recog_memoized (insn); | |
821 | if (code < 0) | |
822 | { | |
823 | ra_debug_msg (DUMP_CONSTRAINTS, | |
824 | "%d: asm insn or not recognizable.\n", uid); | |
825 | continue; | |
826 | } | |
827 | ra_debug_msg (DUMP_CONSTRAINTS, | |
828 | "%d: code %d {%s}, %d operands, constraints: ", | |
829 | uid, code, insn_data[code].name, recog_data.n_operands); | |
830 | extract_insn (insn); | |
831 | /*preprocess_constraints ();*/ | |
832 | for (o = 0; o < recog_data.n_operands; o++) | |
833 | { | |
834 | ra_debug_msg (DUMP_CONSTRAINTS, | |
835 | "%d:%s ", o, recog_data.constraints[o]); | |
836 | } | |
837 | if (constrain_operands (1)) | |
838 | ra_debug_msg (DUMP_CONSTRAINTS, "matches strictly alternative %d", | |
839 | which_alternative); | |
840 | else | |
841 | ra_debug_msg (DUMP_CONSTRAINTS, "doesn't match strictly"); | |
842 | ra_debug_msg (DUMP_CONSTRAINTS, "\n"); | |
843 | } | |
844 | for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) | |
f8cfc6aa | 845 | if (regno_reg_rtx[i] && REG_P (regno_reg_rtx[i])) |
ed8d2920 MM |
846 | REGNO (regno_reg_rtx[i]) = i; |
847 | } | |
848 | ||
849 | /* This counts and emits the cumulated cost of all spilled webs, | |
850 | preceded by a custom message MSG, with debug level LEVEL. */ | |
851 | ||
852 | void | |
93bad80e | 853 | dump_graph_cost (unsigned int level, const char *msg) |
ed8d2920 MM |
854 | { |
855 | unsigned int i; | |
856 | unsigned HOST_WIDE_INT cost; | |
c263766c | 857 | if (!dump_file || (debug_new_regalloc & level) == 0) |
ed8d2920 MM |
858 | return; |
859 | ||
860 | cost = 0; | |
861 | for (i = 0; i < num_webs; i++) | |
862 | { | |
863 | struct web *web = id2web[i]; | |
864 | if (alias (web)->type == SPILLED) | |
865 | cost += web->orig_spill_cost; | |
866 | } | |
90ff44cf KG |
867 | ra_debug_msg (level, " spill cost of graph (%s) = " |
868 | HOST_WIDE_INT_PRINT_UNSIGNED "\n", | |
869 | msg ? msg : "", cost); | |
ed8d2920 MM |
870 | } |
871 | ||
872 | /* Dump the color assignment per web, the coalesced and spilled webs. */ | |
873 | ||
874 | void | |
93bad80e | 875 | dump_ra (struct df *df ATTRIBUTE_UNUSED) |
ed8d2920 MM |
876 | { |
877 | struct web *web; | |
878 | struct dlist *d; | |
c263766c | 879 | if (!dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0) |
ed8d2920 MM |
880 | return; |
881 | ||
882 | ra_debug_msg (DUMP_RESULTS, "\nColored:\n"); | |
883 | for (d = WEBS(COLORED); d; d = d->next) | |
884 | { | |
885 | web = DLIST_WEB (d); | |
886 | ra_debug_msg (DUMP_RESULTS, " %4d : color %d\n", web->id, web->color); | |
887 | } | |
888 | ra_debug_msg (DUMP_RESULTS, "\nCoalesced:\n"); | |
889 | for (d = WEBS(COALESCED); d; d = d->next) | |
890 | { | |
891 | web = DLIST_WEB (d); | |
892 | ra_debug_msg (DUMP_RESULTS, " %4d : to web %d, color %d\n", web->id, | |
893 | alias (web)->id, web->color); | |
894 | } | |
895 | ra_debug_msg (DUMP_RESULTS, "\nSpilled:\n"); | |
896 | for (d = WEBS(SPILLED); d; d = d->next) | |
897 | { | |
898 | web = DLIST_WEB (d); | |
899 | ra_debug_msg (DUMP_RESULTS, " %4d\n", web->id); | |
900 | } | |
901 | ra_debug_msg (DUMP_RESULTS, "\n"); | |
902 | dump_cost (DUMP_RESULTS); | |
903 | } | |
904 | ||
905 | /* Calculate and dump the cumulated costs of certain types of insns | |
906 | (loads, stores and copies). */ | |
907 | ||
908 | void | |
93bad80e | 909 | dump_static_insn_cost (FILE *file, const char *message, const char *prefix) |
ed8d2920 MM |
910 | { |
911 | struct cost | |
912 | { | |
913 | unsigned HOST_WIDE_INT cost; | |
914 | unsigned int count; | |
915 | }; | |
ed8d2920 | 916 | basic_block bb; |
533c4863 KG |
917 | struct cost load, store, regcopy, selfcopy, overall; |
918 | memset (&load, 0, sizeof(load)); | |
919 | memset (&store, 0, sizeof(store)); | |
920 | memset (®copy, 0, sizeof(regcopy)); | |
921 | memset (&selfcopy, 0, sizeof(selfcopy)); | |
922 | memset (&overall, 0, sizeof(overall)); | |
ed8d2920 MM |
923 | |
924 | if (!file) | |
925 | return; | |
926 | ||
927 | FOR_EACH_BB (bb) | |
928 | { | |
929 | unsigned HOST_WIDE_INT block_cost = bb->frequency; | |
930 | rtx insn, set; | |
a813c111 | 931 | for (insn = BB_HEAD (bb); insn; insn = NEXT_INSN (insn)) |
ed8d2920 MM |
932 | { |
933 | /* Yes, yes. We don't calculate the costs precisely. | |
934 | Only for "simple enough" insns. Those containing single | |
935 | sets only. */ | |
936 | if (INSN_P (insn) && ((set = single_set (insn)) != NULL)) | |
937 | { | |
938 | rtx src = SET_SRC (set); | |
939 | rtx dest = SET_DEST (set); | |
940 | struct cost *pcost = NULL; | |
941 | overall.cost += block_cost; | |
942 | overall.count++; | |
943 | if (rtx_equal_p (src, dest)) | |
944 | pcost = &selfcopy; | |
945 | else if (GET_CODE (src) == GET_CODE (dest) | |
f8cfc6aa | 946 | && ((REG_P (src)) |
ed8d2920 | 947 | || (GET_CODE (src) == SUBREG |
f8cfc6aa JQ |
948 | && REG_P (SUBREG_REG (src)) |
949 | && REG_P (SUBREG_REG (dest))))) | |
950 | /* XXX is dest guaranteed to be a subreg? */ | |
ed8d2920 MM |
951 | pcost = ®copy; |
952 | else | |
953 | { | |
954 | if (GET_CODE (src) == SUBREG) | |
955 | src = SUBREG_REG (src); | |
956 | if (GET_CODE (dest) == SUBREG) | |
957 | dest = SUBREG_REG (dest); | |
3c0cb5de | 958 | if (MEM_P (src) && !MEM_P (dest) |
ed8d2920 MM |
959 | && memref_is_stack_slot (src)) |
960 | pcost = &load; | |
3c0cb5de | 961 | else if (!MEM_P (src) && MEM_P (dest) |
ed8d2920 MM |
962 | && memref_is_stack_slot (dest)) |
963 | pcost = &store; | |
964 | } | |
965 | if (pcost) | |
966 | { | |
967 | pcost->cost += block_cost; | |
968 | pcost->count++; | |
969 | } | |
970 | } | |
a813c111 | 971 | if (insn == BB_END (bb)) |
ed8d2920 MM |
972 | break; |
973 | } | |
974 | } | |
975 | ||
976 | if (!prefix) | |
977 | prefix = ""; | |
978 | fprintf (file, "static insn cost %s\n", message ? message : ""); | |
85f015e1 KG |
979 | fprintf (file, " %soverall:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", |
980 | prefix, overall.count, overall.cost); | |
981 | fprintf (file, " %sloads:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", | |
982 | prefix, load.count, load.cost); | |
983 | fprintf (file, " %sstores:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", | |
984 | prefix, store.count, store.cost); | |
985 | fprintf (file, " %sregcopy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", | |
986 | prefix, regcopy.count, regcopy.cost); | |
987 | fprintf (file, " %sselfcpy:\tnum=%6d\tcost=% 8" HOST_WIDE_INT_PRINT "d\n", | |
988 | prefix, selfcopy.count, selfcopy.cost); | |
ed8d2920 MM |
989 | } |
990 | ||
991 | /* Returns nonzero, if WEB1 and WEB2 have some possible | |
992 | hardregs in common. */ | |
993 | ||
994 | int | |
93bad80e | 995 | web_conflicts_p (struct web *web1, struct web *web2) |
ed8d2920 MM |
996 | { |
997 | if (web1->type == PRECOLORED && web2->type == PRECOLORED) | |
998 | return 0; | |
999 | ||
1000 | if (web1->type == PRECOLORED) | |
1001 | return TEST_HARD_REG_BIT (web2->usable_regs, web1->regno); | |
1002 | ||
1003 | if (web2->type == PRECOLORED) | |
1004 | return TEST_HARD_REG_BIT (web1->usable_regs, web2->regno); | |
1005 | ||
1006 | return hard_regs_intersect_p (&web1->usable_regs, &web2->usable_regs); | |
1007 | } | |
1008 | ||
1009 | /* Dump all uids of insns in which WEB is mentioned. */ | |
1010 | ||
1011 | void | |
93bad80e | 1012 | dump_web_insns (struct web *web) |
ed8d2920 MM |
1013 | { |
1014 | unsigned int i; | |
1015 | ||
1016 | ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", | |
1017 | web->id, web->regno, web->add_hardregs, | |
1018 | reg_class_names[web->regclass], | |
1019 | web->num_freedom, web->num_conflicts); | |
1020 | ra_debug_msg (DUMP_EVER, " def insns:"); | |
1021 | ||
1022 | for (i = 0; i < web->num_defs; ++i) | |
1023 | { | |
1024 | ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn)); | |
1025 | } | |
1026 | ||
1027 | ra_debug_msg (DUMP_EVER, "\n use insns:"); | |
1028 | for (i = 0; i < web->num_uses; ++i) | |
1029 | { | |
1030 | ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn)); | |
1031 | } | |
1032 | ra_debug_msg (DUMP_EVER, "\n"); | |
1033 | } | |
1034 | ||
1035 | /* Dump conflicts for web WEB. */ | |
1036 | ||
1037 | void | |
93bad80e | 1038 | dump_web_conflicts (struct web *web) |
ed8d2920 MM |
1039 | { |
1040 | int num = 0; | |
1041 | unsigned int def2; | |
1042 | ||
1043 | ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", | |
1044 | web->id, web->regno, web->add_hardregs, | |
1045 | reg_class_names[web->regclass], | |
1046 | web->num_freedom, web->num_conflicts); | |
1047 | ||
1048 | for (def2 = 0; def2 < num_webs; def2++) | |
1049 | if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2) | |
1050 | { | |
1051 | if ((num % 9) == 5) | |
1052 | ra_debug_msg (DUMP_EVER, "\n "); | |
1053 | num++; | |
1054 | ||
1055 | ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno); | |
1056 | if (id2web[def2]->add_hardregs) | |
1057 | ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs); | |
1058 | ||
1059 | if (web_conflicts_p (web, id2web[def2])) | |
1060 | ra_debug_msg (DUMP_EVER, "/x"); | |
1061 | ||
1062 | if (id2web[def2]->type == SELECT) | |
1063 | ra_debug_msg (DUMP_EVER, "/s"); | |
1064 | ||
1065 | if (id2web[def2]->type == COALESCED) | |
1066 | ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id); | |
1067 | } | |
1068 | ra_debug_msg (DUMP_EVER, "\n"); | |
1069 | { | |
1070 | struct conflict_link *wl; | |
1071 | num = 0; | |
1072 | ra_debug_msg (DUMP_EVER, "By conflicts: "); | |
1073 | for (wl = web->conflict_list; wl; wl = wl->next) | |
1074 | { | |
1075 | struct web* w = wl->t; | |
1076 | if ((num % 9) == 8) | |
1077 | ra_debug_msg (DUMP_EVER, "\n "); | |
1078 | num++; | |
1079 | ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno, | |
1080 | web_conflicts_p (web, w) ? "+" : ""); | |
1081 | } | |
1082 | ra_debug_msg (DUMP_EVER, "\n"); | |
1083 | } | |
1084 | } | |
1085 | ||
1086 | /* Output HARD_REG_SET to stderr. */ | |
1087 | ||
1088 | void | |
93bad80e | 1089 | debug_hard_reg_set (HARD_REG_SET set) |
ed8d2920 MM |
1090 | { |
1091 | int i; | |
6a87d634 | 1092 | for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) |
ed8d2920 MM |
1093 | { |
1094 | if (TEST_HARD_REG_BIT (set, i)) | |
1095 | { | |
1096 | fprintf (stderr, "%s ", reg_names[i]); | |
1097 | } | |
1098 | } | |
1099 | fprintf (stderr, "\n"); | |
1100 | } | |
1101 | ||
1102 | /* | |
1103 | vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: | |
1104 | */ |