00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022 #include "system.h"
00023 #include "rtl.h"
00024 #include "insn-config.h"
00025 #include "recog.h"
00026 #include "function.h"
00027 #include "hard-reg-set.h"
00028 #include "basic-block.h"
00029 #include "df.h"
00030 #include "output.h"
00031 #include "ra.h"
00032 #include "tm_p.h"
00033
00034
00035
00036
00037 static void ra_print_rtx_1op PARAMS ((FILE *, rtx));
00038 static void ra_print_rtx_2op PARAMS ((FILE *, rtx));
00039 static void ra_print_rtx_3op PARAMS ((FILE *, rtx));
00040 static void ra_print_rtx_object PARAMS ((FILE *, rtx));
00041
00042
00043 static const char *const reg_class_names[] = REG_CLASS_NAMES;
00044
00045
00046
00047
00048 void
00049 ra_debug_msg VPARAMS ((unsigned int level, const char *format, ...))
00050 {
00051 VA_OPEN (ap, format);
00052 VA_FIXEDARG (ap, unsigned int, level);
00053 VA_FIXEDARG (ap, const char *, format);
00054 if ((debug_new_regalloc & level) != 0 && rtl_dump_file != NULL)
00055 vfprintf (rtl_dump_file, format, ap);
00056 VA_CLOSE (ap);
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 static void
00071 ra_print_rtx_1op (file, x)
00072 FILE *file;
00073 rtx x;
00074 {
00075 enum rtx_code code = GET_CODE (x);
00076 rtx op0 = XEXP (x, 0);
00077 switch (code)
00078 {
00079 case NEG:
00080 case NOT:
00081 fputs ((code == NEG) ? "-(" : "~(", file);
00082 ra_print_rtx (file, op0, 0);
00083 fputs (")", file);
00084 break;
00085 case HIGH:
00086 fputs ("hi(", file);
00087 ra_print_rtx (file, op0, 0);
00088 fputs (")", file);
00089 break;
00090 default:
00091 fprintf (file, "%s", GET_RTX_NAME (code));
00092 if (GET_MODE (x) != VOIDmode)
00093 fprintf (file, ":%s(", GET_MODE_NAME (GET_MODE (x)));
00094 else
00095 fputs ("(", file);
00096 ra_print_rtx (file, op0, 0);
00097 fputs (")", file);
00098 break;
00099 }
00100 }
00101
00102
00103
00104
00105
00106 static void
00107 ra_print_rtx_2op (file, x)
00108 FILE *file;
00109 rtx x;
00110 {
00111 int infix = 1;
00112 const char *opname = "shitop";
00113 enum rtx_code code = GET_CODE (x);
00114 rtx op0 = XEXP (x, 0);
00115 rtx op1 = XEXP (x, 1);
00116 switch (code)
00117 {
00118
00119 case COMPARE: opname = "?"; break;
00120 case MINUS: opname = "-"; break;
00121 case DIV: opname = "/"; break;
00122 case UDIV: opname = "u/"; break;
00123 case MOD: opname = "%"; break;
00124 case UMOD: opname = "u%"; break;
00125 case ASHIFT: opname = "<<"; break;
00126 case ASHIFTRT: opname = "a>>"; break;
00127 case LSHIFTRT: opname = "l>>"; break;
00128
00129 case PLUS: opname = "+"; break;
00130 case MULT: opname = "*"; break;
00131 case AND: opname = "&"; break;
00132 case IOR: opname = "|"; break;
00133 case XOR: opname = "^"; break;
00134
00135 case NE: opname = "!="; break;
00136 case EQ: opname = "=="; break;
00137 case GE: opname = "s>="; break;
00138 case GT: opname = "s>"; break;
00139 case LE: opname = "s<="; break;
00140 case LT: opname = "s<"; break;
00141 case GEU: opname = "u>="; break;
00142 case GTU: opname = "u>"; break;
00143 case LEU: opname = "u<="; break;
00144 case LTU: opname = "u<"; break;
00145 default:
00146 infix = 0;
00147 opname = GET_RTX_NAME (code);
00148 break;
00149 }
00150 if (infix)
00151 {
00152 fputs ("(", file);
00153 ra_print_rtx (file, op0, 0);
00154 fprintf (file, " %s ", opname);
00155 ra_print_rtx (file, op1, 0);
00156 fputs (")", file);
00157 }
00158 else
00159 {
00160 fprintf (file, "%s(", opname);
00161 ra_print_rtx (file, op0, 0);
00162 fputs (", ", file);
00163 ra_print_rtx (file, op1, 0);
00164 fputs (")", file);
00165 }
00166 }
00167
00168
00169
00170
00171 static void
00172 ra_print_rtx_3op (file, x)
00173 FILE *file;
00174 rtx x;
00175 {
00176 enum rtx_code code = GET_CODE (x);
00177 rtx op0 = XEXP (x, 0);
00178 rtx op1 = XEXP (x, 1);
00179 rtx op2 = XEXP (x, 2);
00180 if (code == IF_THEN_ELSE)
00181 {
00182 ra_print_rtx (file, op0, 0);
00183 fputs (" ? ", file);
00184 ra_print_rtx (file, op1, 0);
00185 fputs (" : ", file);
00186 ra_print_rtx (file, op2, 0);
00187 }
00188 else
00189 {
00190
00191 fprintf (file, "%s:%s(", GET_RTX_NAME (code),
00192 GET_MODE_NAME (GET_MODE (x)));
00193 ra_print_rtx (file, op0, 0);
00194 fputs (", ", file);
00195 ra_print_rtx (file, op1, 0);
00196 fputs (", ", file);
00197 ra_print_rtx (file, op2, 0);
00198 fputs (")", file);
00199 }
00200 }
00201
00202
00203
00204
00205
00206
00207
00208 static void
00209 ra_print_rtx_object (file, x)
00210 FILE *file;
00211 rtx x;
00212 {
00213 enum rtx_code code = GET_CODE (x);
00214 enum machine_mode mode = GET_MODE (x);
00215 switch (code)
00216 {
00217 case CONST_INT:
00218 fprintf (file, HOST_WIDE_INT_PRINT_DEC, XWINT (x, 0));
00219 break;
00220 case CONST_DOUBLE:
00221 {
00222 int i, num = 0;
00223 const char *fmt = GET_RTX_FORMAT (code);
00224 fputs ("dbl(", file);
00225 for (i = 0; i < GET_RTX_LENGTH (code); i++)
00226 {
00227 if (num)
00228 fputs (", ", file);
00229 if (fmt[i] == 'e' && XEXP (x, i))
00230
00231 {
00232 ra_print_rtx (file, XEXP (x, i), 0);
00233 num++;
00234 }
00235 else if (fmt[i] == 'w')
00236 {
00237 fprintf (file, HOST_WIDE_INT_PRINT_HEX, XWINT (x, i));
00238 num++;
00239 }
00240 }
00241 break;
00242 }
00243 case CONST_STRING: fprintf (file, "\"%s\"", XSTR (x, 0)); break;
00244 case CONST: fputs ("const(", file);
00245 ra_print_rtx (file, XEXP (x, 0), 0);
00246 fputs (")", file);
00247 break;
00248 case PC: fputs ("pc", file); break;
00249 case REG:
00250 {
00251 int regno = REGNO (x);
00252 if (regno < FIRST_PSEUDO_REGISTER)
00253 {
00254 int i, nregs = HARD_REGNO_NREGS (regno, mode);
00255 if (nregs > 1)
00256 fputs ("[", file);
00257 for (i = 0; i < nregs; i++)
00258 {
00259 if (i)
00260 fputs (", ", file);
00261 if (reg_names[regno+i] && *reg_names[regno + i])
00262 fprintf (file, "%s", reg_names[regno + i]);
00263 else
00264 fprintf (file, "h%d", regno + i);
00265 }
00266 if (nregs > 1)
00267 fputs ("]", file);
00268 }
00269 else
00270 fprintf (file, "p%d", regno);
00271 break;
00272 }
00273 case SUBREG:
00274 {
00275 rtx sub = SUBREG_REG (x);
00276 int ofs = SUBREG_BYTE (x);
00277 if (GET_CODE (sub) == REG
00278 && REGNO (sub) < FIRST_PSEUDO_REGISTER)
00279 {
00280 int regno = REGNO (sub);
00281 int i, nregs = HARD_REGNO_NREGS (regno, mode);
00282 regno += subreg_regno_offset (regno, GET_MODE (sub),
00283 ofs, mode);
00284 if (nregs > 1)
00285 fputs ("[", file);
00286 for (i = 0; i < nregs; i++)
00287 {
00288 if (i)
00289 fputs (", ", file);
00290 if (reg_names[regno+i])
00291 fprintf (file, "%s", reg_names[regno + i]);
00292 else
00293 fprintf (file, "h%d", regno + i);
00294 }
00295 if (nregs > 1)
00296 fputs ("]", file);
00297 }
00298 else
00299 {
00300 ra_print_rtx (file, sub, 0);
00301 fprintf (file, ":[%s+%d]", GET_MODE_NAME (mode), ofs);
00302 }
00303 break;
00304 }
00305 case SCRATCH: fputs ("scratch", file); break;
00306 case CONCAT: ra_print_rtx_2op (file, x); break;
00307 case HIGH: ra_print_rtx_1op (file, x); break;
00308 case LO_SUM:
00309 fputs ("(", file);
00310 ra_print_rtx (file, XEXP (x, 0), 0);
00311 fputs (" + lo(", file);
00312 ra_print_rtx (file, XEXP (x, 1), 0);
00313 fputs ("))", file);
00314 break;
00315 case MEM: fputs ("[", file);
00316 ra_print_rtx (file, XEXP (x, 0), 0);
00317 fprintf (file, "]:%s", GET_MODE_NAME (GET_MODE (x)));
00318
00319 break;
00320 case LABEL_REF:
00321 {
00322 rtx sub = XEXP (x, 0);
00323 if (GET_CODE (sub) == NOTE
00324 && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
00325 fprintf (file, "(deleted uid=%d)", INSN_UID (sub));
00326 else if (GET_CODE (sub) == CODE_LABEL)
00327 fprintf (file, "L%d", CODE_LABEL_NUMBER (sub));
00328 else
00329 fprintf (file, "(nonlabel uid=%d)", INSN_UID (sub));
00330 }
00331 break;
00332 case SYMBOL_REF:
00333 fprintf (file, "sym(\"%s\")", XSTR (x, 0)); break;
00334 case CC0: fputs ("cc0", file); break;
00335 default: print_inline_rtx (file, x, 0); break;
00336 }
00337 }
00338
00339
00340
00341
00342
00343
00344 void
00345 ra_print_rtx (file, x, with_pn)
00346 FILE *file;
00347 rtx x;
00348 int with_pn;
00349 {
00350 enum rtx_code code;
00351 char class;
00352 int unhandled = 0;
00353 if (!x)
00354 return;
00355 code = GET_CODE (x);
00356 class = GET_RTX_CLASS (code);
00357
00358
00359 if (INSN_P (x) || code == NOTE || code == CODE_LABEL || code == BARRIER)
00360 {
00361 if (INSN_P (x))
00362 fputs (" ", file);
00363
00364 if (code == BARRIER)
00365 fputs ("; ", file);
00366 else if (code == NOTE)
00367
00368 fprintf (file, "\t\t\t\t\t; ");
00369 else if (code == CODE_LABEL)
00370
00371 {
00372 fprintf (file, "L%d:\t; ", CODE_LABEL_NUMBER (x));
00373 if (LABEL_NAME (x))
00374 fprintf (file, "(%s) ", LABEL_NAME (x));
00375 switch (LABEL_KIND (x))
00376 {
00377 case LABEL_NORMAL: break;
00378 case LABEL_STATIC_ENTRY: fputs (" (entry)", file); break;
00379 case LABEL_GLOBAL_ENTRY: fputs (" (global entry)", file); break;
00380 case LABEL_WEAK_ENTRY: fputs (" (weak entry)", file); break;
00381 default: abort();
00382 }
00383 fprintf (file, " [%d uses] uid=(", LABEL_NUSES (x));
00384 }
00385 fprintf (file, "%d", INSN_UID (x));
00386 if (with_pn)
00387 fprintf (file, " %d %d", PREV_INSN (x) ? INSN_UID (PREV_INSN (x)) : 0,
00388 NEXT_INSN (x) ? INSN_UID (NEXT_INSN (x)) : 0);
00389 if (code == BARRIER)
00390 fputs (" -------- barrier ---------", file);
00391 else if (code == CODE_LABEL)
00392 fputs (")", file);
00393 else if (code == NOTE)
00394 {
00395 int ln = NOTE_LINE_NUMBER (x);
00396 if (ln >= (int) NOTE_INSN_BIAS && ln < (int) NOTE_INSN_MAX)
00397 fprintf (file, " %s", GET_NOTE_INSN_NAME (ln));
00398 else
00399 {
00400 fprintf (file, " line %d", ln);
00401 if (NOTE_SOURCE_FILE (x))
00402 fprintf (file, ":%s", NOTE_SOURCE_FILE (x));
00403 }
00404 }
00405 else
00406 {
00407 fprintf (file, "\t");
00408 ra_print_rtx (file, PATTERN (x), 0);
00409 }
00410 return;
00411 }
00412 switch (code)
00413 {
00414
00415 case PARALLEL:
00416 {
00417 int j;
00418 for (j = 0; j < XVECLEN (x, 0); j++)
00419 {
00420 if (j)
00421 fputs ("\t;; ", file);
00422 ra_print_rtx (file, XVECEXP (x, 0, j), 0);
00423 }
00424 break;
00425 }
00426 case UNSPEC: case UNSPEC_VOLATILE:
00427 {
00428 int j;
00429 fprintf (file, "unspec%s(%d",
00430 (code == UNSPEC) ? "" : "_vol", XINT (x, 1));
00431 for (j = 0; j < XVECLEN (x, 0); j++)
00432 {
00433 fputs (", ", file);
00434 ra_print_rtx (file, XVECEXP (x, 0, j), 0);
00435 }
00436 fputs (")", file);
00437 break;
00438 }
00439 case SET:
00440 if (GET_CODE (SET_DEST (x)) == PC)
00441 {
00442 if (GET_CODE (SET_SRC (x)) == IF_THEN_ELSE
00443 && GET_CODE (XEXP (SET_SRC(x), 2)) == PC)
00444 {
00445 fputs ("if ", file);
00446 ra_print_rtx (file, XEXP (SET_SRC (x), 0), 0);
00447 fputs (" jump ", file);
00448 ra_print_rtx (file, XEXP (SET_SRC (x), 1), 0);
00449 }
00450 else
00451 {
00452 fputs ("jump ", file);
00453 ra_print_rtx (file, SET_SRC (x), 0);
00454 }
00455 }
00456 else
00457 {
00458 ra_print_rtx (file, SET_DEST (x), 0);
00459 fputs (" <= ", file);
00460 ra_print_rtx (file, SET_SRC (x), 0);
00461 }
00462 break;
00463 case USE:
00464 fputs ("use <= ", file);
00465 ra_print_rtx (file, XEXP (x, 0), 0);
00466 break;
00467 case CLOBBER:
00468 ra_print_rtx (file, XEXP (x, 0), 0);
00469 fputs (" <= clobber", file);
00470 break;
00471 case CALL:
00472 fputs ("call ", file);
00473 ra_print_rtx (file, XEXP (x, 0), 0);
00474 fputs (" numargs=", file);
00475 ra_print_rtx (file, XEXP (x, 1), 0);
00476 break;
00477 case RETURN:
00478 fputs ("return", file);
00479 break;
00480 case TRAP_IF:
00481 fputs ("if (", file);
00482 ra_print_rtx (file, XEXP (x, 0), 0);
00483 fputs (") trap ", file);
00484 ra_print_rtx (file, XEXP (x, 1), 0);
00485 break;
00486 case RESX:
00487 fprintf (file, "resx from region %d", XINT (x, 0));
00488 break;
00489
00490
00491 case SUBREG: ra_print_rtx_object (file, x); break;
00492 case STRICT_LOW_PART:
00493 fputs ("low(", file);
00494 ra_print_rtx (file, XEXP (x, 0), 0);
00495 fputs (")", file);
00496 break;
00497 default:
00498 unhandled = 1;
00499 break;
00500 }
00501 if (!unhandled)
00502 return;
00503 if (class == '1')
00504 ra_print_rtx_1op (file, x);
00505 else if (class == '2' || class == 'c' || class == '<')
00506 ra_print_rtx_2op (file, x);
00507 else if (class == '3' || class == 'b')
00508 ra_print_rtx_3op (file, x);
00509 else if (class == 'o')
00510 ra_print_rtx_object (file, x);
00511 else
00512 print_inline_rtx (file, x, 0);
00513 }
00514
00515
00516
00517 void
00518 ra_print_rtx_top (file, x, with_pn)
00519 FILE *file;
00520 rtx x;
00521 int with_pn;
00522 {
00523 ra_print_rtx (file, x, with_pn);
00524 fprintf (file, "\n");
00525 }
00526
00527
00528
00529 void
00530 ra_debug_rtx (x)
00531 rtx x;
00532 {
00533 ra_print_rtx_top (stderr, x, 1);
00534 }
00535
00536
00537
00538
00539 void
00540 ra_debug_bbi (bbi)
00541 int bbi;
00542 {
00543 basic_block bb = BASIC_BLOCK (bbi);
00544 rtx insn;
00545 for (insn = bb->head; insn; insn = NEXT_INSN (insn))
00546 {
00547 ra_print_rtx_top (stderr, insn, (insn == bb->head || insn == bb->end));
00548 fprintf (stderr, "\n");
00549 if (insn == bb->end)
00550 break;
00551 }
00552 }
00553
00554
00555
00556
00557 void
00558 ra_debug_insns (insn, num)
00559 rtx insn;
00560 int num;
00561 {
00562 int i, count = (num == 0 ? 1 : num < 0 ? -num : num);
00563 if (num < 0)
00564 for (i = count / 2; i > 0 && PREV_INSN (insn); i--)
00565 insn = PREV_INSN (insn);
00566 for (i = count; i > 0 && insn; insn = NEXT_INSN (insn), i--)
00567 {
00568 if (GET_CODE (insn) == CODE_LABEL)
00569 fprintf (stderr, "\n");
00570 ra_print_rtx_top (stderr, insn, (i == count || i == 1));
00571 }
00572 }
00573
00574
00575
00576
00577
00578 void
00579 ra_print_rtl_with_bb (file, insn)
00580 FILE *file;
00581 rtx insn;
00582 {
00583 basic_block last_bb, bb;
00584 unsigned int num = 0;
00585 if (!insn)
00586 fputs ("nil", file);
00587 last_bb = NULL;
00588 for (; insn; insn = NEXT_INSN (insn))
00589 {
00590 if (GET_CODE (insn) == BARRIER)
00591 bb = NULL;
00592 else
00593 bb = BLOCK_FOR_INSN (insn);
00594 if (bb != last_bb)
00595 {
00596 if (last_bb)
00597 fprintf (file, ";; End of basic block %d\n", last_bb->index);
00598 if (bb)
00599 fprintf (file, ";; Begin of basic block %d\n", bb->index);
00600 last_bb = bb;
00601 }
00602 if (GET_CODE (insn) == CODE_LABEL)
00603 fputc ('\n', file);
00604 if (GET_CODE (insn) == NOTE)
00605 {
00606
00607
00608 if (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK
00609 && (flag_ra_dump_notes
00610 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED
00611 || NOTE_LINE_NUMBER (insn) == NOTE_INSN_DELETED_LABEL))
00612 {
00613 ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn)));
00614 num++;
00615 }
00616 }
00617 else
00618 {
00619 ra_print_rtx_top (file, insn, (num == 0 || !NEXT_INSN (insn)));
00620 num++;
00621 }
00622 }
00623 }
00624
00625
00626
00627
00628 void
00629 dump_number_seen ()
00630 {
00631 #define N 17
00632 int num[N];
00633 int i;
00634
00635 for (i = 0; i < N; i++)
00636 num[i] = 0;
00637 for (i = 0; i < get_max_uid (); i++)
00638 if (number_seen[i] < N - 1)
00639 num[number_seen[i]]++;
00640 else
00641 num[N - 1]++;
00642 for (i = 0; i < N - 1; i++)
00643 if (num[i])
00644 ra_debug_msg (DUMP_PROCESS, "%d insns seen %d times\n", num[i], i);
00645 if (num[N - 1])
00646 ra_debug_msg (DUMP_PROCESS, "%d insns seen %d and more times\n", num[i],
00647 N - 1);
00648 ra_debug_msg (DUMP_PROCESS, "from overall %d insns\n", get_max_uid ());
00649 #undef N
00650 }
00651
00652
00653
00654 void
00655 dump_igraph (df)
00656 struct df *df ATTRIBUTE_UNUSED;
00657 {
00658 struct move_list *ml;
00659 unsigned int def1, def2;
00660 int num = 0;
00661 int num2;
00662 unsigned int i;
00663 if (!rtl_dump_file || (debug_new_regalloc & (DUMP_IGRAPH | DUMP_WEBS)) == 0)
00664 return;
00665 ra_debug_msg (DUMP_IGRAPH, "conflicts:\n ");
00666 for (def1 = 0; def1 < num_webs; def1++)
00667 {
00668 int num1 = num;
00669 for (num2=0, def2 = 0; def2 < num_webs; def2++)
00670 if (def1 != def2 && TEST_BIT (igraph, igraph_index (def1, def2)))
00671 {
00672 if (num1 == num)
00673 {
00674 if (SUBWEB_P (ID2WEB (def1)))
00675 ra_debug_msg (DUMP_IGRAPH, "%d (SUBREG %d, %d) with ", def1,
00676 ID2WEB (def1)->regno,
00677 SUBREG_BYTE (ID2WEB (def1)->orig_x));
00678 else
00679 ra_debug_msg (DUMP_IGRAPH, "%d (REG %d) with ", def1,
00680 ID2WEB (def1)->regno);
00681 }
00682 if ((num2 % 9) == 8)
00683 ra_debug_msg (DUMP_IGRAPH, "\n ");
00684 num++;
00685 num2++;
00686 if (SUBWEB_P (ID2WEB (def2)))
00687 ra_debug_msg (DUMP_IGRAPH, "%d(%d,%d) ", def2, ID2WEB (def2)->regno,
00688 SUBREG_BYTE (ID2WEB (def2)->orig_x));
00689 else
00690 ra_debug_msg (DUMP_IGRAPH, "%d(%d) ", def2, ID2WEB (def2)->regno);
00691 }
00692 if (num1 != num)
00693 ra_debug_msg (DUMP_IGRAPH, "\n ");
00694 }
00695 ra_debug_msg (DUMP_IGRAPH, "\n");
00696 for (ml = wl_moves; ml; ml = ml->next)
00697 if (ml->move)
00698 {
00699 ra_debug_msg (DUMP_IGRAPH, "move: insn %d: Web %d <-- Web %d\n",
00700 INSN_UID (ml->move->insn), ml->move->target_web->id,
00701 ml->move->source_web->id);
00702 }
00703 ra_debug_msg (DUMP_WEBS, "\nWebs:\n");
00704 for (i = 0; i < num_webs; i++)
00705 {
00706 struct web *web = ID2WEB (i);
00707
00708 ra_debug_msg (DUMP_WEBS, " %4d : regno %3d", i, web->regno);
00709 if (SUBWEB_P (web))
00710 {
00711 ra_debug_msg (DUMP_WEBS, " sub %d", SUBREG_BYTE (web->orig_x));
00712 ra_debug_msg (DUMP_WEBS, " par %d", find_web_for_subweb (web)->id);
00713 }
00714 ra_debug_msg (DUMP_WEBS, " +%d (span %d, cost ",
00715 web->add_hardregs, web->span_deaths);
00716 ra_debug_msg (DUMP_WEBS, HOST_WIDE_INT_PRINT_DEC, web->spill_cost);
00717 ra_debug_msg (DUMP_WEBS, ") (%s)", reg_class_names[web->regclass]);
00718 if (web->spill_temp == 1)
00719 ra_debug_msg (DUMP_WEBS, " (spilltemp)");
00720 else if (web->spill_temp == 2)
00721 ra_debug_msg (DUMP_WEBS, " (spilltem2)");
00722 else if (web->spill_temp == 3)
00723 ra_debug_msg (DUMP_WEBS, " (short)");
00724 if (web->type == PRECOLORED)
00725 ra_debug_msg (DUMP_WEBS, " (precolored, color=%d)", web->color);
00726 else if (find_web_for_subweb (web)->num_uses == 0)
00727 ra_debug_msg (DUMP_WEBS, " dead");
00728 if (web->crosses_call)
00729 ra_debug_msg (DUMP_WEBS, " xcall");
00730 if (web->regno >= max_normal_pseudo)
00731 ra_debug_msg (DUMP_WEBS, " stack");
00732 ra_debug_msg (DUMP_WEBS, "\n");
00733 }
00734 }
00735
00736
00737
00738
00739
00740 void
00741 dump_igraph_machine ()
00742 {
00743 unsigned int i;
00744
00745 if (!rtl_dump_file || (debug_new_regalloc & DUMP_IGRAPH_M) == 0)
00746 return;
00747 ra_debug_msg (DUMP_IGRAPH_M, "g %d %d\n", num_webs - num_subwebs,
00748 FIRST_PSEUDO_REGISTER);
00749 for (i = 0; i < num_webs - num_subwebs; i++)
00750 {
00751 struct web *web = ID2WEB (i);
00752 struct conflict_link *cl;
00753 int flags = 0;
00754 int numc = 0;
00755 int col = 0;
00756 flags = web->spill_temp & 0xF;
00757 flags |= ((web->type == PRECOLORED) ? 1 : 0) << 4;
00758 flags |= (web->add_hardregs & 0xF) << 5;
00759 for (cl = web->conflict_list; cl; cl = cl->next)
00760 if (cl->t->id < web->id)
00761 numc++;
00762 ra_debug_msg (DUMP_IGRAPH_M, "n %d %d %d %d %d %d %d\n",
00763 web->id, web->color, flags,
00764 (unsigned int)web->spill_cost, web->num_defs, web->num_uses,
00765 numc);
00766 if (web->type != PRECOLORED)
00767 {
00768 ra_debug_msg (DUMP_IGRAPH_M, "s %d", web->id);
00769 while (1)
00770 {
00771 unsigned int u = 0;
00772 int n;
00773 for (n = 0; n < 32 && col < FIRST_PSEUDO_REGISTER; n++, col++)
00774 if (TEST_HARD_REG_BIT (web->usable_regs, col))
00775 u |= 1 << n;
00776 ra_debug_msg (DUMP_IGRAPH_M, " %u", u);
00777 if (col >= FIRST_PSEUDO_REGISTER)
00778 break;
00779 }
00780 ra_debug_msg (DUMP_IGRAPH_M, "\n");
00781 }
00782 if (numc)
00783 {
00784 ra_debug_msg (DUMP_IGRAPH_M, "c %d", web->id);
00785 for (cl = web->conflict_list; cl; cl = cl->next)
00786 {
00787 if (cl->t->id < web->id)
00788 ra_debug_msg (DUMP_IGRAPH_M, " %d", cl->t->id);
00789 }
00790 ra_debug_msg (DUMP_IGRAPH_M, "\n");
00791 }
00792 }
00793 ra_debug_msg (DUMP_IGRAPH_M, "e\n");
00794 }
00795
00796
00797
00798
00799
00800 void
00801 dump_constraints ()
00802 {
00803 rtx insn;
00804 int i;
00805 if (!rtl_dump_file || (debug_new_regalloc & DUMP_CONSTRAINTS) == 0)
00806 return;
00807 for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++)
00808 if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG)
00809 REGNO (regno_reg_rtx[i])
00810 = ra_reg_renumber[i] >= 0 ? ra_reg_renumber[i] : i;
00811 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
00812 if (INSN_P (insn))
00813 {
00814 int code;
00815 int uid = INSN_UID (insn);
00816 int o;
00817
00818
00819
00820
00821 code = recog_memoized (insn);
00822 if (code < 0)
00823 {
00824 ra_debug_msg (DUMP_CONSTRAINTS,
00825 "%d: asm insn or not recognizable.\n", uid);
00826 continue;
00827 }
00828 ra_debug_msg (DUMP_CONSTRAINTS,
00829 "%d: code %d {%s}, %d operands, constraints: ",
00830 uid, code, insn_data[code].name, recog_data.n_operands);
00831 extract_insn (insn);
00832
00833 for (o = 0; o < recog_data.n_operands; o++)
00834 {
00835 ra_debug_msg (DUMP_CONSTRAINTS,
00836 "%d:%s ", o, recog_data.constraints[o]);
00837 }
00838 if (constrain_operands (1))
00839 ra_debug_msg (DUMP_CONSTRAINTS, "matches strictly alternative %d",
00840 which_alternative);
00841 else
00842 ra_debug_msg (DUMP_CONSTRAINTS, "doesn't match strictly");
00843 ra_debug_msg (DUMP_CONSTRAINTS, "\n");
00844 }
00845 for (i = FIRST_PSEUDO_REGISTER; i < ra_max_regno; i++)
00846 if (regno_reg_rtx[i] && GET_CODE (regno_reg_rtx[i]) == REG)
00847 REGNO (regno_reg_rtx[i]) = i;
00848 }
00849
00850
00851
00852
00853 void
00854 dump_graph_cost (level, msg)
00855 unsigned int level;
00856 const char *msg;
00857 {
00858 unsigned int i;
00859 unsigned HOST_WIDE_INT cost;
00860 if (!rtl_dump_file || (debug_new_regalloc & level) == 0)
00861 return;
00862
00863 cost = 0;
00864 for (i = 0; i < num_webs; i++)
00865 {
00866 struct web *web = id2web[i];
00867 if (alias (web)->type == SPILLED)
00868 cost += web->orig_spill_cost;
00869 }
00870 ra_debug_msg (level, " spill cost of graph (%s) = ", msg ? msg : "");
00871 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, cost);
00872 ra_debug_msg (level, "\n");
00873 }
00874
00875
00876
00877 void
00878 dump_ra (df)
00879 struct df *df ATTRIBUTE_UNUSED;
00880 {
00881 struct web *web;
00882 struct dlist *d;
00883 if (!rtl_dump_file || (debug_new_regalloc & DUMP_RESULTS) == 0)
00884 return;
00885
00886 ra_debug_msg (DUMP_RESULTS, "\nColored:\n");
00887 for (d = WEBS(COLORED); d; d = d->next)
00888 {
00889 web = DLIST_WEB (d);
00890 ra_debug_msg (DUMP_RESULTS, " %4d : color %d\n", web->id, web->color);
00891 }
00892 ra_debug_msg (DUMP_RESULTS, "\nCoalesced:\n");
00893 for (d = WEBS(COALESCED); d; d = d->next)
00894 {
00895 web = DLIST_WEB (d);
00896 ra_debug_msg (DUMP_RESULTS, " %4d : to web %d, color %d\n", web->id,
00897 alias (web)->id, web->color);
00898 }
00899 ra_debug_msg (DUMP_RESULTS, "\nSpilled:\n");
00900 for (d = WEBS(SPILLED); d; d = d->next)
00901 {
00902 web = DLIST_WEB (d);
00903 ra_debug_msg (DUMP_RESULTS, " %4d\n", web->id);
00904 }
00905 ra_debug_msg (DUMP_RESULTS, "\n");
00906 dump_cost (DUMP_RESULTS);
00907 }
00908
00909
00910
00911
00912 void
00913 dump_static_insn_cost (file, message, prefix)
00914 FILE *file;
00915 const char *message;
00916 const char *prefix;
00917 {
00918 struct cost
00919 {
00920 unsigned HOST_WIDE_INT cost;
00921 unsigned int count;
00922 };
00923 basic_block bb;
00924 struct cost load, store, regcopy, selfcopy, overall;
00925 memset (&load, 0, sizeof(load));
00926 memset (&store, 0, sizeof(store));
00927 memset (®copy, 0, sizeof(regcopy));
00928 memset (&selfcopy, 0, sizeof(selfcopy));
00929 memset (&overall, 0, sizeof(overall));
00930
00931 if (!file)
00932 return;
00933
00934 FOR_EACH_BB (bb)
00935 {
00936 unsigned HOST_WIDE_INT block_cost = bb->frequency;
00937 rtx insn, set;
00938 for (insn = bb->head; insn; insn = NEXT_INSN (insn))
00939 {
00940
00941
00942
00943 if (INSN_P (insn) && ((set = single_set (insn)) != NULL))
00944 {
00945 rtx src = SET_SRC (set);
00946 rtx dest = SET_DEST (set);
00947 struct cost *pcost = NULL;
00948 overall.cost += block_cost;
00949 overall.count++;
00950 if (rtx_equal_p (src, dest))
00951 pcost = &selfcopy;
00952 else if (GET_CODE (src) == GET_CODE (dest)
00953 && ((GET_CODE (src) == REG)
00954 || (GET_CODE (src) == SUBREG
00955 && GET_CODE (SUBREG_REG (src)) == REG
00956 && GET_CODE (SUBREG_REG (dest)) == REG)))
00957 pcost = ®copy;
00958 else
00959 {
00960 if (GET_CODE (src) == SUBREG)
00961 src = SUBREG_REG (src);
00962 if (GET_CODE (dest) == SUBREG)
00963 dest = SUBREG_REG (dest);
00964 if (GET_CODE (src) == MEM && GET_CODE (dest) != MEM
00965 && memref_is_stack_slot (src))
00966 pcost = &load;
00967 else if (GET_CODE (src) != MEM && GET_CODE (dest) == MEM
00968 && memref_is_stack_slot (dest))
00969 pcost = &store;
00970 }
00971 if (pcost)
00972 {
00973 pcost->cost += block_cost;
00974 pcost->count++;
00975 }
00976 }
00977 if (insn == bb->end)
00978 break;
00979 }
00980 }
00981
00982 if (!prefix)
00983 prefix = "";
00984 fprintf (file, "static insn cost %s\n", message ? message : "");
00985 fprintf (file, " %soverall:\tnum=%6d\tcost=", prefix, overall.count);
00986 fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, overall.cost);
00987 fprintf (file, "\n");
00988 fprintf (file, " %sloads:\tnum=%6d\tcost=", prefix, load.count);
00989 fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, load.cost);
00990 fprintf (file, "\n");
00991 fprintf (file, " %sstores:\tnum=%6d\tcost=", prefix, store.count);
00992 fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, store.cost);
00993 fprintf (file, "\n");
00994 fprintf (file, " %sregcopy:\tnum=%6d\tcost=", prefix, regcopy.count);
00995 fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, regcopy.cost);
00996 fprintf (file, "\n");
00997 fprintf (file, " %sselfcpy:\tnum=%6d\tcost=", prefix, selfcopy.count);
00998 fprintf (file, HOST_WIDE_INT_PRINT_DEC_SPACE, 8, selfcopy.cost);
00999 fprintf (file, "\n");
01000 }
01001
01002
01003
01004
01005 int
01006 web_conflicts_p (web1, web2)
01007 struct web *web1;
01008 struct web *web2;
01009 {
01010 if (web1->type == PRECOLORED && web2->type == PRECOLORED)
01011 return 0;
01012
01013 if (web1->type == PRECOLORED)
01014 return TEST_HARD_REG_BIT (web2->usable_regs, web1->regno);
01015
01016 if (web2->type == PRECOLORED)
01017 return TEST_HARD_REG_BIT (web1->usable_regs, web2->regno);
01018
01019 return hard_regs_intersect_p (&web1->usable_regs, &web2->usable_regs);
01020 }
01021
01022
01023
01024 void
01025 dump_web_insns (web)
01026 struct web *web;
01027 {
01028 unsigned int i;
01029
01030 ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
01031 web->id, web->regno, web->add_hardregs,
01032 reg_class_names[web->regclass],
01033 web->num_freedom, web->num_conflicts);
01034 ra_debug_msg (DUMP_EVER, " def insns:");
01035
01036 for (i = 0; i < web->num_defs; ++i)
01037 {
01038 ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->defs[i]->insn));
01039 }
01040
01041 ra_debug_msg (DUMP_EVER, "\n use insns:");
01042 for (i = 0; i < web->num_uses; ++i)
01043 {
01044 ra_debug_msg (DUMP_EVER, " %d ", INSN_UID (web->uses[i]->insn));
01045 }
01046 ra_debug_msg (DUMP_EVER, "\n");
01047 }
01048
01049
01050
01051 void
01052 dump_web_conflicts (web)
01053 struct web *web;
01054 {
01055 int num = 0;
01056 unsigned int def2;
01057
01058 ra_debug_msg (DUMP_EVER, "Web: %i(%i)+%i class: %s freedom: %i degree %i\n",
01059 web->id, web->regno, web->add_hardregs,
01060 reg_class_names[web->regclass],
01061 web->num_freedom, web->num_conflicts);
01062
01063 for (def2 = 0; def2 < num_webs; def2++)
01064 if (TEST_BIT (igraph, igraph_index (web->id, def2)) && web->id != def2)
01065 {
01066 if ((num % 9) == 5)
01067 ra_debug_msg (DUMP_EVER, "\n ");
01068 num++;
01069
01070 ra_debug_msg (DUMP_EVER, " %d(%d)", def2, id2web[def2]->regno);
01071 if (id2web[def2]->add_hardregs)
01072 ra_debug_msg (DUMP_EVER, "+%d", id2web[def2]->add_hardregs);
01073
01074 if (web_conflicts_p (web, id2web[def2]))
01075 ra_debug_msg (DUMP_EVER, "/x");
01076
01077 if (id2web[def2]->type == SELECT)
01078 ra_debug_msg (DUMP_EVER, "/s");
01079
01080 if (id2web[def2]->type == COALESCED)
01081 ra_debug_msg (DUMP_EVER,"/c/%d", alias (id2web[def2])->id);
01082 }
01083 ra_debug_msg (DUMP_EVER, "\n");
01084 {
01085 struct conflict_link *wl;
01086 num = 0;
01087 ra_debug_msg (DUMP_EVER, "By conflicts: ");
01088 for (wl = web->conflict_list; wl; wl = wl->next)
01089 {
01090 struct web* w = wl->t;
01091 if ((num % 9) == 8)
01092 ra_debug_msg (DUMP_EVER, "\n ");
01093 num++;
01094 ra_debug_msg (DUMP_EVER, "%d(%d)%s ", w->id, w->regno,
01095 web_conflicts_p (web, w) ? "+" : "");
01096 }
01097 ra_debug_msg (DUMP_EVER, "\n");
01098 }
01099 }
01100
01101
01102
01103 void
01104 debug_hard_reg_set (set)
01105 HARD_REG_SET set;
01106 {
01107 int i;
01108 for (i=0; i < FIRST_PSEUDO_REGISTER; ++i)
01109 {
01110 if (TEST_HARD_REG_BIT (set, i))
01111 {
01112 fprintf (stderr, "%s ", reg_names[i]);
01113 }
01114 }
01115 fprintf (stderr, "\n");
01116 }
01117
01118
01119
01120