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