00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "machmode.h"
00028 #include "hard-reg-set.h"
00029 #include "rtl.h"
00030 #include "tm_p.h"
00031 #include "flags.h"
00032 #include "regs.h"
00033 #include "function.h"
00034 #include "insn-config.h"
00035 #include "recog.h"
00036 #include "reload.h"
00037 #include "output.h"
00038 #include "toplev.h"
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 static int max_allocno;
00082
00083
00084
00085
00086 static int *reg_allocno;
00087
00088 struct allocno
00089 {
00090 int reg;
00091
00092
00093 int size;
00094
00095
00096 int calls_crossed;
00097
00098
00099 int throwing_calls_crossed;
00100
00101
00102 int n_refs;
00103
00104
00105 int freq;
00106
00107
00108
00109 int live_length;
00110
00111
00112
00113 HARD_REG_SET hard_reg_conflicts;
00114
00115
00116
00117
00118
00119 HARD_REG_SET hard_reg_preferences;
00120
00121
00122
00123
00124
00125
00126 HARD_REG_SET hard_reg_copy_preferences;
00127
00128
00129
00130
00131
00132 HARD_REG_SET hard_reg_full_preferences;
00133
00134
00135
00136 HARD_REG_SET regs_someone_prefers;
00137
00138 #ifdef STACK_REGS
00139
00140 bool no_stack_reg;
00141 #endif
00142 };
00143
00144 static struct allocno *allocno;
00145
00146
00147
00148
00149 static int *allocno_order;
00150
00151
00152
00153
00154
00155 static int *reg_may_share;
00156
00157
00158
00159
00160
00161 #define INT_BITS HOST_BITS_PER_WIDE_INT
00162 #define INT_TYPE HOST_WIDE_INT
00163
00164
00165
00166
00167
00168
00169
00170 static INT_TYPE *conflicts;
00171
00172
00173
00174
00175 static int allocno_row_words;
00176
00177
00178
00179 #define CONFLICTP(I, J) \
00180 (conflicts[(I) * allocno_row_words + (unsigned) (J) / INT_BITS] \
00181 & ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS)))
00182
00183
00184
00185 #define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE) \
00186 do { \
00187 int i_; \
00188 int allocno_; \
00189 INT_TYPE *p_ = (ALLOCNO_SET); \
00190 \
00191 for (i_ = allocno_row_words - 1, allocno_ = 0; i_ >= 0; \
00192 i_--, allocno_ += INT_BITS) \
00193 { \
00194 unsigned INT_TYPE word_ = (unsigned INT_TYPE) *p_++; \
00195 \
00196 for ((ALLOCNO) = allocno_; word_; word_ >>= 1, (ALLOCNO)++) \
00197 { \
00198 if (word_ & 1) \
00199 {CODE;} \
00200 } \
00201 } \
00202 } while (0)
00203
00204
00205 #if 0
00206
00207
00208
00209 #define EXECUTE_IF_CONFLICT(IN_ALLOCNO, OUT_ALLOCNO, CODE)\
00210 EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + (IN_ALLOCNO) * allocno_row_words,\
00211 OUT_ALLOCNO, (CODE))
00212 #endif
00213
00214
00215
00216 static HARD_REG_SET hard_regs_live;
00217
00218
00219
00220 static HARD_REG_SET no_global_alloc_regs;
00221
00222
00223
00224 static HARD_REG_SET regs_used_so_far;
00225
00226
00227
00228
00229 static int local_reg_n_refs[FIRST_PSEUDO_REGISTER];
00230
00231
00232 static int local_reg_freq[FIRST_PSEUDO_REGISTER];
00233
00234
00235
00236
00237 static int local_reg_live_length[FIRST_PSEUDO_REGISTER];
00238
00239
00240
00241
00242 #define SET_REGBIT(TABLE, I, J) SET_HARD_REG_BIT (allocno[I].TABLE, J)
00243
00244
00245
00246 static INT_TYPE *allocnos_live;
00247
00248
00249
00250
00251 #define SET_ALLOCNO_LIVE(I) \
00252 (allocnos_live[(unsigned) (I) / INT_BITS] \
00253 |= ((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS)))
00254
00255 #define CLEAR_ALLOCNO_LIVE(I) \
00256 (allocnos_live[(unsigned) (I) / INT_BITS] \
00257 &= ~((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS)))
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273 #if 0
00274
00275
00276
00277 #define NUM_NO_CONFLICT_PAIRS 4
00278
00279 int n_no_conflict_pairs;
00280 static struct { int allocno1, allocno2;}
00281 no_conflict_pairs[NUM_NO_CONFLICT_PAIRS];
00282 #endif
00283
00284
00285
00286
00287 static rtx *regs_set;
00288 static int n_regs_set;
00289
00290
00291
00292 static HARD_REG_SET eliminable_regset;
00293
00294 static int allocno_compare (const void *, const void *);
00295 static void global_conflicts (void);
00296 static void mirror_conflicts (void);
00297 static void expand_preferences (void);
00298 static void prune_preferences (void);
00299 static void find_reg (int, HARD_REG_SET, int, int, int);
00300 static void record_one_conflict (int);
00301 static void record_conflicts (int *, int);
00302 static void mark_reg_store (rtx, rtx, void *);
00303 static void mark_reg_clobber (rtx, rtx, void *);
00304 static void mark_reg_conflicts (rtx);
00305 static void mark_reg_death (rtx);
00306 static void mark_reg_live_nc (int, enum machine_mode);
00307 static void set_preference (rtx, rtx);
00308 static void dump_conflicts (FILE *);
00309 static void reg_becomes_live (rtx, rtx, void *);
00310 static void reg_dies (int, enum machine_mode, struct insn_chain *);
00311
00312 static void allocate_bb_info (void);
00313 static void free_bb_info (void);
00314 static bool check_earlyclobber (rtx);
00315 static void mark_reg_use_for_earlyclobber_1 (rtx *, void *);
00316 static int mark_reg_use_for_earlyclobber (rtx *, void *);
00317 static void calculate_local_reg_bb_info (void);
00318 static void set_up_bb_rts_numbers (void);
00319 static int rpost_cmp (const void *, const void *);
00320 static void calculate_reg_pav (void);
00321 static void modify_reg_pav (void);
00322 static void make_accurate_live_analysis (void);
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int
00334 global_alloc (FILE *file)
00335 {
00336 int retval;
00337 #ifdef ELIMINABLE_REGS
00338 static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
00339 #endif
00340 int need_fp
00341 = (! flag_omit_frame_pointer
00342 || (current_function_calls_alloca && EXIT_IGNORE_STACK)
00343 || FRAME_POINTER_REQUIRED);
00344
00345 size_t i;
00346 rtx x;
00347
00348 make_accurate_live_analysis ();
00349
00350 max_allocno = 0;
00351
00352
00353
00354
00355 CLEAR_HARD_REG_SET (no_global_alloc_regs);
00356
00357
00358
00359 #ifdef ELIMINABLE_REGS
00360 for (i = 0; i < ARRAY_SIZE (eliminables); i++)
00361 {
00362 bool cannot_elim
00363 = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to)
00364 || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
00365
00366 if (!regs_asm_clobbered[eliminables[i].from])
00367 {
00368 SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
00369
00370 if (cannot_elim)
00371 SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from);
00372 }
00373 else if (cannot_elim)
00374 error ("%s cannot be used in asm here",
00375 reg_names[eliminables[i].from]);
00376 else
00377 regs_ever_live[eliminables[i].from] = 1;
00378 }
00379 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
00380 if (!regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
00381 {
00382 SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
00383 if (need_fp)
00384 SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM);
00385 }
00386 else if (need_fp)
00387 error ("%s cannot be used in asm here",
00388 reg_names[HARD_FRAME_POINTER_REGNUM]);
00389 else
00390 regs_ever_live[HARD_FRAME_POINTER_REGNUM] = 1;
00391 #endif
00392
00393 #else
00394 if (!regs_asm_clobbered[FRAME_POINTER_REGNUM])
00395 {
00396 SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
00397 if (need_fp)
00398 SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM);
00399 }
00400 else if (need_fp)
00401 error ("%s cannot be used in asm here", reg_names[FRAME_POINTER_REGNUM]);
00402 else
00403 regs_ever_live[FRAME_POINTER_REGNUM] = 1;
00404 #endif
00405
00406
00407
00408
00409
00410 CLEAR_HARD_REG_SET (regs_used_so_far);
00411 #ifdef LEAF_REGISTERS
00412
00413
00414
00415
00416 {
00417 const char *cheap_regs;
00418 const char *const leaf_regs = LEAF_REGISTERS;
00419
00420 if (only_leaf_regs_used () && leaf_function_p ())
00421 cheap_regs = leaf_regs;
00422 else
00423 cheap_regs = call_used_regs;
00424 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00425 if (regs_ever_live[i] || cheap_regs[i])
00426 SET_HARD_REG_BIT (regs_used_so_far, i);
00427 }
00428 #else
00429
00430
00431 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00432 if (regs_ever_live[i] || call_used_regs[i])
00433 SET_HARD_REG_BIT (regs_used_so_far, i);
00434 #endif
00435
00436 for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
00437 if (reg_renumber[i] >= 0)
00438 SET_HARD_REG_BIT (regs_used_so_far, reg_renumber[i]);
00439
00440
00441
00442
00443 reg_allocno = xmalloc (max_regno * sizeof (int));
00444
00445 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00446 reg_allocno[i] = -1;
00447
00448
00449
00450 reg_may_share = xcalloc (max_regno, sizeof (int));
00451 for (x = regs_may_share; x; x = XEXP (XEXP (x, 1), 1))
00452 {
00453 int r1 = REGNO (XEXP (x, 0));
00454 int r2 = REGNO (XEXP (XEXP (x, 1), 0));
00455 if (r1 > r2)
00456 reg_may_share[r1] = r2;
00457 else
00458 reg_may_share[r2] = r1;
00459 }
00460
00461 for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
00462
00463
00464
00465 if (REG_N_REFS (i) != 0 && REG_LIVE_LENGTH (i) != -1
00466
00467
00468 && (! current_function_has_nonlocal_label
00469 || REG_N_CALLS_CROSSED (i) == 0))
00470 {
00471 if (reg_renumber[i] < 0
00472 && reg_may_share[i] && reg_allocno[reg_may_share[i]] >= 0)
00473 reg_allocno[i] = reg_allocno[reg_may_share[i]];
00474 else
00475 reg_allocno[i] = max_allocno++;
00476 gcc_assert (REG_LIVE_LENGTH (i));
00477 }
00478 else
00479 reg_allocno[i] = -1;
00480
00481 allocno = xcalloc (max_allocno, sizeof (struct allocno));
00482
00483 for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
00484 if (reg_allocno[i] >= 0)
00485 {
00486 int num = reg_allocno[i];
00487 allocno[num].reg = i;
00488 allocno[num].size = PSEUDO_REGNO_SIZE (i);
00489 allocno[num].calls_crossed += REG_N_CALLS_CROSSED (i);
00490 allocno[num].throwing_calls_crossed
00491 += REG_N_THROWING_CALLS_CROSSED (i);
00492 allocno[num].n_refs += REG_N_REFS (i);
00493 allocno[num].freq += REG_FREQ (i);
00494 if (allocno[num].live_length < REG_LIVE_LENGTH (i))
00495 allocno[num].live_length = REG_LIVE_LENGTH (i);
00496 }
00497
00498
00499
00500
00501 memset (local_reg_live_length, 0, sizeof local_reg_live_length);
00502 memset (local_reg_n_refs, 0, sizeof local_reg_n_refs);
00503 memset (local_reg_freq, 0, sizeof local_reg_freq);
00504 for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++)
00505 if (reg_renumber[i] >= 0)
00506 {
00507 int regno = reg_renumber[i];
00508 int endregno = regno + hard_regno_nregs[regno][PSEUDO_REGNO_MODE (i)];
00509 int j;
00510
00511 for (j = regno; j < endregno; j++)
00512 {
00513 local_reg_n_refs[j] += REG_N_REFS (i);
00514 local_reg_freq[j] += REG_FREQ (i);
00515 local_reg_live_length[j] += REG_LIVE_LENGTH (i);
00516 }
00517 }
00518
00519
00520 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00521 if (regs_ever_live[i])
00522 local_reg_n_refs[i] = 0, local_reg_freq[i] = 0;
00523
00524 allocno_row_words = (max_allocno + INT_BITS - 1) / INT_BITS;
00525
00526
00527
00528
00529 conflicts = xcalloc (max_allocno * allocno_row_words, sizeof (INT_TYPE));
00530
00531 allocnos_live = xmalloc (allocno_row_words * sizeof (INT_TYPE));
00532
00533
00534
00535
00536 if (max_allocno > 0)
00537 {
00538
00539
00540
00541 global_conflicts ();
00542
00543 mirror_conflicts ();
00544
00545
00546
00547
00548
00549
00550
00551
00552 for (i = 0; i < (size_t) max_allocno; i++)
00553 {
00554 AND_COMPL_HARD_REG_SET (allocno[i].hard_reg_conflicts,
00555 eliminable_regset);
00556 AND_COMPL_HARD_REG_SET (allocno[i].hard_reg_copy_preferences,
00557 eliminable_regset);
00558 AND_COMPL_HARD_REG_SET (allocno[i].hard_reg_preferences,
00559 eliminable_regset);
00560 }
00561
00562
00563
00564 expand_preferences ();
00565
00566
00567
00568 allocno_order = xmalloc (max_allocno * sizeof (int));
00569 for (i = 0; i < (size_t) max_allocno; i++)
00570 allocno_order[i] = i;
00571
00572
00573
00574
00575
00576
00577
00578
00579 for (i = 0; i < (size_t) max_allocno; i++)
00580 {
00581 if (allocno[i].size == 0)
00582 allocno[i].size = 1;
00583 if (allocno[i].live_length == 0)
00584 allocno[i].live_length = -1;
00585 }
00586
00587 qsort (allocno_order, max_allocno, sizeof (int), allocno_compare);
00588
00589 prune_preferences ();
00590
00591 if (file)
00592 dump_conflicts (file);
00593
00594
00595
00596
00597 for (i = 0; i < (size_t) max_allocno; i++)
00598 if (reg_renumber[allocno[allocno_order[i]].reg] < 0
00599 && REG_LIVE_LENGTH (allocno[allocno_order[i]].reg) >= 0)
00600 {
00601
00602
00603
00604 if (N_REG_CLASSES > 1)
00605 {
00606 find_reg (allocno_order[i], 0, 0, 0, 0);
00607 if (reg_renumber[allocno[allocno_order[i]].reg] >= 0)
00608 continue;
00609 }
00610 if (reg_alternate_class (allocno[allocno_order[i]].reg) != NO_REGS)
00611 find_reg (allocno_order[i], 0, 1, 0, 0);
00612 }
00613
00614 free (allocno_order);
00615 }
00616
00617
00618
00619
00620 #if 0
00621
00622 if (n_basic_blocks > 0)
00623 #endif
00624 {
00625 build_insn_chain (get_insns ());
00626 retval = reload (get_insns (), 1);
00627 }
00628
00629
00630 free (reg_allocno);
00631 free (reg_may_share);
00632 free (allocno);
00633 free (conflicts);
00634 free (allocnos_live);
00635
00636 return retval;
00637 }
00638
00639
00640
00641
00642 static int
00643 allocno_compare (const void *v1p, const void *v2p)
00644 {
00645 int v1 = *(const int *)v1p, v2 = *(const int *)v2p;
00646
00647
00648
00649
00650
00651 int pri1
00652 = (((double) (floor_log2 (allocno[v1].n_refs) * allocno[v1].freq)
00653 / allocno[v1].live_length)
00654 * (10000 / REG_FREQ_MAX) * allocno[v1].size);
00655 int pri2
00656 = (((double) (floor_log2 (allocno[v2].n_refs) * allocno[v2].freq)
00657 / allocno[v2].live_length)
00658 * (10000 / REG_FREQ_MAX) * allocno[v2].size);
00659 if (pri2 - pri1)
00660 return pri2 - pri1;
00661
00662
00663
00664 return v1 - v2;
00665 }
00666
00667
00668
00669
00670 static void
00671 global_conflicts (void)
00672 {
00673 unsigned i;
00674 basic_block b;
00675 rtx insn;
00676 int *block_start_allocnos;
00677
00678
00679 regs_set = xmalloc (max_parallel * sizeof (rtx) * 2);
00680
00681 block_start_allocnos = xmalloc (max_allocno * sizeof (int));
00682
00683 FOR_EACH_BB (b)
00684 {
00685 memset (allocnos_live, 0, allocno_row_words * sizeof (INT_TYPE));
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 {
00702 regset old = b->global_live_at_start;
00703 int ax = 0;
00704 reg_set_iterator rsi;
00705
00706 REG_SET_TO_HARD_REG_SET (hard_regs_live, old);
00707 EXECUTE_IF_SET_IN_REG_SET (old, FIRST_PSEUDO_REGISTER, i, rsi)
00708 {
00709 int a = reg_allocno[i];
00710 if (a >= 0)
00711 {
00712 SET_ALLOCNO_LIVE (a);
00713 block_start_allocnos[ax++] = a;
00714 }
00715 else if ((a = reg_renumber[i]) >= 0)
00716 mark_reg_live_nc (a, PSEUDO_REGNO_MODE (i));
00717 }
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743 record_conflicts (block_start_allocnos, ax);
00744
00745
00746
00747
00748
00749
00750 {
00751 edge e;
00752 edge_iterator ei;
00753
00754 FOR_EACH_EDGE (e, ei, b->preds)
00755 if (e->flags & EDGE_ABNORMAL)
00756 break;
00757
00758 if (e != NULL)
00759 {
00760 #ifdef STACK_REGS
00761 EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax,
00762 {
00763 allocno[ax].no_stack_reg = 1;
00764 });
00765 for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++)
00766 record_one_conflict (ax);
00767 #endif
00768
00769
00770
00771
00772 if (! current_function_has_nonlocal_label)
00773 for (ax = 0; ax < FIRST_PSEUDO_REGISTER; ax++)
00774 if (call_used_regs [ax])
00775 record_one_conflict (ax);
00776 }
00777 }
00778 }
00779
00780 insn = BB_HEAD (b);
00781
00782
00783
00784
00785
00786 while (1)
00787 {
00788 RTX_CODE code = GET_CODE (insn);
00789 rtx link;
00790
00791
00792
00793 n_regs_set = 0;
00794
00795 if (code == INSN || code == CALL_INSN || code == JUMP_INSN)
00796 {
00797
00798 #if 0
00799 int i = 0;
00800 for (link = REG_NOTES (insn);
00801 link && i < NUM_NO_CONFLICT_PAIRS;
00802 link = XEXP (link, 1))
00803 if (REG_NOTE_KIND (link) == REG_NO_CONFLICT)
00804 {
00805 no_conflict_pairs[i].allocno1
00806 = reg_allocno[REGNO (SET_DEST (PATTERN (insn)))];
00807 no_conflict_pairs[i].allocno2
00808 = reg_allocno[REGNO (XEXP (link, 0))];
00809 i++;
00810 }
00811 #endif
00812
00813
00814
00815
00816 note_stores (PATTERN (insn), mark_reg_clobber, NULL);
00817
00818
00819
00820 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
00821 if (REG_NOTE_KIND (link) == REG_DEAD)
00822 mark_reg_death (XEXP (link, 0));
00823
00824
00825
00826
00827
00828
00829 note_stores (PATTERN (insn), mark_reg_store, NULL);
00830
00831 #ifdef AUTO_INC_DEC
00832 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
00833 if (REG_NOTE_KIND (link) == REG_INC)
00834 mark_reg_store (XEXP (link, 0), NULL_RTX, NULL);
00835 #endif
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 if (GET_CODE (PATTERN (insn)) == PARALLEL && multiple_sets (insn))
00849 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
00850 if (REG_NOTE_KIND (link) == REG_DEAD)
00851 {
00852 int used_in_output = 0;
00853 int i;
00854 rtx reg = XEXP (link, 0);
00855
00856 for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
00857 {
00858 rtx set = XVECEXP (PATTERN (insn), 0, i);
00859 if (GET_CODE (set) == SET
00860 && !REG_P (SET_DEST (set))
00861 && !rtx_equal_p (reg, SET_DEST (set))
00862 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
00863 used_in_output = 1;
00864 }
00865 if (used_in_output)
00866 mark_reg_conflicts (reg);
00867 }
00868
00869
00870
00871 while (n_regs_set-- > 0)
00872 {
00873 rtx note = find_regno_note (insn, REG_UNUSED,
00874 REGNO (regs_set[n_regs_set]));
00875 if (note)
00876 mark_reg_death (XEXP (note, 0));
00877 }
00878 }
00879
00880 if (insn == BB_END (b))
00881 break;
00882 insn = NEXT_INSN (insn);
00883 }
00884 }
00885
00886
00887 free (block_start_allocnos);
00888 free (regs_set);
00889 }
00890
00891
00892
00893
00894 static void
00895 expand_preferences (void)
00896 {
00897 rtx insn;
00898 rtx link;
00899 rtx set;
00900
00901
00902
00903
00904 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
00905 if (INSN_P (insn)
00906 && (set = single_set (insn)) != 0
00907 && REG_P (SET_DEST (set))
00908 && reg_allocno[REGNO (SET_DEST (set))] >= 0)
00909 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
00910 if (REG_NOTE_KIND (link) == REG_DEAD
00911 && REG_P (XEXP (link, 0))
00912 && reg_allocno[REGNO (XEXP (link, 0))] >= 0
00913 && ! CONFLICTP (reg_allocno[REGNO (SET_DEST (set))],
00914 reg_allocno[REGNO (XEXP (link, 0))]))
00915 {
00916 int a1 = reg_allocno[REGNO (SET_DEST (set))];
00917 int a2 = reg_allocno[REGNO (XEXP (link, 0))];
00918
00919 if (XEXP (link, 0) == SET_SRC (set))
00920 {
00921 IOR_HARD_REG_SET (allocno[a1].hard_reg_copy_preferences,
00922 allocno[a2].hard_reg_copy_preferences);
00923 IOR_HARD_REG_SET (allocno[a2].hard_reg_copy_preferences,
00924 allocno[a1].hard_reg_copy_preferences);
00925 }
00926
00927 IOR_HARD_REG_SET (allocno[a1].hard_reg_preferences,
00928 allocno[a2].hard_reg_preferences);
00929 IOR_HARD_REG_SET (allocno[a2].hard_reg_preferences,
00930 allocno[a1].hard_reg_preferences);
00931 IOR_HARD_REG_SET (allocno[a1].hard_reg_full_preferences,
00932 allocno[a2].hard_reg_full_preferences);
00933 IOR_HARD_REG_SET (allocno[a2].hard_reg_full_preferences,
00934 allocno[a1].hard_reg_full_preferences);
00935 }
00936 }
00937
00938
00939
00940
00941
00942
00943
00944
00945 static void
00946 prune_preferences (void)
00947 {
00948 int i;
00949 int num;
00950 int *allocno_to_order = xmalloc (max_allocno * sizeof (int));
00951
00952
00953
00954
00955
00956
00957 for (i = max_allocno - 1; i >= 0; i--)
00958 {
00959 HARD_REG_SET temp;
00960
00961 num = allocno_order[i];
00962 allocno_to_order[num] = i;
00963 COPY_HARD_REG_SET (temp, allocno[num].hard_reg_conflicts);
00964
00965 if (allocno[num].calls_crossed == 0)
00966 IOR_HARD_REG_SET (temp, fixed_reg_set);
00967 else
00968 IOR_HARD_REG_SET (temp, call_used_reg_set);
00969
00970 IOR_COMPL_HARD_REG_SET
00971 (temp,
00972 reg_class_contents[(int) reg_preferred_class (allocno[num].reg)]);
00973
00974 AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_preferences, temp);
00975 AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_copy_preferences, temp);
00976 AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_full_preferences, temp);
00977 }
00978
00979 for (i = max_allocno - 1; i >= 0; i--)
00980 {
00981
00982
00983
00984
00985
00986 HARD_REG_SET temp, temp2;
00987 int allocno2;
00988
00989 num = allocno_order[i];
00990
00991 CLEAR_HARD_REG_SET (temp);
00992 CLEAR_HARD_REG_SET (temp2);
00993
00994 EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + num * allocno_row_words,
00995 allocno2,
00996 {
00997 if (allocno_to_order[allocno2] > i)
00998 {
00999 if (allocno[allocno2].size <= allocno[num].size)
01000 IOR_HARD_REG_SET (temp,
01001 allocno[allocno2].hard_reg_full_preferences);
01002 else
01003 IOR_HARD_REG_SET (temp2,
01004 allocno[allocno2].hard_reg_full_preferences);
01005 }
01006 });
01007
01008 AND_COMPL_HARD_REG_SET (temp, allocno[num].hard_reg_full_preferences);
01009 IOR_HARD_REG_SET (temp, temp2);
01010 COPY_HARD_REG_SET (allocno[num].regs_someone_prefers, temp);
01011 }
01012 free (allocno_to_order);
01013 }
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033 static void
01034 find_reg (int num, HARD_REG_SET losers, int alt_regs_p, int accept_call_clobbered, int retrying)
01035 {
01036 int i, best_reg, pass;
01037 HARD_REG_SET used, used1, used2;
01038
01039 enum reg_class class = (alt_regs_p
01040 ? reg_alternate_class (allocno[num].reg)
01041 : reg_preferred_class (allocno[num].reg));
01042 enum machine_mode mode = PSEUDO_REGNO_MODE (allocno[num].reg);
01043
01044 if (accept_call_clobbered)
01045 COPY_HARD_REG_SET (used1, call_fixed_reg_set);
01046 else if (allocno[num].calls_crossed == 0)
01047 COPY_HARD_REG_SET (used1, fixed_reg_set);
01048 else
01049 COPY_HARD_REG_SET (used1, call_used_reg_set);
01050
01051
01052 IOR_HARD_REG_SET (used1, no_global_alloc_regs);
01053 if (losers)
01054 IOR_HARD_REG_SET (used1, losers);
01055
01056 IOR_COMPL_HARD_REG_SET (used1, reg_class_contents[(int) class]);
01057 COPY_HARD_REG_SET (used2, used1);
01058
01059 IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts);
01060
01061 #ifdef CANNOT_CHANGE_MODE_CLASS
01062 cannot_change_mode_set_regs (&used1, mode, allocno[num].reg);
01063 #endif
01064
01065
01066
01067
01068
01069
01070
01071 COPY_HARD_REG_SET (used, used1);
01072 IOR_COMPL_HARD_REG_SET (used, regs_used_so_far);
01073 IOR_HARD_REG_SET (used, allocno[num].regs_someone_prefers);
01074
01075 best_reg = -1;
01076 for (i = FIRST_PSEUDO_REGISTER, pass = 0;
01077 pass <= 1 && i >= FIRST_PSEUDO_REGISTER;
01078 pass++)
01079 {
01080 if (pass == 1)
01081 COPY_HARD_REG_SET (used, used1);
01082 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01083 {
01084 #ifdef REG_ALLOC_ORDER
01085 int regno = reg_alloc_order[i];
01086 #else
01087 int regno = i;
01088 #endif
01089 if (! TEST_HARD_REG_BIT (used, regno)
01090 && HARD_REGNO_MODE_OK (regno, mode)
01091 && (allocno[num].calls_crossed == 0
01092 || accept_call_clobbered
01093 || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
01094 {
01095 int j;
01096 int lim = regno + hard_regno_nregs[regno][mode];
01097 for (j = regno + 1;
01098 (j < lim
01099 && ! TEST_HARD_REG_BIT (used, j));
01100 j++);
01101 if (j == lim)
01102 {
01103 best_reg = regno;
01104 break;
01105 }
01106 #ifndef REG_ALLOC_ORDER
01107 i = j;
01108 #endif
01109 }
01110 }
01111 }
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_copy_preferences, used);
01125 GO_IF_HARD_REG_SUBSET (allocno[num].hard_reg_copy_preferences,
01126 reg_class_contents[(int) NO_REGS], no_copy_prefs);
01127
01128 if (best_reg >= 0)
01129 {
01130 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01131 if (TEST_HARD_REG_BIT (allocno[num].hard_reg_copy_preferences, i)
01132 && HARD_REGNO_MODE_OK (i, mode)
01133 && (allocno[num].calls_crossed == 0
01134 || accept_call_clobbered
01135 || ! HARD_REGNO_CALL_PART_CLOBBERED (i, mode))
01136 && (REGNO_REG_CLASS (i) == REGNO_REG_CLASS (best_reg)
01137 || reg_class_subset_p (REGNO_REG_CLASS (i),
01138 REGNO_REG_CLASS (best_reg))
01139 || reg_class_subset_p (REGNO_REG_CLASS (best_reg),
01140 REGNO_REG_CLASS (i))))
01141 {
01142 int j;
01143 int lim = i + hard_regno_nregs[i][mode];
01144 for (j = i + 1;
01145 (j < lim
01146 && ! TEST_HARD_REG_BIT (used, j)
01147 && (REGNO_REG_CLASS (j)
01148 == REGNO_REG_CLASS (best_reg + (j - i))
01149 || reg_class_subset_p (REGNO_REG_CLASS (j),
01150 REGNO_REG_CLASS (best_reg + (j - i)))
01151 || reg_class_subset_p (REGNO_REG_CLASS (best_reg + (j - i)),
01152 REGNO_REG_CLASS (j))));
01153 j++);
01154 if (j == lim)
01155 {
01156 best_reg = i;
01157 goto no_prefs;
01158 }
01159 }
01160 }
01161 no_copy_prefs:
01162
01163 AND_COMPL_HARD_REG_SET (allocno[num].hard_reg_preferences, used);
01164 GO_IF_HARD_REG_SUBSET (allocno[num].hard_reg_preferences,
01165 reg_class_contents[(int) NO_REGS], no_prefs);
01166
01167 if (best_reg >= 0)
01168 {
01169 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01170 if (TEST_HARD_REG_BIT (allocno[num].hard_reg_preferences, i)
01171 && HARD_REGNO_MODE_OK (i, mode)
01172 && (allocno[num].calls_crossed == 0
01173 || accept_call_clobbered
01174 || ! HARD_REGNO_CALL_PART_CLOBBERED (i, mode))
01175 && (REGNO_REG_CLASS (i) == REGNO_REG_CLASS (best_reg)
01176 || reg_class_subset_p (REGNO_REG_CLASS (i),
01177 REGNO_REG_CLASS (best_reg))
01178 || reg_class_subset_p (REGNO_REG_CLASS (best_reg),
01179 REGNO_REG_CLASS (i))))
01180 {
01181 int j;
01182 int lim = i + hard_regno_nregs[i][mode];
01183 for (j = i + 1;
01184 (j < lim
01185 && ! TEST_HARD_REG_BIT (used, j)
01186 && (REGNO_REG_CLASS (j)
01187 == REGNO_REG_CLASS (best_reg + (j - i))
01188 || reg_class_subset_p (REGNO_REG_CLASS (j),
01189 REGNO_REG_CLASS (best_reg + (j - i)))
01190 || reg_class_subset_p (REGNO_REG_CLASS (best_reg + (j - i)),
01191 REGNO_REG_CLASS (j))));
01192 j++);
01193 if (j == lim)
01194 {
01195 best_reg = i;
01196 break;
01197 }
01198 }
01199 }
01200 no_prefs:
01201
01202
01203
01204
01205
01206
01207 if (flag_caller_saves && best_reg < 0)
01208 {
01209
01210
01211
01212
01213 if (! accept_call_clobbered
01214 && allocno[num].calls_crossed != 0
01215 && allocno[num].throwing_calls_crossed == 0
01216 && CALLER_SAVE_PROFITABLE (allocno[num].n_refs,
01217 allocno[num].calls_crossed))
01218 {
01219 HARD_REG_SET new_losers;
01220 if (! losers)
01221 CLEAR_HARD_REG_SET (new_losers);
01222 else
01223 COPY_HARD_REG_SET (new_losers, losers);
01224
01225 IOR_HARD_REG_SET(new_losers, losing_caller_save_reg_set);
01226 find_reg (num, new_losers, alt_regs_p, 1, retrying);
01227 if (reg_renumber[allocno[num].reg] >= 0)
01228 {
01229 caller_save_needed = 1;
01230 return;
01231 }
01232 }
01233 }
01234
01235
01236
01237
01238
01239
01240 if (best_reg < 0 && !retrying
01241
01242 && allocno[num].size == 1)
01243 {
01244
01245 for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--)
01246 {
01247 #ifdef REG_ALLOC_ORDER
01248 int regno = reg_alloc_order[i];
01249 #else
01250 int regno = i;
01251 #endif
01252
01253 if (local_reg_n_refs[regno] != 0
01254
01255 && ! TEST_HARD_REG_BIT (used2, regno)
01256 && HARD_REGNO_MODE_OK (regno, mode)
01257
01258
01259
01260
01261 && hard_regno_nregs[regno][mode] == 1
01262 && (allocno[num].calls_crossed == 0
01263 || accept_call_clobbered
01264 || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
01265 #ifdef CANNOT_CHANGE_MODE_CLASS
01266 && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno),
01267 mode)
01268 #endif
01269 #ifdef STACK_REGS
01270 && (!allocno[num].no_stack_reg
01271 || regno < FIRST_STACK_REG || regno > LAST_STACK_REG)
01272 #endif
01273 )
01274 {
01275
01276
01277
01278
01279 double tmp1 = ((double) local_reg_freq[regno]
01280 / local_reg_live_length[regno]);
01281 double tmp2 = ((double) allocno[num].freq
01282 / allocno[num].live_length);
01283
01284 if (tmp1 < tmp2)
01285 {
01286
01287
01288 int k;
01289 for (k = 0; k < max_regno; k++)
01290 if (reg_renumber[k] >= 0)
01291 {
01292 int r = reg_renumber[k];
01293 int endregno
01294 = r + hard_regno_nregs[r][PSEUDO_REGNO_MODE (k)];
01295
01296 if (regno >= r && regno < endregno)
01297 reg_renumber[k] = -1;
01298 }
01299
01300 best_reg = regno;
01301 break;
01302 }
01303 }
01304 }
01305 }
01306
01307
01308
01309 if (best_reg >= 0)
01310 {
01311 int lim, j;
01312 HARD_REG_SET this_reg;
01313
01314
01315 reg_renumber[allocno[num].reg] = best_reg;
01316
01317 if (reg_may_share[allocno[num].reg])
01318 for (j = FIRST_PSEUDO_REGISTER; j < max_regno; j++)
01319 if (reg_allocno[j] == num)
01320 reg_renumber[j] = best_reg;
01321
01322
01323 CLEAR_HARD_REG_SET (this_reg);
01324 lim = best_reg + hard_regno_nregs[best_reg][mode];
01325 for (j = best_reg; j < lim; j++)
01326 {
01327 SET_HARD_REG_BIT (this_reg, j);
01328 SET_HARD_REG_BIT (regs_used_so_far, j);
01329
01330 local_reg_n_refs[j] = 0;
01331 local_reg_freq[j] = 0;
01332 }
01333
01334
01335 lim = num;
01336 EXECUTE_IF_SET_IN_ALLOCNO_SET (conflicts + lim * allocno_row_words, j,
01337 {
01338 IOR_HARD_REG_SET (allocno[j].hard_reg_conflicts, this_reg);
01339 });
01340 }
01341 }
01342
01343
01344
01345
01346
01347
01348
01349
01350 void
01351 retry_global_alloc (int regno, HARD_REG_SET forbidden_regs)
01352 {
01353 int alloc_no = reg_allocno[regno];
01354 if (alloc_no >= 0)
01355 {
01356
01357
01358
01359 if (N_REG_CLASSES > 1)
01360 find_reg (alloc_no, forbidden_regs, 0, 0, 1);
01361 if (reg_renumber[regno] < 0
01362 && reg_alternate_class (regno) != NO_REGS)
01363 find_reg (alloc_no, forbidden_regs, 1, 0, 1);
01364
01365
01366
01367 if (reg_renumber[regno] >= 0)
01368 {
01369 REGNO (regno_reg_rtx[regno]) = reg_renumber[regno];
01370 mark_home_live (regno);
01371 }
01372 }
01373 }
01374
01375
01376
01377
01378
01379
01380
01381 static void
01382 record_one_conflict (int regno)
01383 {
01384 int j;
01385
01386 if (regno < FIRST_PSEUDO_REGISTER)
01387
01388
01389 EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, j,
01390 {
01391 SET_HARD_REG_BIT (allocno[j].hard_reg_conflicts, regno);
01392 });
01393 else
01394
01395
01396
01397 {
01398 int ialloc = reg_allocno[regno];
01399 int ialloc_prod = ialloc * allocno_row_words;
01400
01401 IOR_HARD_REG_SET (allocno[ialloc].hard_reg_conflicts, hard_regs_live);
01402 for (j = allocno_row_words - 1; j >= 0; j--)
01403 conflicts[ialloc_prod + j] |= allocnos_live[j];
01404 }
01405 }
01406
01407
01408
01409
01410
01411
01412
01413 static void
01414 record_conflicts (int *allocno_vec, int len)
01415 {
01416 while (--len >= 0)
01417 IOR_HARD_REG_SET (allocno[allocno_vec[len]].hard_reg_conflicts,
01418 hard_regs_live);
01419 }
01420
01421
01422 static void
01423 mirror_conflicts (void)
01424 {
01425 int i, j;
01426 int rw = allocno_row_words;
01427 int rwb = rw * INT_BITS;
01428 INT_TYPE *p = conflicts;
01429 INT_TYPE *q0 = conflicts, *q1, *q2;
01430 unsigned INT_TYPE mask;
01431
01432 for (i = max_allocno - 1, mask = 1; i >= 0; i--, mask <<= 1)
01433 {
01434 if (! mask)
01435 {
01436 mask = 1;
01437 q0++;
01438 }
01439 for (j = allocno_row_words - 1, q1 = q0; j >= 0; j--, q1 += rwb)
01440 {
01441 unsigned INT_TYPE word;
01442
01443 for (word = (unsigned INT_TYPE) *p++, q2 = q1; word;
01444 word >>= 1, q2 += rw)
01445 {
01446 if (word & 1)
01447 *q2 |= mask;
01448 }
01449 }
01450 }
01451 }
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470 static void
01471 mark_reg_store (rtx reg, rtx setter, void *data ATTRIBUTE_UNUSED)
01472 {
01473 int regno;
01474
01475 if (GET_CODE (reg) == SUBREG)
01476 reg = SUBREG_REG (reg);
01477
01478 if (!REG_P (reg))
01479 return;
01480
01481 regs_set[n_regs_set++] = reg;
01482
01483 if (setter && GET_CODE (setter) != CLOBBER)
01484 set_preference (reg, SET_SRC (setter));
01485
01486 regno = REGNO (reg);
01487
01488
01489
01490 if (regno >= FIRST_PSEUDO_REGISTER)
01491 {
01492 if (reg_allocno[regno] >= 0)
01493 {
01494 SET_ALLOCNO_LIVE (reg_allocno[regno]);
01495 record_one_conflict (regno);
01496 }
01497 }
01498
01499 if (reg_renumber[regno] >= 0)
01500 regno = reg_renumber[regno];
01501
01502
01503 if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
01504 {
01505 int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
01506 while (regno < last)
01507 {
01508 record_one_conflict (regno);
01509 SET_HARD_REG_BIT (hard_regs_live, regno);
01510 regno++;
01511 }
01512 }
01513 }
01514
01515
01516
01517 static void
01518 mark_reg_clobber (rtx reg, rtx setter, void *data)
01519 {
01520 if (GET_CODE (setter) == CLOBBER)
01521 mark_reg_store (reg, setter, data);
01522 }
01523
01524
01525
01526
01527 static void
01528 mark_reg_conflicts (rtx reg)
01529 {
01530 int regno;
01531
01532 if (GET_CODE (reg) == SUBREG)
01533 reg = SUBREG_REG (reg);
01534
01535 if (!REG_P (reg))
01536 return;
01537
01538 regno = REGNO (reg);
01539
01540
01541
01542 if (regno >= FIRST_PSEUDO_REGISTER)
01543 {
01544 if (reg_allocno[regno] >= 0)
01545 record_one_conflict (regno);
01546 }
01547
01548 if (reg_renumber[regno] >= 0)
01549 regno = reg_renumber[regno];
01550
01551
01552 if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
01553 {
01554 int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
01555 while (regno < last)
01556 {
01557 record_one_conflict (regno);
01558 regno++;
01559 }
01560 }
01561 }
01562
01563
01564
01565
01566 static void
01567 mark_reg_death (rtx reg)
01568 {
01569 int regno = REGNO (reg);
01570
01571
01572
01573 if (regno >= FIRST_PSEUDO_REGISTER)
01574 {
01575 if (reg_allocno[regno] >= 0)
01576 CLEAR_ALLOCNO_LIVE (reg_allocno[regno]);
01577 }
01578
01579
01580 if (reg_renumber[regno] >= 0)
01581 regno = reg_renumber[regno];
01582
01583
01584 if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
01585 {
01586
01587
01588 int last = regno + hard_regno_nregs[regno][GET_MODE (reg)];
01589 while (regno < last)
01590 {
01591 CLEAR_HARD_REG_BIT (hard_regs_live, regno);
01592 regno++;
01593 }
01594 }
01595 }
01596
01597
01598
01599
01600
01601
01602 static void
01603 mark_reg_live_nc (int regno, enum machine_mode mode)
01604 {
01605 int last = regno + hard_regno_nregs[regno][mode];
01606 while (regno < last)
01607 {
01608 SET_HARD_REG_BIT (hard_regs_live, regno);
01609 regno++;
01610 }
01611 }
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622 static void
01623 set_preference (rtx dest, rtx src)
01624 {
01625 unsigned int src_regno, dest_regno;
01626
01627
01628 int offset = 0;
01629 unsigned int i;
01630 int copy = 1;
01631
01632 if (GET_RTX_FORMAT (GET_CODE (src))[0] == 'e')
01633 src = XEXP (src, 0), copy = 0;
01634
01635
01636
01637
01638 if (REG_P (src))
01639 src_regno = REGNO (src);
01640 else if (GET_CODE (src) == SUBREG && REG_P (SUBREG_REG (src)))
01641 {
01642 src_regno = REGNO (SUBREG_REG (src));
01643
01644 if (REGNO (SUBREG_REG (src)) < FIRST_PSEUDO_REGISTER)
01645 offset += subreg_regno_offset (REGNO (SUBREG_REG (src)),
01646 GET_MODE (SUBREG_REG (src)),
01647 SUBREG_BYTE (src),
01648 GET_MODE (src));
01649 else
01650 offset += (SUBREG_BYTE (src)
01651 / REGMODE_NATURAL_SIZE (GET_MODE (src)));
01652 }
01653 else
01654 return;
01655
01656 if (REG_P (dest))
01657 dest_regno = REGNO (dest);
01658 else if (GET_CODE (dest) == SUBREG && REG_P (SUBREG_REG (dest)))
01659 {
01660 dest_regno = REGNO (SUBREG_REG (dest));
01661
01662 if (REGNO (SUBREG_REG (dest)) < FIRST_PSEUDO_REGISTER)
01663 offset -= subreg_regno_offset (REGNO (SUBREG_REG (dest)),
01664 GET_MODE (SUBREG_REG (dest)),
01665 SUBREG_BYTE (dest),
01666 GET_MODE (dest));
01667 else
01668 offset -= (SUBREG_BYTE (dest)
01669 / REGMODE_NATURAL_SIZE (GET_MODE (dest)));
01670 }
01671 else
01672 return;
01673
01674
01675
01676 if (reg_renumber[src_regno] >= 0)
01677 src_regno = reg_renumber[src_regno];
01678
01679 if (reg_renumber[dest_regno] >= 0)
01680 dest_regno = reg_renumber[dest_regno];
01681
01682
01683
01684
01685 if (dest_regno < FIRST_PSEUDO_REGISTER && src_regno >= FIRST_PSEUDO_REGISTER
01686 && reg_allocno[src_regno] >= 0)
01687 {
01688 dest_regno -= offset;
01689 if (dest_regno < FIRST_PSEUDO_REGISTER)
01690 {
01691 if (copy)
01692 SET_REGBIT (hard_reg_copy_preferences,
01693 reg_allocno[src_regno], dest_regno);
01694
01695 SET_REGBIT (hard_reg_preferences,
01696 reg_allocno[src_regno], dest_regno);
01697 for (i = dest_regno;
01698 i < dest_regno + hard_regno_nregs[dest_regno][GET_MODE (dest)];
01699 i++)
01700 SET_REGBIT (hard_reg_full_preferences, reg_allocno[src_regno], i);
01701 }
01702 }
01703
01704 if (src_regno < FIRST_PSEUDO_REGISTER && dest_regno >= FIRST_PSEUDO_REGISTER
01705 && reg_allocno[dest_regno] >= 0)
01706 {
01707 src_regno += offset;
01708 if (src_regno < FIRST_PSEUDO_REGISTER)
01709 {
01710 if (copy)
01711 SET_REGBIT (hard_reg_copy_preferences,
01712 reg_allocno[dest_regno], src_regno);
01713
01714 SET_REGBIT (hard_reg_preferences,
01715 reg_allocno[dest_regno], src_regno);
01716 for (i = src_regno;
01717 i < src_regno + hard_regno_nregs[src_regno][GET_MODE (src)];
01718 i++)
01719 SET_REGBIT (hard_reg_full_preferences, reg_allocno[dest_regno], i);
01720 }
01721 }
01722 }
01723
01724
01725
01726
01727
01728
01729 void
01730 mark_elimination (int from, int to)
01731 {
01732 basic_block bb;
01733
01734 FOR_EACH_BB (bb)
01735 {
01736 regset r = bb->global_live_at_start;
01737 if (REGNO_REG_SET_P (r, from))
01738 {
01739 CLEAR_REGNO_REG_SET (r, from);
01740 SET_REGNO_REG_SET (r, to);
01741 }
01742 }
01743 }
01744
01745
01746
01747 static regset live_relevant_regs;
01748
01749
01750
01751 static void
01752 reg_becomes_live (rtx reg, rtx setter ATTRIBUTE_UNUSED, void *regs_set)
01753 {
01754 int regno;
01755
01756 if (GET_CODE (reg) == SUBREG)
01757 reg = SUBREG_REG (reg);
01758
01759 if (!REG_P (reg))
01760 return;
01761
01762 regno = REGNO (reg);
01763 if (regno < FIRST_PSEUDO_REGISTER)
01764 {
01765 int nregs = hard_regno_nregs[regno][GET_MODE (reg)];
01766 while (nregs-- > 0)
01767 {
01768 SET_REGNO_REG_SET (live_relevant_regs, regno);
01769 if (! fixed_regs[regno])
01770 SET_REGNO_REG_SET ((regset) regs_set, regno);
01771 regno++;
01772 }
01773 }
01774 else if (reg_renumber[regno] >= 0)
01775 {
01776 SET_REGNO_REG_SET (live_relevant_regs, regno);
01777 SET_REGNO_REG_SET ((regset) regs_set, regno);
01778 }
01779 }
01780
01781
01782 static void
01783 reg_dies (int regno, enum machine_mode mode, struct insn_chain *chain)
01784 {
01785 if (regno < FIRST_PSEUDO_REGISTER)
01786 {
01787 int nregs = hard_regno_nregs[regno][mode];
01788 while (nregs-- > 0)
01789 {
01790 CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
01791 if (! fixed_regs[regno])
01792 SET_REGNO_REG_SET (&chain->dead_or_set, regno);
01793 regno++;
01794 }
01795 }
01796 else
01797 {
01798 CLEAR_REGNO_REG_SET (live_relevant_regs, regno);
01799 if (reg_renumber[regno] >= 0)
01800 SET_REGNO_REG_SET (&chain->dead_or_set, regno);
01801 }
01802 }
01803
01804
01805
01806 void
01807 build_insn_chain (rtx first)
01808 {
01809 struct insn_chain **p = &reload_insn_chain;
01810 struct insn_chain *prev = 0;
01811 basic_block b = ENTRY_BLOCK_PTR->next_bb;
01812
01813 live_relevant_regs = ALLOC_REG_SET (®_obstack);
01814
01815 for (; first; first = NEXT_INSN (first))
01816 {
01817 struct insn_chain *c;
01818
01819 if (first == BB_HEAD (b))
01820 {
01821 unsigned i;
01822 bitmap_iterator bi;
01823
01824 CLEAR_REG_SET (live_relevant_regs);
01825
01826 EXECUTE_IF_SET_IN_BITMAP (b->global_live_at_start, 0, i, bi)
01827 {
01828 if (i < FIRST_PSEUDO_REGISTER
01829 ? ! TEST_HARD_REG_BIT (eliminable_regset, i)
01830 : reg_renumber[i] >= 0)
01831 SET_REGNO_REG_SET (live_relevant_regs, i);
01832 }
01833 }
01834
01835 if (!NOTE_P (first) && !BARRIER_P (first))
01836 {
01837 c = new_insn_chain ();
01838 c->prev = prev;
01839 prev = c;
01840 *p = c;
01841 p = &c->next;
01842 c->insn = first;
01843 c->block = b->index;
01844
01845 if (INSN_P (first))
01846 {
01847 rtx link;
01848
01849
01850
01851 for (link = REG_NOTES (first); link; link = XEXP (link, 1))
01852 if (REG_NOTE_KIND (link) == REG_DEAD
01853 && REG_P (XEXP (link, 0)))
01854 reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
01855 c);
01856
01857 COPY_REG_SET (&c->live_throughout, live_relevant_regs);
01858
01859
01860
01861 note_stores (PATTERN (first), reg_becomes_live,
01862 &c->dead_or_set);
01863 }
01864 else
01865 COPY_REG_SET (&c->live_throughout, live_relevant_regs);
01866
01867 if (INSN_P (first))
01868 {
01869 rtx link;
01870
01871
01872
01873 for (link = REG_NOTES (first); link; link = XEXP (link, 1))
01874 if (REG_NOTE_KIND (link) == REG_UNUSED
01875 && REG_P (XEXP (link, 0)))
01876 reg_dies (REGNO (XEXP (link, 0)), GET_MODE (XEXP (link, 0)),
01877 c);
01878 }
01879 }
01880
01881 if (first == BB_END (b))
01882 b = b->next_bb;
01883
01884
01885
01886
01887
01888
01889
01890 if (b == EXIT_BLOCK_PTR)
01891 {
01892 #ifdef ENABLE_CHECKING
01893 for (first = NEXT_INSN (first); first; first = NEXT_INSN (first))
01894 gcc_assert (!INSN_P (first)
01895 || GET_CODE (PATTERN (first)) == USE
01896 || ((GET_CODE (PATTERN (first)) == ADDR_VEC
01897 || GET_CODE (PATTERN (first)) == ADDR_DIFF_VEC)
01898 && prev_real_insn (first) != 0
01899 && JUMP_P (prev_real_insn (first))));
01900 #endif
01901 break;
01902 }
01903 }
01904 FREE_REG_SET (live_relevant_regs);
01905 *p = 0;
01906 }
01907
01908
01909
01910
01911 static void
01912 dump_conflicts (FILE *file)
01913 {
01914 int i;
01915 int has_preferences;
01916 int nregs;
01917 nregs = 0;
01918 for (i = 0; i < max_allocno; i++)
01919 {
01920 if (reg_renumber[allocno[allocno_order[i]].reg] >= 0)
01921 continue;
01922 nregs++;
01923 }
01924 fprintf (file, ";; %d regs to allocate:", nregs);
01925 for (i = 0; i < max_allocno; i++)
01926 {
01927 int j;
01928 if (reg_renumber[allocno[allocno_order[i]].reg] >= 0)
01929 continue;
01930 fprintf (file, " %d", allocno[allocno_order[i]].reg);
01931 for (j = 0; j < max_regno; j++)
01932 if (reg_allocno[j] == allocno_order[i]
01933 && j != allocno[allocno_order[i]].reg)
01934 fprintf (file, "+%d", j);
01935 if (allocno[allocno_order[i]].size != 1)
01936 fprintf (file, " (%d)", allocno[allocno_order[i]].size);
01937 }
01938 fprintf (file, "\n");
01939
01940 for (i = 0; i < max_allocno; i++)
01941 {
01942 int j;
01943 fprintf (file, ";; %d conflicts:", allocno[i].reg);
01944 for (j = 0; j < max_allocno; j++)
01945 if (CONFLICTP (j, i))
01946 fprintf (file, " %d", allocno[j].reg);
01947 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
01948 if (TEST_HARD_REG_BIT (allocno[i].hard_reg_conflicts, j))
01949 fprintf (file, " %d", j);
01950 fprintf (file, "\n");
01951
01952 has_preferences = 0;
01953 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
01954 if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
01955 has_preferences = 1;
01956
01957 if (! has_preferences)
01958 continue;
01959 fprintf (file, ";; %d preferences:", allocno[i].reg);
01960 for (j = 0; j < FIRST_PSEUDO_REGISTER; j++)
01961 if (TEST_HARD_REG_BIT (allocno[i].hard_reg_preferences, j))
01962 fprintf (file, " %d", j);
01963 fprintf (file, "\n");
01964 }
01965 fprintf (file, "\n");
01966 }
01967
01968 void
01969 dump_global_regs (FILE *file)
01970 {
01971 int i, j;
01972
01973 fprintf (file, ";; Register dispositions:\n");
01974 for (i = FIRST_PSEUDO_REGISTER, j = 0; i < max_regno; i++)
01975 if (reg_renumber[i] >= 0)
01976 {
01977 fprintf (file, "%d in %d ", i, reg_renumber[i]);
01978 if (++j % 6 == 0)
01979 fprintf (file, "\n");
01980 }
01981
01982 fprintf (file, "\n\n;; Hard regs used: ");
01983 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01984 if (regs_ever_live[i])
01985 fprintf (file, " %d", i);
01986 fprintf (file, "\n\n");
01987 }
01988
01989
01990
01991
01992
01993
01994
01995
01996
01997
01998
01999
02000
02001
02002
02003
02004
02005
02006
02007
02008
02009 struct bb_info
02010 {
02011
02012 int rts_number;
02013
02014
02015 bitmap earlyclobber;
02016
02017
02018 bitmap killed, avloc;
02019
02020
02021
02022 bitmap live_pavin, live_pavout;
02023 };
02024
02025
02026
02027 #define BB_INFO(BB) ((struct bb_info *) (BB)->aux)
02028 #define BB_INFO_BY_INDEX(N) BB_INFO (BASIC_BLOCK(N))
02029
02030
02031
02032
02033
02034 static void
02035 allocate_bb_info (void)
02036 {
02037 int i;
02038 basic_block bb;
02039 struct bb_info *bb_info;
02040 bitmap init;
02041
02042 alloc_aux_for_blocks (sizeof (struct bb_info));
02043 init = BITMAP_ALLOC (NULL);
02044 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
02045 bitmap_set_bit (init, i);
02046 FOR_EACH_BB (bb)
02047 {
02048 bb_info = bb->aux;
02049 bb_info->earlyclobber = BITMAP_ALLOC (NULL);
02050 bb_info->avloc = BITMAP_ALLOC (NULL);
02051 bb_info->killed = BITMAP_ALLOC (NULL);
02052 bb_info->live_pavin = BITMAP_ALLOC (NULL);
02053 bb_info->live_pavout = BITMAP_ALLOC (NULL);
02054 bitmap_copy (bb_info->live_pavin, init);
02055 bitmap_copy (bb_info->live_pavout, init);
02056 }
02057 BITMAP_FREE (init);
02058 }
02059
02060
02061
02062 static void
02063 free_bb_info (void)
02064 {
02065 basic_block bb;
02066 struct bb_info *bb_info;
02067
02068 FOR_EACH_BB (bb)
02069 {
02070 bb_info = BB_INFO (bb);
02071 BITMAP_FREE (bb_info->live_pavout);
02072 BITMAP_FREE (bb_info->live_pavin);
02073 BITMAP_FREE (bb_info->killed);
02074 BITMAP_FREE (bb_info->avloc);
02075 BITMAP_FREE (bb_info->earlyclobber);
02076 }
02077 free_aux_for_blocks ();
02078 }
02079
02080
02081
02082
02083 static void
02084 mark_reg_change (rtx reg, rtx setter, void *data)
02085 {
02086 int regno;
02087 basic_block bb = data;
02088 struct bb_info *bb_info = BB_INFO (bb);
02089
02090 if (GET_CODE (reg) == SUBREG)
02091 reg = SUBREG_REG (reg);
02092
02093 if (!REG_P (reg))
02094 return;
02095
02096 regno = REGNO (reg);
02097 bitmap_set_bit (bb_info->killed, regno);
02098
02099 if (GET_CODE (setter) != CLOBBER)
02100 bitmap_set_bit (bb_info->avloc, regno);
02101 else
02102 bitmap_clear_bit (bb_info->avloc, regno);
02103 }
02104
02105
02106
02107
02108 static varray_type earlyclobber_regclass;
02109
02110
02111
02112
02113
02114 static bool
02115 check_earlyclobber (rtx insn)
02116 {
02117 int opno;
02118 bool found = false;
02119
02120 extract_insn (insn);
02121
02122 VARRAY_POP_ALL (earlyclobber_regclass);
02123 for (opno = 0; opno < recog_data.n_operands; opno++)
02124 {
02125 char c;
02126 bool amp_p;
02127 int i;
02128 enum reg_class class;
02129 const char *p = recog_data.constraints[opno];
02130
02131 class = NO_REGS;
02132 amp_p = false;
02133 for (;;)
02134 {
02135 c = *p;
02136 switch (c)
02137 {
02138 case '=': case '+': case '?':
02139 case '#': case '!':
02140 case '*': case '%':
02141 case 'm': case '<': case '>': case 'V': case 'o':
02142 case 'E': case 'F': case 'G': case 'H':
02143 case 's': case 'i': case 'n':
02144 case 'I': case 'J': case 'K': case 'L':
02145 case 'M': case 'N': case 'O': case 'P':
02146 case 'X':
02147 case '0': case '1': case '2': case '3': case '4':
02148 case '5': case '6': case '7': case '8': case '9':
02149
02150 break;
02151
02152 case '&':
02153 amp_p = true;
02154 break;
02155 case '\0':
02156 case ',':
02157 if (amp_p && class != NO_REGS)
02158 {
02159 found = true;
02160 for (i = VARRAY_ACTIVE_SIZE (earlyclobber_regclass) - 1;
02161 i >= 0; i--)
02162 if (VARRAY_INT (earlyclobber_regclass, i) == (int) class)
02163 break;
02164 if (i < 0)
02165 VARRAY_PUSH_INT (earlyclobber_regclass, (int) class);
02166 }
02167
02168 amp_p = false;
02169 class = NO_REGS;
02170 break;
02171
02172 case 'r':
02173 class = GENERAL_REGS;
02174 break;
02175
02176 default:
02177 class = REG_CLASS_FROM_CONSTRAINT (c, p);
02178 break;
02179 }
02180 if (c == '\0')
02181 break;
02182 p += CONSTRAINT_LEN (c, p);
02183 }
02184 }
02185
02186 return found;
02187 }
02188
02189
02190
02191
02192
02193
02194 static int
02195 mark_reg_use_for_earlyclobber (rtx *x, void *data ATTRIBUTE_UNUSED)
02196 {
02197 enum reg_class pref_class, alt_class;
02198 int i, regno;
02199 basic_block bb = data;
02200 struct bb_info *bb_info = BB_INFO (bb);
02201
02202 if (GET_CODE (*x) == REG && REGNO (*x) >= FIRST_PSEUDO_REGISTER)
02203 {
02204 regno = REGNO (*x);
02205 if (bitmap_bit_p (bb_info->killed, regno)
02206 || bitmap_bit_p (bb_info->avloc, regno))
02207 return 0;
02208 pref_class = reg_preferred_class (regno);
02209 alt_class = reg_alternate_class (regno);
02210 for (i = VARRAY_ACTIVE_SIZE (earlyclobber_regclass) - 1; i >= 0; i--)
02211 if (reg_classes_intersect_p (VARRAY_INT (earlyclobber_regclass, i),
02212 pref_class)
02213 || (VARRAY_INT (earlyclobber_regclass, i) != NO_REGS
02214 && reg_classes_intersect_p (VARRAY_INT (earlyclobber_regclass,
02215 i),
02216 alt_class)))
02217 {
02218 bitmap_set_bit (bb_info->earlyclobber, regno);
02219 break;
02220 }
02221 }
02222 return 0;
02223 }
02224
02225
02226
02227
02228 static void
02229 mark_reg_use_for_earlyclobber_1 (rtx *x, void *data)
02230 {
02231 for_each_rtx (x, mark_reg_use_for_earlyclobber, data);
02232 }
02233
02234
02235
02236 static void
02237 calculate_local_reg_bb_info (void)
02238 {
02239 basic_block bb;
02240 rtx insn, bound;
02241
02242 VARRAY_INT_INIT (earlyclobber_regclass, 20,
02243 "classes of registers early clobbered in an insn");
02244 FOR_EACH_BB (bb)
02245 {
02246 bound = NEXT_INSN (BB_END (bb));
02247 for (insn = BB_HEAD (bb); insn != bound; insn = NEXT_INSN (insn))
02248 if (INSN_P (insn))
02249 {
02250 note_stores (PATTERN (insn), mark_reg_change, bb);
02251 if (check_earlyclobber (insn))
02252 note_uses (&PATTERN (insn), mark_reg_use_for_earlyclobber_1, bb);
02253 }
02254 }
02255 }
02256
02257
02258
02259
02260 static void
02261 set_up_bb_rts_numbers (void)
02262 {
02263 int i;
02264 int *rts_order;
02265
02266 rts_order = xmalloc (sizeof (int) * n_basic_blocks);
02267 flow_reverse_top_sort_order_compute (rts_order);
02268 for (i = 0; i < n_basic_blocks; i++)
02269 BB_INFO_BY_INDEX (rts_order [i])->rts_number = i;
02270 free (rts_order);
02271 }
02272
02273
02274
02275 static int
02276 rpost_cmp (const void *bb1, const void *bb2)
02277 {
02278 basic_block b1 = *(basic_block *) bb1, b2 = *(basic_block *) bb2;
02279
02280 return BB_INFO (b2)->rts_number - BB_INFO (b1)->rts_number;
02281 }
02282
02283
02284 static bitmap temp_bitmap;
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295 static void
02296 calculate_reg_pav (void)
02297 {
02298 basic_block bb, succ;
02299 edge e;
02300 int i, nel;
02301 varray_type bbs, new_bbs, temp;
02302 basic_block *bb_array;
02303 sbitmap wset;
02304
02305 VARRAY_BB_INIT (bbs, n_basic_blocks, "basic blocks");
02306 VARRAY_BB_INIT (new_bbs, n_basic_blocks, "basic blocks for the next iter.");
02307 temp_bitmap = BITMAP_ALLOC (NULL);
02308 FOR_EACH_BB (bb)
02309 {
02310 VARRAY_PUSH_BB (bbs, bb);
02311 }
02312 wset = sbitmap_alloc (n_basic_blocks + 1);
02313 while (VARRAY_ACTIVE_SIZE (bbs))
02314 {
02315 bb_array = &VARRAY_BB (bbs, 0);
02316 nel = VARRAY_ACTIVE_SIZE (bbs);
02317 qsort (bb_array, nel, sizeof (basic_block), rpost_cmp);
02318 sbitmap_zero (wset);
02319 for (i = 0; i < nel; i++)
02320 {
02321 edge_iterator ei;
02322 struct bb_info *bb_info;
02323 bitmap bb_live_pavin, bb_live_pavout;
02324
02325 bb = bb_array [i];
02326 bb_info = BB_INFO (bb);
02327 bb_live_pavin = bb_info->live_pavin;
02328 bb_live_pavout = bb_info->live_pavout;
02329 FOR_EACH_EDGE (e, ei, bb->preds)
02330 {
02331 basic_block pred = e->src;
02332
02333 if (pred->index != ENTRY_BLOCK)
02334 bitmap_ior_into (bb_live_pavin, BB_INFO (pred)->live_pavout);
02335 }
02336 bitmap_and_into (bb_live_pavin, bb->global_live_at_start);
02337 bitmap_ior_and_compl (temp_bitmap, bb_info->avloc,
02338 bb_live_pavin, bb_info->killed);
02339 bitmap_and_into (temp_bitmap, bb->global_live_at_end);
02340 if (! bitmap_equal_p (temp_bitmap, bb_live_pavout))
02341 {
02342 bitmap_copy (bb_live_pavout, temp_bitmap);
02343 FOR_EACH_EDGE (e, ei, bb->succs)
02344 {
02345 succ = e->dest;
02346 if (succ->index != EXIT_BLOCK
02347 && !TEST_BIT (wset, succ->index))
02348 {
02349 SET_BIT (wset, succ->index);
02350 VARRAY_PUSH_BB (new_bbs, succ);
02351 }
02352 }
02353 }
02354 }
02355 temp = bbs;
02356 bbs = new_bbs;
02357 new_bbs = temp;
02358 VARRAY_POP_ALL (new_bbs);
02359 }
02360 sbitmap_free (wset);
02361 BITMAP_FREE (temp_bitmap);
02362 }
02363
02364
02365
02366
02367
02368
02369 static void
02370 modify_reg_pav (void)
02371 {
02372 basic_block bb;
02373 struct bb_info *bb_info;
02374 #ifdef STACK_REGS
02375 int i;
02376 HARD_REG_SET zero, stack_hard_regs, used;
02377 bitmap stack_regs;
02378
02379 CLEAR_HARD_REG_SET (zero);
02380 CLEAR_HARD_REG_SET (stack_hard_regs);
02381 for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
02382 SET_HARD_REG_BIT(stack_hard_regs, i);
02383 stack_regs = BITMAP_ALLOC (NULL);
02384 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
02385 {
02386 COPY_HARD_REG_SET (used, reg_class_contents[reg_preferred_class (i)]);
02387 IOR_HARD_REG_SET (used, reg_class_contents[reg_alternate_class (i)]);
02388 AND_HARD_REG_SET (used, stack_hard_regs);
02389 GO_IF_HARD_REG_EQUAL(used, zero, skip);
02390 bitmap_set_bit (stack_regs, i);
02391 skip:
02392 ;
02393 }
02394 #endif
02395 FOR_EACH_BB (bb)
02396 {
02397 bb_info = BB_INFO (bb);
02398
02399
02400
02401
02402
02403
02404 bitmap_ior_into (bb_info->live_pavin, bb_info->earlyclobber);
02405 #ifdef STACK_REGS
02406
02407
02408
02409
02410
02411 bitmap_ior_into (bb_info->live_pavin, stack_regs);
02412 #endif
02413 }
02414 #ifdef STACK_REGS
02415 BITMAP_FREE (stack_regs);
02416 #endif
02417 }
02418
02419
02420
02421
02422
02423
02424
02425
02426
02427
02428
02429
02430
02431
02432
02433
02434
02435
02436
02437
02438
02439
02440
02441 static void
02442 make_accurate_live_analysis (void)
02443 {
02444 basic_block bb;
02445 struct bb_info *bb_info;
02446
02447 max_regno = max_reg_num ();
02448 compact_blocks ();
02449 allocate_bb_info ();
02450 calculate_local_reg_bb_info ();
02451 set_up_bb_rts_numbers ();
02452 calculate_reg_pav ();
02453 modify_reg_pav ();
02454 FOR_EACH_BB (bb)
02455 {
02456 bb_info = BB_INFO (bb);
02457
02458 bitmap_and_into (bb->global_live_at_start, bb_info->live_pavin);
02459 bitmap_and_into (bb->global_live_at_end, bb_info->live_pavout);
02460 }
02461 free_bb_info ();
02462 }