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 "tm_p.h"
00025 #include "function.h"
00026 #include "regs.h"
00027 #include "hard-reg-set.h"
00028 #include "basic-block.h"
00029 #include "df.h"
00030 #include "expr.h"
00031 #include "output.h"
00032 #include "except.h"
00033 #include "ra.h"
00034 #include "insn-config.h"
00035 #include "reload.h"
00036
00037
00038
00039
00040
00041
00042 struct rewrite_info;
00043 struct rtx_list;
00044
00045 static void spill_coalescing PARAMS ((sbitmap, sbitmap));
00046 static unsigned HOST_WIDE_INT spill_prop_savings PARAMS ((struct web *,
00047 sbitmap));
00048 static void spill_prop_insert PARAMS ((struct web *, sbitmap, sbitmap));
00049 static int spill_propagation PARAMS ((sbitmap, sbitmap, sbitmap));
00050 static void spill_coalprop PARAMS ((void));
00051 static void allocate_spill_web PARAMS ((struct web *));
00052 static void choose_spill_colors PARAMS ((void));
00053 static void rewrite_program PARAMS ((bitmap));
00054 static void remember_slot PARAMS ((struct rtx_list **, rtx));
00055 static int slots_overlap_p PARAMS ((rtx, rtx));
00056 static void delete_overlapping_slots PARAMS ((struct rtx_list **, rtx));
00057 static int slot_member_p PARAMS ((struct rtx_list *, rtx));
00058 static void insert_stores PARAMS ((bitmap));
00059 static int spill_same_color_p PARAMS ((struct web *, struct web *));
00060 static bool is_partly_live_1 PARAMS ((sbitmap, struct web *));
00061 static void update_spill_colors PARAMS ((HARD_REG_SET *, struct web *, int));
00062 static int spill_is_free PARAMS ((HARD_REG_SET *, struct web *));
00063 static void emit_loads PARAMS ((struct rewrite_info *, int, rtx));
00064 static void reloads_to_loads PARAMS ((struct rewrite_info *, struct ref **,
00065 unsigned int, struct web **));
00066 static void rewrite_program2 PARAMS ((bitmap));
00067 static void mark_refs_for_checking PARAMS ((struct web *, bitmap));
00068 static void detect_web_parts_to_rebuild PARAMS ((void));
00069 static void delete_useless_defs PARAMS ((void));
00070 static void detect_non_changed_webs PARAMS ((void));
00071 static void reset_changed_flag PARAMS ((void));
00072
00073
00074
00075 static unsigned int deleted_move_insns;
00076 static unsigned HOST_WIDE_INT deleted_move_cost;
00077
00078
00079
00080
00081
00082
00083
00084 static void
00085 spill_coalescing (coalesce, spilled)
00086 sbitmap coalesce, spilled;
00087 {
00088 struct move_list *ml;
00089 struct move *m;
00090 for (ml = wl_moves; ml; ml = ml->next)
00091 if ((m = ml->move) != NULL)
00092 {
00093 struct web *s = alias (m->source_web);
00094 struct web *t = alias (m->target_web);
00095 if ((TEST_BIT (spilled, s->id) && TEST_BIT (coalesce, t->id))
00096 || (TEST_BIT (spilled, t->id) && TEST_BIT (coalesce, s->id)))
00097 {
00098 struct conflict_link *wl;
00099 if (TEST_BIT (sup_igraph, s->id * num_webs + t->id)
00100 || TEST_BIT (sup_igraph, t->id * num_webs + s->id)
00101 || s->pattern || t->pattern)
00102 continue;
00103
00104 deleted_move_insns++;
00105 deleted_move_cost += BLOCK_FOR_INSN (m->insn)->frequency + 1;
00106 PUT_CODE (m->insn, NOTE);
00107 NOTE_LINE_NUMBER (m->insn) = NOTE_INSN_DELETED;
00108 df_insn_modify (df, BLOCK_FOR_INSN (m->insn), m->insn);
00109
00110 m->target_web->target_of_spilled_move = 1;
00111 if (s == t)
00112
00113 continue;
00114
00115
00116
00117
00118
00119
00120
00121
00122 if (t->type != SPILLED || s->type != SPILLED)
00123 abort ();
00124 remove_list (t->dlink, &WEBS(SPILLED));
00125 put_web (t, COALESCED);
00126 t->alias = s;
00127 s->is_coalesced = 1;
00128 t->is_coalesced = 1;
00129 merge_moves (s, t);
00130 for (wl = t->conflict_list; wl; wl = wl->next)
00131 {
00132 struct web *pweb = wl->t;
00133 if (wl->sub == NULL)
00134 record_conflict (s, pweb);
00135 else
00136 {
00137 struct sub_conflict *sl;
00138 for (sl = wl->sub; sl; sl = sl->next)
00139 {
00140 struct web *sweb = NULL;
00141 if (SUBWEB_P (sl->s))
00142 sweb = find_subweb (s, sl->s->orig_x);
00143 if (!sweb)
00144 sweb = s;
00145 record_conflict (sweb, sl->t);
00146 }
00147 }
00148
00149
00150
00151 pweb->num_conflicts -= 1 + t->add_hardregs;
00152 }
00153 }
00154 }
00155 }
00156
00157
00158
00159
00160 static unsigned HOST_WIDE_INT
00161 spill_prop_savings (web, spilled)
00162 struct web *web;
00163 sbitmap spilled;
00164 {
00165 unsigned HOST_WIDE_INT savings = 0;
00166 struct move_list *ml;
00167 struct move *m;
00168 unsigned int cost;
00169 if (web->pattern)
00170 return 0;
00171 cost = 1 + MEMORY_MOVE_COST (GET_MODE (web->orig_x), web->regclass, 1);
00172 cost += 1 + MEMORY_MOVE_COST (GET_MODE (web->orig_x), web->regclass, 0);
00173 for (ml = wl_moves; ml; ml = ml->next)
00174 if ((m = ml->move) != NULL)
00175 {
00176 struct web *s = alias (m->source_web);
00177 struct web *t = alias (m->target_web);
00178 if (s != web)
00179 {
00180 struct web *h = s;
00181 s = t;
00182 t = h;
00183 }
00184 if (s != web || !TEST_BIT (spilled, t->id) || t->pattern
00185 || TEST_BIT (sup_igraph, s->id * num_webs + t->id)
00186 || TEST_BIT (sup_igraph, t->id * num_webs + s->id))
00187 continue;
00188 savings += BLOCK_FOR_INSN (m->insn)->frequency * cost;
00189 }
00190 return savings;
00191 }
00192
00193
00194
00195
00196 static void
00197 spill_prop_insert (web, list, processed)
00198 struct web *web;
00199 sbitmap list, processed;
00200 {
00201 struct move_list *ml;
00202 struct move *m;
00203 for (ml = wl_moves; ml; ml = ml->next)
00204 if ((m = ml->move) != NULL)
00205 {
00206 struct web *s = alias (m->source_web);
00207 struct web *t = alias (m->target_web);
00208 if (s != web)
00209 {
00210 struct web *h = s;
00211 s = t;
00212 t = h;
00213 }
00214 if (s != web || t->type != COLORED || TEST_BIT (processed, t->id))
00215 continue;
00216 SET_BIT (list, t->id);
00217 SET_BIT (processed, t->id);
00218 }
00219 }
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static int
00233 spill_propagation (to_prop, spilled, processed)
00234 sbitmap to_prop, spilled, processed;
00235 {
00236 int id;
00237 int again = 0;
00238 sbitmap list = sbitmap_alloc (num_webs);
00239 sbitmap_zero (list);
00240
00241
00242 EXECUTE_IF_SET_IN_SBITMAP (to_prop, 0, id,
00243 {
00244 spill_prop_insert (ID2WEB (id), list, processed);
00245 });
00246 sbitmap_zero (to_prop);
00247
00248
00249
00250 while ((id = sbitmap_first_set_bit (list)) >= 0)
00251 {
00252 struct web *web = ID2WEB (id);
00253 RESET_BIT (list, id);
00254 if (spill_prop_savings (web, spilled) >= web->spill_cost)
00255 {
00256
00257
00258
00259 remove_web_from_list (web);
00260 web->color = -1;
00261 put_web (web, SPILLED);
00262 SET_BIT (spilled, id);
00263 SET_BIT (to_prop, id);
00264 spill_prop_insert (web, list, processed);
00265 again = 1;
00266 }
00267 }
00268 sbitmap_free (list);
00269 return again;
00270 }
00271
00272
00273
00274
00275 static void
00276 spill_coalprop ()
00277 {
00278 sbitmap spilled, processed, to_prop;
00279 struct dlist *d;
00280 int again;
00281 spilled = sbitmap_alloc (num_webs);
00282 processed = sbitmap_alloc (num_webs);
00283 to_prop = sbitmap_alloc (num_webs);
00284 sbitmap_zero (spilled);
00285 for (d = WEBS(SPILLED); d; d = d->next)
00286 SET_BIT (spilled, DLIST_WEB (d)->id);
00287 sbitmap_copy (to_prop, spilled);
00288 sbitmap_zero (processed);
00289 do
00290 {
00291 spill_coalescing (to_prop, spilled);
00292
00293
00294
00295
00296
00297 again = 0 && spill_propagation (to_prop, spilled, processed);
00298 }
00299 while (again);
00300 sbitmap_free (to_prop);
00301 sbitmap_free (processed);
00302 sbitmap_free (spilled);
00303 }
00304
00305
00306
00307
00308
00309
00310
00311 static void
00312 allocate_spill_web (web)
00313 struct web *web;
00314 {
00315 int regno = web->regno;
00316 rtx slot;
00317 if (web->stack_slot)
00318 return;
00319 slot = gen_reg_rtx (PSEUDO_REGNO_MODE (regno));
00320 web->stack_slot = slot;
00321 }
00322
00323
00324
00325
00326 static void
00327 choose_spill_colors ()
00328 {
00329 struct dlist *d;
00330 unsigned HOST_WIDE_INT *costs = (unsigned HOST_WIDE_INT *)
00331 xmalloc (FIRST_PSEUDO_REGISTER * sizeof (costs[0]));
00332 for (d = WEBS(SPILLED); d; d = d->next)
00333 {
00334 struct web *web = DLIST_WEB (d);
00335 struct conflict_link *wl;
00336 int bestc, c;
00337 HARD_REG_SET avail;
00338 memset (costs, 0, FIRST_PSEUDO_REGISTER * sizeof (costs[0]));
00339 for (wl = web->conflict_list; wl; wl = wl->next)
00340 {
00341 struct web *pweb = wl->t;
00342 if (pweb->type == COLORED || pweb->type == PRECOLORED)
00343 costs[pweb->color] += pweb->spill_cost;
00344 }
00345
00346 COPY_HARD_REG_SET (avail, web->usable_regs);
00347 if (web->crosses_call)
00348 {
00349
00350
00351 for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
00352 if (TEST_HARD_REG_BIT (call_used_reg_set, c))
00353 costs[c] += 1000;
00354 }
00355 bestc = -1;
00356 for (c = 0; c < FIRST_PSEUDO_REGISTER; c++)
00357 if ((bestc < 0 || costs[bestc] > costs[c])
00358 && TEST_HARD_REG_BIT (avail, c)
00359 && HARD_REGNO_MODE_OK (c, PSEUDO_REGNO_MODE (web->regno)))
00360 {
00361 int i, size;
00362 size = HARD_REGNO_NREGS (c, PSEUDO_REGNO_MODE (web->regno));
00363 for (i = 1; i < size
00364 && TEST_HARD_REG_BIT (avail, c + i); i++);
00365 if (i == size)
00366 bestc = c;
00367 }
00368 web->color = bestc;
00369 ra_debug_msg (DUMP_PROCESS, "choosing color %d for spilled web %d\n",
00370 bestc, web->id);
00371 }
00372
00373 free (costs);
00374 }
00375
00376
00377
00378 static unsigned int emitted_spill_loads;
00379 static unsigned int emitted_spill_stores;
00380 static unsigned int emitted_remat;
00381 static unsigned HOST_WIDE_INT spill_load_cost;
00382 static unsigned HOST_WIDE_INT spill_store_cost;
00383 static unsigned HOST_WIDE_INT spill_remat_cost;
00384
00385
00386
00387
00388 static bitmap useless_defs;
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 static void
00399 rewrite_program (new_deaths)
00400 bitmap new_deaths;
00401 {
00402 unsigned int i;
00403 struct dlist *d;
00404 bitmap b = BITMAP_XMALLOC ();
00405
00406
00407
00408
00409 for (i = 0; i < 2; i++)
00410 for (d = (i == 0) ? WEBS(SPILLED) : WEBS(COALESCED); d; d = d->next)
00411 {
00412 struct web *web = DLIST_WEB (d);
00413 struct web *aweb = alias (web);
00414 unsigned int j;
00415 rtx slot;
00416
00417
00418 if (aweb->type != SPILLED)
00419 continue;
00420
00421
00422 if (flag_ra_spill_every_use)
00423 {
00424 bitmap_clear (b);
00425 allocate_spill_web (aweb);
00426 slot = aweb->stack_slot;
00427 for (j = 0; j < web->num_uses; j++)
00428 {
00429 rtx insns, target, source;
00430 rtx insn = DF_REF_INSN (web->uses[j]);
00431 rtx prev = PREV_INSN (insn);
00432 basic_block bb = BLOCK_FOR_INSN (insn);
00433
00434 if (!INSN_P (insn))
00435 continue;
00436
00437
00438
00439
00440 if (bitmap_bit_p (b, INSN_UID (insn)))
00441 continue;
00442 bitmap_set_bit (b, INSN_UID (insn));
00443 target = DF_REF_REG (web->uses[j]);
00444 source = slot;
00445 start_sequence ();
00446 if (GET_CODE (target) == SUBREG)
00447 source = simplify_gen_subreg (GET_MODE (target), source,
00448 GET_MODE (source),
00449 SUBREG_BYTE (target));
00450 ra_emit_move_insn (target, source);
00451 insns = get_insns ();
00452 end_sequence ();
00453 emit_insn_before (insns, insn);
00454
00455 if (bb->head == insn)
00456 bb->head = NEXT_INSN (prev);
00457 for (insn = PREV_INSN (insn); insn != prev;
00458 insn = PREV_INSN (insn))
00459 {
00460 set_block_for_insn (insn, bb);
00461 df_insn_modify (df, bb, insn);
00462 }
00463
00464 emitted_spill_loads++;
00465 spill_load_cost += bb->frequency + 1;
00466 }
00467 }
00468
00469
00470
00471
00472
00473
00474 slot = aweb->stack_slot;
00475 bitmap_clear (b);
00476 if (slot)
00477 for (j = 0; j < web->num_defs; j++)
00478 {
00479 rtx insns, source, dest;
00480 rtx insn = DF_REF_INSN (web->defs[j]);
00481 rtx following = NEXT_INSN (insn);
00482 basic_block bb = BLOCK_FOR_INSN (insn);
00483
00484 if (!INSN_P (insn))
00485 continue;
00486 if (bitmap_bit_p (b, INSN_UID (insn)))
00487 continue;
00488 bitmap_set_bit (b, INSN_UID (insn));
00489 start_sequence ();
00490 source = DF_REF_REG (web->defs[j]);
00491 dest = slot;
00492 if (GET_CODE (source) == SUBREG)
00493 dest = simplify_gen_subreg (GET_MODE (source), dest,
00494 GET_MODE (dest),
00495 SUBREG_BYTE (source));
00496 ra_emit_move_insn (dest, source);
00497
00498 insns = get_insns ();
00499 end_sequence ();
00500 if (insns)
00501 {
00502 emit_insn_after (insns, insn);
00503 if (bb->end == insn)
00504 bb->end = PREV_INSN (following);
00505 for (insn = insns; insn != following; insn = NEXT_INSN (insn))
00506 {
00507 set_block_for_insn (insn, bb);
00508 df_insn_modify (df, bb, insn);
00509 }
00510 }
00511 else
00512 df_insn_modify (df, bb, insn);
00513 emitted_spill_stores++;
00514 spill_store_cost += bb->frequency + 1;
00515
00516
00517
00518
00519
00520
00521
00522
00523 bitmap_set_bit (new_deaths, INSN_UID (PREV_INSN (following)));
00524 }
00525 }
00526
00527 BITMAP_XFREE (b);
00528 }
00529
00530
00531 struct rtx_list
00532 {
00533 struct rtx_list *next;
00534 rtx x;
00535 };
00536
00537
00538
00539 static void
00540 remember_slot (list, x)
00541 struct rtx_list **list;
00542 rtx x;
00543 {
00544 struct rtx_list *l;
00545
00546 l = (struct rtx_list *) ra_alloc (sizeof (*l));
00547 l->next = *list;
00548 l->x = x;
00549 *list = l;
00550 }
00551
00552
00553
00554
00555
00556
00557 static int
00558 slots_overlap_p (s1, s2)
00559 rtx s1, s2;
00560 {
00561 rtx base1, base2;
00562 HOST_WIDE_INT ofs1 = 0, ofs2 = 0;
00563 int size1 = GET_MODE_SIZE (GET_MODE (s1));
00564 int size2 = GET_MODE_SIZE (GET_MODE (s2));
00565 if (GET_CODE (s1) == SUBREG)
00566 ofs1 = SUBREG_BYTE (s1), s1 = SUBREG_REG (s1);
00567 if (GET_CODE (s2) == SUBREG)
00568 ofs2 = SUBREG_BYTE (s2), s2 = SUBREG_REG (s2);
00569
00570 if (s1 == s2)
00571 return 1;
00572
00573 if (GET_CODE (s1) != GET_CODE (s2))
00574 return 0;
00575
00576 if (GET_CODE (s1) == REG && GET_CODE (s2) == REG)
00577 {
00578 if (REGNO (s1) != REGNO (s2))
00579 return 0;
00580 if (ofs1 >= ofs2 + size2 || ofs2 >= ofs1 + size1)
00581 return 0;
00582 return 1;
00583 }
00584 if (GET_CODE (s1) != MEM || GET_CODE (s2) != MEM)
00585 abort ();
00586 s1 = XEXP (s1, 0);
00587 s2 = XEXP (s2, 0);
00588 if (GET_CODE (s1) != PLUS || GET_CODE (XEXP (s1, 0)) != REG
00589 || GET_CODE (XEXP (s1, 1)) != CONST_INT)
00590 return 1;
00591 if (GET_CODE (s2) != PLUS || GET_CODE (XEXP (s2, 0)) != REG
00592 || GET_CODE (XEXP (s2, 1)) != CONST_INT)
00593 return 1;
00594 base1 = XEXP (s1, 0);
00595 base2 = XEXP (s2, 0);
00596 if (!rtx_equal_p (base1, base2))
00597 return 1;
00598 ofs1 += INTVAL (XEXP (s1, 1));
00599 ofs2 += INTVAL (XEXP (s2, 1));
00600 if (ofs1 >= ofs2 + size2 || ofs2 >= ofs1 + size1)
00601 return 0;
00602 return 1;
00603 }
00604
00605
00606
00607
00608 static void
00609 delete_overlapping_slots (list, x)
00610 struct rtx_list **list;
00611 rtx x;
00612 {
00613 while (*list)
00614 {
00615 if (slots_overlap_p ((*list)->x, x))
00616 *list = (*list)->next;
00617 else
00618 list = &((*list)->next);
00619 }
00620 }
00621
00622
00623
00624 static int
00625 slot_member_p (list, x)
00626 struct rtx_list *list;
00627 rtx x;
00628 {
00629 for (;list; list = list->next)
00630 if (rtx_equal_p (list->x, x))
00631 return 1;
00632 return 0;
00633 }
00634
00635
00636
00637
00638
00639
00640
00641 static void
00642 insert_stores (new_deaths)
00643 bitmap new_deaths;
00644 {
00645 rtx insn;
00646 rtx last_slot = NULL_RTX;
00647 struct rtx_list *slots = NULL;
00648
00649
00650 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
00651 {
00652 int uid = INSN_UID (insn);
00653
00654
00655
00656 if (GET_CODE (insn) == BARRIER
00657 || JUMP_P (insn) || can_throw_internal (insn))
00658 {
00659 last_slot = NULL_RTX;
00660 slots = NULL;
00661 }
00662 if (!INSN_P (insn))
00663 continue;
00664
00665
00666 if (uid < insn_df_max_uid)
00667 {
00668 unsigned int n;
00669 rtx following = NEXT_INSN (insn);
00670 basic_block bb = BLOCK_FOR_INSN (insn);
00671 struct ra_insn_info info;
00672
00673 info = insn_df[uid];
00674 for (n = 0; n < info.num_defs; n++)
00675 {
00676 struct web *web = def2web[DF_REF_ID (info.defs[n])];
00677 struct web *aweb = alias (find_web_for_subweb (web));
00678 rtx slot, source;
00679 if (aweb->type != SPILLED || !aweb->stack_slot)
00680 continue;
00681 slot = aweb->stack_slot;
00682 source = DF_REF_REG (info.defs[n]);
00683
00684 start_sequence ();
00685 if (GET_CODE (source) == SUBREG)
00686 slot = simplify_gen_subreg (GET_MODE (source), slot,
00687 GET_MODE (slot),
00688 SUBREG_BYTE (source));
00689
00690
00691
00692 if ((!last_slot || !rtx_equal_p (slot, last_slot))
00693 && ! slot_member_p (slots, slot))
00694 {
00695 rtx insns, ni;
00696 last_slot = slot;
00697 remember_slot (&slots, slot);
00698 ra_emit_move_insn (slot, source);
00699 insns = get_insns ();
00700 end_sequence ();
00701 if (insns)
00702 {
00703 emit_insn_after (insns, insn);
00704 if (bb->end == insn)
00705 bb->end = PREV_INSN (following);
00706 for (ni = insns; ni != following; ni = NEXT_INSN (ni))
00707 {
00708 set_block_for_insn (ni, bb);
00709 df_insn_modify (df, bb, ni);
00710 }
00711 }
00712 else
00713 df_insn_modify (df, bb, insn);
00714 emitted_spill_stores++;
00715 spill_store_cost += bb->frequency + 1;
00716 bitmap_set_bit (new_deaths, INSN_UID (PREV_INSN (following)));
00717 }
00718 else
00719 {
00720
00721 end_sequence ();
00722 }
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731
00732 if (uid >= last_max_uid)
00733 {
00734 rtx set = single_set (insn);
00735 last_slot = NULL_RTX;
00736
00737 if (!set)
00738 slots = NULL;
00739 else
00740 {
00741 if (1 || GET_CODE (SET_SRC (set)) == MEM)
00742 delete_overlapping_slots (&slots, SET_SRC (set));
00743 }
00744 }
00745 }
00746 }
00747
00748
00749
00750
00751 static int
00752 spill_same_color_p (web1, web2)
00753 struct web *web1, *web2;
00754 {
00755 int c1, size1, c2, size2;
00756 if ((c1 = alias (web1)->color) < 0 || c1 == an_unusable_color)
00757 return 0;
00758 if ((c2 = alias (web2)->color) < 0 || c2 == an_unusable_color)
00759 return 0;
00760
00761 size1 = web1->type == PRECOLORED
00762 ? 1 : HARD_REGNO_NREGS (c1, PSEUDO_REGNO_MODE (web1->regno));
00763 size2 = web2->type == PRECOLORED
00764 ? 1 : HARD_REGNO_NREGS (c2, PSEUDO_REGNO_MODE (web2->regno));
00765 if (c1 >= c2 + size2 || c2 >= c1 + size1)
00766 return 0;
00767 return 1;
00768 }
00769
00770
00771
00772
00773 static bool
00774 is_partly_live_1 (live, web)
00775 sbitmap live;
00776 struct web *web;
00777 {
00778 do
00779 if (TEST_BIT (live, web->id))
00780 return 1;
00781 while ((web = web->subreg_next));
00782 return 0;
00783 }
00784
00785
00786 #define is_partly_live(live, web) ((!web->subreg_next) \
00787 ? TEST_BIT (live, web->id) \
00788 : is_partly_live_1 (live, web))
00789
00790
00791
00792
00793
00794 static void
00795 update_spill_colors (in_use, web, add)
00796 HARD_REG_SET *in_use;
00797 struct web *web;
00798 int add;
00799 {
00800 int c, size;
00801 if ((c = alias (find_web_for_subweb (web))->color) < 0
00802 || c == an_unusable_color)
00803 return;
00804 size = HARD_REGNO_NREGS (c, GET_MODE (web->orig_x));
00805 if (SUBWEB_P (web))
00806 {
00807 c += subreg_regno_offset (c, GET_MODE (SUBREG_REG (web->orig_x)),
00808 SUBREG_BYTE (web->orig_x),
00809 GET_MODE (web->orig_x));
00810 }
00811 else if (web->type == PRECOLORED)
00812 size = 1;
00813 if (add)
00814 for (; size--;)
00815 SET_HARD_REG_BIT (*in_use, c + size);
00816 else
00817 for (; size--;)
00818 CLEAR_HARD_REG_BIT (*in_use, c + size);
00819 }
00820
00821
00822
00823
00824
00825
00826 static int
00827 spill_is_free (in_use, web)
00828 HARD_REG_SET *in_use;
00829 struct web *web;
00830 {
00831 int c, size;
00832 if ((c = alias (web)->color) < 0)
00833 return -1;
00834 if (c == an_unusable_color)
00835 return 1;
00836 size = web->type == PRECOLORED
00837 ? 1 : HARD_REGNO_NREGS (c, PSEUDO_REGNO_MODE (web->regno));
00838 for (; size--;)
00839 if (TEST_HARD_REG_BIT (*in_use, c + size))
00840 return 0;
00841 return 1;
00842 }
00843
00844
00845
00846 struct rewrite_info
00847 {
00848
00849
00850 bitmap need_reload;
00851
00852
00853 bitmap scratch;
00854
00855
00856
00857 sbitmap live;
00858
00859
00860 struct web **needed_loads;
00861
00862 int nl_size;
00863
00864 int num_reloads;
00865
00866 HARD_REG_SET colors_in_use;
00867
00868
00869
00870 int any_spilltemps_spilled;
00871
00872
00873 int need_load;
00874 };
00875
00876
00877
00878
00879
00880
00881
00882 static void
00883 emit_loads (ri, nl_first_reload, last_block_insn)
00884 struct rewrite_info *ri;
00885 int nl_first_reload;
00886 rtx last_block_insn;
00887 {
00888 int j;
00889 for (j = ri->nl_size; j;)
00890 {
00891 struct web *web = ri->needed_loads[--j];
00892 struct web *supweb;
00893 struct web *aweb;
00894 rtx ni, slot, reg;
00895 rtx before = NULL_RTX, after = NULL_RTX;
00896 basic_block bb;
00897
00898
00899
00900 if (!web)
00901 continue;
00902 supweb = find_web_for_subweb (web);
00903 if (supweb->regno >= max_normal_pseudo)
00904 abort ();
00905
00906
00907
00908
00909 if (!ri->need_load)
00910 {
00911 if (!supweb->spill_temp)
00912 continue;
00913 else
00914 ri->needed_loads[j] = 0;
00915 }
00916 web->in_load = 0;
00917
00918 if (j < nl_first_reload && !TEST_BIT (ri->live, web->id))
00919 continue;
00920 aweb = alias (supweb);
00921 aweb->changed = 1;
00922 start_sequence ();
00923 if (supweb->pattern)
00924 {
00925
00926
00927
00928
00929
00930 if (aweb != supweb)
00931 abort ();
00932 slot = copy_rtx (supweb->pattern);
00933 reg = copy_rtx (supweb->orig_x);
00934
00935
00936 if (reg != supweb->orig_x)
00937 abort ();
00938 }
00939 else
00940 {
00941 allocate_spill_web (aweb);
00942 slot = aweb->stack_slot;
00943
00944
00945
00946
00947 reg = copy_rtx (web->orig_x);
00948 if (GET_CODE (reg) == SUBREG)
00949
00950
00951 slot = simplify_gen_subreg (GET_MODE (reg), slot, GET_MODE (slot),
00952 SUBREG_BYTE (reg));
00953 }
00954 ra_emit_move_insn (reg, slot);
00955 ni = get_insns ();
00956 end_sequence ();
00957 before = web->last_use_insn;
00958 web->last_use_insn = NULL_RTX;
00959 if (!before)
00960 {
00961 if (JUMP_P (last_block_insn))
00962 before = last_block_insn;
00963 else
00964 after = last_block_insn;
00965 }
00966 if (after)
00967 {
00968 rtx foll = NEXT_INSN (after);
00969 bb = BLOCK_FOR_INSN (after);
00970 emit_insn_after (ni, after);
00971 if (bb->end == after)
00972 bb->end = PREV_INSN (foll);
00973 for (ni = NEXT_INSN (after); ni != foll; ni = NEXT_INSN (ni))
00974 {
00975 set_block_for_insn (ni, bb);
00976 df_insn_modify (df, bb, ni);
00977 }
00978 }
00979 else
00980 {
00981 rtx prev = PREV_INSN (before);
00982 bb = BLOCK_FOR_INSN (before);
00983 emit_insn_before (ni, before);
00984 if (bb->head == before)
00985 bb->head = NEXT_INSN (prev);
00986 for (; ni != before; ni = NEXT_INSN (ni))
00987 {
00988 set_block_for_insn (ni, bb);
00989 df_insn_modify (df, bb, ni);
00990 }
00991 }
00992 if (supweb->pattern)
00993 {
00994 emitted_remat++;
00995 spill_remat_cost += bb->frequency + 1;
00996 }
00997 else
00998 {
00999 emitted_spill_loads++;
01000 spill_load_cost += bb->frequency + 1;
01001 }
01002 RESET_BIT (ri->live, web->id);
01003
01004
01005 if (ri->need_load == 2 && j < nl_first_reload)
01006 break;
01007 }
01008 if (ri->need_load)
01009 ri->nl_size = j;
01010 }
01011
01012
01013
01014
01015
01016
01017
01018
01019 static void
01020 reloads_to_loads (ri, refs, num_refs, ref2web)
01021 struct rewrite_info *ri;
01022 struct ref **refs;
01023 unsigned int num_refs;
01024 struct web **ref2web;
01025 {
01026 unsigned int n;
01027 int num_reloads = ri->num_reloads;
01028 for (n = 0; n < num_refs && num_reloads; n++)
01029 {
01030 struct web *web = ref2web[DF_REF_ID (refs[n])];
01031 struct web *supweb = find_web_for_subweb (web);
01032 int is_death;
01033 int j;
01034
01035
01036
01037 if (alias (supweb)->type == SPILLED)
01038 continue;
01039 if (supweb->type == PRECOLORED
01040 && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
01041 continue;
01042
01043
01044
01045 is_death = !TEST_BIT (ri->live, supweb->id);
01046 is_death &= !TEST_BIT (ri->live, web->id);
01047 if (is_death)
01048 {
01049 int old_num_r = num_reloads;
01050 bitmap_clear (ri->scratch);
01051 EXECUTE_IF_SET_IN_BITMAP (ri->need_reload, 0, j,
01052 {
01053 struct web *web2 = ID2WEB (j);
01054 struct web *aweb2 = alias (find_web_for_subweb (web2));
01055 if (spill_is_free (&(ri->colors_in_use), aweb2) == 0)
01056 abort ();
01057 if (spill_same_color_p (supweb, aweb2)
01058 )
01059 {
01060 if (!web2->in_load)
01061 {
01062 ri->needed_loads[ri->nl_size++] = web2;
01063 web2->in_load = 1;
01064 }
01065 bitmap_set_bit (ri->scratch, j);
01066 num_reloads--;
01067 }
01068 });
01069 if (num_reloads != old_num_r)
01070 bitmap_operation (ri->need_reload, ri->need_reload, ri->scratch,
01071 BITMAP_AND_COMPL);
01072 }
01073 }
01074 ri->num_reloads = num_reloads;
01075 }
01076
01077
01078
01079
01080
01081
01082 static void
01083 rewrite_program2 (new_deaths)
01084 bitmap new_deaths;
01085 {
01086 basic_block bb;
01087 int nl_first_reload;
01088 struct rewrite_info ri;
01089 rtx insn;
01090 ri.needed_loads = (struct web **) xmalloc (num_webs * sizeof (struct web *));
01091 ri.need_reload = BITMAP_XMALLOC ();
01092 ri.scratch = BITMAP_XMALLOC ();
01093 ri.live = sbitmap_alloc (num_webs);
01094 ri.nl_size = 0;
01095 ri.num_reloads = 0;
01096 for (insn = get_last_insn (); insn; insn = PREV_INSN (insn))
01097 {
01098 basic_block last_bb = NULL;
01099 rtx last_block_insn;
01100 int i, j;
01101 if (!INSN_P (insn))
01102 insn = prev_real_insn (insn);
01103 while (insn && !(bb = BLOCK_FOR_INSN (insn)))
01104 insn = prev_real_insn (insn);
01105 if (!insn)
01106 break;
01107 i = bb->index + 2;
01108 last_block_insn = insn;
01109
01110 sbitmap_zero (ri.live);
01111 CLEAR_HARD_REG_SET (ri.colors_in_use);
01112 EXECUTE_IF_SET_IN_BITMAP (live_at_end[i - 2], 0, j,
01113 {
01114 struct web *web = use2web[j];
01115 struct web *aweb = alias (find_web_for_subweb (web));
01116
01117
01118
01119
01120
01121
01122
01123 if (aweb->type != SPILLED )
01124 {
01125 SET_BIT (ri.live, web->id);
01126 if (aweb->type != SPILLED)
01127 update_spill_colors (&(ri.colors_in_use), web, 1);
01128 }
01129 });
01130
01131 bitmap_clear (ri.need_reload);
01132 ri.num_reloads = 0;
01133 ri.any_spilltemps_spilled = 0;
01134 if (flag_ra_ir_spilling)
01135 {
01136 struct dlist *d;
01137 int pass;
01138
01139
01140 for (pass = 0; pass < 2; pass++)
01141 for (d = (pass) ? WEBS(SPILLED) : WEBS(COALESCED); d; d = d->next)
01142 {
01143 struct web *web = DLIST_WEB (d);
01144 struct web *aweb = alias (web);
01145 if (aweb->type != SPILLED)
01146 continue;
01147 if (is_partly_live (ri.live, web)
01148 && spill_is_free (&(ri.colors_in_use), web) > 0)
01149 {
01150 ri.num_reloads++;
01151 bitmap_set_bit (ri.need_reload, web->id);
01152
01153 web->last_use_insn = NULL_RTX;
01154 }
01155 }
01156 }
01157
01158 last_bb = bb;
01159 for (; insn; insn = PREV_INSN (insn))
01160 {
01161 struct ra_insn_info info;
01162 unsigned int n;
01163
01164 if (INSN_P (insn) && BLOCK_FOR_INSN (insn) != last_bb)
01165 {
01166 int index = BLOCK_FOR_INSN (insn)->index + 2;
01167 EXECUTE_IF_SET_IN_BITMAP (live_at_end[index - 2], 0, j,
01168 {
01169 struct web *web = use2web[j];
01170 struct web *aweb = alias (find_web_for_subweb (web));
01171 if (aweb->type != SPILLED)
01172 {
01173 SET_BIT (ri.live, web->id);
01174 update_spill_colors (&(ri.colors_in_use), web, 1);
01175 }
01176 });
01177 bitmap_clear (ri.scratch);
01178 EXECUTE_IF_SET_IN_BITMAP (ri.need_reload, 0, j,
01179 {
01180 struct web *web2 = ID2WEB (j);
01181 struct web *supweb2 = find_web_for_subweb (web2);
01182 struct web *aweb2 = alias (supweb2);
01183 if (spill_is_free (&(ri.colors_in_use), aweb2) <= 0)
01184 {
01185 if (!web2->in_load)
01186 {
01187 ri.needed_loads[ri.nl_size++] = web2;
01188 web2->in_load = 1;
01189 }
01190 bitmap_set_bit (ri.scratch, j);
01191 ri.num_reloads--;
01192 }
01193 });
01194 bitmap_operation (ri.need_reload, ri.need_reload, ri.scratch,
01195 BITMAP_AND_COMPL);
01196 last_bb = BLOCK_FOR_INSN (insn);
01197 last_block_insn = insn;
01198 if (!INSN_P (last_block_insn))
01199 last_block_insn = prev_real_insn (last_block_insn);
01200 }
01201
01202 ri.need_load = 0;
01203 if (INSN_P (insn))
01204 info = insn_df[INSN_UID (insn)];
01205
01206 if (INSN_P (insn))
01207 for (n = 0; n < info.num_defs; n++)
01208 {
01209 struct ref *ref = info.defs[n];
01210 struct web *web = def2web[DF_REF_ID (ref)];
01211 struct web *supweb = find_web_for_subweb (web);
01212 int is_non_def = 0;
01213 unsigned int n2;
01214
01215 supweb = find_web_for_subweb (web);
01216
01217
01218
01219
01220
01221 for (n2 = 0; n2 < info.num_uses; n2++)
01222 {
01223 struct web *web2 = use2web[DF_REF_ID (info.uses[n2])];
01224 if (supweb == find_web_for_subweb (web2))
01225 {
01226 is_non_def = 1;
01227 break;
01228 }
01229 }
01230 if (is_non_def)
01231 continue;
01232
01233 if (!is_partly_live (ri.live, supweb))
01234 bitmap_set_bit (useless_defs, DF_REF_ID (ref));
01235
01236 RESET_BIT (ri.live, web->id);
01237 if (bitmap_bit_p (ri.need_reload, web->id))
01238 {
01239 ri.num_reloads--;
01240 bitmap_clear_bit (ri.need_reload, web->id);
01241 }
01242 if (web != supweb)
01243 {
01244
01245
01246
01247
01248
01249
01250 if (!is_partly_live (ri.live, supweb)
01251 && bitmap_bit_p (ri.need_reload, supweb->id))
01252 {
01253 ri.num_reloads--;
01254 bitmap_clear_bit (ri.need_reload, supweb->id);
01255 }
01256 }
01257 else
01258 {
01259 struct web *sweb;
01260
01261
01262 for (sweb = supweb->subreg_next; sweb;
01263 sweb = sweb->subreg_next)
01264 {
01265 RESET_BIT (ri.live, sweb->id);
01266 if (bitmap_bit_p (ri.need_reload, sweb->id))
01267 {
01268 ri.num_reloads--;
01269 bitmap_clear_bit (ri.need_reload, sweb->id);
01270 }
01271 }
01272 }
01273 if (alias (supweb)->type != SPILLED)
01274 update_spill_colors (&(ri.colors_in_use), web, 0);
01275 }
01276
01277 nl_first_reload = ri.nl_size;
01278
01279
01280
01281
01282
01283
01284 if (GET_CODE (insn) == CALL_INSN)
01285 ri.need_load = 1;
01286 else if (INSN_P (insn))
01287 for (n = 0; n < info.num_uses; n++)
01288 {
01289 struct web *web = use2web[DF_REF_ID (info.uses[n])];
01290 struct web *supweb = find_web_for_subweb (web);
01291 int is_death;
01292 if (supweb->type == PRECOLORED
01293 && TEST_HARD_REG_BIT (never_use_colors, supweb->color))
01294 continue;
01295 is_death = !TEST_BIT (ri.live, supweb->id);
01296 is_death &= !TEST_BIT (ri.live, web->id);
01297 if (is_death)
01298 {
01299 ri.need_load = 1;
01300 bitmap_set_bit (new_deaths, INSN_UID (insn));
01301 break;
01302 }
01303 }
01304
01305 if (INSN_P (insn) && ri.num_reloads)
01306 {
01307 int old_num_reloads = ri.num_reloads;
01308 reloads_to_loads (&ri, info.uses, info.num_uses, use2web);
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318 if (ri.num_reloads)
01319 reloads_to_loads (&ri, info.defs, info.num_defs, def2web);
01320 if (ri.num_reloads != old_num_reloads && !ri.need_load)
01321 ri.need_load = 1;
01322 }
01323
01324 if (ri.nl_size && (ri.need_load || ri.any_spilltemps_spilled))
01325 emit_loads (&ri, nl_first_reload, last_block_insn);
01326
01327 if (INSN_P (insn) && flag_ra_ir_spilling)
01328 for (n = 0; n < info.num_uses; n++)
01329 {
01330 struct web *web = use2web[DF_REF_ID (info.uses[n])];
01331 struct web *aweb = alias (find_web_for_subweb (web));
01332 if (aweb->type != SPILLED)
01333 update_spill_colors (&(ri.colors_in_use), web, 1);
01334 }
01335
01336 ri.any_spilltemps_spilled = 0;
01337 if (INSN_P (insn))
01338 for (n = 0; n < info.num_uses; n++)
01339 {
01340 struct web *web = use2web[DF_REF_ID (info.uses[n])];
01341 struct web *supweb = find_web_for_subweb (web);
01342 struct web *aweb = alias (supweb);
01343 SET_BIT (ri.live, web->id);
01344 if (aweb->type != SPILLED)
01345 continue;
01346 if (supweb->spill_temp)
01347 ri.any_spilltemps_spilled = 1;
01348 web->last_use_insn = insn;
01349 if (!web->in_load)
01350 {
01351 if (spill_is_free (&(ri.colors_in_use), aweb) <= 0
01352 || !flag_ra_ir_spilling)
01353 {
01354 ri.needed_loads[ri.nl_size++] = web;
01355 web->in_load = 1;
01356 web->one_load = 1;
01357 }
01358 else if (!bitmap_bit_p (ri.need_reload, web->id))
01359 {
01360 bitmap_set_bit (ri.need_reload, web->id);
01361 ri.num_reloads++;
01362 web->one_load = 1;
01363 }
01364 else
01365 web->one_load = 0;
01366 }
01367 else
01368 web->one_load = 0;
01369 }
01370
01371 if (GET_CODE (insn) == CODE_LABEL)
01372 break;
01373 }
01374
01375 nl_first_reload = ri.nl_size;
01376 if (ri.num_reloads)
01377 {
01378 int in_ir = 0;
01379 edge e;
01380 int num = 0;
01381 HARD_REG_SET cum_colors, colors;
01382 CLEAR_HARD_REG_SET (cum_colors);
01383 for (e = bb->pred; e && num < 5; e = e->pred_next, num++)
01384 {
01385 int j;
01386 CLEAR_HARD_REG_SET (colors);
01387 EXECUTE_IF_SET_IN_BITMAP (live_at_end[e->src->index], 0, j,
01388 {
01389 struct web *web = use2web[j];
01390 struct web *aweb = alias (find_web_for_subweb (web));
01391 if (aweb->type != SPILLED)
01392 update_spill_colors (&colors, web, 1);
01393 });
01394 IOR_HARD_REG_SET (cum_colors, colors);
01395 }
01396 if (num == 5)
01397 in_ir = 1;
01398
01399 bitmap_clear (ri.scratch);
01400 EXECUTE_IF_SET_IN_BITMAP (ri.need_reload, 0, j,
01401 {
01402 struct web *web2 = ID2WEB (j);
01403 struct web *supweb2 = find_web_for_subweb (web2);
01404 struct web *aweb2 = alias (supweb2);
01405
01406
01407 if (((ra_pass > 0 || supweb2->target_of_spilled_move)
01408 && (1 || in_ir || spill_is_free (&cum_colors, aweb2) <= 0))
01409 || (ra_pass == 1
01410 && (in_ir
01411 || spill_is_free (&cum_colors, aweb2) <= 0)))
01412 {
01413 if (!web2->in_load)
01414 {
01415 ri.needed_loads[ri.nl_size++] = web2;
01416 web2->in_load = 1;
01417 }
01418 bitmap_set_bit (ri.scratch, j);
01419 ri.num_reloads--;
01420 }
01421 });
01422 bitmap_operation (ri.need_reload, ri.need_reload, ri.scratch,
01423 BITMAP_AND_COMPL);
01424 }
01425
01426 ri.need_load = 1;
01427 emit_loads (&ri, nl_first_reload, last_block_insn);
01428 if (ri.nl_size != 0 )
01429 abort ();
01430 if (!insn)
01431 break;
01432 }
01433 free (ri.needed_loads);
01434 sbitmap_free (ri.live);
01435 BITMAP_XFREE (ri.scratch);
01436 BITMAP_XFREE (ri.need_reload);
01437 }
01438
01439
01440
01441
01442
01443
01444
01445
01446 static void
01447 mark_refs_for_checking (web, uses_as_bitmap)
01448 struct web *web;
01449 bitmap uses_as_bitmap;
01450 {
01451 unsigned int i;
01452 for (i = 0; i < web->num_uses; i++)
01453 {
01454 unsigned int id = DF_REF_ID (web->uses[i]);
01455 SET_BIT (last_check_uses, id);
01456 bitmap_set_bit (uses_as_bitmap, id);
01457 web_parts[df->def_id + id].spanned_deaths = 0;
01458 web_parts[df->def_id + id].crosses_call = 0;
01459 }
01460 for (i = 0; i < web->num_defs; i++)
01461 {
01462 unsigned int id = DF_REF_ID (web->defs[i]);
01463 web_parts[id].spanned_deaths = 0;
01464 web_parts[id].crosses_call = 0;
01465 }
01466 }
01467
01468
01469
01470
01471
01472
01473
01474 static void
01475 detect_web_parts_to_rebuild ()
01476 {
01477 bitmap uses_as_bitmap;
01478 unsigned int i, pass;
01479 struct dlist *d;
01480 sbitmap already_webs = sbitmap_alloc (num_webs);
01481
01482 uses_as_bitmap = BITMAP_XMALLOC ();
01483 if (last_check_uses)
01484 sbitmap_free (last_check_uses);
01485 last_check_uses = sbitmap_alloc (df->use_id);
01486 sbitmap_zero (last_check_uses);
01487 sbitmap_zero (already_webs);
01488
01489
01490
01491
01492 for (pass = 0; pass < 2; pass++)
01493 for (d = (pass == 0) ? WEBS(SPILLED) : WEBS(COALESCED); d; d = d->next)
01494 {
01495 struct web *web = DLIST_WEB (d);
01496 struct conflict_link *wl;
01497 unsigned int j;
01498
01499 if (alias (web)->type != SPILLED)
01500 continue;
01501
01502
01503
01504
01505 for (i = 0; i < web->num_uses; i++)
01506 {
01507 unsigned int id = DF_REF_ID (web->uses[i]);
01508 SET_BIT (last_check_uses, id);
01509 bitmap_set_bit (uses_as_bitmap, id);
01510 web_parts[df->def_id + id].uplink = NULL;
01511 web_parts[df->def_id + id].spanned_deaths = 0;
01512 web_parts[df->def_id + id].crosses_call = 0;
01513 }
01514 for (i = 0; i < web->num_defs; i++)
01515 {
01516 unsigned int id = DF_REF_ID (web->defs[i]);
01517 web_parts[id].uplink = NULL;
01518 web_parts[id].spanned_deaths = 0;
01519 web_parts[id].crosses_call = 0;
01520 }
01521
01522
01523 if (web->have_orig_conflicts)
01524 wl = web->orig_conflict_list;
01525 else
01526 wl = web->conflict_list;
01527 for (; wl; wl = wl->next)
01528 {
01529 if (TEST_BIT (already_webs, wl->t->id))
01530 continue;
01531 SET_BIT (already_webs, wl->t->id);
01532 mark_refs_for_checking (wl->t, uses_as_bitmap);
01533 }
01534 EXECUTE_IF_SET_IN_BITMAP (web->useless_conflicts, 0, j,
01535 {
01536 struct web *web2 = ID2WEB (j);
01537 if (TEST_BIT (already_webs, web2->id))
01538 continue;
01539 SET_BIT (already_webs, web2->id);
01540 mark_refs_for_checking (web2, uses_as_bitmap);
01541 });
01542 }
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01553 if (!fixed_regs[i])
01554 {
01555 struct df_link *link;
01556 for (link = df->regs[i].uses; link; link = link->next)
01557 if (link->ref)
01558 bitmap_set_bit (uses_as_bitmap, DF_REF_ID (link->ref));
01559 }
01560
01561
01562
01563
01564 live_at_end -= 2;
01565 for (i = 0; i < (unsigned int) last_basic_block + 2; i++)
01566 bitmap_operation (live_at_end[i], live_at_end[i], uses_as_bitmap,
01567 BITMAP_AND_COMPL);
01568 live_at_end += 2;
01569
01570 if (rtl_dump_file && (debug_new_regalloc & DUMP_REBUILD) != 0)
01571 {
01572 ra_debug_msg (DUMP_REBUILD, "need to check these uses:\n");
01573 dump_sbitmap_file (rtl_dump_file, last_check_uses);
01574 }
01575 sbitmap_free (already_webs);
01576 BITMAP_XFREE (uses_as_bitmap);
01577 }
01578
01579
01580 static unsigned int deleted_def_insns;
01581 static unsigned HOST_WIDE_INT deleted_def_cost;
01582
01583
01584
01585
01586 static void
01587 delete_useless_defs ()
01588 {
01589 unsigned int i;
01590
01591
01592
01593 EXECUTE_IF_SET_IN_BITMAP (useless_defs, 0, i,
01594 {
01595 rtx insn = DF_REF_INSN (df->defs[i]);
01596 rtx set = single_set (insn);
01597 struct web *web = find_web_for_subweb (def2web[i]);
01598 if (set && web->type == SPILLED && web->stack_slot == NULL)
01599 {
01600 deleted_def_insns++;
01601 deleted_def_cost += BLOCK_FOR_INSN (insn)->frequency + 1;
01602 PUT_CODE (insn, NOTE);
01603 NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
01604 df_insn_modify (df, BLOCK_FOR_INSN (insn), insn);
01605 }
01606 });
01607 }
01608
01609
01610
01611
01612
01613
01614 static void
01615 detect_non_changed_webs ()
01616 {
01617 struct dlist *d, *d_next;
01618 for (d = WEBS(SPILLED); d; d = d_next)
01619 {
01620 struct web *web = DLIST_WEB (d);
01621 d_next = d->next;
01622 if (!web->changed)
01623 {
01624 ra_debug_msg (DUMP_PROCESS, "no insns emitted for spilled web %d\n",
01625 web->id);
01626 remove_web_from_list (web);
01627 put_web (web, COLORED);
01628 web->changed = 1;
01629 }
01630 else
01631 web->changed = 0;
01632
01633
01634
01635 }
01636 }
01637
01638
01639
01640 static void
01641 reset_changed_flag ()
01642 {
01643 struct dlist *d;
01644 for (d = WEBS(SPILLED); d; d = d->next)
01645 DLIST_WEB(d)->changed = 0;
01646 }
01647
01648
01649
01650
01651
01652
01653 void
01654 actual_spill ()
01655 {
01656 int i;
01657 bitmap new_deaths = BITMAP_XMALLOC ();
01658 reset_changed_flag ();
01659 spill_coalprop ();
01660 choose_spill_colors ();
01661 useless_defs = BITMAP_XMALLOC ();
01662 if (flag_ra_improved_spilling)
01663 rewrite_program2 (new_deaths);
01664 else
01665 rewrite_program (new_deaths);
01666 insert_stores (new_deaths);
01667 delete_useless_defs ();
01668 BITMAP_XFREE (useless_defs);
01669 sbitmap_free (insns_with_deaths);
01670 insns_with_deaths = sbitmap_alloc (get_max_uid ());
01671 death_insns_max_uid = get_max_uid ();
01672 sbitmap_zero (insns_with_deaths);
01673 EXECUTE_IF_SET_IN_BITMAP (new_deaths, 0, i,
01674 { SET_BIT (insns_with_deaths, i);});
01675 detect_non_changed_webs ();
01676 detect_web_parts_to_rebuild ();
01677 BITMAP_XFREE (new_deaths);
01678 }
01679
01680
01681
01682
01683 static bitmap regnos_coalesced_to_hardregs;
01684
01685
01686
01687
01688 void
01689 emit_colors (df)
01690 struct df *df;
01691 {
01692 unsigned int i;
01693 int si;
01694 struct web *web;
01695 int old_max_regno = max_reg_num ();
01696 regset old_regs;
01697 basic_block bb;
01698
01699
01700
01701 regnos_coalesced_to_hardregs = BITMAP_XMALLOC ();
01702
01703
01704
01705 for (i = 0; i < num_webs - num_subwebs; i++)
01706 {
01707 web = ID2WEB (i);
01708 if (web->type != COLORED && web->type != COALESCED)
01709 continue;
01710 if (web->type == COALESCED && alias (web)->type == COLORED)
01711 continue;
01712 if (web->reg_rtx || web->regno < FIRST_PSEUDO_REGISTER)
01713 abort ();
01714
01715 if (web->regno >= max_normal_pseudo)
01716 {
01717 rtx place;
01718 if (web->color == an_unusable_color)
01719 {
01720 unsigned int inherent_size = PSEUDO_REGNO_BYTES (web->regno);
01721 unsigned int total_size = MAX (inherent_size, 0);
01722 place = assign_stack_local (PSEUDO_REGNO_MODE (web->regno),
01723 total_size,
01724 inherent_size == total_size ? 0 : -1);
01725 RTX_UNCHANGING_P (place) =
01726 RTX_UNCHANGING_P (regno_reg_rtx[web->regno]);
01727 set_mem_alias_set (place, new_alias_set ());
01728 }
01729 else
01730 {
01731 place = gen_reg_rtx (PSEUDO_REGNO_MODE (web->regno));
01732 }
01733 web->reg_rtx = place;
01734 }
01735 else
01736 {
01737
01738
01739
01740 if (web->num_uses == 0 && web->num_defs == 1)
01741 web->reg_rtx = gen_reg_rtx (GET_MODE (DF_REF_REAL_REG (web->defs[0])));
01742 else
01743 web->reg_rtx = gen_reg_rtx (PSEUDO_REGNO_MODE (web->regno));
01744
01745 if (web->type == COALESCED)
01746 bitmap_set_bit (regnos_coalesced_to_hardregs, REGNO (web->reg_rtx));
01747 }
01748 }
01749 ra_max_regno = max_regno = max_reg_num ();
01750 allocate_reg_info (max_regno, FALSE, FALSE);
01751 ra_reg_renumber = (short *) xmalloc (max_regno * sizeof (short));
01752 for (si = 0; si < max_regno; si++)
01753 ra_reg_renumber[si] = -1;
01754
01755
01756
01757
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769 for (i = 0; i < df->use_id; i++)
01770 if (df->uses[i])
01771 {
01772 regset rs = DF_REF_BB (df->uses[i])->global_live_at_start;
01773 rtx regrtx;
01774 web = use2web[i];
01775 web = find_web_for_subweb (web);
01776 if (web->type != COLORED && web->type != COALESCED)
01777 continue;
01778 regrtx = alias (web)->reg_rtx;
01779 if (!regrtx)
01780 regrtx = web->reg_rtx;
01781 *DF_REF_REAL_LOC (df->uses[i]) = regrtx;
01782 if (REGNO_REG_SET_P (rs, web->regno) && REG_P (regrtx))
01783 {
01784
01785 SET_REGNO_REG_SET (rs, REGNO (regrtx));
01786 }
01787 }
01788
01789
01790 for (i = 0; i < df->def_id; i++)
01791 {
01792 regset rs;
01793 rtx regrtx;
01794 if (!df->defs[i])
01795 continue;
01796 rs = DF_REF_BB (df->defs[i])->global_live_at_start;
01797 web = def2web[i];
01798 web = find_web_for_subweb (web);
01799 if (web->type != COLORED && web->type != COALESCED)
01800 continue;
01801 regrtx = alias (web)->reg_rtx;
01802 if (!regrtx)
01803 regrtx = web->reg_rtx;
01804 *DF_REF_REAL_LOC (df->defs[i]) = regrtx;
01805 if (REGNO_REG_SET_P (rs, web->regno) && REG_P (regrtx))
01806 {
01807
01808
01809
01810 SET_REGNO_REG_SET (rs, REGNO (regrtx));
01811 }
01812 }
01813
01814
01815
01816 for (i = 0; i < num_webs - num_subwebs; i++)
01817 {
01818 web = ID2WEB (i);
01819 if (web->reg_rtx && REG_P (web->reg_rtx))
01820 {
01821 int r = REGNO (web->reg_rtx);
01822 ra_reg_renumber[r] = web->color;
01823 ra_debug_msg (DUMP_COLORIZE, "Renumber pseudo %d (== web %d) to %d\n",
01824 r, web->id, ra_reg_renumber[r]);
01825 }
01826 }
01827
01828 old_regs = BITMAP_XMALLOC ();
01829 for (si = FIRST_PSEUDO_REGISTER; si < old_max_regno; si++)
01830 SET_REGNO_REG_SET (old_regs, si);
01831 FOR_EACH_BB (bb)
01832 {
01833 AND_COMPL_REG_SET (bb->global_live_at_start, old_regs);
01834 AND_COMPL_REG_SET (bb->global_live_at_end, old_regs);
01835 }
01836 BITMAP_XFREE (old_regs);
01837 }
01838
01839
01840
01841 void
01842 delete_moves ()
01843 {
01844 struct move_list *ml;
01845 struct web *s, *t;
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862
01863
01864
01865
01866
01867
01868
01869
01870
01871 for (ml = wl_moves; ml; ml = ml->next)
01872
01873
01874
01875 if (ml->move
01876 && (s = alias (ml->move->source_web))->reg_rtx
01877 == (t = alias (ml->move->target_web))->reg_rtx
01878 && s->type != PRECOLORED && t->type != PRECOLORED)
01879 {
01880 basic_block bb = BLOCK_FOR_INSN (ml->move->insn);
01881 df_insn_delete (df, bb, ml->move->insn);
01882 deleted_move_insns++;
01883 deleted_move_cost += bb->frequency + 1;
01884 }
01885 }
01886
01887
01888
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899 void
01900 remove_suspicious_death_notes ()
01901 {
01902 rtx insn;
01903 for (insn = get_insns(); insn; insn = NEXT_INSN (insn))
01904 if (INSN_P (insn))
01905 {
01906 rtx *pnote = ®_NOTES (insn);
01907 while (*pnote)
01908 {
01909 rtx note = *pnote;
01910 if ((REG_NOTE_KIND (note) == REG_DEAD
01911 || REG_NOTE_KIND (note) == REG_UNUSED)
01912 && (GET_CODE (XEXP (note, 0)) == REG
01913 && bitmap_bit_p (regnos_coalesced_to_hardregs,
01914 REGNO (XEXP (note, 0)))))
01915 *pnote = XEXP (note, 1);
01916 else
01917 pnote = &XEXP (*pnote, 1);
01918 }
01919 }
01920 BITMAP_XFREE (regnos_coalesced_to_hardregs);
01921 regnos_coalesced_to_hardregs = NULL;
01922 }
01923
01924
01925
01926
01927
01928 void
01929 setup_renumber (free_it)
01930 int free_it;
01931 {
01932 int i;
01933 max_regno = max_reg_num ();
01934 allocate_reg_info (max_regno, FALSE, TRUE);
01935 for (i = 0; i < max_regno; i++)
01936 {
01937 reg_renumber[i] = (i < ra_max_regno) ? ra_reg_renumber[i] : -1;
01938 }
01939 if (free_it)
01940 {
01941 free (ra_reg_renumber);
01942 ra_reg_renumber = NULL;
01943 ra_max_regno = 0;
01944 }
01945 }
01946
01947
01948
01949
01950 void
01951 dump_cost (level)
01952 unsigned int level;
01953 {
01954 ra_debug_msg (level, "Instructions for spilling\n added:\n");
01955 ra_debug_msg (level, " loads =%d cost=", emitted_spill_loads);
01956 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_load_cost);
01957 ra_debug_msg (level, "\n stores=%d cost=", emitted_spill_stores);
01958 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_store_cost);
01959 ra_debug_msg (level, "\n remat =%d cost=", emitted_remat);
01960 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, spill_remat_cost);
01961 ra_debug_msg (level, "\n removed:\n moves =%d cost=", deleted_move_insns);
01962 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, deleted_move_cost);
01963 ra_debug_msg (level, "\n others=%d cost=", deleted_def_insns);
01964 ra_debug_msg (level, HOST_WIDE_INT_PRINT_UNSIGNED, deleted_def_cost);
01965 ra_debug_msg (level, "\n");
01966 }
01967
01968
01969
01970 void
01971 ra_rewrite_init ()
01972 {
01973 emitted_spill_loads = 0;
01974 emitted_spill_stores = 0;
01975 emitted_remat = 0;
01976 spill_load_cost = 0;
01977 spill_store_cost = 0;
01978 spill_remat_cost = 0;
01979 deleted_move_insns = 0;
01980 deleted_move_cost = 0;
01981 deleted_def_insns = 0;
01982 deleted_def_cost = 0;
01983 }
01984
01985
01986
01987