]>
Commit | Line | Data |
---|---|---|
cb5c5698 | 1 | /* Graph coloring register allocator |
2 | Copyright (C) 2001, 2002 Free Software Foundation, Inc. | |
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" | |
805e22b2 | 23 | #include "coretypes.h" |
24 | #include "tm.h" | |
cb5c5698 | 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" | |
a5c71710 | 34 | #include "tm_p.h" |
cb5c5698 | 35 | |
36 | /* This file contains various dumping and debug functions for | |
37 | the graph coloring register allocator. */ | |
38 | ||
39 | static void ra_print_rtx_1op PARAMS ((FILE *, rtx)); | |
40 | static void ra_print_rtx_2op PARAMS ((FILE *, rtx)); | |
41 | static void ra_print_rtx_3op PARAMS ((FILE *, rtx)); | |
42 | static void ra_print_rtx_object PARAMS ((FILE *, rtx)); | |
43 | ||
44 | /* The hardregs as names, for debugging. */ | |
45 | static const char *const reg_class_names[] = REG_CLASS_NAMES; | |
46 | ||
47 | /* Print a message to the dump file, if debug_new_regalloc and LEVEL | |
48 | have any bits in common. */ | |
49 | ||
50 | void | |
51 | ra_debug_msg VPARAMS ((unsigned int level, const char *format, ...)) | |
52 | { | |
6e898352 | 53 | VA_OPEN (ap, format); |
54 | VA_FIXEDARG (ap, unsigned int, level); | |
55 | VA_FIXEDARG (ap, const char *, format); | |
cb5c5698 | 56 | if ((debug_new_regalloc & level) != 0 && rtl_dump_file != NULL) |
6e898352 | 57 | vfprintf (rtl_dump_file, format, ap); |
58 | VA_CLOSE (ap); | |
cb5c5698 | 59 | } |
60 | ||
61 | ||
62 | /* The following ra_print_xxx() functions print RTL expressions | |
63 | in concise infix form. If the mode can be seen from context it's | |
64 | left out. Most operators are represented by their graphical | |
65 | characters, e.g. LE as "<=". Unknown constructs are currently | |
66 | printed with print_inline_rtx(), which disrupts the nice layout. | |
67 | Currently only the inline asm things are written this way. */ | |
68 | ||
69 | /* Print rtx X, which is a one operand rtx (op:mode (Y)), as | |
70 | "op(Y)" to FILE. */ | |
71 | ||
72 | static void | |
73 | ra_print_rtx_1op (file, x) | |
74 | FILE *file; | |
75 | rtx x; | |
76 | { | |
77 | enum rtx_code code = GET_CODE (x); | |
78 | rtx op0 = XEXP (x, 0); | |
79 | switch (code) | |
80 | { | |
81 | case NEG: | |
82 | case NOT: | |
83 | fputs ((code == NEG) ? "-(" : "~(", file); | |
84 | ra_print_rtx (file, op0, 0); | |
85 | fputs (")", file); | |
86 | break; | |
87 | case HIGH: | |
88 | fputs ("hi(", file); | |
89 | ra_print_rtx (file, op0, 0); | |
90 | fputs (")", file); | |
91 | break; | |
92 | default: | |
93 | fprintf (file, "%s", GET_RTX_NAME (code)); | |
94 | if (GET_MODE (x) != VOIDmode) | |
95 | fprintf (file, ":%s(", GET_MODE_NAME (GET_MODE (x))); | |
96 | else | |
97 | fputs ("(", file); | |
98 | ra_print_rtx (file, op0, 0); | |
99 | fputs (")", file); | |
100 | break; | |
101 | } | |
102 | } | |
103 | ||
104 | /* Print rtx X, which is a two operand rtx (op:mode (Y) (Z)) | |
105 | as "(Y op Z)", if the operand is know, or as "op(Y, Z)", if not, | |
106 | to FILE. */ | |
107 | ||
108 | static void | |
109 | ra_print_rtx_2op (file, x) | |
110 | FILE *file; | |
111 | rtx x; | |
112 | { | |
113 | int infix = 1; | |
114 | const char *opname = "shitop"; | |
115 | enum rtx_code code = GET_CODE (x); | |
116 | rtx op0 = XEXP (x, 0); | |
117 | rtx op1 = XEXP (x, 1); | |
118 | switch (code) | |
119 | { | |
120 | /* class '2' */ | |
121 | case COMPARE: opname = "?"; break; | |
122 | case MINUS: opname = "-"; break; | |
123 | case DIV: opname = "/"; break; | |
124 | case UDIV: opname = "u/"; break; | |
125 | case MOD: opname = "%"; break; | |
126 | case UMOD: opname = "u%"; break; | |
127 | case ASHIFT: opname = "<<"; break; | |
128 | case ASHIFTRT: opname = "a>>"; break; | |
129 | case LSHIFTRT: opname = "l>>"; break; | |
130 | /* class 'c' */ | |
131 | case PLUS: opname = "+"; break; | |
132 | case MULT: opname = "*"; break; | |
133 | case AND: opname = "&"; break; | |
134 | case IOR: opname = "|"; break; | |
135 | case XOR: opname = "^"; break; | |
136 | /* class '<' */ | |
137 | case NE: opname = "!="; break; | |
138 | case EQ: opname = "=="; break; | |
139 | case GE: opname = "s>="; break; | |
140 | case GT: opname = "s>"; break; | |
141 | case LE: opname = "s<="; break; | |
142 | case LT: opname = "s<"; break; | |
143 | case GEU: opname = "u>="; break; | |
144 | case GTU: opname = "u>"; break; | |
145 | case LEU: opname = "u<="; break; | |
146 | case LTU: opname = "u<"; break; | |
147 | default: | |
148 | infix = 0; | |
149 | opname = GET_RTX_NAME (code); | |
150 | break; | |
151 | } | |
152 | if (infix) | |
153 | { | |
154 | fputs ("(", file); | |
155 | ra_print_rtx (file, op0, 0); | |
156 | fprintf (file, " %s ", opname); | |
157 | ra_print_rtx (file, op1, 0); | |
158 | fputs (")", file); | |
159 | } | |
160 | else | |
161 | { | |
162 | fprintf (file, "%s(", opname); | |
163 | ra_print_rtx (file, op0, 0); | |
164 | fputs (", ", file); | |
165 | ra_print_rtx (file, op1, 0); | |
166 | fputs (")", file); | |
167 | } | |
168 | } | |
169 | ||
170 | /* Print rtx X, which a three operand rtx to FILE. | |
171 | I.e. X is either an IF_THEN_ELSE, or a bitmap operation. */ | |
172 | ||
173 | static void | |
174 | ra_print_rtx_3op (file, x) | |
175 | FILE *file; | |
176 | rtx x; | |
177 | { | |
178 | enum rtx_code code = GET_CODE (x); | |
179 | rtx op0 = XEXP (x, 0); | |
180 | rtx op1 = XEXP (x, 1); | |
181 | rtx op2 = XEXP (x, 2); | |
182 | if (code == IF_THEN_ELSE) | |
183 | { | |
184 | ra_print_rtx (file, op0, 0); | |
185 | fputs (" ? ", file); | |
186 | ra_print_rtx (file, op1, 0); | |
187 | fputs (" : ", file); | |
188 | ra_print_rtx (file, op2, 0); | |
189 | } | |
190 | else | |
191 | { | |
192 | /* Bitmap-operation */ | |
193 | fprintf (file, "%s:%s(", GET_RTX_NAME (code), | |
194 | GET_MODE_NAME (GET_MODE (x))); | |
195 | ra_print_rtx (file, op0, 0); | |
196 | fputs (", ", file); | |
197 | ra_print_rtx (file, op1, 0); | |
198 | fputs (", ", file); | |
199 | ra_print_rtx (file, op2, 0); | |
200 | fputs (")", file); | |
201 | } | |
202 | } | |
203 | ||
204 | /* Print rtx X, which represents an object (class 'o' or some constructs | |
205 | of class 'x' (e.g. subreg)), to FILE. | |
206 | (reg XX) rtl is represented as "pXX", of XX was a pseudo, | |
207 | as "name" it name is the nonnull hardreg name, or as "hXX", if XX | |
208 | is a hardreg, whose name is NULL, or empty. */ | |
209 | ||
210 | static void | |
211 | ra_print_rtx_object (file, x) | |
212 | FILE *file; | |
213 | rtx x; | |
214 | { | |
215 | enum rtx_code code = GET_CODE (x); | |
216 | enum machine_mode mode = GET_MODE (x); | |
217 | switch (code) | |
218 | { | |
219 | case CONST_INT: | |
220 | fprintf (file, HOST_WIDE_INT_PRINT_DEC, XWINT (x, 0)); | |
221 | break; | |
222 | case CONST_DOUBLE: | |
223 | { | |
224 | int i, num = 0; | |
225 | const char *fmt = GET_RTX_FORMAT (code); | |
226 | fputs ("dbl(", file); | |
227 | for (i = 0; i < GET_RTX_LENGTH (code); i++) | |
228 | { | |
229 | if (num) | |
230 | fputs (", ", file); | |
231 | if (fmt[i] == 'e' && XEXP (x, i)) | |
232 | /* The MEM or other stuff */ | |
233 | { | |
234 | ra_print_rtx (file, XEXP (x, i), 0); | |
235 | num++; | |
236 | } | |
237 | else if (fmt[i] == 'w') | |
238 | { | |
239 | fprintf (file, HOST_WIDE_INT_PRINT_HEX, XWINT (x, i)); | |
240 | num++; | |
241 | } | |
242 | } | |
243 | break; | |
244 | } | |
245 | case CONST_STRING: fprintf (file, "\"%s\"", XSTR (x, 0)); break; | |
246 | case CONST: fputs ("const(", file); | |
247 | ra_print_rtx (file, XEXP (x, 0), 0); | |
248 | fputs (")", file); | |
249 | break; | |
250 | case PC: fputs ("pc", file); break; | |
251 | case REG: | |
252 | { | |
253 | int regno = REGNO (x); | |
254 | if (regno < FIRST_PSEUDO_REGISTER) | |
255 | { | |
256 | int i, nregs = HARD_REGNO_NREGS (regno, mode); | |
257 | if (nregs > 1) | |
258 | fputs ("[", file); | |
259 | for (i = 0; i < nregs; i++) | |
260 | { | |
261 | if (i) | |
262 | fputs (", ", file); | |
263 | if (reg_names[regno+i] && *reg_names[regno + i]) | |
264 | fprintf (file, "%s", reg_names[regno + i]); | |
265 | else | |
266 | fprintf (file, "h%d", regno + i); | |
267 | } | |
268 | if (nregs > 1) | |
269 | fputs ("]", file); | |
270 | } | |
271 | else | |
272 | fprintf (file, "p%d", regno); | |
273 | break; | |
274 | } | |
275 | case SUBREG: | |
276 | { | |
277 | rtx sub = SUBREG_REG (x); | |
278 | int ofs = SUBREG_BYTE (x); | |
279 | if (GET_CODE (sub) == REG | |
280 | && REGNO (sub) < FIRST_PSEUDO_REGISTER) | |
281 | { | |
282 | int regno = REGNO (sub); | |
283 | int i, nregs = HARD_REGNO_NREGS (regno, mode); | |
284 | regno += subreg_regno_offset (regno, GET_MODE (sub), | |
285 | ofs, mode); | |
286 | if (nregs > 1) | |
287 | fputs ("[", file); | |
288 | for (i = 0; i < nregs; i++) | |
289 | { | |
290 | if (i) | |
291 | fputs (", ", file); | |
292 | if (reg_names[regno+i]) | |
293 | fprintf (file, "%s", reg_names[regno + i]); | |
294 | else | |
295 | fprintf (file, "h%d", regno + i); | |
296 | } | |
297 | if (nregs > 1) | |
298 | fputs ("]", file); | |
299 | } | |
300 | else | |
301 | { | |
302 | ra_print_rtx (file, sub, 0); | |
303 | fprintf (file, ":[%s+%d]", GET_MODE_NAME (mode), ofs); | |
304 | } | |
305 | break; | |
306 | } | |
307 | case SCRATCH: fputs ("scratch", file); break; | |
308 | case CONCAT: ra_print_rtx_2op (file, x); break; | |
309 | case HIGH: ra_print_rtx_1op (file, x); break; | |
310 | case LO_SUM: | |
311 | fputs ("(", file); | |
312 | ra_print_rtx (file, XEXP (x, 0), 0); | |
313 | fputs (" + lo(", file); | |
314 | ra_print_rtx (file, XEXP (x, 1), 0); | |
315 | fputs ("))", file); | |
316 | break; | |
317 | case MEM: fputs ("[", file); | |
318 | ra_print_rtx (file, XEXP (x, 0), 0); | |
319 | fprintf (file, "]:%s", GET_MODE_NAME (GET_MODE (x))); | |
320 | /* XXX print alias set too ?? */ | |
321 | break; | |
322 | case LABEL_REF: | |
323 | { | |
324 | rtx sub = XEXP (x, 0); | |
325 | if (GET_CODE (sub) == NOTE | |
326 | && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL) | |
327 | fprintf (file, "(deleted uid=%d)", INSN_UID (sub)); | |
328 | else if (GET_CODE (sub) == CODE_LABEL) | |
329 | fprintf (file, "L%d", CODE_LABEL_NUMBER (sub)); | |
330 | else | |
331 | fprintf (file, "(nonlabel uid=%d)", INSN_UID (sub)); | |
332 | } | |
333 | break; | |
334 | case SYMBOL_REF: | |
335 | fprintf (file, "sym(\"%s\")", XSTR (x, 0)); break; | |
336 | case CC0: fputs ("cc0", file); break; | |
337 | default: print_inline_rtx (file, x, 0); break; | |
338 | } | |
339 | } | |
340 | ||
341 | /* Print a general rtx X to FILE in nice infix form. | |
342 | If WITH_PN is set, and X is one of the toplevel constructs | |
343 | (insns, notes, labels or barriers), then print also the UIDs of | |
344 | the preceding and following insn. */ | |
345 | ||
346 | void | |
347 | ra_print_rtx (file, x, with_pn) | |
348 | FILE *file; | |
349 | rtx x; | |
350 | int with_pn; | |
351 | { | |
352 | enum rtx_code code; | |
353 | char class; | |
354 | int unhandled = 0; | |
355 | if (!x) | |
356 | return; | |
357 | code = GET_CODE (x); | |
358 | class = GET_RTX_CLASS (code); | |
359 | ||
360 | /* First handle the insn like constructs. */ | |
361 | if (INSN_P (x) || code == NOTE || code == CODE_LABEL || code == BARRIER) | |
362 | { | |
363 | if (INSN_P (x)) | |
364 | fputs (" ", file); | |
365 | /* Non-insns are prefixed by a ';'. */ | |
366 | if (code == BARRIER) | |
367 | fputs ("; ", file); | |
368 | else if (code == NOTE) | |
369 | /* But notes are indented very far right. */ | |
370 | fprintf (file, "\t\t\t\t\t; "); | |
371 | else if (code == CODE_LABEL) | |
372 | /* And labels have their Lxx name first, before the actual UID. */ | |
373 | { | |
374 | fprintf (file, "L%d:\t; ", CODE_LABEL_NUMBER (x)); | |
375 | if (LABEL_NAME (x)) | |
376 | fprintf (file, "(%s) ", LABEL_NAME (x)); | |
a7ae1e59 | 377 | switch (LABEL_KIND (x)) |
378 | { | |
379 | case LABEL_NORMAL: break; | |
380 | case LABEL_STATIC_ENTRY: fputs (" (entry)", file); break; | |
381 | case LABEL_GLOBAL_ENTRY: fputs (" (global entry)", file); break; | |
382 | case LABEL_WEAK_ENTRY: fputs (" (weak entry)", file); break; | |
383 | default: abort(); | |
384 | } | |
cb5c5698 | 385 | fprintf (file, " [%d uses] uid=(", LABEL_NUSES (x)); |
386 | } | |
387 | fprintf (file, "%d", INSN_UID (x)); | |
388 | if (with_pn) | |
389 | fprintf (file, " %d %d", PREV_INSN (x) ? INSN_UID (PREV_INSN (x)) : 0, | |
390 | NEXT_INSN (x) ? INSN_UID (NEXT_INSN (x)) : 0); | |
391 | if (code == BARRIER) | |
392 | fputs (" -------- barrier ---------", file); | |
393 | else if (code == CODE_LABEL) | |
394 | fputs (")", file); | |
395 | else if (code == NOTE) | |
396 | { | |
397 | int ln = NOTE_LINE_NUMBER (x); | |
398 | if (ln >= (int) NOTE_INSN_BIAS && ln < (int) NOTE_INSN_MAX) | |
399 | fprintf (file, " %s", GET_NOTE_INSN_NAME (ln)); | |
400 | else | |
401 | { | |
402 | fprintf (file, " line %d", ln); | |
403 | if (NOTE_SOURCE_FILE (x)) | |
404 | fprintf (file, ":%s", NOTE_SOURCE_FILE (x)); | |
405 | } | |
406 | } | |
407 | else | |
408 | { | |
409 | fprintf (file, "\t"); | |
410 | ra_print_rtx (file, PATTERN (x), 0); | |
411 | } | |
412 | return; | |
413 | } | |
414 | switch (code) | |
415 | { | |
416 | /* Top-level stuff. */ | |
417 | case PARALLEL: | |
418 | { | |
419 | int j; | |
420 | for (j = 0; j < XVECLEN (x, 0); j++) | |
421 | { | |
422 | if (j) | |
423 | fputs ("\t;; ", file); | |
424 | ra_print_rtx (file, XVECEXP (x, 0, j), 0); | |
425 | } | |
426 | break; | |
427 | } | |
428 | case UNSPEC: case UNSPEC_VOLATILE: | |
429 | { | |
430 | int j; | |
431 | fprintf (file, "unspec%s(%d", | |
432 | (code == UNSPEC) ? "" : "_vol", XINT (x, 1)); | |
433 | for (j = 0; j < XVECLEN (x, 0); j++) | |
434 | { | |
435 | fputs (", ", file); | |
436 | ra_print_rtx (file, XVECEXP (x, 0, j), 0); | |
437 | } | |
438 | fputs (")", file); | |
439 | break; | |
440 | } | |
441 | case SET: | |
442 | if (GET_CODE (SET_DEST (x)) == PC) | |
443 | { | |
444 | if (GET_CODE (SET_SRC (x)) == IF_THEN_ELSE | |
445 | && GET_CODE (XEXP (SET_SRC(x), 2)) == PC) | |
446 | { | |
447 | fputs ("if ", file); | |
448 | ra_print_rtx (file, XEXP (SET_SRC (x), 0), 0); | |
449 | fputs (" jump ", file); | |
450 | ra_print_rtx (file, XEXP (SET_SRC (x), 1), 0); | |
451 | } | |
452 | else | |
453 | { | |
454 | fputs ("jump ", file); | |
455 | ra_print_rtx (file, SET_SRC (x), 0); | |
456 | } | |
457 | } | |
458 | else | |
459 | { | |
460 | ra_print_rtx (file, SET_DEST (x), 0); | |
461 | fputs (" <= ", file); | |
462 | ra_print_rtx (file, SET_SRC (x), 0); | |
463 | } | |
464 | break; | |
465 | case USE: | |
466 | fputs ("use <= ", file); | |
467 | ra_print_rtx (file, XEXP (x, 0), 0); | |
468 | break; | |
469 | case CLOBBER: | |
470 | ra_print_rtx (file, XEXP (x, 0), 0); | |
471 | fputs (" <= clobber", file); | |
472 | break; | |
473 | case CALL: | |
474 | fputs ("call ", file); | |
475 | ra_print_rtx (file, XEXP (x, 0), 0); /* Address */ | |
476 | fputs (" numargs=", file); | |
477 | ra_print_rtx (file, XEXP (x, 1), 0); /* Num arguments */ | |
478 | break; | |
479 | case RETURN: | |
480 | fputs ("return", file); | |
481 | break; | |
482 | case TRAP_IF: | |
483 | fputs ("if (", file); | |
484 | ra_print_rtx (file, XEXP (x, 0), 0); | |
485 | fputs (") trap ", file); | |
486 | ra_print_rtx (file, XEXP (x, 1), 0); | |
487 | break; | |
488 | case RESX: | |
489 | fprintf (file, "resx from region %d", XINT (x, 0)); | |
490 | break; | |
491 | ||
492 | /* Different things of class 'x' */ | |
493 | case SUBREG: ra_print_rtx_object (file, x); break; | |
494 | case STRICT_LOW_PART: | |
495 | fputs ("low(", file); | |
496 | ra_print_rtx (file, XEXP (x, 0), 0); | |
497 | fputs (")", file); | |
498 | break; | |
499 | default: | |
500 | unhandled = 1; | |
501 | break; | |
502 | } | |
503 | if (!unhandled) | |
504 | return; | |
505 | if (class == '1') | |
506 | ra_print_rtx_1op (file, x); | |
507 | else if (class == '2' || class == 'c' || class == '<') | |
508 | ra_print_rtx_2op (file, x); | |
509 | else if (class == '3' || class == 'b') | |
510 | ra_print_rtx_3op (file, x); | |
511 | else if (class == 'o') | |
512 | ra_print_rtx_object (file, x); | |
513 | else | |
514 | print_inline_rtx (file, x, 0); | |
515 | } | |
516 | ||
517 | /* This only calls ra_print_rtx(), but emits a final newline. */ | |
518 | ||
519 | void | |
520 | ra_print_rtx_top (file, x, with_pn) | |
521 | FILE *file; | |
522 | rtx x; | |
523 | int with_pn; | |
524 | { | |
525 | ra_print_rtx (file, x, with_pn); | |
526 | fprintf (file, "\n"); | |
527 | } | |
528 | ||
529 | /* Callable from gdb. This prints rtx X onto stderr. */ | |
530 | ||
531 | void | |
532 | ra_debug_rtx (x) | |
533 | rtx x; | |
534 | { | |
535 | ra_print_rtx_top (stderr, x, 1); | |
536 | } | |
537 | ||
538 | /* This prints the content of basic block with index BBI. | |
539 | The first and last insn are emitted with UIDs of prev and next insns. */ | |
540 | ||
541 | void | |
542 | ra_debug_bbi (bbi) | |
543 | int bbi; | |
544 | { | |
545 | basic_block bb = BASIC_BLOCK (bbi); | |
546 | rtx insn; | |
547 | for (insn = bb->head; insn; insn = NEXT_INSN (insn)) | |
548 | { | |
549 | ra_print_rtx_top (stderr, insn, (insn == bb->head || insn == bb->end)); | |
550 | fprintf (stderr, "\n"); | |
551 | if (insn == bb->end) | |
552 | break; | |
553 | } | |
554 | } | |
555 | ||
556 | /* Beginning from INSN, emit NUM insns (if NUM is non-negative) | |
557 | or emit a window of NUM insns around INSN, to stderr. */ | |
558 | ||
559 | void | |
560 | ra_debug_insns (insn, num) | |
561 | rtx insn; | |
562 | int num; | |
563 | { | |
564 | int i, count = (num == 0 ? 1 : num < 0 ? -num : num); | |
565 | if (num < 0) | |
566 | for (i = count / 2; i > 0 && PREV_INSN (insn); i--) | |
567 | insn = PREV_INSN (insn); | |
568 | for (i = count; i > 0 && insn; insn = NEXT_INSN (insn), i--) | |
569 | { | |
570 | if (GET_CODE (insn) == CODE_LABEL) | |
571 | fprintf (stderr, "\n"); | |
572 | ra_print_rtx_top (stderr, insn, (i == count || i == 1)); | |
573 | } | |
574 | } | |
575 | ||
576 | /* Beginning with INSN, emit the whole insn chain into FILE. | |
577 | This also outputs comments when basic blocks start or end and omits | |
578 | some notes, if flag_ra_dump_notes is zero. */ | |
579 | ||
580 | void | |
581 | ra_print_rtl_with_bb (file, insn) | |
582 | FILE *file; | |
583 | rtx insn; | |
584 | { | |
585 | basic_block last_bb, bb; | |
586 | unsigned int num = 0; | |
587 | if (!insn) | |
588 | fputs ("nil", file); | |
589 | last_bb = NULL; | |
590 | for (; insn; insn = NEXT_INSN (insn)) | |
591 | { | |
592 | if (GET_CODE (insn) == BARRIER) | |
593 | bb = NULL; | |
594 | else | |
595 | bb = BLOCK_FOR_INSN (insn); | |
596 | if (bb != last_bb) | |
597 | { | |
598 | if (last_bb) | |
599 | fprintf (file, ";; End of basic block %d\n", last_bb->index); | |
600 | if (bb) | |
601 | fprintf (file, ";; Begin of basic block %d\n", bb->index); | |
602 | last_bb = bb; | |
603 | } | |
604 | if (GET_CODE (insn) == CODE_LABEL) | |
605 | fputc ('\n', file); | |
606 | if (GET_CODE (insn) == NOTE) | |
607 | { | |
608 | /* Ignore basic block and maybe other notes not referencing | |
609 | deleted things. */ | |
610 | if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK | |
611 | && (flag_ra_dump_notes | |
612 | || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED | |
613 | || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL)) | |
614 | { | |
615 | ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); | |
616 | num++; | |
617 | } | |
618 | } | |
619 | else | |
620 | { | |
621 | ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn))); | |
622 | num++; | |
623 | } | |
624 | } | |
625 | } | |
626 | ||
627 | /* Count how many insns were seen how often, while building the interference | |
628 | graph, and prints the findings. */ | |
629 | ||
630 | void | |
631 | dump_number_seen () | |
632 | { | |
633 | #define N 17 | |
634 | int num[N]; | |
635 | int i; | |
636 | ||
637 | for (i = 0; i < N; i++) | |
638 | num[i] = 0; | |
639 | for (i = 0; i < get_max_uid (); i++) | |
640 | if (number_seen[i] < N - 1) | |
641 | num[number_seen[i]]++; | |
642 | else | |
643 | num[N - 1]++; | |
644 | for (i = 0; i < N - 1; i++) | |
645 | if (num[i]) | |
646 | ra_debug_msg (DUMP_PROCESS, "%d insns seen %d times\n", num[i], i); | |
647 | if (num[N - 1]) | |
648 | ra_debug_msg (DUMP_PROCESS, "%d insns seen %d and more times\n", num[i], | |
649 | N - 1); | |
650 | ra_debug_msg (DUMP_PROCESS, "from overall %d insns\n", get_max_uid ()); | |
651 | #undef N | |
652 | } | |
653 | ||
654 | /* Dump the interference graph, the move list and the webs. */ | |
655 | ||
656 | void | |
657 | dump_igraph (df) | |
658 | struct df *df ATTRIBUTE_UNUSED; | |
659 | { | |
660 | struct move_list *ml; | |
661 | unsigned int def1, def2; | |
662 | int num = 0; | |
663 | int num2; | |
664 | unsigned int i; | |
665 | if (!rtl_dump_file || (debug_new_regalloc & (DUMP_IGRAPH | DUMP_WEBS)) == 0) | |
666 | return; | |
667 | ra_debug_msg (DUMP_IGRAPH, "conflicts:\n "); | |
668 | for (def1 = 0; def1 < num_webs; def1++) | |
669 | { | |
670 | int num1 = num; | |
671 | for (num2=0, def2 = 0; def2 < num_webs; def2++) | |
672 | if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2))) | |
673 | { | |
674 | if (num1 == num) | |
675 | { | |
676 | if (SUBWEB_P (ID2WEB (def1))) | |
677 | ra_debug_msg (DUMP_IGRAPH, "%d (SUBREG %d, %d) with ", def1, | |
678 | ID2WEB (def1)->regno, | |
679 | SUBREG_BYTE (ID2WEB (def1)->orig_x)); | |
680 | else | |
681 | ra_debug_msg (DUMP_IGRAPH, "%d (REG %d) with ", def1, | |
682 | ID2WEB (def1)->regno); | |
683 | } | |
684 | if ((num2 % 9) == 8) | |
685 | ra_debug_msg (DUMP_IGRAPH, "\n "); | |
686 | num++; | |
687 | num2++; | |
688 | if (SUBWEB_P (ID2WEB (def2))) | |
689 | ra_debug_msg (DUMP_IGRAPH, "%d(%d,%d) ", def2, ID2WEB (def2)->regno, | |
690 | SUBREG_BYTE (ID2WEB (def2)->orig_x)); | |
691 | else | |
692 | ra_debug_msg (DUMP_IGRAPH, "%d(%d) ", def2, ID2WEB (def2)->regno); | |
693 | } | |
694 | if (num1 != num) | |
695 | ra_debug_msg (DUMP_IGRAPH, "\n "); | |
696 | } | |
697 | ra_debug_msg (DUMP_IGRAPH, "\n"); | |
698 | for (ml = wl_moves; ml; ml = ml->next) | |
699 | if (ml->move) | |
700 | { | |
701 | ra_debug_msg (DUMP_IGRAPH, "move: insn %d: Web %d <-- Web %d\n", | |
702 | INSN_UID (ml->move->insn), ml->move->target_web->id, | |
703 | ml->move->source_web->id); | |
704 | } | |
705 | ra_debug_msg (DUMP_WEBS, "\nWebs:\n"); | |
706 | for (i = 0; i < num_webs; i++) | |
707 | { | |
708 | struct web *web = ID2WEB (i); | |
709 | ||
710 | ra_debug_msg (DUMP_WEBS, " %4d : regno %3d", i, web->regno); | |
711 | if (SUBWEB_P (web)) | |
712 | { | |
713 | ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x)); | |
714 | ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id); | |
715 | } | |
6e898352 | 716 | ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost ", |
717 | web->add_hardregs, web->span_deaths); | |
718 | ra_debug_msg (DUMP_WEBS, HOST_WIDE_INT_PRINT_DEC, web->spill_cost); | |
719 | ra_debug_msg (DUMP_WEBS, ") (%s)", reg_class_names[web->regclass]); | |
cb5c5698 | 720 | if (web->spill_temp == 1) |
721 | ra_debug_msg (DUMP_WEBS, " (spilltemp)"); | |
722 | else if (web->spill_temp == 2) | |
723 | ra_debug_msg (DUMP_WEBS, " (spilltem2)"); | |
724 | else if (web->spill_temp == 3) | |
725 | ra_debug_msg (DUMP_WEBS, " (short)"); | |
726 | if (web->type == PRECOLORED) | |
727 | ra_debug_msg (DUMP_WEBS, " (precolored, color=%d)", web->color); | |
728 | else if (find_web_for_subweb (web)->num_uses == 0) | |
729 | ra_debug_msg (DUMP_WEBS, " dead"); | |
730 | if (web->crosses_call) | |
731 | ra_debug_msg (DUMP_WEBS, " xcall"); | |
732 | if (web->regno >= max_normal_pseudo) | |
733 | ra_debug_msg (DUMP_WEBS, " stack"); | |
734 | ra_debug_msg (DUMP_WEBS, "\n"); | |
735 | } | |
736 | } | |
737 | ||
738 | /* Dump the interference graph and webs in a format easily | |
739 | parsable by programs. Used to emit real world interference graph | |
740 | to my custom graph colorizer. */ | |
741 | ||
742 | void | |
743 | dump_igraph_machine () | |
744 | { | |
745 | unsigned int i; | |
746 | ||
747 | if (!rtl_dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0) | |
748 | return; | |
749 | ra_debug_msg (DUMP_IGRAPH_M, "g %d %d\n", num_webs - num_subwebs, | |
750 | FIRST_PSEUDO_REGISTER); | |
751 | for (i = 0; i < num_webs - num_subwebs; i++) | |
752 | { | |
753 | struct web *web = ID2WEB (i); | |
754 | struct conflict_link *cl; | |
755 | int flags = 0; | |
756 | int numc = 0; | |
757 | int col = 0; | |
758 | flags = web->spill_temp & 0xF; | |
759 | flags |= ((web->type == PRECOLORED) ? 1 : 0) << 4; | |
760 | flags |= (web->add_hardregs & 0xF) << 5; | |
761 | for (cl = web->conflict_list; cl; cl = cl->next) | |
762 | if (cl->t->id < web->id) | |
763 | numc++; | |
764 | ra_debug_msg (DUMP_IGRAPH_M, "n %d %d %d %d %d %d %d\n", | |
765 | web->id, web->color, flags, | |
766 | (unsigned int)web->spill_cost, web->num_defs, web->num_uses, | |
767 | numc); | |
768 | if (web->type != PRECOLORED) | |
769 | { | |
770 | ra_debug_msg (DUMP_IGRAPH_M, "s %d", web->id); | |
771 | while (1) | |
772 | { | |
773 | unsigned int u = 0; | |
774 | int n; | |
775 | for (n = 0; n < 32 && col < FIRST_PSEUDO_REGISTER; n++, col++) | |
776 | if (TEST_HARD_REG_BIT (web->usable_regs, col)) | |
777 | u |= 1 << n; | |
778 | ra_debug_msg (DUMP_IGRAPH_M, " %u", u); | |
779 | if (col >= FIRST_PSEUDO_REGISTER) | |
780 | break; | |
781 | } | |
782 | ra_debug_msg (DUMP_IGRAPH_M, "\n"); | |
783 | } | |
784 | if (numc) | |
785 | { | |
786 | ra_debug_msg (DUMP_IGRAPH_M, "c %d", web->id); | |
787 | for (cl = web->conflict_list; cl; cl = cl->next) | |
788 | { | |
789 | if (cl->t->id < web->id) | |
790 | ra_debug_msg (DUMP_IGRAPH_M, " %d", cl->t->id); | |
791 | } | |
792 | ra_debug_msg (DUMP_IGRAPH_M, "\n"); | |
793 | } | |
794 | } | |
795 | ra_debug_msg (DUMP_IGRAPH_M, "e\n"); | |
796 | } | |
797 | ||
798 | /* This runs after colorization and changing the insn stream. | |
799 | It temporarily replaces all pseudo registers with their colors, | |
800 | and emits information, if the resulting insns are strictly valid. */ | |
801 | ||
802 | void | |
803 | dump_constraints () | |
804 | { | |
805 | rtx insn; | |
806 | int i; | |
807 | if (!rtl_dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0) | |
808 | return; | |
809 | for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) | |
810 | if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG) | |
811 | REGNO (regno_reg_rtx[i]) | |
812 | = ra_reg_renumber[i] >= 0 ? ra_reg_renumber[i] : i; | |
813 | for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) | |
814 | if (INSN_P (insn)) | |
815 | { | |
816 | int code; | |
817 | int uid = INSN_UID (insn); | |
818 | int o; | |
819 | /* Don't simply force rerecognition, as combine might left us | |
820 | with some unrecongnizable ones, which later leads to aborts | |
821 | in regclass, if we now destroy the remembered INSN_CODE(). */ | |
822 | /*INSN_CODE (insn) = -1;*/ | |
823 | code = recog_memoized (insn); | |
824 | if (code < 0) | |
825 | { | |
826 | ra_debug_msg (DUMP_CONSTRAINTS, | |
827 | "%d: asm insn or not recognizable.\n", uid); | |
828 | continue; | |
829 | } | |
830 | ra_debug_msg (DUMP_CONSTRAINTS, | |
831 | "%d: code %d {%s}, %d operands, constraints: ", | |
832 | uid, code, insn_data[code].name, recog_data.n_operands); | |
833 | extract_insn (insn); | |
834 | /*preprocess_constraints ();*/ | |
835 | for (o = 0; o < recog_data.n_operands; o++) | |
836 | { | |
837 | ra_debug_msg (DUMP_CONSTRAINTS, | |
838 | "%d:%s ", o, recog_data.constraints[o]); | |
839 | } | |
840 | if (constrain_operands (1)) | |
841 | ra_debug_msg (DUMP_CONSTRAINTS, "matches strictly alternative %d", | |
842 | which_alternative); | |
843 | else | |
844 | ra_debug_msg (DUMP_CONSTRAINTS, "doesn't match strictly"); | |
845 | ra_debug_msg (DUMP_CONSTRAINTS, "\n"); | |
846 | } | |
847 | for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++) | |
848 | if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG) | |
849 | REGNO (regno_reg_rtx[i]) = i; | |
850 | } | |
851 | ||
852 | /* This counts and emits the cumulated cost of all spilled webs, | |
853 | preceded by a custom message MSG, with debug level LEVEL. */ | |
854 | ||
855 | void | |
856 | dump_graph_cost (level, msg) | |
857 | unsigned int level; | |
858 | const char *msg; | |
859 | { | |
860 | unsigned int i; | |
861 | unsigned HOST_WIDE_INT cost; | |
cb5c5698 | 862 | if (!rtl_dump_file || (debug_new_regalloc & level) == 0) |
863 | return; | |
864 | ||
865 | cost = 0; | |
866 | for (i = 0; i < num_webs; i++) | |
867 | { | |
868 | struct web *web = id2web[i]; | |
869 | if (alias (web)->type == SPILLED) | |
870 | cost += web->orig_spill_cost; | |
871 | } | |
6e898352 | 872 | ra_debug_msg (level, " spill cost of graph (%s) = ", msg ? msg : ""); |
873 | ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, cost); | |
874 | ra_debug_msg (level, "\n"); | |
cb5c5698 | 875 | } |
876 | ||
877 | /* Dump the color assignment per web, the coalesced and spilled webs. */ | |
878 | ||
879 | void | |
880 | dump_ra (df) | |
881 | struct df *df ATTRIBUTE_UNUSED; | |
882 | { | |
883 | struct web *web; | |
884 | struct dlist *d; | |
885 | if (!rtl_dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0) | |
886 | return; | |
887 | ||
888 | ra_debug_msg (DUMP_RESULTS, "\nColored:\n"); | |
889 | for (d = WEBS(COLORED); d; d = d->next) | |
890 | { | |
891 | web = DLIST_WEB (d); | |
892 | ra_debug_msg (DUMP_RESULTS, " %4d : color %d\n", web->id, web->color); | |
893 | } | |
894 | ra_debug_msg (DUMP_RESULTS, "\nCoalesced:\n"); | |
895 | for (d = WEBS(COALESCED); d; d = d->next) | |
896 | { | |
897 | web = DLIST_WEB (d); | |
898 | ra_debug_msg (DUMP_RESULTS, " %4d : to web %d, color %d\n", web->id, | |
899 | alias (web)->id, web->color); | |
900 | } | |
901 | ra_debug_msg (DUMP_RESULTS, "\nSpilled:\n"); | |
902 | for (d = WEBS(SPILLED); d; d = d->next) | |
903 | { | |
904 | web = DLIST_WEB (d); | |
905 | ra_debug_msg (DUMP_RESULTS, " %4d\n", web->id); | |
906 | } | |
907 | ra_debug_msg (DUMP_RESULTS, "\n"); | |
908 | dump_cost (DUMP_RESULTS); | |
909 | } | |
910 | ||
911 | /* Calculate and dump the cumulated costs of certain types of insns | |
912 | (loads, stores and copies). */ | |
913 | ||
914 | void | |
915 | dump_static_insn_cost (file, message, prefix) | |
916 | FILE *file; | |
917 | const char *message; | |
918 | const char *prefix; | |
919 | { | |
920 | struct cost | |
921 | { | |
922 | unsigned HOST_WIDE_INT cost; | |
923 | unsigned int count; | |
924 | }; | |
cb5c5698 | 925 | basic_block bb; |
6e898352 | 926 | struct cost load, store, regcopy, selfcopy, overall; |
927 | memset (&load, 0, sizeof(load)); | |
928 | memset (&store, 0, sizeof(store)); | |
929 | memset (®copy, 0, sizeof(regcopy)); | |
930 | memset (&selfcopy, 0, sizeof(selfcopy)); | |
931 | memset (&overall, 0, sizeof(overall)); | |
cb5c5698 | 932 | |
933 | if (!file) | |
934 | return; | |
935 | ||
936 | FOR_EACH_BB (bb) | |
937 | { | |
938 | unsigned HOST_WIDE_INT block_cost = bb->frequency; | |
939 | rtx insn, set; | |
940 | for (insn = bb->head; insn; insn = NEXT_INSN (insn)) | |
941 | { | |
942 | /* Yes, yes. We don't calculate the costs precisely. | |
943 | Only for "simple enough" insns. Those containing single | |
944 | sets only. */ | |
945 | if (INSN_P (insn) && ((set = single_set (insn)) != NULL)) | |
946 | { | |
947 | rtx src = SET_SRC (set); | |
948 | rtx dest = SET_DEST (set); | |
949 | struct cost *pcost = NULL; | |
950 | overall.cost += block_cost; | |
951 | overall.count++; | |
952 | if (rtx_equal_p (src, dest)) | |
953 | pcost = &selfcopy; | |
954 | else if (GET_CODE (src) == GET_CODE (dest) | |
955 | && ((GET_CODE (src) == REG) | |
956 | || (GET_CODE (src) == SUBREG | |
957 | && GET_CODE (SUBREG_REG (src)) == REG | |
958 | && GET_CODE (SUBREG_REG (dest)) == REG))) | |
959 | pcost = ®copy; | |
960 | else | |
961 | { | |
962 | if (GET_CODE (src) == SUBREG) | |
963 | src = SUBREG_REG (src); | |
964 | if (GET_CODE (dest) == SUBREG) | |
965 | dest = SUBREG_REG (dest); | |
966 | if (GET_CODE (src) == MEM && GET_CODE (dest) != MEM | |
967 | && memref_is_stack_slot (src)) | |
968 | pcost = &load; | |
969 | else if (GET_CODE (src) != MEM && GET_CODE (dest) == MEM | |
970 | && memref_is_stack_slot (dest)) | |
971 | pcost = &store; | |
972 | } | |
973 | if (pcost) | |
974 | { | |
975 | pcost->cost += block_cost; | |
976 | pcost->count++; | |
977 | } | |
978 | } | |
979 | if (insn == bb->end) | |
980 | break; | |
981 | } | |
982 | } | |
983 | ||
984 | if (!prefix) | |
985 | prefix = ""; | |
986 | fprintf (file, "static insn cost %s\n", message ? message : ""); | |
8397f403 | 987 | fprintf (file, " %soverall:\tnum=%6d\tcost=", prefix, overall.count); |
988 | fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, overall.cost); | |
989 | fprintf (file, "\n"); | |
990 | fprintf (file, " %sloads:\tnum=%6d\tcost=", prefix, load.count); | |
991 | fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, load.cost); | |
992 | fprintf (file, "\n"); | |
993 | fprintf (file, " %sstores:\tnum=%6d\tcost=", prefix, store.count); | |
994 | fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, store.cost); | |
995 | fprintf (file, "\n"); | |
996 | fprintf (file, " %sregcopy:\tnum=%6d\tcost=", prefix, regcopy.count); | |
997 | fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, regcopy.cost); | |
998 | fprintf (file, "\n"); | |
999 | fprintf (file, " %sselfcpy:\tnum=%6d\tcost=", prefix, selfcopy.count); | |
1000 | fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, selfcopy.cost); | |
1001 | fprintf (file, "\n"); | |
cb5c5698 | 1002 | } |
1003 | ||
1004 | /* Returns nonzero, if WEB1 and WEB2 have some possible | |
1005 | hardregs in common. */ | |
1006 | ||
1007 | int | |
1008 | web_conflicts_p (web1, web2) | |
1009 | struct web *web1; | |
1010 | struct web *web2; | |
1011 | { | |
1012 | if (web1->type == PRECOLORED && web2->type == PRECOLORED) | |
1013 | return 0; | |
1014 | ||
1015 | if (web1->type == PRECOLORED) | |
1016 | return TEST_HARD_REG_BIT (web2->usable_regs, web1->regno); | |
1017 | ||
1018 | if (web2->type == PRECOLORED) | |
1019 | return TEST_HARD_REG_BIT (web1->usable_regs, web2->regno); | |
1020 | ||
1021 | return hard_regs_intersect_p (&web1->usable_regs, &web2->usable_regs); | |
1022 | } | |
1023 | ||
1024 | /* Dump all uids of insns in which WEB is mentioned. */ | |
1025 | ||
1026 | void | |
1027 | dump_web_insns (web) | |
1028 | struct web *web; | |
1029 | { | |
1030 | unsigned int i; | |
1031 | ||
1032 | ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", | |
1033 | web->id, web->regno, web->add_hardregs, | |
1034 | reg_class_names[web->regclass], | |
1035 | web->num_freedom, web->num_conflicts); | |
1036 | ra_debug_msg (DUMP_EVER, " def insns:"); | |
1037 | ||
1038 | for (i = 0; i < web->num_defs; ++i) | |
1039 | { | |
1040 | ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn)); | |
1041 | } | |
1042 | ||
1043 | ra_debug_msg (DUMP_EVER, "\n use insns:"); | |
1044 | for (i = 0; i < web->num_uses; ++i) | |
1045 | { | |
1046 | ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn)); | |
1047 | } | |
1048 | ra_debug_msg (DUMP_EVER, "\n"); | |
1049 | } | |
1050 | ||
1051 | /* Dump conflicts for web WEB. */ | |
1052 | ||
1053 | void | |
1054 | dump_web_conflicts (web) | |
1055 | struct web *web; | |
1056 | { | |
1057 | int num = 0; | |
1058 | unsigned int def2; | |
1059 | ||
1060 | ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n", | |
1061 | web->id, web->regno, web->add_hardregs, | |
1062 | reg_class_names[web->regclass], | |
1063 | web->num_freedom, web->num_conflicts); | |
1064 | ||
1065 | for (def2 = 0; def2 < num_webs; def2++) | |
1066 | if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2) | |
1067 | { | |
1068 | if ((num % 9) == 5) | |
1069 | ra_debug_msg (DUMP_EVER, "\n "); | |
1070 | num++; | |
1071 | ||
1072 | ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno); | |
1073 | if (id2web[def2]->add_hardregs) | |
1074 | ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs); | |
1075 | ||
1076 | if (web_conflicts_p (web, id2web[def2])) | |
1077 | ra_debug_msg (DUMP_EVER, "/x"); | |
1078 | ||
1079 | if (id2web[def2]->type == SELECT) | |
1080 | ra_debug_msg (DUMP_EVER, "/s"); | |
1081 | ||
1082 | if (id2web[def2]->type == COALESCED) | |
1083 | ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id); | |
1084 | } | |
1085 | ra_debug_msg (DUMP_EVER, "\n"); | |
1086 | { | |
1087 | struct conflict_link *wl; | |
1088 | num = 0; | |
1089 | ra_debug_msg (DUMP_EVER, "By conflicts: "); | |
1090 | for (wl = web->conflict_list; wl; wl = wl->next) | |
1091 | { | |
1092 | struct web* w = wl->t; | |
1093 | if ((num % 9) == 8) | |
1094 | ra_debug_msg (DUMP_EVER, "\n "); | |
1095 | num++; | |
1096 | ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno, | |
1097 | web_conflicts_p (web, w) ? "+" : ""); | |
1098 | } | |
1099 | ra_debug_msg (DUMP_EVER, "\n"); | |
1100 | } | |
1101 | } | |
1102 | ||
1103 | /* Output HARD_REG_SET to stderr. */ | |
1104 | ||
1105 | void | |
1106 | debug_hard_reg_set (set) | |
1107 | HARD_REG_SET set; | |
1108 | { | |
1109 | int i; | |
1110 | for (i=0; i < FIRST_PSEUDO_REGISTER; ++i) | |
1111 | { | |
1112 | if (TEST_HARD_REG_BIT (set, i)) | |
1113 | { | |
1114 | fprintf (stderr, "%s ", reg_names[i]); | |
1115 | } | |
1116 | } | |
1117 | fprintf (stderr, "\n"); | |
1118 | } | |
1119 | ||
1120 | /* | |
1121 | vim:cinoptions={.5s,g0,p5,t0,(0,^-0.5s,n-0.5s:tw=78:cindent:sw=4: | |
1122 | */ |