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
00028 #include "machmode.h"
00029 #include "hard-reg-set.h"
00030 #include "rtl.h"
00031 #include "tm_p.h"
00032 #include "obstack.h"
00033 #include "insn-config.h"
00034 #include "flags.h"
00035 #include "function.h"
00036 #include "expr.h"
00037 #include "optabs.h"
00038 #include "regs.h"
00039 #include "addresses.h"
00040 #include "basic-block.h"
00041 #include "reload.h"
00042 #include "recog.h"
00043 #include "output.h"
00044 #include "real.h"
00045 #include "toplev.h"
00046 #include "except.h"
00047 #include "tree.h"
00048 #include "target.h"
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
00085
00086 static rtx *reg_last_reload_reg;
00087
00088
00089
00090 static regset_head reg_has_output_reload;
00091
00092
00093
00094 static HARD_REG_SET reg_is_output_reload;
00095
00096
00097
00098
00099
00100 rtx *reg_equiv_constant;
00101
00102
00103
00104
00105 rtx *reg_equiv_invariant;
00106
00107
00108
00109
00110
00111 rtx *reg_equiv_memory_loc;
00112
00113
00114
00115 VEC(rtx,gc) *reg_equiv_memory_loc_vec;
00116
00117
00118
00119
00120 rtx *reg_equiv_address;
00121
00122
00123
00124 rtx *reg_equiv_mem;
00125
00126
00127
00128 rtx *reg_equiv_alt_mem_list;
00129
00130
00131 static unsigned int *reg_max_ref_width;
00132
00133
00134
00135 rtx *reg_equiv_init;
00136 int reg_equiv_init_size;
00137
00138
00139 static short *reg_old_renumber;
00140
00141
00142
00143
00144
00145 static int reg_reloaded_contents[FIRST_PSEUDO_REGISTER];
00146
00147
00148
00149
00150 static rtx reg_reloaded_insn[FIRST_PSEUDO_REGISTER];
00151
00152
00153 static HARD_REG_SET reg_reloaded_valid;
00154
00155
00156 static HARD_REG_SET reg_reloaded_dead;
00157
00158
00159
00160
00161 static HARD_REG_SET reg_reloaded_call_part_clobbered;
00162
00163
00164 static int n_spills;
00165
00166
00167
00168
00169
00170 static rtx spill_reg_rtx[FIRST_PSEUDO_REGISTER];
00171
00172
00173
00174
00175 static rtx spill_reg_store[FIRST_PSEUDO_REGISTER];
00176
00177
00178
00179
00180 static rtx spill_reg_stored_to[FIRST_PSEUDO_REGISTER];
00181
00182
00183
00184
00185
00186
00187
00188 static short spill_reg_order[FIRST_PSEUDO_REGISTER];
00189
00190
00191
00192
00193
00194 static HARD_REG_SET bad_spill_regs;
00195
00196
00197
00198
00199
00200 static HARD_REG_SET bad_spill_regs_global;
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 static short spill_regs[FIRST_PSEUDO_REGISTER];
00212
00213
00214
00215
00216
00217
00218 static HARD_REG_SET *pseudo_previous_regs;
00219
00220
00221
00222
00223
00224 static HARD_REG_SET *pseudo_forbidden_regs;
00225
00226
00227
00228 static HARD_REG_SET used_spill_regs;
00229
00230
00231
00232 static int last_spill_reg;
00233
00234
00235
00236
00237
00238
00239
00240 static char spill_indirect_levels;
00241
00242
00243
00244
00245 char indirect_symref_ok;
00246
00247
00248 char double_reg_address_ok;
00249
00250
00251 static rtx spill_stack_slot[FIRST_PSEUDO_REGISTER];
00252
00253
00254 static unsigned int spill_stack_slot_width[FIRST_PSEUDO_REGISTER];
00255
00256
00257 static regset_head spilled_pseudos;
00258
00259
00260
00261 static regset_head pseudos_counted;
00262
00263
00264
00265 int reload_first_uid;
00266
00267
00268
00269 int caller_save_needed;
00270
00271
00272
00273 int reload_in_progress = 0;
00274
00275
00276
00277
00278 enum insn_code reload_in_optab[NUM_MACHINE_MODES];
00279 enum insn_code reload_out_optab[NUM_MACHINE_MODES];
00280
00281
00282
00283
00284 static struct obstack reload_obstack;
00285
00286
00287
00288 static char *reload_startobj;
00289
00290
00291
00292 static char *reload_firstobj;
00293
00294
00295
00296 static char *reload_insn_firstobj;
00297
00298
00299
00300 struct insn_chain *reload_insn_chain;
00301
00302
00303 static struct insn_chain *insns_need_reload;
00304
00305
00306
00307
00308
00309
00310 struct elim_table
00311 {
00312 int from;
00313 int to;
00314 HOST_WIDE_INT initial_offset;
00315 int can_eliminate;
00316 int can_eliminate_previous;
00317
00318 HOST_WIDE_INT offset;
00319 HOST_WIDE_INT previous_offset;
00320 int ref_outside_mem;
00321 rtx from_rtx;
00322
00323
00324
00325
00326 rtx to_rtx;
00327 };
00328
00329 static struct elim_table *reg_eliminate = 0;
00330
00331
00332
00333 static const struct elim_table_1
00334 {
00335 const int from;
00336 const int to;
00337 } reg_eliminate_1[] =
00338
00339
00340
00341
00342
00343 #ifdef ELIMINABLE_REGS
00344 ELIMINABLE_REGS;
00345 #else
00346 {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}};
00347 #endif
00348
00349 #define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1)
00350
00351
00352
00353
00354 int num_not_at_initial_offset;
00355
00356
00357 static int num_eliminable;
00358
00359
00360 static int num_eliminable_invariants;
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 static int first_label_num;
00372 static char *offsets_known_at;
00373 static HOST_WIDE_INT (*offsets_at)[NUM_ELIMINABLE_REGS];
00374
00375
00376
00377 static int num_labels;
00378
00379 static void replace_pseudos_in (rtx *, enum machine_mode, rtx);
00380 static void maybe_fix_stack_asms (void);
00381 static void copy_reloads (struct insn_chain *);
00382 static void calculate_needs_all_insns (int);
00383 static int find_reg (struct insn_chain *, int);
00384 static void find_reload_regs (struct insn_chain *);
00385 static void select_reload_regs (void);
00386 static void delete_caller_save_insns (void);
00387
00388 static void spill_failure (rtx, enum reg_class);
00389 static void count_spilled_pseudo (int, int, int);
00390 static void delete_dead_insn (rtx);
00391 static void alter_reg (int, int);
00392 static void set_label_offsets (rtx, rtx, int);
00393 static void check_eliminable_occurrences (rtx);
00394 static void elimination_effects (rtx, enum machine_mode);
00395 static int eliminate_regs_in_insn (rtx, int);
00396 static void update_eliminable_offsets (void);
00397 static void mark_not_eliminable (rtx, rtx, void *);
00398 static void set_initial_elim_offsets (void);
00399 static bool verify_initial_elim_offsets (void);
00400 static void set_initial_label_offsets (void);
00401 static void set_offsets_for_label (rtx);
00402 static void init_elim_table (void);
00403 static void update_eliminables (HARD_REG_SET *);
00404 static void spill_hard_reg (unsigned int, int);
00405 static int finish_spills (int);
00406 static void scan_paradoxical_subregs (rtx);
00407 static void count_pseudo (int);
00408 static void order_regs_for_reload (struct insn_chain *);
00409 static void reload_as_needed (int);
00410 static void forget_old_reloads_1 (rtx, rtx, void *);
00411 static void forget_marked_reloads (regset);
00412 static int reload_reg_class_lower (const void *, const void *);
00413 static void mark_reload_reg_in_use (unsigned int, int, enum reload_type,
00414 enum machine_mode);
00415 static void clear_reload_reg_in_use (unsigned int, int, enum reload_type,
00416 enum machine_mode);
00417 static int reload_reg_free_p (unsigned int, int, enum reload_type);
00418 static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
00419 rtx, rtx, int, int);
00420 static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
00421 rtx, rtx, int, int);
00422 static int reload_reg_reaches_end_p (unsigned int, int, enum reload_type);
00423 static int allocate_reload_reg (struct insn_chain *, int, int);
00424 static int conflicts_with_override (rtx);
00425 static void failed_reload (rtx, int);
00426 static int set_reload_reg (int, int);
00427 static void choose_reload_regs_init (struct insn_chain *, rtx *);
00428 static void choose_reload_regs (struct insn_chain *);
00429 static void merge_assigned_reloads (rtx);
00430 static void emit_input_reload_insns (struct insn_chain *, struct reload *,
00431 rtx, int);
00432 static void emit_output_reload_insns (struct insn_chain *, struct reload *,
00433 int);
00434 static void do_input_reload (struct insn_chain *, struct reload *, int);
00435 static void do_output_reload (struct insn_chain *, struct reload *, int);
00436 static bool inherit_piecemeal_p (int, int);
00437 static void emit_reload_insns (struct insn_chain *);
00438 static void delete_output_reload (rtx, int, int);
00439 static void delete_address_reloads (rtx, rtx);
00440 static void delete_address_reloads_1 (rtx, rtx, rtx);
00441 static rtx inc_for_reload (rtx, rtx, rtx, int);
00442 #ifdef AUTO_INC_DEC
00443 static void add_auto_inc_notes (rtx, rtx);
00444 #endif
00445 static void copy_eh_notes (rtx, rtx);
00446 static int reloads_conflict (int, int);
00447 static rtx gen_reload (rtx, rtx, int, enum reload_type);
00448 static rtx emit_insn_if_valid_for_reload (rtx);
00449
00450
00451
00452 void
00453 init_reload (void)
00454 {
00455 int i;
00456
00457
00458
00459
00460
00461 rtx tem
00462 = gen_rtx_MEM (Pmode,
00463 gen_rtx_PLUS (Pmode,
00464 gen_rtx_REG (Pmode,
00465 LAST_VIRTUAL_REGISTER + 1),
00466 GEN_INT (4)));
00467 spill_indirect_levels = 0;
00468
00469 while (memory_address_p (QImode, tem))
00470 {
00471 spill_indirect_levels++;
00472 tem = gen_rtx_MEM (Pmode, tem);
00473 }
00474
00475
00476
00477 tem = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "foo"));
00478 indirect_symref_ok = memory_address_p (QImode, tem);
00479
00480
00481
00482 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00483 {
00484 tem = gen_rtx_PLUS (Pmode,
00485 gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM),
00486 gen_rtx_REG (Pmode, i));
00487
00488
00489 tem = plus_constant (tem, 4);
00490
00491 if (memory_address_p (QImode, tem))
00492 {
00493 double_reg_address_ok = 1;
00494 break;
00495 }
00496 }
00497
00498
00499 gcc_obstack_init (&reload_obstack);
00500 reload_startobj = obstack_alloc (&reload_obstack, 0);
00501
00502 INIT_REG_SET (&spilled_pseudos);
00503 INIT_REG_SET (&pseudos_counted);
00504 }
00505
00506
00507 static struct insn_chain *unused_insn_chains = 0;
00508
00509
00510 struct insn_chain *
00511 new_insn_chain (void)
00512 {
00513 struct insn_chain *c;
00514
00515 if (unused_insn_chains == 0)
00516 {
00517 c = obstack_alloc (&reload_obstack, sizeof (struct insn_chain));
00518 INIT_REG_SET (&c->live_throughout);
00519 INIT_REG_SET (&c->dead_or_set);
00520 }
00521 else
00522 {
00523 c = unused_insn_chains;
00524 unused_insn_chains = c->next;
00525 }
00526 c->is_caller_save_insn = 0;
00527 c->need_operand_change = 0;
00528 c->need_reload = 0;
00529 c->need_elim = 0;
00530 return c;
00531 }
00532
00533
00534
00535
00536 void
00537 compute_use_by_pseudos (HARD_REG_SET *to, regset from)
00538 {
00539 unsigned int regno;
00540 reg_set_iterator rsi;
00541
00542 EXECUTE_IF_SET_IN_REG_SET (from, FIRST_PSEUDO_REGISTER, regno, rsi)
00543 {
00544 int r = reg_renumber[regno];
00545 int nregs;
00546
00547 if (r < 0)
00548 {
00549
00550
00551
00552
00553 gcc_assert (reload_completed);
00554 }
00555 else
00556 {
00557 nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (regno)];
00558 while (nregs-- > 0)
00559 SET_HARD_REG_BIT (*to, r + nregs);
00560 }
00561 }
00562 }
00563
00564
00565
00566
00567 static void
00568 replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage)
00569 {
00570 rtx x = *loc;
00571 enum rtx_code code;
00572 const char *fmt;
00573 int i, j;
00574
00575 if (! x)
00576 return;
00577
00578 code = GET_CODE (x);
00579 if (code == REG)
00580 {
00581 unsigned int regno = REGNO (x);
00582
00583 if (regno < FIRST_PSEUDO_REGISTER)
00584 return;
00585
00586 x = eliminate_regs (x, mem_mode, usage);
00587 if (x != *loc)
00588 {
00589 *loc = x;
00590 replace_pseudos_in (loc, mem_mode, usage);
00591 return;
00592 }
00593
00594 if (reg_equiv_constant[regno])
00595 *loc = reg_equiv_constant[regno];
00596 else if (reg_equiv_mem[regno])
00597 *loc = reg_equiv_mem[regno];
00598 else if (reg_equiv_address[regno])
00599 *loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]);
00600 else
00601 {
00602 gcc_assert (!REG_P (regno_reg_rtx[regno])
00603 || REGNO (regno_reg_rtx[regno]) != regno);
00604 *loc = regno_reg_rtx[regno];
00605 }
00606
00607 return;
00608 }
00609 else if (code == MEM)
00610 {
00611 replace_pseudos_in (& XEXP (x, 0), GET_MODE (x), usage);
00612 return;
00613 }
00614
00615
00616 fmt = GET_RTX_FORMAT (code);
00617 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
00618 if (*fmt == 'e')
00619 replace_pseudos_in (&XEXP (x, i), mem_mode, usage);
00620 else if (*fmt == 'E')
00621 for (j = 0; j < XVECLEN (x, i); j++)
00622 replace_pseudos_in (& XVECEXP (x, i, j), mem_mode, usage);
00623 }
00624
00625
00626
00627
00628
00629 static int something_needs_elimination;
00630
00631 static int something_needs_operands_changed;
00632
00633
00634 static int failure;
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 int
00650 reload (rtx first, int global)
00651 {
00652 int i;
00653 rtx insn;
00654 struct elim_table *ep;
00655 basic_block bb;
00656
00657
00658 init_recog ();
00659
00660 failure = 0;
00661
00662 reload_firstobj = obstack_alloc (&reload_obstack, 0);
00663
00664
00665
00666 emit_note (NOTE_INSN_DELETED);
00667
00668
00669 reload_first_uid = get_max_uid ();
00670
00671 #ifdef SECONDARY_MEMORY_NEEDED
00672
00673 clear_secondary_mem ();
00674 #endif
00675
00676
00677 memset (spill_stack_slot, 0, sizeof spill_stack_slot);
00678 memset (spill_stack_slot_width, 0, sizeof spill_stack_slot_width);
00679
00680
00681
00682 init_save_areas ();
00683
00684
00685
00686
00687
00688 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00689 mark_home_live (i);
00690
00691
00692
00693 if (current_function_has_nonlocal_label)
00694 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
00695 if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i))
00696 regs_ever_live[i] = 1;
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708 reg_equiv_constant = XCNEWVEC (rtx, max_regno);
00709 reg_equiv_invariant = XCNEWVEC (rtx, max_regno);
00710 reg_equiv_mem = XCNEWVEC (rtx, max_regno);
00711 reg_equiv_alt_mem_list = XCNEWVEC (rtx, max_regno);
00712 reg_equiv_address = XCNEWVEC (rtx, max_regno);
00713 reg_max_ref_width = XCNEWVEC (unsigned int, max_regno);
00714 reg_old_renumber = XCNEWVEC (short, max_regno);
00715 memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short));
00716 pseudo_forbidden_regs = XNEWVEC (HARD_REG_SET, max_regno);
00717 pseudo_previous_regs = XCNEWVEC (HARD_REG_SET, max_regno);
00718
00719 CLEAR_HARD_REG_SET (bad_spill_regs_global);
00720
00721
00722
00723
00724
00725 num_eliminable_invariants = 0;
00726 for (insn = first; insn; insn = NEXT_INSN (insn))
00727 {
00728 rtx set = single_set (insn);
00729
00730
00731
00732
00733 if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
00734 && GET_MODE (insn) != VOIDmode)
00735 PUT_MODE (insn, VOIDmode);
00736
00737 if (INSN_P (insn))
00738 scan_paradoxical_subregs (PATTERN (insn));
00739
00740 if (set != 0 && REG_P (SET_DEST (set)))
00741 {
00742 rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
00743 rtx x;
00744
00745 if (! note)
00746 continue;
00747
00748 i = REGNO (SET_DEST (set));
00749 x = XEXP (note, 0);
00750
00751 if (i <= LAST_VIRTUAL_REGISTER)
00752 continue;
00753
00754 if (! function_invariant_p (x)
00755 || ! flag_pic
00756
00757
00758
00759 || (CONSTANT_P (x)
00760 && LEGITIMATE_PIC_OPERAND_P (x)))
00761 {
00762
00763
00764
00765
00766
00767 if (memory_operand (x, VOIDmode))
00768 {
00769
00770
00771
00772 reg_equiv_memory_loc[i] = copy_rtx (x);
00773 }
00774 else if (function_invariant_p (x))
00775 {
00776 if (GET_CODE (x) == PLUS)
00777 {
00778
00779
00780 reg_equiv_invariant[i] = copy_rtx (x);
00781 num_eliminable_invariants++;
00782 }
00783 else if (x == frame_pointer_rtx || x == arg_pointer_rtx)
00784 {
00785 reg_equiv_invariant[i] = x;
00786 num_eliminable_invariants++;
00787 }
00788 else if (LEGITIMATE_CONSTANT_P (x))
00789 reg_equiv_constant[i] = x;
00790 else
00791 {
00792 reg_equiv_memory_loc[i]
00793 = force_const_mem (GET_MODE (SET_DEST (set)), x);
00794 if (! reg_equiv_memory_loc[i])
00795 reg_equiv_init[i] = NULL_RTX;
00796 }
00797 }
00798 else
00799 {
00800 reg_equiv_init[i] = NULL_RTX;
00801 continue;
00802 }
00803 }
00804 else
00805 reg_equiv_init[i] = NULL_RTX;
00806 }
00807 }
00808
00809 if (dump_file)
00810 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00811 if (reg_equiv_init[i])
00812 {
00813 fprintf (dump_file, "init_insns for %u: ", i);
00814 print_inline_rtx (dump_file, reg_equiv_init[i], 20);
00815 fprintf (dump_file, "\n");
00816 }
00817
00818 init_elim_table ();
00819
00820 first_label_num = get_first_label_num ();
00821 num_labels = max_label_num () - first_label_num;
00822
00823
00824
00825
00826
00827 offsets_known_at = XNEWVEC (char, num_labels);
00828 offsets_at = (HOST_WIDE_INT (*)[NUM_ELIMINABLE_REGS]) xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (HOST_WIDE_INT));
00829
00830
00831
00832
00833
00834 for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++)
00835 alter_reg (i, -1);
00836
00837
00838
00839
00840
00841
00842
00843 for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn))
00844 if (INSN_P (insn))
00845 note_stores (PATTERN (insn), mark_not_eliminable, NULL);
00846
00847 maybe_fix_stack_asms ();
00848
00849 insns_need_reload = 0;
00850 something_needs_elimination = 0;
00851
00852
00853 last_spill_reg = -1;
00854
00855
00856 CLEAR_HARD_REG_SET (used_spill_regs);
00857
00858
00859
00860 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; )
00861 {
00862 int from = ep->from;
00863 int can_eliminate = 0;
00864 do
00865 {
00866 can_eliminate |= ep->can_eliminate;
00867 ep++;
00868 }
00869 while (ep < ®_eliminate[NUM_ELIMINABLE_REGS] && ep->from == from);
00870 if (! can_eliminate)
00871 spill_hard_reg (from, 1);
00872 }
00873
00874 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
00875 if (frame_pointer_needed)
00876 spill_hard_reg (HARD_FRAME_POINTER_REGNUM, 1);
00877 #endif
00878 finish_spills (global);
00879
00880
00881
00882
00883 reload_in_progress = 1;
00884
00885
00886
00887 for (;;)
00888 {
00889 int something_changed;
00890 int did_spill;
00891
00892 HOST_WIDE_INT starting_frame_size;
00893
00894
00895
00896
00897
00898 if (cfun->stack_alignment_needed)
00899 assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed);
00900
00901 starting_frame_size = get_frame_size ();
00902
00903 set_initial_elim_offsets ();
00904 set_initial_label_offsets ();
00905
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
00931 if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i])
00932 {
00933 rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX);
00934
00935 if (strict_memory_address_p (GET_MODE (regno_reg_rtx[i]),
00936 XEXP (x, 0)))
00937 reg_equiv_mem[i] = x, reg_equiv_address[i] = 0;
00938 else if (CONSTANT_P (XEXP (x, 0))
00939 || (REG_P (XEXP (x, 0))
00940 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER)
00941 || (GET_CODE (XEXP (x, 0)) == PLUS
00942 && REG_P (XEXP (XEXP (x, 0), 0))
00943 && (REGNO (XEXP (XEXP (x, 0), 0))
00944 < FIRST_PSEUDO_REGISTER)
00945 && CONSTANT_P (XEXP (XEXP (x, 0), 1))))
00946 reg_equiv_address[i] = XEXP (x, 0), reg_equiv_mem[i] = 0;
00947 else
00948 {
00949
00950
00951
00952
00953
00954
00955 reg_equiv_memory_loc[i] = 0;
00956 reg_equiv_init[i] = 0;
00957 alter_reg (i, -1);
00958 }
00959 }
00960
00961 if (caller_save_needed)
00962 setup_save_areas ();
00963
00964
00965 if (starting_frame_size != get_frame_size ())
00966 continue;
00967
00968 if (caller_save_needed)
00969 {
00970 save_call_clobbered_regs ();
00971
00972 reload_firstobj = obstack_alloc (&reload_obstack, 0);
00973 }
00974
00975 calculate_needs_all_insns (global);
00976
00977 CLEAR_REG_SET (&spilled_pseudos);
00978 did_spill = 0;
00979
00980 something_changed = 0;
00981
00982
00983
00984 if (starting_frame_size != get_frame_size ())
00985 something_changed = 1;
00986
00987
00988
00989
00990
00991 else if (!verify_initial_elim_offsets ())
00992 something_changed = 1;
00993
00994 {
00995 HARD_REG_SET to_spill;
00996 CLEAR_HARD_REG_SET (to_spill);
00997 update_eliminables (&to_spill);
00998 AND_COMPL_HARD_REG_SET(used_spill_regs, to_spill);
00999
01000 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01001 if (TEST_HARD_REG_BIT (to_spill, i))
01002 {
01003 spill_hard_reg (i, 1);
01004 did_spill = 1;
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015 something_changed = 1;
01016 }
01017 }
01018
01019 select_reload_regs ();
01020 if (failure)
01021 goto failed;
01022
01023 if (insns_need_reload != 0 || did_spill)
01024 something_changed |= finish_spills (global);
01025
01026 if (! something_changed)
01027 break;
01028
01029 if (caller_save_needed)
01030 delete_caller_save_insns ();
01031
01032 obstack_free (&reload_obstack, reload_firstobj);
01033 }
01034
01035
01036
01037 if (global)
01038 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
01039 if (ep->can_eliminate)
01040 mark_elimination (ep->from, ep->to);
01041
01042
01043
01044
01045
01046
01047
01048
01049 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
01050 {
01051 if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0)
01052 {
01053 rtx list;
01054 for (list = reg_equiv_init[i]; list; list = XEXP (list, 1))
01055 {
01056 rtx equiv_insn = XEXP (list, 0);
01057
01058
01059
01060
01061
01062
01063 if (NOTE_P (equiv_insn)
01064 || can_throw_internal (equiv_insn))
01065 ;
01066 else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn)))
01067 delete_dead_insn (equiv_insn);
01068 else
01069 SET_INSN_DELETED (equiv_insn);
01070 }
01071 }
01072 }
01073
01074
01075
01076
01077
01078 if (insns_need_reload != 0 || something_needs_elimination
01079 || something_needs_operands_changed)
01080 {
01081 HOST_WIDE_INT old_frame_size = get_frame_size ();
01082
01083 reload_as_needed (global);
01084
01085 gcc_assert (old_frame_size == get_frame_size ());
01086
01087 gcc_assert (verify_initial_elim_offsets ());
01088 }
01089
01090
01091
01092
01093
01094
01095
01096 if (! frame_pointer_needed)
01097 FOR_EACH_BB (bb)
01098 CLEAR_REGNO_REG_SET (bb->il.rtl->global_live_at_start,
01099 HARD_FRAME_POINTER_REGNUM);
01100
01101
01102
01103 failed:
01104
01105 CLEAR_REG_SET (&spilled_pseudos);
01106 reload_in_progress = 0;
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
01119 {
01120 rtx addr = 0;
01121
01122 if (reg_equiv_mem[i])
01123 addr = XEXP (reg_equiv_mem[i], 0);
01124
01125 if (reg_equiv_address[i])
01126 addr = reg_equiv_address[i];
01127
01128 if (addr)
01129 {
01130 if (reg_renumber[i] < 0)
01131 {
01132 rtx reg = regno_reg_rtx[i];
01133
01134 REG_USERVAR_P (reg) = 0;
01135 PUT_CODE (reg, MEM);
01136 XEXP (reg, 0) = addr;
01137 if (reg_equiv_memory_loc[i])
01138 MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc[i]);
01139 else
01140 {
01141 MEM_IN_STRUCT_P (reg) = MEM_SCALAR_P (reg) = 0;
01142 MEM_ATTRS (reg) = 0;
01143 }
01144 MEM_NOTRAP_P (reg) = 1;
01145 }
01146 else if (reg_equiv_mem[i])
01147 XEXP (reg_equiv_mem[i], 0) = addr;
01148 }
01149 }
01150
01151
01152
01153
01154 reload_completed = 1;
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 for (insn = first; insn; insn = NEXT_INSN (insn))
01166 if (INSN_P (insn))
01167 {
01168 rtx *pnote;
01169
01170 if (CALL_P (insn))
01171 replace_pseudos_in (& CALL_INSN_FUNCTION_USAGE (insn),
01172 VOIDmode, CALL_INSN_FUNCTION_USAGE (insn));
01173
01174 if ((GET_CODE (PATTERN (insn)) == USE
01175
01176 && (GET_MODE (insn) == QImode
01177 || find_reg_note (insn, REG_EQUAL, NULL_RTX)))
01178 || (GET_CODE (PATTERN (insn)) == CLOBBER
01179 && (!MEM_P (XEXP (PATTERN (insn), 0))
01180 || GET_MODE (XEXP (PATTERN (insn), 0)) != BLKmode
01181 || (GET_CODE (XEXP (XEXP (PATTERN (insn), 0), 0)) != SCRATCH
01182 && XEXP (XEXP (PATTERN (insn), 0), 0)
01183 != stack_pointer_rtx))
01184 && (!REG_P (XEXP (PATTERN (insn), 0))
01185 || ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))))
01186 {
01187 delete_insn (insn);
01188 continue;
01189 }
01190
01191
01192
01193
01194 if (GET_CODE (PATTERN (insn)) == CLOBBER)
01195 replace_pseudos_in (& XEXP (PATTERN (insn), 0),
01196 VOIDmode, PATTERN (insn));
01197
01198
01199
01200 if (NONJUMP_INSN_P (insn)
01201 && GET_CODE (PATTERN (insn)) == SET
01202 && REG_P (SET_SRC (PATTERN (insn)))
01203 && REG_P (SET_DEST (PATTERN (insn)))
01204 && (REGNO (SET_SRC (PATTERN (insn)))
01205 == REGNO (SET_DEST (PATTERN (insn)))))
01206 {
01207 delete_insn (insn);
01208 continue;
01209 }
01210
01211 pnote = ®_NOTES (insn);
01212 while (*pnote != 0)
01213 {
01214 if (REG_NOTE_KIND (*pnote) == REG_DEAD
01215 || REG_NOTE_KIND (*pnote) == REG_UNUSED
01216 || REG_NOTE_KIND (*pnote) == REG_INC
01217 || REG_NOTE_KIND (*pnote) == REG_RETVAL
01218 || REG_NOTE_KIND (*pnote) == REG_LIBCALL)
01219 *pnote = XEXP (*pnote, 1);
01220 else
01221 pnote = &XEXP (*pnote, 1);
01222 }
01223
01224 #ifdef AUTO_INC_DEC
01225 add_auto_inc_notes (insn, PATTERN (insn));
01226 #endif
01227
01228
01229 cleanup_subreg_operands (insn);
01230
01231
01232
01233 if (asm_noperands (PATTERN (insn)) >= 0)
01234 {
01235 extract_insn (insn);
01236 if (!constrain_operands (1))
01237 {
01238 error_for_asm (insn,
01239 "%<asm%> operand has impossible constraints");
01240 delete_insn (insn);
01241 continue;
01242 }
01243 }
01244 }
01245
01246
01247
01248 if (flag_stack_check && ! STACK_CHECK_BUILTIN)
01249 {
01250 HOST_WIDE_INT size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE;
01251 static int verbose_warned = 0;
01252
01253 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01254 if (regs_ever_live[i] && ! fixed_regs[i] && call_used_regs[i])
01255 size += UNITS_PER_WORD;
01256
01257 if (size > STACK_CHECK_MAX_FRAME_SIZE)
01258 {
01259 warning (0, "frame size too large for reliable stack checking");
01260 if (! verbose_warned)
01261 {
01262 warning (0, "try reducing the number of local variables");
01263 verbose_warned = 1;
01264 }
01265 }
01266 }
01267
01268
01269 if (reg_equiv_constant)
01270 free (reg_equiv_constant);
01271 if (reg_equiv_invariant)
01272 free (reg_equiv_invariant);
01273 reg_equiv_constant = 0;
01274 reg_equiv_invariant = 0;
01275 VEC_free (rtx, gc, reg_equiv_memory_loc_vec);
01276 reg_equiv_memory_loc = 0;
01277
01278 if (offsets_known_at)
01279 free (offsets_known_at);
01280 if (offsets_at)
01281 free (offsets_at);
01282
01283 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01284 if (reg_equiv_alt_mem_list[i])
01285 free_EXPR_LIST_list (®_equiv_alt_mem_list[i]);
01286 free (reg_equiv_alt_mem_list);
01287
01288 free (reg_equiv_mem);
01289 reg_equiv_init = 0;
01290 free (reg_equiv_address);
01291 free (reg_max_ref_width);
01292 free (reg_old_renumber);
01293 free (pseudo_previous_regs);
01294 free (pseudo_forbidden_regs);
01295
01296 CLEAR_HARD_REG_SET (used_spill_regs);
01297 for (i = 0; i < n_spills; i++)
01298 SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]);
01299
01300
01301 obstack_free (&reload_obstack, reload_startobj);
01302 unused_insn_chains = 0;
01303 fixup_abnormal_edges ();
01304
01305
01306
01307
01308 unshare_all_rtl_again (first);
01309
01310 #ifdef STACK_BOUNDARY
01311
01312
01313
01314 if (!frame_pointer_needed)
01315 REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = BITS_PER_UNIT;
01316 #endif
01317
01318 return failure;
01319 }
01320
01321
01322
01323
01324
01325
01326
01327
01328 static void
01329 maybe_fix_stack_asms (void)
01330 {
01331 #ifdef STACK_REGS
01332 const char *constraints[MAX_RECOG_OPERANDS];
01333 enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
01334 struct insn_chain *chain;
01335
01336 for (chain = reload_insn_chain; chain != 0; chain = chain->next)
01337 {
01338 int i, noperands;
01339 HARD_REG_SET clobbered, allowed;
01340 rtx pat;
01341
01342 if (! INSN_P (chain->insn)
01343 || (noperands = asm_noperands (PATTERN (chain->insn))) < 0)
01344 continue;
01345 pat = PATTERN (chain->insn);
01346 if (GET_CODE (pat) != PARALLEL)
01347 continue;
01348
01349 CLEAR_HARD_REG_SET (clobbered);
01350 CLEAR_HARD_REG_SET (allowed);
01351
01352
01353 for (i = 0; i < XVECLEN (pat, 0); i++)
01354 {
01355 rtx t = XVECEXP (pat, 0, i);
01356 if (GET_CODE (t) == CLOBBER && STACK_REG_P (XEXP (t, 0)))
01357 SET_HARD_REG_BIT (clobbered, REGNO (XEXP (t, 0)));
01358 }
01359
01360
01361 decode_asm_operands (pat, recog_data.operand, recog_data.operand_loc,
01362 constraints, operand_mode);
01363
01364
01365 for (i = 0; i < noperands; i++)
01366 {
01367 const char *p = constraints[i];
01368
01369
01370
01371 int cls = (int) NO_REGS;
01372
01373 for (;;)
01374 {
01375 char c = *p;
01376
01377 if (c == '\0' || c == ',' || c == '#')
01378 {
01379
01380
01381 IOR_HARD_REG_SET (allowed, reg_class_contents[cls]);
01382 cls = NO_REGS;
01383 p++;
01384 if (c == '#')
01385 do {
01386 c = *p++;
01387 } while (c != '\0' && c != ',');
01388 if (c == '\0')
01389 break;
01390 continue;
01391 }
01392
01393 switch (c)
01394 {
01395 case '=': case '+': case '*': case '%': case '?': case '!':
01396 case '0': case '1': case '2': case '3': case '4': case 'm':
01397 case '<': case '>': case 'V': case 'o': case '&': case 'E':
01398 case 'F': case 's': case 'i': case 'n': case 'X': case 'I':
01399 case 'J': case 'K': case 'L': case 'M': case 'N': case 'O':
01400 case 'P':
01401 break;
01402
01403 case 'p':
01404 cls = (int) reg_class_subunion[cls]
01405 [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
01406 break;
01407
01408 case 'g':
01409 case 'r':
01410 cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS];
01411 break;
01412
01413 default:
01414 if (EXTRA_ADDRESS_CONSTRAINT (c, p))
01415 cls = (int) reg_class_subunion[cls]
01416 [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
01417 else
01418 cls = (int) reg_class_subunion[cls]
01419 [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
01420 }
01421 p += CONSTRAINT_LEN (c, p);
01422 }
01423 }
01424
01425
01426
01427 AND_HARD_REG_SET (allowed, clobbered);
01428 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01429 if (TEST_HARD_REG_BIT (allowed, i))
01430 {
01431 CLEAR_REGNO_REG_SET (&chain->live_throughout, i);
01432 CLEAR_REGNO_REG_SET (&chain->dead_or_set, i);
01433 }
01434 }
01435
01436 #endif
01437 }
01438
01439
01440
01441 static void
01442 copy_reloads (struct insn_chain *chain)
01443 {
01444 chain->n_reloads = n_reloads;
01445 chain->rld = obstack_alloc (&reload_obstack,
01446 n_reloads * sizeof (struct reload));
01447 memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
01448 reload_insn_firstobj = obstack_alloc (&reload_obstack, 0);
01449 }
01450
01451
01452
01453
01454 static void
01455 calculate_needs_all_insns (int global)
01456 {
01457 struct insn_chain **pprev_reload = &insns_need_reload;
01458 struct insn_chain *chain, *next = 0;
01459
01460 something_needs_elimination = 0;
01461
01462 reload_insn_firstobj = obstack_alloc (&reload_obstack, 0);
01463 for (chain = reload_insn_chain; chain != 0; chain = next)
01464 {
01465 rtx insn = chain->insn;
01466
01467 next = chain->next;
01468
01469
01470 chain->n_reloads = 0;
01471 chain->need_elim = 0;
01472 chain->need_reload = 0;
01473 chain->need_operand_change = 0;
01474
01475
01476
01477
01478
01479 if (LABEL_P (insn) || JUMP_P (insn)
01480 || (INSN_P (insn) && REG_NOTES (insn) != 0))
01481 set_label_offsets (insn, insn, 0);
01482
01483 if (INSN_P (insn))
01484 {
01485 rtx old_body = PATTERN (insn);
01486 int old_code = INSN_CODE (insn);
01487 rtx old_notes = REG_NOTES (insn);
01488 int did_elimination = 0;
01489 int operands_changed = 0;
01490 rtx set = single_set (insn);
01491
01492
01493 if (set && REG_P (SET_DEST (set))
01494 && reg_renumber[REGNO (SET_DEST (set))] < 0
01495 && (reg_equiv_constant[REGNO (SET_DEST (set))]
01496 || (reg_equiv_invariant[REGNO (SET_DEST (set))]))
01497 && reg_equiv_init[REGNO (SET_DEST (set))])
01498 continue;
01499
01500
01501 if (num_eliminable || num_eliminable_invariants)
01502 did_elimination = eliminate_regs_in_insn (insn, 0);
01503
01504
01505 operands_changed = find_reloads (insn, 0, spill_indirect_levels,
01506 global, spill_reg_order);
01507
01508
01509
01510
01511
01512
01513
01514
01515 if (flag_expensive_optimizations && n_reloads > 1)
01516 {
01517 rtx set = single_set (insn);
01518 if (set
01519 && SET_SRC (set) == SET_DEST (set)
01520 && REG_P (SET_SRC (set))
01521 && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER)
01522 {
01523 delete_insn (insn);
01524
01525 if (chain->prev)
01526 chain->prev->next = next;
01527 else
01528 reload_insn_chain = next;
01529 if (next)
01530 next->prev = chain->prev;
01531 chain->next = unused_insn_chains;
01532 unused_insn_chains = chain;
01533 continue;
01534 }
01535 }
01536 if (num_eliminable)
01537 update_eliminable_offsets ();
01538
01539
01540
01541 chain->need_elim = did_elimination;
01542 chain->need_reload = n_reloads > 0;
01543 chain->need_operand_change = operands_changed;
01544
01545
01546 if (did_elimination)
01547 {
01548 obstack_free (&reload_obstack, reload_insn_firstobj);
01549 PATTERN (insn) = old_body;
01550 INSN_CODE (insn) = old_code;
01551 REG_NOTES (insn) = old_notes;
01552 something_needs_elimination = 1;
01553 }
01554
01555 something_needs_operands_changed |= operands_changed;
01556
01557 if (n_reloads != 0)
01558 {
01559 copy_reloads (chain);
01560 *pprev_reload = chain;
01561 pprev_reload = &chain->next_need_reload;
01562 }
01563 }
01564 }
01565 *pprev_reload = 0;
01566 }
01567
01568
01569
01570
01571 static int
01572 reload_reg_class_lower (const void *r1p, const void *r2p)
01573 {
01574 int r1 = *(const short *) r1p, r2 = *(const short *) r2p;
01575 int t;
01576
01577
01578 t = rld[r1].optional - rld[r2].optional;
01579 if (t != 0)
01580 return t;
01581
01582
01583 t = ((reg_class_size[(int) rld[r2].class] == 1)
01584 - (reg_class_size[(int) rld[r1].class] == 1));
01585 if (t != 0)
01586 return t;
01587
01588
01589 t = rld[r2].nregs - rld[r1].nregs;
01590 if (t != 0)
01591 return t;
01592
01593
01594 t = (int) rld[r1].class - (int) rld[r2].class;
01595 if (t != 0)
01596 return t;
01597
01598
01599
01600 return r1 - r2;
01601 }
01602
01603
01604 static int spill_cost[FIRST_PSEUDO_REGISTER];
01605
01606
01607
01608
01609 static int spill_add_cost[FIRST_PSEUDO_REGISTER];
01610
01611
01612
01613 static void
01614 count_pseudo (int reg)
01615 {
01616 int freq = REG_FREQ (reg);
01617 int r = reg_renumber[reg];
01618 int nregs;
01619
01620 if (REGNO_REG_SET_P (&pseudos_counted, reg)
01621 || REGNO_REG_SET_P (&spilled_pseudos, reg))
01622 return;
01623
01624 SET_REGNO_REG_SET (&pseudos_counted, reg);
01625
01626 gcc_assert (r >= 0);
01627
01628 spill_add_cost[r] += freq;
01629
01630 nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
01631 while (nregs-- > 0)
01632 spill_cost[r + nregs] += freq;
01633 }
01634
01635
01636
01637
01638 static void
01639 order_regs_for_reload (struct insn_chain *chain)
01640 {
01641 unsigned i;
01642 HARD_REG_SET used_by_pseudos;
01643 HARD_REG_SET used_by_pseudos2;
01644 reg_set_iterator rsi;
01645
01646 COPY_HARD_REG_SET (bad_spill_regs, fixed_reg_set);
01647
01648 memset (spill_cost, 0, sizeof spill_cost);
01649 memset (spill_add_cost, 0, sizeof spill_add_cost);
01650
01651
01652
01653
01654
01655 REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout);
01656 REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set);
01657 IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos);
01658 IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos2);
01659
01660
01661
01662 CLEAR_REG_SET (&pseudos_counted);
01663
01664 EXECUTE_IF_SET_IN_REG_SET
01665 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, rsi)
01666 {
01667 count_pseudo (i);
01668 }
01669 EXECUTE_IF_SET_IN_REG_SET
01670 (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi)
01671 {
01672 count_pseudo (i);
01673 }
01674 CLEAR_REG_SET (&pseudos_counted);
01675 }
01676
01677
01678
01679 static short reload_order[MAX_RELOADS];
01680
01681
01682 static HARD_REG_SET used_spill_regs_local;
01683
01684
01685
01686
01687
01688
01689 static void
01690 count_spilled_pseudo (int spilled, int spilled_nregs, int reg)
01691 {
01692 int r = reg_renumber[reg];
01693 int nregs = hard_regno_nregs[r][PSEUDO_REGNO_MODE (reg)];
01694
01695 if (REGNO_REG_SET_P (&spilled_pseudos, reg)
01696 || spilled + spilled_nregs <= r || r + nregs <= spilled)
01697 return;
01698
01699 SET_REGNO_REG_SET (&spilled_pseudos, reg);
01700
01701 spill_add_cost[r] -= REG_FREQ (reg);
01702 while (nregs-- > 0)
01703 spill_cost[r + nregs] -= REG_FREQ (reg);
01704 }
01705
01706
01707
01708 static int
01709 find_reg (struct insn_chain *chain, int order)
01710 {
01711 int rnum = reload_order[order];
01712 struct reload *rl = rld + rnum;
01713 int best_cost = INT_MAX;
01714 int best_reg = -1;
01715 unsigned int i, j;
01716 int k;
01717 HARD_REG_SET not_usable;
01718 HARD_REG_SET used_by_other_reload;
01719 reg_set_iterator rsi;
01720
01721 COPY_HARD_REG_SET (not_usable, bad_spill_regs);
01722 IOR_HARD_REG_SET (not_usable, bad_spill_regs_global);
01723 IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->class]);
01724
01725 CLEAR_HARD_REG_SET (used_by_other_reload);
01726 for (k = 0; k < order; k++)
01727 {
01728 int other = reload_order[k];
01729
01730 if (rld[other].regno >= 0 && reloads_conflict (other, rnum))
01731 for (j = 0; j < rld[other].nregs; j++)
01732 SET_HARD_REG_BIT (used_by_other_reload, rld[other].regno + j);
01733 }
01734
01735 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
01736 {
01737 unsigned int regno = i;
01738
01739 if (! TEST_HARD_REG_BIT (not_usable, regno)
01740 && ! TEST_HARD_REG_BIT (used_by_other_reload, regno)
01741 && HARD_REGNO_MODE_OK (regno, rl->mode))
01742 {
01743 int this_cost = spill_cost[regno];
01744 int ok = 1;
01745 unsigned int this_nregs = hard_regno_nregs[regno][rl->mode];
01746
01747 for (j = 1; j < this_nregs; j++)
01748 {
01749 this_cost += spill_add_cost[regno + j];
01750 if ((TEST_HARD_REG_BIT (not_usable, regno + j))
01751 || TEST_HARD_REG_BIT (used_by_other_reload, regno + j))
01752 ok = 0;
01753 }
01754 if (! ok)
01755 continue;
01756 if (rl->in && REG_P (rl->in) && REGNO (rl->in) == regno)
01757 this_cost--;
01758 if (rl->out && REG_P (rl->out) && REGNO (rl->out) == regno)
01759 this_cost--;
01760 if (this_cost < best_cost
01761
01762
01763 || (this_cost == best_cost
01764 #ifdef REG_ALLOC_ORDER
01765 && (inv_reg_alloc_order[regno]
01766 < inv_reg_alloc_order[best_reg])
01767 #else
01768 && call_used_regs[regno]
01769 && ! call_used_regs[best_reg]
01770 #endif
01771 ))
01772 {
01773 best_reg = regno;
01774 best_cost = this_cost;
01775 }
01776 }
01777 }
01778 if (best_reg == -1)
01779 return 0;
01780
01781 if (dump_file)
01782 fprintf (dump_file, "Using reg %d for reload %d\n", best_reg, rnum);
01783
01784 rl->nregs = hard_regno_nregs[best_reg][rl->mode];
01785 rl->regno = best_reg;
01786
01787 EXECUTE_IF_SET_IN_REG_SET
01788 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, j, rsi)
01789 {
01790 count_spilled_pseudo (best_reg, rl->nregs, j);
01791 }
01792
01793 EXECUTE_IF_SET_IN_REG_SET
01794 (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, j, rsi)
01795 {
01796 count_spilled_pseudo (best_reg, rl->nregs, j);
01797 }
01798
01799 for (i = 0; i < rl->nregs; i++)
01800 {
01801 gcc_assert (spill_cost[best_reg + i] == 0);
01802 gcc_assert (spill_add_cost[best_reg + i] == 0);
01803 SET_HARD_REG_BIT (used_spill_regs_local, best_reg + i);
01804 }
01805 return 1;
01806 }
01807
01808
01809
01810
01811
01812
01813
01814 static void
01815 find_reload_regs (struct insn_chain *chain)
01816 {
01817 int i;
01818
01819
01820
01821
01822
01823 for (i = 0; i < chain->n_reloads; i++)
01824 {
01825
01826 if (chain->rld[i].reg_rtx)
01827 {
01828 int regno = REGNO (chain->rld[i].reg_rtx);
01829 chain->rld[i].regno = regno;
01830 chain->rld[i].nregs
01831 = hard_regno_nregs[regno][GET_MODE (chain->rld[i].reg_rtx)];
01832 }
01833 else
01834 chain->rld[i].regno = -1;
01835 reload_order[i] = i;
01836 }
01837
01838 n_reloads = chain->n_reloads;
01839 memcpy (rld, chain->rld, n_reloads * sizeof (struct reload));
01840
01841 CLEAR_HARD_REG_SET (used_spill_regs_local);
01842
01843 if (dump_file)
01844 fprintf (dump_file, "Spilling for insn %d.\n", INSN_UID (chain->insn));
01845
01846 qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);
01847
01848
01849
01850 order_regs_for_reload (chain);
01851
01852 for (i = 0; i < n_reloads; i++)
01853 {
01854 int r = reload_order[i];
01855
01856
01857 if ((rld[r].out != 0 || rld[r].in != 0 || rld[r].secondary_p)
01858 && ! rld[r].optional
01859 && rld[r].regno == -1)
01860 if (! find_reg (chain, i))
01861 {
01862 if (dump_file)
01863 fprintf(dump_file, "reload failure for reload %d\n", r);
01864 spill_failure (chain->insn, rld[r].class);
01865 failure = 1;
01866 return;
01867 }
01868 }
01869
01870 COPY_HARD_REG_SET (chain->used_spill_regs, used_spill_regs_local);
01871 IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local);
01872
01873 memcpy (chain->rld, rld, n_reloads * sizeof (struct reload));
01874 }
01875
01876 static void
01877 select_reload_regs (void)
01878 {
01879 struct insn_chain *chain;
01880
01881
01882 for (chain = insns_need_reload; chain != 0;
01883 chain = chain->next_need_reload)
01884 find_reload_regs (chain);
01885 }
01886
01887
01888
01889 static void
01890 delete_caller_save_insns (void)
01891 {
01892 struct insn_chain *c = reload_insn_chain;
01893
01894 while (c != 0)
01895 {
01896 while (c != 0 && c->is_caller_save_insn)
01897 {
01898 struct insn_chain *next = c->next;
01899 rtx insn = c->insn;
01900
01901 if (c == reload_insn_chain)
01902 reload_insn_chain = next;
01903 delete_insn (insn);
01904
01905 if (next)
01906 next->prev = c->prev;
01907 if (c->prev)
01908 c->prev->next = next;
01909 c->next = unused_insn_chains;
01910 unused_insn_chains = c;
01911 c = next;
01912 }
01913 if (c != 0)
01914 c = c->next;
01915 }
01916 }
01917
01918
01919
01920
01921 static void
01922 spill_failure (rtx insn, enum reg_class class)
01923 {
01924 if (asm_noperands (PATTERN (insn)) >= 0)
01925 error_for_asm (insn, "can't find a register in class %qs while "
01926 "reloading %<asm%>",
01927 reg_class_names[class]);
01928 else
01929 {
01930 error ("unable to find a register to spill in class %qs",
01931 reg_class_names[class]);
01932
01933 if (dump_file)
01934 {
01935 fprintf (dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
01936 debug_reload_to_stream (dump_file);
01937 }
01938 fatal_insn ("this is the insn:", insn);
01939 }
01940 }
01941
01942
01943
01944
01945 static void
01946 delete_dead_insn (rtx insn)
01947 {
01948 rtx prev = prev_real_insn (insn);
01949 rtx prev_dest;
01950
01951
01952
01953 if (prev && GET_CODE (PATTERN (prev)) == SET
01954 && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
01955 && reg_mentioned_p (prev_dest, PATTERN (insn))
01956 && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
01957 && ! side_effects_p (SET_SRC (PATTERN (prev))))
01958 delete_dead_insn (prev);
01959
01960 SET_INSN_DELETED (insn);
01961 }
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971 static void
01972 alter_reg (int i, int from_reg)
01973 {
01974
01975
01976 if (regno_reg_rtx[i] == 0)
01977 return;
01978
01979
01980
01981 if (!REG_P (regno_reg_rtx[i]))
01982 return;
01983
01984
01985
01986 REGNO (regno_reg_rtx[i])
01987 = reg_renumber[i] >= 0 ? reg_renumber[i] : i;
01988
01989
01990
01991
01992 if (reg_renumber[i] < 0
01993 && REG_N_REFS (i) > 0
01994 && reg_equiv_constant[i] == 0
01995 && (reg_equiv_invariant[i] == 0 || reg_equiv_init[i] == 0)
01996 && reg_equiv_memory_loc[i] == 0)
01997 {
01998 rtx x;
01999 enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
02000 unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
02001 unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
02002 unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
02003 unsigned int min_align = reg_max_ref_width[i] * BITS_PER_UNIT;
02004 int adjust = 0;
02005
02006
02007
02008
02009
02010
02011
02012
02013
02014 if (from_reg == -1)
02015 {
02016
02017 x = assign_stack_local (mode, total_size,
02018 min_align > inherent_align
02019 || total_size > inherent_size ? -1 : 0);
02020 if (BYTES_BIG_ENDIAN)
02021
02022
02023
02024
02025 adjust = inherent_size - total_size;
02026
02027
02028 set_mem_alias_set (x, new_alias_set ());
02029 }
02030
02031
02032 else if (spill_stack_slot[from_reg] != 0
02033 && spill_stack_slot_width[from_reg] >= total_size
02034 && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
02035 >= inherent_size)
02036 && MEM_ALIGN (spill_stack_slot[from_reg]) >= min_align)
02037 x = spill_stack_slot[from_reg];
02038
02039
02040 else
02041 {
02042
02043
02044 rtx stack_slot;
02045
02046 if (spill_stack_slot[from_reg])
02047 {
02048 if (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg]))
02049 > inherent_size)
02050 mode = GET_MODE (spill_stack_slot[from_reg]);
02051 if (spill_stack_slot_width[from_reg] > total_size)
02052 total_size = spill_stack_slot_width[from_reg];
02053 if (MEM_ALIGN (spill_stack_slot[from_reg]) > min_align)
02054 min_align = MEM_ALIGN (spill_stack_slot[from_reg]);
02055 }
02056
02057
02058 x = assign_stack_local (mode, total_size,
02059 min_align > inherent_align
02060 || total_size > inherent_size ? -1 : 0);
02061 stack_slot = x;
02062
02063
02064 if (spill_stack_slot[from_reg])
02065 set_mem_alias_set (x, MEM_ALIAS_SET (spill_stack_slot[from_reg]));
02066 else
02067 set_mem_alias_set (x, new_alias_set ());
02068
02069 if (BYTES_BIG_ENDIAN)
02070 {
02071
02072
02073
02074
02075 adjust = GET_MODE_SIZE (mode) - total_size;
02076 if (adjust)
02077 stack_slot
02078 = adjust_address_nv (x, mode_for_size (total_size
02079 * BITS_PER_UNIT,
02080 MODE_INT, 1),
02081 adjust);
02082 }
02083
02084 spill_stack_slot[from_reg] = stack_slot;
02085 spill_stack_slot_width[from_reg] = total_size;
02086 }
02087
02088
02089
02090 if (BYTES_BIG_ENDIAN && inherent_size < total_size)
02091 adjust += (total_size - inherent_size);
02092
02093
02094
02095 x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust);
02096
02097
02098
02099 if (REG_EXPR (regno_reg_rtx[i])
02100 && DECL_P (REG_EXPR (regno_reg_rtx[i])))
02101 {
02102 rtx decl = DECL_RTL_IF_SET (REG_EXPR (regno_reg_rtx[i]));
02103
02104
02105
02106
02107
02108 if (decl && REG_P (decl) && REGNO (decl) == (unsigned) i)
02109 {
02110 if (from_reg != -1 && spill_stack_slot[from_reg] == x)
02111 x = copy_rtx (x);
02112
02113 set_mem_attrs_from_reg (x, regno_reg_rtx[i]);
02114 }
02115 }
02116
02117
02118 reg_equiv_memory_loc[i] = x;
02119 }
02120 }
02121
02122
02123
02124
02125 void
02126 mark_home_live (int regno)
02127 {
02128 int i, lim;
02129
02130 i = reg_renumber[regno];
02131 if (i < 0)
02132 return;
02133 lim = i + hard_regno_nregs[i][PSEUDO_REGNO_MODE (regno)];
02134 while (i < lim)
02135 regs_ever_live[i++] = 1;
02136 }
02137
02138
02139
02140
02141
02142
02143
02144
02145
02146
02147
02148 static void
02149 set_label_offsets (rtx x, rtx insn, int initial_p)
02150 {
02151 enum rtx_code code = GET_CODE (x);
02152 rtx tem;
02153 unsigned int i;
02154 struct elim_table *p;
02155
02156 switch (code)
02157 {
02158 case LABEL_REF:
02159 if (LABEL_REF_NONLOCAL_P (x))
02160 return;
02161
02162 x = XEXP (x, 0);
02163
02164
02165
02166 case CODE_LABEL:
02167
02168
02169
02170
02171
02172
02173
02174 if (! offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num])
02175 {
02176 for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
02177 offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
02178 = (initial_p ? reg_eliminate[i].initial_offset
02179 : reg_eliminate[i].offset);
02180 offsets_known_at[CODE_LABEL_NUMBER (x) - first_label_num] = 1;
02181 }
02182
02183
02184
02185
02186
02187 else if (x == insn
02188 && (tem = prev_nonnote_insn (insn)) != 0
02189 && BARRIER_P (tem))
02190 set_offsets_for_label (insn);
02191 else
02192
02193
02194
02195
02196 for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
02197 if (offsets_at[CODE_LABEL_NUMBER (x) - first_label_num][i]
02198 != (initial_p ? reg_eliminate[i].initial_offset
02199 : reg_eliminate[i].offset))
02200 reg_eliminate[i].can_eliminate = 0;
02201
02202 return;
02203
02204 case JUMP_INSN:
02205 set_label_offsets (PATTERN (insn), insn, initial_p);
02206
02207
02208
02209 case INSN:
02210 case CALL_INSN:
02211
02212
02213 for (tem = REG_NOTES (x); tem; tem = XEXP (tem, 1))
02214 if (REG_NOTE_KIND (tem) == REG_LABEL)
02215 set_label_offsets (XEXP (tem, 0), insn, 1);
02216 return;
02217
02218 case PARALLEL:
02219 case ADDR_VEC:
02220 case ADDR_DIFF_VEC:
02221
02222
02223
02224
02225 for (i = 0; i < (unsigned) XVECLEN (x, code == ADDR_DIFF_VEC); i++)
02226 set_label_offsets (XVECEXP (x, code == ADDR_DIFF_VEC, i),
02227 insn, initial_p);
02228 return;
02229
02230 case SET:
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243 if (SET_DEST (x) != pc_rtx)
02244 return;
02245
02246 switch (GET_CODE (SET_SRC (x)))
02247 {
02248 case PC:
02249 case RETURN:
02250 return;
02251
02252 case LABEL_REF:
02253 set_label_offsets (SET_SRC (x), insn, initial_p);
02254 return;
02255
02256 case IF_THEN_ELSE:
02257 tem = XEXP (SET_SRC (x), 1);
02258 if (GET_CODE (tem) == LABEL_REF)
02259 set_label_offsets (XEXP (tem, 0), insn, initial_p);
02260 else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
02261 break;
02262
02263 tem = XEXP (SET_SRC (x), 2);
02264 if (GET_CODE (tem) == LABEL_REF)
02265 set_label_offsets (XEXP (tem, 0), insn, initial_p);
02266 else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
02267 break;
02268 return;
02269
02270 default:
02271 break;
02272 }
02273
02274
02275
02276 for (p = reg_eliminate; p < ®_eliminate[NUM_ELIMINABLE_REGS]; p++)
02277 if (p->offset != p->initial_offset)
02278 p->can_eliminate = 0;
02279 break;
02280
02281 default:
02282 break;
02283 }
02284 }
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301
02302
02303
02304
02305
02306
02307
02308
02309
02310
02311 static rtx
02312 eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
02313 bool may_use_invariant)
02314 {
02315 enum rtx_code code = GET_CODE (x);
02316 struct elim_table *ep;
02317 int regno;
02318 rtx new;
02319 int i, j;
02320 const char *fmt;
02321 int copied = 0;
02322
02323 if (! current_function_decl)
02324 return x;
02325
02326 switch (code)
02327 {
02328 case CONST_INT:
02329 case CONST_DOUBLE:
02330 case CONST_VECTOR:
02331 case CONST:
02332 case SYMBOL_REF:
02333 case CODE_LABEL:
02334 case PC:
02335 case CC0:
02336 case ASM_INPUT:
02337 case ADDR_VEC:
02338 case ADDR_DIFF_VEC:
02339 case RETURN:
02340 return x;
02341
02342 case REG:
02343 regno = REGNO (x);
02344
02345
02346
02347 if (regno < FIRST_PSEUDO_REGISTER)
02348 {
02349 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
02350 ep++)
02351 if (ep->from_rtx == x && ep->can_eliminate)
02352 return plus_constant (ep->to_rtx, ep->previous_offset);
02353
02354 }
02355 else if (reg_renumber && reg_renumber[regno] < 0
02356 && reg_equiv_invariant && reg_equiv_invariant[regno])
02357 {
02358 if (may_use_invariant)
02359 return eliminate_regs_1 (copy_rtx (reg_equiv_invariant[regno]),
02360 mem_mode, insn, true);
02361
02362
02363 reg_equiv_init[regno] = NULL_RTX;
02364 alter_reg (regno, -1);
02365 }
02366 return x;
02367
02368
02369
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380
02381
02382 case PLUS:
02383
02384
02385 if (REG_P (XEXP (x, 0))
02386 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
02387 && CONSTANT_P (XEXP (x, 1)))
02388 {
02389 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
02390 ep++)
02391 if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
02392 {
02393
02394
02395
02396
02397
02398
02399
02400
02401 if (mem_mode != 0 && GET_CODE (XEXP (x, 1)) == CONST_INT
02402 && INTVAL (XEXP (x, 1)) == - ep->previous_offset)
02403 return ep->to_rtx;
02404 else
02405 return gen_rtx_PLUS (Pmode, ep->to_rtx,
02406 plus_constant (XEXP (x, 1),
02407 ep->previous_offset));
02408 }
02409
02410
02411
02412 return x;
02413 }
02414
02415
02416
02417
02418
02419
02420
02421
02422
02423
02424 {
02425 rtx new0 = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, true);
02426 rtx new1 = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true);
02427
02428 if (reg_renumber && (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)))
02429 {
02430
02431
02432
02433
02434 if (GET_CODE (new0) == PLUS && REG_P (new1)
02435 && REGNO (new1) >= FIRST_PSEUDO_REGISTER
02436 && reg_renumber[REGNO (new1)] < 0
02437 && reg_equiv_constant != 0
02438 && reg_equiv_constant[REGNO (new1)] != 0)
02439 new1 = reg_equiv_constant[REGNO (new1)];
02440 else if (GET_CODE (new1) == PLUS && REG_P (new0)
02441 && REGNO (new0) >= FIRST_PSEUDO_REGISTER
02442 && reg_renumber[REGNO (new0)] < 0
02443 && reg_equiv_constant[REGNO (new0)] != 0)
02444 new0 = reg_equiv_constant[REGNO (new0)];
02445
02446 new = form_sum (new0, new1);
02447
02448
02449
02450
02451 if (! mem_mode && GET_CODE (new) != PLUS)
02452 return gen_rtx_PLUS (GET_MODE (x), new, const0_rtx);
02453 else
02454 return new;
02455 }
02456 }
02457 return x;
02458
02459 case MULT:
02460
02461
02462
02463
02464
02465 if (REG_P (XEXP (x, 0))
02466 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER
02467 && GET_CODE (XEXP (x, 1)) == CONST_INT)
02468 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
02469 ep++)
02470 if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate)
02471 {
02472 if (! mem_mode
02473
02474 && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST
02475 || GET_CODE (insn) == INSN_LIST)))
02476 ep->ref_outside_mem = 1;
02477
02478 return
02479 plus_constant (gen_rtx_MULT (Pmode, ep->to_rtx, XEXP (x, 1)),
02480 ep->previous_offset * INTVAL (XEXP (x, 1)));
02481 }
02482
02483
02484
02485 case CALL:
02486 case COMPARE:
02487
02488 case MINUS:
02489 case DIV: case UDIV:
02490 case MOD: case UMOD:
02491 case AND: case IOR: case XOR:
02492 case ROTATERT: case ROTATE:
02493 case ASHIFTRT: case LSHIFTRT: case ASHIFT:
02494 case NE: case EQ:
02495 case GE: case GT: case GEU: case GTU:
02496 case LE: case LT: case LEU: case LTU:
02497 {
02498 rtx new0 = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false);
02499 rtx new1 = XEXP (x, 1)
02500 ? eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, false) : 0;
02501
02502 if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))
02503 return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1);
02504 }
02505 return x;
02506
02507 case EXPR_LIST:
02508
02509 if (XEXP (x, 0))
02510 {
02511 new = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, true);
02512 if (new != XEXP (x, 0))
02513 {
02514
02515
02516
02517 if (GET_MODE (x) == REG_DEAD)
02518 return (XEXP (x, 1)
02519 ? eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true)
02520 : NULL_RTX);
02521
02522 x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new, XEXP (x, 1));
02523 }
02524 }
02525
02526
02527
02528 case INSN_LIST:
02529
02530
02531
02532 if (XEXP (x, 1))
02533 {
02534 new = eliminate_regs_1 (XEXP (x, 1), mem_mode, insn, true);
02535 if (new != XEXP (x, 1))
02536 return
02537 gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new);
02538 }
02539 return x;
02540
02541 case PRE_INC:
02542 case POST_INC:
02543 case PRE_DEC:
02544 case POST_DEC:
02545 case STRICT_LOW_PART:
02546 case NEG: case NOT:
02547 case SIGN_EXTEND: case ZERO_EXTEND:
02548 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
02549 case FLOAT: case FIX:
02550 case UNSIGNED_FIX: case UNSIGNED_FLOAT:
02551 case ABS:
02552 case SQRT:
02553 case FFS:
02554 case CLZ:
02555 case CTZ:
02556 case POPCOUNT:
02557 case PARITY:
02558 new = eliminate_regs_1 (XEXP (x, 0), mem_mode, insn, false);
02559 if (new != XEXP (x, 0))
02560 return gen_rtx_fmt_e (code, GET_MODE (x), new);
02561 return x;
02562
02563 case SUBREG:
02564
02565
02566
02567
02568
02569
02570 if (REG_P (SUBREG_REG (x))
02571 && (GET_MODE_SIZE (GET_MODE (x))
02572 <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
02573 && reg_equiv_memory_loc != 0
02574 && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
02575 {
02576 new = SUBREG_REG (x);
02577 }
02578 else
02579 new = eliminate_regs_1 (SUBREG_REG (x), mem_mode, insn, false);
02580
02581 if (new != SUBREG_REG (x))
02582 {
02583 int x_size = GET_MODE_SIZE (GET_MODE (x));
02584 int new_size = GET_MODE_SIZE (GET_MODE (new));
02585
02586 if (MEM_P (new)
02587 && ((x_size < new_size
02588 #ifdef WORD_REGISTER_OPERATIONS
02589
02590
02591
02592
02593
02594
02595
02596 && ! ((x_size - 1) / UNITS_PER_WORD
02597 == (new_size -1 ) / UNITS_PER_WORD)
02598 #endif
02599 )
02600 || x_size == new_size)
02601 )
02602 return adjust_address_nv (new, GET_MODE (x), SUBREG_BYTE (x));
02603 else
02604 return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_BYTE (x));
02605 }
02606
02607 return x;
02608
02609 case MEM:
02610
02611
02612
02613 return
02614 replace_equiv_address_nv (x,
02615 eliminate_regs_1 (XEXP (x, 0), GET_MODE (x),
02616 insn, true));
02617
02618 case USE:
02619
02620 new = eliminate_regs_1 (XEXP (x, 0), 0, insn, false);
02621 if (new != XEXP (x, 0))
02622 return gen_rtx_USE (GET_MODE (x), new);
02623 return x;
02624
02625 case CLOBBER:
02626 case ASM_OPERANDS:
02627 case SET:
02628 gcc_unreachable ();
02629
02630 default:
02631 break;
02632 }
02633
02634
02635
02636 fmt = GET_RTX_FORMAT (code);
02637 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
02638 {
02639 if (*fmt == 'e')
02640 {
02641 new = eliminate_regs_1 (XEXP (x, i), mem_mode, insn, false);
02642 if (new != XEXP (x, i) && ! copied)
02643 {
02644 x = shallow_copy_rtx (x);
02645 copied = 1;
02646 }
02647 XEXP (x, i) = new;
02648 }
02649 else if (*fmt == 'E')
02650 {
02651 int copied_vec = 0;
02652 for (j = 0; j < XVECLEN (x, i); j++)
02653 {
02654 new = eliminate_regs_1 (XVECEXP (x, i, j), mem_mode, insn, false);
02655 if (new != XVECEXP (x, i, j) && ! copied_vec)
02656 {
02657 rtvec new_v = gen_rtvec_v (XVECLEN (x, i),
02658 XVEC (x, i)->elem);
02659 if (! copied)
02660 {
02661 x = shallow_copy_rtx (x);
02662 copied = 1;
02663 }
02664 XVEC (x, i) = new_v;
02665 copied_vec = 1;
02666 }
02667 XVECEXP (x, i, j) = new;
02668 }
02669 }
02670 }
02671
02672 return x;
02673 }
02674
02675 rtx
02676 eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
02677 {
02678 return eliminate_regs_1 (x, mem_mode, insn, false);
02679 }
02680
02681
02682
02683
02684
02685 static void
02686 elimination_effects (rtx x, enum machine_mode mem_mode)
02687 {
02688 enum rtx_code code = GET_CODE (x);
02689 struct elim_table *ep;
02690 int regno;
02691 int i, j;
02692 const char *fmt;
02693
02694 switch (code)
02695 {
02696 case CONST_INT:
02697 case CONST_DOUBLE:
02698 case CONST_VECTOR:
02699 case CONST:
02700 case SYMBOL_REF:
02701 case CODE_LABEL:
02702 case PC:
02703 case CC0:
02704 case ASM_INPUT:
02705 case ADDR_VEC:
02706 case ADDR_DIFF_VEC:
02707 case RETURN:
02708 return;
02709
02710 case REG:
02711 regno = REGNO (x);
02712
02713
02714
02715 if (regno < FIRST_PSEUDO_REGISTER)
02716 {
02717 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
02718 ep++)
02719 if (ep->from_rtx == x && ep->can_eliminate)
02720 {
02721 if (! mem_mode)
02722 ep->ref_outside_mem = 1;
02723 return;
02724 }
02725
02726 }
02727 else if (reg_renumber[regno] < 0 && reg_equiv_constant
02728 && reg_equiv_constant[regno]
02729 && ! function_invariant_p (reg_equiv_constant[regno]))
02730 elimination_effects (reg_equiv_constant[regno], mem_mode);
02731 return;
02732
02733 case PRE_INC:
02734 case POST_INC:
02735 case PRE_DEC:
02736 case POST_DEC:
02737 case POST_MODIFY:
02738 case PRE_MODIFY:
02739 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
02740 if (ep->to_rtx == XEXP (x, 0))
02741 {
02742 int size = GET_MODE_SIZE (mem_mode);
02743
02744
02745 #ifdef PUSH_ROUNDING
02746 if (ep->to_rtx == stack_pointer_rtx)
02747 size = PUSH_ROUNDING (size);
02748 #endif
02749 if (code == PRE_DEC || code == POST_DEC)
02750 ep->offset += size;
02751 else if (code == PRE_INC || code == POST_INC)
02752 ep->offset -= size;
02753 else if ((code == PRE_MODIFY || code == POST_MODIFY)
02754 && GET_CODE (XEXP (x, 1)) == PLUS
02755 && XEXP (x, 0) == XEXP (XEXP (x, 1), 0)
02756 && CONSTANT_P (XEXP (XEXP (x, 1), 1)))
02757 ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1));
02758 }
02759
02760
02761 if (code == POST_MODIFY || code == PRE_MODIFY)
02762 break;
02763
02764
02765 case STRICT_LOW_PART:
02766 case NEG: case NOT:
02767 case SIGN_EXTEND: case ZERO_EXTEND:
02768 case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE:
02769 case FLOAT: case FIX:
02770 case UNSIGNED_FIX: case UNSIGNED_FLOAT:
02771 case ABS:
02772 case SQRT:
02773 case FFS:
02774 case CLZ:
02775 case CTZ:
02776 case POPCOUNT:
02777 case PARITY:
02778 elimination_effects (XEXP (x, 0), mem_mode);
02779 return;
02780
02781 case SUBREG:
02782 if (REG_P (SUBREG_REG (x))
02783 && (GET_MODE_SIZE (GET_MODE (x))
02784 <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
02785 && reg_equiv_memory_loc != 0
02786 && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0)
02787 return;
02788
02789 elimination_effects (SUBREG_REG (x), mem_mode);
02790 return;
02791
02792 case USE:
02793
02794
02795
02796 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
02797 if (ep->from_rtx == XEXP (x, 0))
02798 ep->can_eliminate = 0;
02799
02800 elimination_effects (XEXP (x, 0), mem_mode);
02801 return;
02802
02803 case CLOBBER:
02804
02805
02806
02807 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
02808 if (ep->to_rtx == XEXP (x, 0))
02809 ep->can_eliminate = 0;
02810
02811 elimination_effects (XEXP (x, 0), mem_mode);
02812 return;
02813
02814 case SET:
02815
02816 if (REG_P (SET_DEST (x)))
02817 {
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
02830 ep++)
02831 if (ep->to_rtx == SET_DEST (x)
02832 && SET_DEST (x) != hard_frame_pointer_rtx)
02833 {
02834
02835
02836 rtx src = SET_SRC (x);
02837
02838 if (GET_CODE (src) == PLUS
02839 && XEXP (src, 0) == SET_DEST (x)
02840 && GET_CODE (XEXP (src, 1)) == CONST_INT)
02841 ep->offset -= INTVAL (XEXP (src, 1));
02842 else
02843 ep->can_eliminate = 0;
02844 }
02845 }
02846
02847 elimination_effects (SET_DEST (x), 0);
02848 elimination_effects (SET_SRC (x), 0);
02849 return;
02850
02851 case MEM:
02852
02853
02854 elimination_effects (XEXP (x, 0), GET_MODE (x));
02855 return;
02856
02857 default:
02858 break;
02859 }
02860
02861 fmt = GET_RTX_FORMAT (code);
02862 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
02863 {
02864 if (*fmt == 'e')
02865 elimination_effects (XEXP (x, i), mem_mode);
02866 else if (*fmt == 'E')
02867 for (j = 0; j < XVECLEN (x, i); j++)
02868 elimination_effects (XVECEXP (x, i, j), mem_mode);
02869 }
02870 }
02871
02872
02873
02874
02875
02876 static void
02877 check_eliminable_occurrences (rtx x)
02878 {
02879 const char *fmt;
02880 int i;
02881 enum rtx_code code;
02882
02883 if (x == 0)
02884 return;
02885
02886 code = GET_CODE (x);
02887
02888 if (code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
02889 {
02890 struct elim_table *ep;
02891
02892 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
02893 if (ep->from_rtx == x)
02894 ep->can_eliminate = 0;
02895 return;
02896 }
02897
02898 fmt = GET_RTX_FORMAT (code);
02899 for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
02900 {
02901 if (*fmt == 'e')
02902 check_eliminable_occurrences (XEXP (x, i));
02903 else if (*fmt == 'E')
02904 {
02905 int j;
02906 for (j = 0; j < XVECLEN (x, i); j++)
02907 check_eliminable_occurrences (XVECEXP (x, i, j));
02908 }
02909 }
02910 }
02911
02912
02913
02914
02915
02916
02917
02918
02919
02920
02921
02922
02923
02924
02925 static int
02926 eliminate_regs_in_insn (rtx insn, int replace)
02927 {
02928 int icode = recog_memoized (insn);
02929 rtx old_body = PATTERN (insn);
02930 int insn_is_asm = asm_noperands (old_body) >= 0;
02931 rtx old_set = single_set (insn);
02932 rtx new_body;
02933 int val = 0;
02934 int i;
02935 rtx substed_operand[MAX_RECOG_OPERANDS];
02936 rtx orig_operand[MAX_RECOG_OPERANDS];
02937 struct elim_table *ep;
02938 rtx plus_src, plus_cst_src;
02939
02940 if (! insn_is_asm && icode < 0)
02941 {
02942 gcc_assert (GET_CODE (PATTERN (insn)) == USE
02943 || GET_CODE (PATTERN (insn)) == CLOBBER
02944 || GET_CODE (PATTERN (insn)) == ADDR_VEC
02945 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
02946 || GET_CODE (PATTERN (insn)) == ASM_INPUT);
02947 return 0;
02948 }
02949
02950 if (old_set != 0 && REG_P (SET_DEST (old_set))
02951 && REGNO (SET_DEST (old_set)) < FIRST_PSEUDO_REGISTER)
02952 {
02953
02954 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
02955 if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate)
02956 {
02957 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
02958
02959
02960
02961
02962
02963 if (ep->from == FRAME_POINTER_REGNUM
02964 && ep->to == HARD_FRAME_POINTER_REGNUM)
02965 {
02966 rtx base = SET_SRC (old_set);
02967 rtx base_insn = insn;
02968 HOST_WIDE_INT offset = 0;
02969
02970 while (base != ep->to_rtx)
02971 {
02972 rtx prev_insn, prev_set;
02973
02974 if (GET_CODE (base) == PLUS
02975 && GET_CODE (XEXP (base, 1)) == CONST_INT)
02976 {
02977 offset += INTVAL (XEXP (base, 1));
02978 base = XEXP (base, 0);
02979 }
02980 else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0
02981 && (prev_set = single_set (prev_insn)) != 0
02982 && rtx_equal_p (SET_DEST (prev_set), base))
02983 {
02984 base = SET_SRC (prev_set);
02985 base_insn = prev_insn;
02986 }
02987 else
02988 break;
02989 }
02990
02991 if (base == ep->to_rtx)
02992 {
02993 rtx src
02994 = plus_constant (ep->to_rtx, offset - ep->offset);
02995
02996 new_body = old_body;
02997 if (! replace)
02998 {
02999 new_body = copy_insn (old_body);
03000 if (REG_NOTES (insn))
03001 REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
03002 }
03003 PATTERN (insn) = new_body;
03004 old_set = single_set (insn);
03005
03006
03007
03008
03009 validate_change (insn, &SET_SRC (old_set), src, 1);
03010 validate_change (insn, &SET_DEST (old_set),
03011 ep->to_rtx, 1);
03012 if (! apply_change_group ())
03013 {
03014 SET_SRC (old_set) = src;
03015 SET_DEST (old_set) = ep->to_rtx;
03016 }
03017
03018 val = 1;
03019 goto done;
03020 }
03021 }
03022 #endif
03023
03024
03025
03026
03027
03028
03029
03030 if (replace)
03031 {
03032 delete_dead_insn (insn);
03033 return 1;
03034 }
03035 val = 1;
03036 goto done;
03037 }
03038 }
03039
03040
03041
03042
03043 plus_src = plus_cst_src = 0;
03044 if (old_set && REG_P (SET_DEST (old_set)))
03045 {
03046 if (GET_CODE (SET_SRC (old_set)) == PLUS)
03047 plus_src = SET_SRC (old_set);
03048
03049 if (plus_src
03050 && GET_CODE (XEXP (plus_src, 1)) == CONST_INT)
03051 plus_cst_src = plus_src;
03052 else if (REG_P (SET_SRC (old_set))
03053 || plus_src)
03054 {
03055
03056
03057 rtx links;
03058 for (links = REG_NOTES (insn); links; links = XEXP (links, 1))
03059 {
03060 if (REG_NOTE_KIND (links) == REG_EQUAL
03061 && GET_CODE (XEXP (links, 0)) == PLUS
03062 && GET_CODE (XEXP (XEXP (links, 0), 1)) == CONST_INT)
03063 {
03064 plus_cst_src = XEXP (links, 0);
03065 break;
03066 }
03067 }
03068 }
03069
03070
03071
03072 if (plus_cst_src)
03073 {
03074 rtx reg = XEXP (plus_cst_src, 0);
03075 if (GET_CODE (reg) == SUBREG && subreg_lowpart_p (reg))
03076 reg = SUBREG_REG (reg);
03077
03078 if (!REG_P (reg) || REGNO (reg) >= FIRST_PSEUDO_REGISTER)
03079 plus_cst_src = 0;
03080 }
03081 }
03082 if (plus_cst_src)
03083 {
03084 rtx reg = XEXP (plus_cst_src, 0);
03085 HOST_WIDE_INT offset = INTVAL (XEXP (plus_cst_src, 1));
03086
03087 if (GET_CODE (reg) == SUBREG)
03088 reg = SUBREG_REG (reg);
03089
03090 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03091 if (ep->from_rtx == reg && ep->can_eliminate)
03092 {
03093 rtx to_rtx = ep->to_rtx;
03094 offset += ep->offset;
03095 offset = trunc_int_for_mode (offset, GET_MODE (reg));
03096
03097 if (GET_CODE (XEXP (plus_cst_src, 0)) == SUBREG)
03098 to_rtx = gen_lowpart (GET_MODE (XEXP (plus_cst_src, 0)),
03099 to_rtx);
03100
03101
03102
03103
03104
03105 if (offset == 0 || plus_src)
03106 {
03107 rtx new_src = plus_constant (to_rtx, offset);
03108
03109 new_body = old_body;
03110 if (! replace)
03111 {
03112 new_body = copy_insn (old_body);
03113 if (REG_NOTES (insn))
03114 REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
03115 }
03116 PATTERN (insn) = new_body;
03117 old_set = single_set (insn);
03118
03119
03120
03121
03122
03123
03124
03125 if (!validate_change (insn, &SET_SRC (old_set), new_src, 0))
03126 {
03127 rtx new_pat = gen_rtx_SET (VOIDmode,
03128 SET_DEST (old_set), new_src);
03129
03130 if (!validate_change (insn, &PATTERN (insn), new_pat, 0))
03131 SET_SRC (old_set) = new_src;
03132 }
03133 }
03134 else
03135 break;
03136
03137 val = 1;
03138
03139
03140 goto done;
03141 }
03142 }
03143
03144
03145 elimination_effects (old_body, 0);
03146
03147
03148
03149 extract_insn (insn);
03150 for (i = 0; i < recog_data.n_operands; i++)
03151 {
03152 orig_operand[i] = recog_data.operand[i];
03153 substed_operand[i] = recog_data.operand[i];
03154
03155
03156 if (insn_is_asm || insn_data[icode].operand[i].eliminable)
03157 {
03158 bool is_set_src, in_plus;
03159
03160
03161 if (recog_data.operand_type[i] != OP_IN
03162 && REG_P (orig_operand[i]))
03163 {
03164
03165
03166
03167
03168 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS];
03169 ep++)
03170 if (ep->from_rtx == orig_operand[i])
03171 ep->can_eliminate = 0;
03172 }
03173
03174
03175
03176 is_set_src = false;
03177 if (old_set && recog_data.operand_loc[i] == &SET_SRC (old_set))
03178 is_set_src = true;
03179 in_plus = false;
03180 if (plus_src
03181 && (recog_data.operand_loc[i] == &XEXP (plus_src, 0)
03182 || recog_data.operand_loc[i] == &XEXP (plus_src, 1)))
03183 in_plus = true;
03184
03185 substed_operand[i]
03186 = eliminate_regs_1 (recog_data.operand[i], 0,
03187 replace ? insn : NULL_RTX,
03188 is_set_src || in_plus);
03189 if (substed_operand[i] != orig_operand[i])
03190 val = 1;
03191
03192
03193 *recog_data.operand_loc[i] = 0;
03194
03195
03196
03197 if (recog_data.operand_type[i] != OP_IN
03198 && REG_P (orig_operand[i])
03199 && MEM_P (substed_operand[i])
03200 && replace)
03201 emit_insn_after (gen_rtx_CLOBBER (VOIDmode, orig_operand[i]),
03202 insn);
03203 }
03204 }
03205
03206 for (i = 0; i < recog_data.n_dups; i++)
03207 *recog_data.dup_loc[i]
03208 = *recog_data.operand_loc[(int) recog_data.dup_num[i]];
03209
03210
03211 check_eliminable_occurrences (old_body);
03212
03213
03214
03215 for (i = 0; i < recog_data.n_operands; i++)
03216 *recog_data.operand_loc[i] = substed_operand[i];
03217 for (i = 0; i < recog_data.n_dups; i++)
03218 *recog_data.dup_loc[i] = substed_operand[(int) recog_data.dup_num[i]];
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228
03229 if (val)
03230 {
03231
03232
03233
03234
03235 new_body = old_body;
03236 if (! replace)
03237 {
03238 new_body = copy_insn (old_body);
03239 if (REG_NOTES (insn))
03240 REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn));
03241 }
03242 PATTERN (insn) = new_body;
03243
03244
03245
03246
03247
03248
03249
03250
03251 if (! insn_is_asm
03252 && old_set != 0
03253 && ((REG_P (SET_SRC (old_set))
03254 && (GET_CODE (new_body) != SET
03255 || !REG_P (SET_SRC (new_body))))
03256
03257
03258
03259 || (old_set != 0
03260 && ((MEM_P (SET_SRC (old_set))
03261 && SET_SRC (old_set) != recog_data.operand[1])
03262 || (MEM_P (SET_DEST (old_set))
03263 && SET_DEST (old_set) != recog_data.operand[0])))
03264
03265 || GET_CODE (SET_SRC (old_set)) == PLUS))
03266 {
03267 int new_icode = recog (PATTERN (insn), insn, 0);
03268 if (new_icode >= 0)
03269 INSN_CODE (insn) = new_icode;
03270 }
03271 }
03272
03273
03274
03275
03276 if (! replace)
03277 {
03278
03279 for (i = 0; i < recog_data.n_operands; i++)
03280 *recog_data.operand_loc[i] = orig_operand[i];
03281 for (i = 0; i < recog_data.n_dups; i++)
03282 *recog_data.dup_loc[i] = orig_operand[(int) recog_data.dup_num[i]];
03283 }
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03299 {
03300 if (ep->previous_offset != ep->offset && ep->ref_outside_mem)
03301 ep->can_eliminate = 0;
03302
03303 ep->ref_outside_mem = 0;
03304
03305 if (ep->previous_offset != ep->offset)
03306 val = 1;
03307 }
03308
03309 done:
03310
03311
03312
03313
03314
03315 if (val && REG_NOTES (insn) != 0)
03316 REG_NOTES (insn)
03317 = eliminate_regs_1 (REG_NOTES (insn), 0, REG_NOTES (insn), true);
03318
03319 return val;
03320 }
03321
03322
03323
03324
03325
03326
03327
03328 static void
03329 update_eliminable_offsets (void)
03330 {
03331 struct elim_table *ep;
03332
03333 num_not_at_initial_offset = 0;
03334 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03335 {
03336 ep->previous_offset = ep->offset;
03337 if (ep->can_eliminate && ep->offset != ep->initial_offset)
03338 num_not_at_initial_offset++;
03339 }
03340 }
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356 static void
03357 mark_not_eliminable (rtx dest, rtx x, void *data ATTRIBUTE_UNUSED)
03358 {
03359 unsigned int i;
03360
03361
03362
03363
03364 if (GET_CODE (dest) == SUBREG)
03365 dest = SUBREG_REG (dest);
03366
03367 if (dest == hard_frame_pointer_rtx)
03368 return;
03369
03370 for (i = 0; i < NUM_ELIMINABLE_REGS; i++)
03371 if (reg_eliminate[i].can_eliminate && dest == reg_eliminate[i].to_rtx
03372 && (GET_CODE (x) != SET
03373 || GET_CODE (SET_SRC (x)) != PLUS
03374 || XEXP (SET_SRC (x), 0) != dest
03375 || GET_CODE (XEXP (SET_SRC (x), 1)) != CONST_INT))
03376 {
03377 reg_eliminate[i].can_eliminate_previous
03378 = reg_eliminate[i].can_eliminate = 0;
03379 num_eliminable--;
03380 }
03381 }
03382
03383
03384
03385
03386
03387
03388 static bool
03389 verify_initial_elim_offsets (void)
03390 {
03391 HOST_WIDE_INT t;
03392
03393 if (!num_eliminable)
03394 return true;
03395
03396 #ifdef ELIMINABLE_REGS
03397 {
03398 struct elim_table *ep;
03399
03400 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03401 {
03402 INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t);
03403 if (t != ep->initial_offset)
03404 return false;
03405 }
03406 }
03407 #else
03408 INITIAL_FRAME_POINTER_OFFSET (t);
03409 if (t != reg_eliminate[0].initial_offset)
03410 return false;
03411 #endif
03412
03413 return true;
03414 }
03415
03416
03417
03418 static void
03419 set_initial_elim_offsets (void)
03420 {
03421 struct elim_table *ep = reg_eliminate;
03422
03423 #ifdef ELIMINABLE_REGS
03424 for (; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03425 {
03426 INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset);
03427 ep->previous_offset = ep->offset = ep->initial_offset;
03428 }
03429 #else
03430 INITIAL_FRAME_POINTER_OFFSET (ep->initial_offset);
03431 ep->previous_offset = ep->offset = ep->initial_offset;
03432 #endif
03433
03434 num_not_at_initial_offset = 0;
03435 }
03436
03437
03438
03439 static void
03440 set_initial_eh_label_offset (rtx label)
03441 {
03442 set_label_offsets (label, NULL_RTX, 1);
03443 }
03444
03445
03446
03447
03448
03449
03450
03451
03452 static void
03453 set_initial_label_offsets (void)
03454 {
03455 rtx x;
03456 memset (offsets_known_at, 0, num_labels);
03457
03458 for (x = forced_labels; x; x = XEXP (x, 1))
03459 if (XEXP (x, 0))
03460 set_label_offsets (XEXP (x, 0), NULL_RTX, 1);
03461
03462 for_each_eh_label (set_initial_eh_label_offset);
03463 }
03464
03465
03466
03467
03468 static void
03469 set_offsets_for_label (rtx insn)
03470 {
03471 unsigned int i;
03472 int label_nr = CODE_LABEL_NUMBER (insn);
03473 struct elim_table *ep;
03474
03475 num_not_at_initial_offset = 0;
03476 for (i = 0, ep = reg_eliminate; i < NUM_ELIMINABLE_REGS; ep++, i++)
03477 {
03478 ep->offset = ep->previous_offset
03479 = offsets_at[label_nr - first_label_num][i];
03480 if (ep->can_eliminate && ep->offset != ep->initial_offset)
03481 num_not_at_initial_offset++;
03482 }
03483 }
03484
03485
03486
03487
03488
03489
03490
03491 static void
03492 update_eliminables (HARD_REG_SET *pset)
03493 {
03494 int previous_frame_pointer_needed = frame_pointer_needed;
03495 struct elim_table *ep;
03496
03497 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03498 if ((ep->from == HARD_FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED)
03499 #ifdef ELIMINABLE_REGS
03500 || ! CAN_ELIMINATE (ep->from, ep->to)
03501 #endif
03502 )
03503 ep->can_eliminate = 0;
03504
03505
03506
03507
03508
03509
03510
03511
03512 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03513 {
03514 struct elim_table *op;
03515 int new_to = -1;
03516
03517 if (! ep->can_eliminate && ep->can_eliminate_previous)
03518 {
03519
03520
03521 for (op = reg_eliminate;
03522 op < ®_eliminate[NUM_ELIMINABLE_REGS]; op++)
03523 if (op->from == ep->from && op->can_eliminate)
03524 {
03525 new_to = op->to;
03526 break;
03527 }
03528
03529
03530
03531 for (op = reg_eliminate;
03532 op < ®_eliminate[NUM_ELIMINABLE_REGS]; op++)
03533 if (op->from == new_to && op->to == ep->to)
03534 op->can_eliminate = 0;
03535 }
03536 }
03537
03538
03539
03540
03541
03542
03543
03544 frame_pointer_needed = 1;
03545 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03546 {
03547 if (ep->can_eliminate && ep->from == FRAME_POINTER_REGNUM
03548 && ep->to != HARD_FRAME_POINTER_REGNUM)
03549 frame_pointer_needed = 0;
03550
03551 if (! ep->can_eliminate && ep->can_eliminate_previous)
03552 {
03553 ep->can_eliminate_previous = 0;
03554 SET_HARD_REG_BIT (*pset, ep->from);
03555 num_eliminable--;
03556 }
03557 }
03558
03559
03560
03561 if (frame_pointer_needed && ! previous_frame_pointer_needed)
03562 SET_HARD_REG_BIT (*pset, HARD_FRAME_POINTER_REGNUM);
03563 }
03564
03565
03566
03567 static void
03568 init_elim_table (void)
03569 {
03570 struct elim_table *ep;
03571 #ifdef ELIMINABLE_REGS
03572 const struct elim_table_1 *ep1;
03573 #endif
03574
03575 if (!reg_eliminate)
03576 reg_eliminate = xcalloc (sizeof (struct elim_table), NUM_ELIMINABLE_REGS);
03577
03578
03579
03580 frame_pointer_needed = (! flag_omit_frame_pointer
03581
03582
03583
03584
03585
03586 || (current_function_calls_alloca
03587 && EXIT_IGNORE_STACK)
03588 || current_function_accesses_prior_frames
03589 || FRAME_POINTER_REQUIRED);
03590
03591 num_eliminable = 0;
03592
03593 #ifdef ELIMINABLE_REGS
03594 for (ep = reg_eliminate, ep1 = reg_eliminate_1;
03595 ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++)
03596 {
03597 ep->from = ep1->from;
03598 ep->to = ep1->to;
03599 ep->can_eliminate = ep->can_eliminate_previous
03600 = (CAN_ELIMINATE (ep->from, ep->to)
03601 && ! (ep->to == STACK_POINTER_REGNUM && frame_pointer_needed));
03602 }
03603 #else
03604 reg_eliminate[0].from = reg_eliminate_1[0].from;
03605 reg_eliminate[0].to = reg_eliminate_1[0].to;
03606 reg_eliminate[0].can_eliminate = reg_eliminate[0].can_eliminate_previous
03607 = ! frame_pointer_needed;
03608 #endif
03609
03610
03611
03612
03613
03614 for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++)
03615 {
03616 num_eliminable += ep->can_eliminate;
03617 ep->from_rtx = gen_rtx_REG (Pmode, ep->from);
03618 ep->to_rtx = gen_rtx_REG (Pmode, ep->to);
03619 }
03620 }
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632 static void
03633 spill_hard_reg (unsigned int regno, int cant_eliminate)
03634 {
03635 int i;
03636
03637 if (cant_eliminate)
03638 {
03639 SET_HARD_REG_BIT (bad_spill_regs_global, regno);
03640 regs_ever_live[regno] = 1;
03641 }
03642
03643
03644
03645
03646 for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
03647 if (reg_renumber[i] >= 0
03648 && (unsigned int) reg_renumber[i] <= regno
03649 && ((unsigned int) reg_renumber[i]
03650 + hard_regno_nregs[(unsigned int) reg_renumber[i]]
03651 [PSEUDO_REGNO_MODE (i)]
03652 > regno))
03653 SET_REGNO_REG_SET (&spilled_pseudos, i);
03654 }
03655
03656
03657
03658
03659
03660
03661 static int
03662 finish_spills (int global)
03663 {
03664 struct insn_chain *chain;
03665 int something_changed = 0;
03666 unsigned i;
03667 reg_set_iterator rsi;
03668
03669
03670
03671
03672
03673
03674
03675
03676
03677
03678
03679
03680
03681 n_spills = 0;
03682 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
03683 if (TEST_HARD_REG_BIT (used_spill_regs, i))
03684 {
03685 spill_reg_order[i] = n_spills;
03686 spill_regs[n_spills++] = i;
03687 if (num_eliminable && ! regs_ever_live[i])
03688 something_changed = 1;
03689 regs_ever_live[i] = 1;
03690 }
03691 else
03692 spill_reg_order[i] = -1;
03693
03694 EXECUTE_IF_SET_IN_REG_SET (&spilled_pseudos, FIRST_PSEUDO_REGISTER, i, rsi)
03695 {
03696
03697
03698
03699 gcc_assert (reg_renumber[i] >= 0);
03700
03701 SET_HARD_REG_BIT (pseudo_previous_regs[i], reg_renumber[i]);
03702
03703 reg_renumber[i] = -1;
03704
03705 something_changed = 1;
03706 }
03707
03708
03709 if (global)
03710 {
03711 memset (pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET));
03712
03713
03714
03715 for (chain = insns_need_reload; chain; chain = chain->next_need_reload)
03716 {
03717 EXECUTE_IF_SET_IN_REG_SET
03718 (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, rsi)
03719 {
03720 IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
03721 chain->used_spill_regs);
03722 }
03723 EXECUTE_IF_SET_IN_REG_SET
03724 (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, rsi)
03725 {
03726 IOR_HARD_REG_SET (pseudo_forbidden_regs[i],
03727 chain->used_spill_regs);
03728 }
03729 }
03730
03731
03732
03733
03734
03735
03736 for (i = FIRST_PSEUDO_REGISTER; i < (unsigned)max_regno; i++)
03737 if (reg_old_renumber[i] != reg_renumber[i])
03738 {
03739 HARD_REG_SET forbidden;
03740 COPY_HARD_REG_SET (forbidden, bad_spill_regs_global);
03741 IOR_HARD_REG_SET (forbidden, pseudo_forbidden_regs[i]);
03742 IOR_HARD_REG_SET (forbidden, pseudo_previous_regs[i]);
03743 retry_global_alloc (i, forbidden);
03744 if (reg_renumber[i] >= 0)
03745 CLEAR_REGNO_REG_SET (&spilled_pseudos, i);
03746 }
03747 }
03748
03749
03750
03751
03752 for (chain = reload_insn_chain; chain; chain = chain->next)
03753 {
03754 HARD_REG_SET used_by_pseudos;
03755 HARD_REG_SET used_by_pseudos2;
03756
03757 AND_COMPL_REG_SET (&chain->live_throughout, &spilled_pseudos);
03758 AND_COMPL_REG_SET (&chain->dead_or_set, &spilled_pseudos);
03759
03760
03761
03762 if (chain->need_reload)
03763 {
03764 REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout);
03765 REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set);
03766 IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2);
03767
03768
03769 COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs);
03770
03771 compute_use_by_pseudos (&used_by_pseudos, &chain->live_throughout);
03772 compute_use_by_pseudos (&used_by_pseudos, &chain->dead_or_set);
03773 COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos);
03774 AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs);
03775
03776
03777 GO_IF_HARD_REG_SUBSET (used_by_pseudos2, chain->used_spill_regs, ok);
03778 gcc_unreachable ();
03779 ok:;
03780 }
03781 }
03782
03783
03784 for (i = FIRST_PSEUDO_REGISTER; i < (unsigned)max_regno; i++)
03785 {
03786 int regno = reg_renumber[i];
03787 if (reg_old_renumber[i] == regno)
03788 continue;
03789
03790 alter_reg (i, reg_old_renumber[i]);
03791 reg_old_renumber[i] = regno;
03792 if (dump_file)
03793 {
03794 if (regno == -1)
03795 fprintf (dump_file, " Register %d now on stack.\n\n", i);
03796 else
03797 fprintf (dump_file, " Register %d now in %d.\n\n",
03798 i, reg_renumber[i]);
03799 }
03800 }
03801
03802 return something_changed;
03803 }
03804
03805
03806
03807 static void
03808 scan_paradoxical_subregs (rtx x)
03809 {
03810 int i;
03811 const char *fmt;
03812 enum rtx_code code = GET_CODE (x);
03813
03814 switch (code)
03815 {
03816 case REG:
03817 case CONST_INT:
03818 case CONST:
03819 case SYMBOL_REF:
03820 case LABEL_REF:
03821 case CONST_DOUBLE:
03822 case CONST_VECTOR:
03823 case CC0:
03824 case PC:
03825 case USE:
03826 case CLOBBER:
03827 return;
03828
03829 case SUBREG:
03830 if (REG_P (SUBREG_REG (x))
03831 && (GET_MODE_SIZE (GET_MODE (x))
03832 > reg_max_ref_width[REGNO (SUBREG_REG (x))]))
03833 reg_max_ref_width[REGNO (SUBREG_REG (x))]
03834 = GET_MODE_SIZE (GET_MODE (x));
03835 return;
03836
03837 default:
03838 break;
03839 }
03840
03841 fmt = GET_RTX_FORMAT (code);
03842 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
03843 {
03844 if (fmt[i] == 'e')
03845 scan_paradoxical_subregs (XEXP (x, i));
03846 else if (fmt[i] == 'E')
03847 {
03848 int j;
03849 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
03850 scan_paradoxical_subregs (XVECEXP (x, i, j));
03851 }
03852 }
03853 }
03854
03855
03856
03857
03858
03859 static void
03860 fixup_eh_region_note (rtx insn, rtx prev, rtx next)
03861 {
03862 rtx note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
03863 unsigned int trap_count;
03864 rtx i;
03865
03866 if (note == NULL)
03867 return;
03868
03869 if (may_trap_p (PATTERN (insn)))
03870 trap_count = 1;
03871 else
03872 {
03873 remove_note (insn, note);
03874 trap_count = 0;
03875 }
03876
03877 for (i = NEXT_INSN (prev); i != next; i = NEXT_INSN (i))
03878 if (INSN_P (i) && i != insn && may_trap_p (PATTERN (i)))
03879 {
03880 trap_count++;
03881 REG_NOTES (i)
03882 = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (note, 0), REG_NOTES (i));
03883 }
03884 }
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895 static void
03896 reload_as_needed (int live_known)
03897 {
03898 struct insn_chain *chain;
03899 #if defined (AUTO_INC_DEC)
03900 int i;
03901 #endif
03902 rtx x;
03903
03904 memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
03905 memset (spill_reg_store, 0, sizeof spill_reg_store);
03906 reg_last_reload_reg = XCNEWVEC (rtx, max_regno);
03907 INIT_REG_SET (®_has_output_reload);
03908 CLEAR_HARD_REG_SET (reg_reloaded_valid);
03909 CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
03910
03911 set_initial_elim_offsets ();
03912
03913 for (chain = reload_insn_chain; chain; chain = chain->next)
03914 {
03915 rtx prev = 0;
03916 rtx insn = chain->insn;
03917 rtx old_next = NEXT_INSN (insn);
03918
03919
03920
03921 if (LABEL_P (insn))
03922 set_offsets_for_label (insn);
03923
03924 else if (INSN_P (insn))
03925 {
03926 regset_head regs_to_forget;
03927 INIT_REG_SET (®s_to_forget);
03928 note_stores (PATTERN (insn), forget_old_reloads_1, ®s_to_forget);
03929
03930
03931
03932
03933 if ((GET_CODE (PATTERN (insn)) == USE
03934 || GET_CODE (PATTERN (insn)) == CLOBBER)
03935 && MEM_P (XEXP (PATTERN (insn), 0)))
03936 XEXP (XEXP (PATTERN (insn), 0), 0)
03937 = eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0),
03938 GET_MODE (XEXP (PATTERN (insn), 0)),
03939 NULL_RTX);
03940
03941
03942
03943 if ((num_eliminable || num_eliminable_invariants) && chain->need_elim)
03944 {
03945 eliminate_regs_in_insn (insn, 1);
03946 if (NOTE_P (insn))
03947 {
03948 update_eliminable_offsets ();
03949 CLEAR_REG_SET (®s_to_forget);
03950 continue;
03951 }
03952 }
03953
03954
03955
03956
03957
03958
03959
03960
03961 if (! chain->need_elim && ! chain->need_reload
03962 && ! chain->need_operand_change)
03963 n_reloads = 0;
03964
03965
03966
03967
03968 else
03969 {
03970 CLEAR_REG_SET (®_has_output_reload);
03971 CLEAR_HARD_REG_SET (reg_is_output_reload);
03972
03973 find_reloads (insn, 1, spill_indirect_levels, live_known,
03974 spill_reg_order);
03975 }
03976
03977 if (n_reloads > 0)
03978 {
03979 rtx next = NEXT_INSN (insn);
03980 rtx p;
03981
03982 prev = PREV_INSN (insn);
03983
03984
03985
03986
03987
03988 choose_reload_regs (chain);
03989
03990
03991
03992
03993 if (SMALL_REGISTER_CLASSES)
03994 merge_assigned_reloads (insn);
03995
03996
03997
03998 emit_reload_insns (chain);
03999
04000
04001
04002
04003
04004 subst_reloads (insn);
04005
04006
04007 if (flag_non_call_exceptions && !CALL_P (insn))
04008 fixup_eh_region_note (insn, prev, next);
04009
04010
04011
04012
04013 if (asm_noperands (PATTERN (insn)) >= 0)
04014 for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p))
04015 if (p != insn && INSN_P (p)
04016 && GET_CODE (PATTERN (p)) != USE
04017 && (recog_memoized (p) < 0
04018 || (extract_insn (p), ! constrain_operands (1))))
04019 {
04020 error_for_asm (insn,
04021 "%<asm%> operand requires "
04022 "impossible reload");
04023 delete_insn (p);
04024 }
04025 }
04026
04027 if (num_eliminable && chain->need_elim)
04028 update_eliminable_offsets ();
04029
04030
04031
04032
04033
04034
04035
04036 forget_marked_reloads (®s_to_forget);
04037 CLEAR_REG_SET (®s_to_forget);
04038
04039
04040
04041 for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
04042 if (NONJUMP_INSN_P (x) && GET_CODE (PATTERN (x)) == CLOBBER)
04043 note_stores (PATTERN (x), forget_old_reloads_1, NULL);
04044
04045 #ifdef AUTO_INC_DEC
04046
04047
04048
04049
04050 for (i = n_reloads - 1; i >= 0; i--)
04051 {
04052 rtx in_reg = rld[i].in_reg;
04053 if (in_reg)
04054 {
04055 enum rtx_code code = GET_CODE (in_reg);
04056
04057
04058
04059
04060
04061 if ((code == POST_INC || code == POST_DEC)
04062 && TEST_HARD_REG_BIT (reg_reloaded_valid,
04063 REGNO (rld[i].reg_rtx))
04064
04065
04066 && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
04067 == REGNO (XEXP (in_reg, 0))))
04068
04069 {
04070 rtx reload_reg = rld[i].reg_rtx;
04071 enum machine_mode mode = GET_MODE (reload_reg);
04072 int n = 0;
04073 rtx p;
04074
04075 for (p = PREV_INSN (old_next); p != prev; p = PREV_INSN (p))
04076 {
04077
04078
04079 if (reg_set_p (reload_reg, PATTERN (p)))
04080 break;
04081 n = count_occurrences (PATTERN (p), reload_reg, 0);
04082 if (! n)
04083 continue;
04084 if (n == 1)
04085 {
04086 n = validate_replace_rtx (reload_reg,
04087 gen_rtx_fmt_e (code,
04088 mode,
04089 reload_reg),
04090 p);
04091
04092
04093
04094 extract_insn (p);
04095 if (n)
04096 n = constrain_operands (1);
04097 else
04098 break;
04099
04100
04101
04102 if (!n)
04103 {
04104 validate_replace_rtx (gen_rtx_fmt_e (code,
04105 mode,
04106 reload_reg),
04107 reload_reg, p);
04108 break;
04109 }
04110
04111 }
04112 break;
04113 }
04114 if (n == 1)
04115 {
04116 REG_NOTES (p)
04117 = gen_rtx_EXPR_LIST (REG_INC, reload_reg,
04118 REG_NOTES (p));
04119
04120
04121
04122 SET_HARD_REG_BIT (reg_is_output_reload,
04123 REGNO (reload_reg));
04124 SET_REGNO_REG_SET (®_has_output_reload,
04125 REGNO (XEXP (in_reg, 0)));
04126 }
04127 else
04128 forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX,
04129 NULL);
04130 }
04131 else if ((code == PRE_INC || code == PRE_DEC)
04132 && TEST_HARD_REG_BIT (reg_reloaded_valid,
04133 REGNO (rld[i].reg_rtx))
04134
04135
04136 && ((unsigned) reg_reloaded_contents[REGNO (rld[i].reg_rtx)]
04137 == REGNO (XEXP (in_reg, 0))))
04138 {
04139 SET_HARD_REG_BIT (reg_is_output_reload,
04140 REGNO (rld[i].reg_rtx));
04141 SET_REGNO_REG_SET (®_has_output_reload,
04142 REGNO (XEXP (in_reg, 0)));
04143 }
04144 }
04145 }
04146
04147
04148
04149 for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
04150 if (REG_NOTE_KIND (x) == REG_INC)
04151 {
04152
04153
04154
04155 for (i = 0; i < n_reloads; i++)
04156 if (rld[i].out == XEXP (x, 0))
04157 break;
04158
04159 if (i == n_reloads)
04160 forget_old_reloads_1 (XEXP (x, 0), NULL_RTX, NULL);
04161 }
04162 #endif
04163 }
04164
04165 if (LABEL_P (insn))
04166 CLEAR_HARD_REG_SET (reg_reloaded_valid);
04167
04168
04169
04170
04171 else if (CALL_P (insn))
04172 {
04173 AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set);
04174 AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered);
04175 }
04176 }
04177
04178
04179 free (reg_last_reload_reg);
04180 CLEAR_REG_SET (®_has_output_reload);
04181 }
04182
04183
04184
04185
04186
04187
04188
04189
04190
04191
04192
04193 static void
04194 forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
04195 void *data)
04196 {
04197 unsigned int regno;
04198 unsigned int nr;
04199 regset regs = (regset) data;
04200
04201
04202
04203 while (GET_CODE (x) == SUBREG)
04204 {
04205
04206
04207
04208 x = SUBREG_REG (x);
04209 }
04210
04211 if (!REG_P (x))
04212 return;
04213
04214 regno = REGNO (x);
04215
04216 if (regno >= FIRST_PSEUDO_REGISTER)
04217 nr = 1;
04218 else
04219 {
04220 unsigned int i;
04221
04222 nr = hard_regno_nregs[regno][GET_MODE (x)];
04223
04224
04225
04226
04227 if (!regs)
04228 for (i = 0; i < nr; i++)
04229
04230
04231 if (n_reloads == 0
04232 || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
04233 {
04234 CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
04235 CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i);
04236 spill_reg_store[regno + i] = 0;
04237 }
04238 }
04239
04240 if (regs)
04241 while (nr-- > 0)
04242 SET_REGNO_REG_SET (regs, regno + nr);
04243 else
04244 {
04245
04246
04247
04248 while (nr-- > 0)
04249
04250
04251 if (n_reloads == 0
04252 || !REGNO_REG_SET_P (®_has_output_reload, regno + nr))
04253 reg_last_reload_reg[regno + nr] = 0;
04254 }
04255 }
04256
04257
04258 static void
04259 forget_marked_reloads (regset regs)
04260 {
04261 unsigned int reg;
04262 reg_set_iterator rsi;
04263 EXECUTE_IF_SET_IN_REG_SET (regs, 0, reg, rsi)
04264 {
04265 if (reg < FIRST_PSEUDO_REGISTER
04266
04267
04268 && (n_reloads == 0
04269 || ! TEST_HARD_REG_BIT (reg_is_output_reload, reg)))
04270 {
04271 CLEAR_HARD_REG_BIT (reg_reloaded_valid, reg);
04272 CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, reg);
04273 spill_reg_store[reg] = 0;
04274 }
04275 if (n_reloads == 0
04276 || !REGNO_REG_SET_P (®_has_output_reload, reg))
04277 reg_last_reload_reg[reg] = 0;
04278 }
04279 }
04280
04281
04282
04283
04284
04285 static HARD_REG_SET reload_reg_unavailable;
04286
04287 static HARD_REG_SET reload_reg_used;
04288
04289 static HARD_REG_SET reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS];
04290
04291 static HARD_REG_SET reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS];
04292
04293 static HARD_REG_SET reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS];
04294
04295 static HARD_REG_SET reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS];
04296
04297 static HARD_REG_SET reload_reg_used_in_input[MAX_RECOG_OPERANDS];
04298
04299 static HARD_REG_SET reload_reg_used_in_output[MAX_RECOG_OPERANDS];
04300
04301 static HARD_REG_SET reload_reg_used_in_op_addr;
04302
04303 static HARD_REG_SET reload_reg_used_in_op_addr_reload;
04304
04305 static HARD_REG_SET reload_reg_used_in_insn;
04306
04307 static HARD_REG_SET reload_reg_used_in_other_addr;
04308
04309
04310 static HARD_REG_SET reload_reg_used_at_all;
04311
04312
04313
04314 static HARD_REG_SET reload_reg_used_for_inherit;
04315
04316
04317
04318 static HARD_REG_SET reg_used_in_insn;
04319
04320
04321
04322
04323
04324 static void
04325 mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
04326 enum machine_mode mode)
04327 {
04328 unsigned int nregs = hard_regno_nregs[regno][mode];
04329 unsigned int i;
04330
04331 for (i = regno; i < nregs + regno; i++)
04332 {
04333 switch (type)
04334 {
04335 case RELOAD_OTHER:
04336 SET_HARD_REG_BIT (reload_reg_used, i);
04337 break;
04338
04339 case RELOAD_FOR_INPUT_ADDRESS:
04340 SET_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i);
04341 break;
04342
04343 case RELOAD_FOR_INPADDR_ADDRESS:
04344 SET_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i);
04345 break;
04346
04347 case RELOAD_FOR_OUTPUT_ADDRESS:
04348 SET_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i);
04349 break;
04350
04351 case RELOAD_FOR_OUTADDR_ADDRESS:
04352 SET_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i);
04353 break;
04354
04355 case RELOAD_FOR_OPERAND_ADDRESS:
04356 SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i);
04357 break;
04358
04359 case RELOAD_FOR_OPADDR_ADDR:
04360 SET_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, i);
04361 break;
04362
04363 case RELOAD_FOR_OTHER_ADDRESS:
04364 SET_HARD_REG_BIT (reload_reg_used_in_other_addr, i);
04365 break;
04366
04367 case RELOAD_FOR_INPUT:
04368 SET_HARD_REG_BIT (reload_reg_used_in_input[opnum], i);
04369 break;
04370
04371 case RELOAD_FOR_OUTPUT:
04372 SET_HARD_REG_BIT (reload_reg_used_in_output[opnum], i);
04373 break;
04374
04375 case RELOAD_FOR_INSN:
04376 SET_HARD_REG_BIT (reload_reg_used_in_insn, i);
04377 break;
04378 }
04379
04380 SET_HARD_REG_BIT (reload_reg_used_at_all, i);
04381 }
04382 }
04383
04384
04385
04386 static void
04387 clear_reload_reg_in_use (unsigned int regno, int opnum,
04388 enum reload_type type, enum machine_mode mode)
04389 {
04390 unsigned int nregs = hard_regno_nregs[regno][mode];
04391 unsigned int start_regno, end_regno, r;
04392 int i;
04393
04394
04395
04396
04397 int check_opnum = 0;
04398 int check_any = 0;
04399 HARD_REG_SET *used_in_set;
04400
04401 switch (type)
04402 {
04403 case RELOAD_OTHER:
04404 used_in_set = &reload_reg_used;
04405 break;
04406
04407 case RELOAD_FOR_INPUT_ADDRESS:
04408 used_in_set = &reload_reg_used_in_input_addr[opnum];
04409 break;
04410
04411 case RELOAD_FOR_INPADDR_ADDRESS:
04412 check_opnum = 1;
04413 used_in_set = &reload_reg_used_in_inpaddr_addr[opnum];
04414 break;
04415
04416 case RELOAD_FOR_OUTPUT_ADDRESS:
04417 used_in_set = &reload_reg_used_in_output_addr[opnum];
04418 break;
04419
04420 case RELOAD_FOR_OUTADDR_ADDRESS:
04421 check_opnum = 1;
04422 used_in_set = &reload_reg_used_in_outaddr_addr[opnum];
04423 break;
04424
04425 case RELOAD_FOR_OPERAND_ADDRESS:
04426 used_in_set = &reload_reg_used_in_op_addr;
04427 break;
04428
04429 case RELOAD_FOR_OPADDR_ADDR:
04430 check_any = 1;
04431 used_in_set = &reload_reg_used_in_op_addr_reload;
04432 break;
04433
04434 case RELOAD_FOR_OTHER_ADDRESS:
04435 used_in_set = &reload_reg_used_in_other_addr;
04436 check_any = 1;
04437 break;
04438
04439 case RELOAD_FOR_INPUT:
04440 used_in_set = &reload_reg_used_in_input[opnum];
04441 break;
04442
04443 case RELOAD_FOR_OUTPUT:
04444 used_in_set = &reload_reg_used_in_output[opnum];
04445 break;
04446
04447 case RELOAD_FOR_INSN:
04448 used_in_set = &reload_reg_used_in_insn;
04449 break;
04450 default:
04451 gcc_unreachable ();
04452 }
04453
04454
04455
04456
04457
04458
04459
04460
04461 start_regno = regno;
04462 end_regno = regno + nregs;
04463 if (check_opnum || check_any)
04464 {
04465 for (i = n_reloads - 1; i >= 0; i--)
04466 {
04467 if (rld[i].when_needed == type
04468 && (check_any || rld[i].opnum == opnum)
04469 && rld[i].reg_rtx)
04470 {
04471 unsigned int conflict_start = true_regnum (rld[i].reg_rtx);
04472 unsigned int conflict_end
04473 = (conflict_start
04474 + hard_regno_nregs[conflict_start][rld[i].mode]);
04475
04476
04477
04478 if (conflict_start <= start_regno && conflict_end > start_regno)
04479 start_regno = conflict_end;
04480
04481
04482 if (conflict_start > start_regno && conflict_start < end_regno)
04483 end_regno = conflict_start;
04484 }
04485 }
04486 }
04487
04488 for (r = start_regno; r < end_regno; r++)
04489 CLEAR_HARD_REG_BIT (*used_in_set, r);
04490 }
04491
04492
04493
04494
04495 static int
04496 reload_reg_free_p (unsigned int regno, int opnum, enum reload_type type)
04497 {
04498 int i;
04499
04500
04501 if (TEST_HARD_REG_BIT (reload_reg_used, regno)
04502 || TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
04503 return 0;
04504
04505 switch (type)
04506 {
04507 case RELOAD_OTHER:
04508
04509 if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno)
04510 || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
04511 || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
04512 || TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
04513 return 0;
04514
04515 for (i = 0; i < reload_n_operands; i++)
04516 if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
04517 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
04518 || TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04519 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
04520 || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
04521 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04522 return 0;
04523
04524 return 1;
04525
04526 case RELOAD_FOR_INPUT:
04527 if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04528 || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno))
04529 return 0;
04530
04531 if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
04532 return 0;
04533
04534
04535 for (i = 0; i < reload_n_operands; i++)
04536 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04537 return 0;
04538
04539
04540 for (i = opnum + 1; i < reload_n_operands; i++)
04541 if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
04542 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
04543 return 0;
04544
04545 return 1;
04546
04547 case RELOAD_FOR_INPUT_ADDRESS:
04548
04549
04550 if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno)
04551 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
04552 return 0;
04553
04554 for (i = 0; i < opnum; i++)
04555 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04556 return 0;
04557
04558 return 1;
04559
04560 case RELOAD_FOR_INPADDR_ADDRESS:
04561
04562
04563
04564 if (TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno))
04565 return 0;
04566
04567 for (i = 0; i < opnum; i++)
04568 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04569 return 0;
04570
04571 return 1;
04572
04573 case RELOAD_FOR_OUTPUT_ADDRESS:
04574
04575
04576
04577
04578 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno))
04579 return 0;
04580
04581 for (i = 0; i <= opnum; i++)
04582 if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04583 return 0;
04584
04585 return 1;
04586
04587 case RELOAD_FOR_OUTADDR_ADDRESS:
04588
04589
04590
04591
04592
04593 if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno))
04594 return 0;
04595
04596 for (i = 0; i <= opnum; i++)
04597 if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04598 return 0;
04599
04600 return 1;
04601
04602 case RELOAD_FOR_OPERAND_ADDRESS:
04603 for (i = 0; i < reload_n_operands; i++)
04604 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04605 return 0;
04606
04607 return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04608 && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));
04609
04610 case RELOAD_FOR_OPADDR_ADDR:
04611 for (i = 0; i < reload_n_operands; i++)
04612 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04613 return 0;
04614
04615 return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno));
04616
04617 case RELOAD_FOR_OUTPUT:
04618
04619
04620
04621
04622 if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno))
04623 return 0;
04624
04625 for (i = 0; i < reload_n_operands; i++)
04626 if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04627 return 0;
04628
04629 for (i = opnum; i < reload_n_operands; i++)
04630 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04631 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
04632 return 0;
04633
04634 return 1;
04635
04636 case RELOAD_FOR_INSN:
04637 for (i = 0; i < reload_n_operands; i++)
04638 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)
04639 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04640 return 0;
04641
04642 return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04643 && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno));
04644
04645 case RELOAD_FOR_OTHER_ADDRESS:
04646 return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno);
04647
04648 default:
04649 gcc_unreachable ();
04650 }
04651 }
04652
04653
04654
04655
04656
04657
04658
04659
04660
04661 static int
04662 reload_reg_reaches_end_p (unsigned int regno, int opnum, enum reload_type type)
04663 {
04664 int i;
04665
04666 switch (type)
04667 {
04668 case RELOAD_OTHER:
04669
04670
04671 return 1;
04672
04673
04674
04675
04676
04677
04678 case RELOAD_FOR_OTHER_ADDRESS:
04679
04680
04681
04682 for (i = 0; i < reload_n_operands; i++)
04683 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04684 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
04685 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)
04686 || TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
04687 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
04688 || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04689 return 0;
04690
04691 return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
04692 && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)
04693 && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04694 && ! TEST_HARD_REG_BIT (reload_reg_used, regno));
04695
04696 case RELOAD_FOR_INPUT_ADDRESS:
04697 case RELOAD_FOR_INPADDR_ADDRESS:
04698
04699
04700
04701
04702
04703 for (i = opnum; i < reload_n_operands; i++)
04704 if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04705 return 0;
04706
04707 for (i = opnum + 1; i < reload_n_operands; i++)
04708 if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
04709 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno))
04710 return 0;
04711
04712 for (i = 0; i < reload_n_operands; i++)
04713 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04714 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
04715 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04716 return 0;
04717
04718 if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno))
04719 return 0;
04720
04721 return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
04722 && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04723 && !TEST_HARD_REG_BIT (reload_reg_used, regno));
04724
04725 case RELOAD_FOR_INPUT:
04726
04727
04728
04729
04730
04731 for (i = opnum + 1; i < reload_n_operands; i++)
04732 if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno)
04733 || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)
04734 || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno))
04735 return 0;
04736
04737
04738
04739 case RELOAD_FOR_OPERAND_ADDRESS:
04740
04741
04742 for (i = 0; i < reload_n_operands; i++)
04743 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04744 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
04745 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04746 return 0;
04747
04748 return (!TEST_HARD_REG_BIT (reload_reg_used, regno));
04749
04750 case RELOAD_FOR_OPADDR_ADDR:
04751 for (i = 0; i < reload_n_operands; i++)
04752 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04753 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)
04754 || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno))
04755 return 0;
04756
04757 return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)
04758 && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)
04759 && !TEST_HARD_REG_BIT (reload_reg_used, regno));
04760
04761 case RELOAD_FOR_INSN:
04762
04763
04764
04765 opnum = reload_n_operands;
04766
04767
04768
04769 case RELOAD_FOR_OUTPUT:
04770 case RELOAD_FOR_OUTPUT_ADDRESS:
04771 case RELOAD_FOR_OUTADDR_ADDRESS:
04772
04773
04774
04775
04776 for (i = 0; i < opnum; i++)
04777 if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno)
04778 || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno))
04779 return 0;
04780
04781 return 1;
04782
04783 default:
04784 gcc_unreachable ();
04785 }
04786 }
04787
04788
04789
04790
04791
04792
04793 static int
04794 reloads_conflict (int r1, int r2)
04795 {
04796 enum reload_type r1_type = rld[r1].when_needed;
04797 enum reload_type r2_type = rld[r2].when_needed;
04798 int r1_opnum = rld[r1].opnum;
04799 int r2_opnum = rld[r2].opnum;
04800
04801
04802 if (r2_type == RELOAD_OTHER)
04803 return 1;
04804
04805
04806
04807 switch (r1_type)
04808 {
04809 case RELOAD_FOR_INPUT:
04810 return (r2_type == RELOAD_FOR_INSN
04811 || r2_type == RELOAD_FOR_OPERAND_ADDRESS
04812 || r2_type == RELOAD_FOR_OPADDR_ADDR
04813 || r2_type == RELOAD_FOR_INPUT
04814 || ((r2_type == RELOAD_FOR_INPUT_ADDRESS
04815 || r2_type == RELOAD_FOR_INPADDR_ADDRESS)
04816 && r2_opnum > r1_opnum));
04817
04818 case RELOAD_FOR_INPUT_ADDRESS:
04819 return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum)
04820 || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));
04821
04822 case RELOAD_FOR_INPADDR_ADDRESS:
04823 return ((r2_type == RELOAD_FOR_INPADDR_ADDRESS && r1_opnum == r2_opnum)
04824 || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum));
04825
04826 case RELOAD_FOR_OUTPUT_ADDRESS:
04827 return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum)
04828 || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));
04829
04830 case RELOAD_FOR_OUTADDR_ADDRESS:
04831 return ((r2_type == RELOAD_FOR_OUTADDR_ADDRESS && r2_opnum == r1_opnum)
04832 || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum));
04833
04834 case RELOAD_FOR_OPERAND_ADDRESS:
04835 return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN
04836 || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
04837
04838 case RELOAD_FOR_OPADDR_ADDR:
04839 return (r2_type == RELOAD_FOR_INPUT
04840 || r2_type == RELOAD_FOR_OPADDR_ADDR);
04841
04842 case RELOAD_FOR_OUTPUT:
04843 return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT
04844 || ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS
04845 || r2_type == RELOAD_FOR_OUTADDR_ADDRESS)
04846 && r2_opnum >= r1_opnum));
04847
04848 case RELOAD_FOR_INSN:
04849 return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT
04850 || r2_type == RELOAD_FOR_INSN
04851 || r2_type == RELOAD_FOR_OPERAND_ADDRESS);
04852
04853 case RELOAD_FOR_OTHER_ADDRESS:
04854 return r2_type == RELOAD_FOR_OTHER_ADDRESS;
04855
04856 case RELOAD_OTHER:
04857 return 1;
04858
04859 default:
04860 gcc_unreachable ();
04861 }
04862 }
04863
04864
04865
04866 static char reload_inherited[MAX_RELOADS];
04867
04868
04869
04870 static rtx reload_inheritance_insn[MAX_RELOADS];
04871
04872
04873
04874 static rtx reload_override_in[MAX_RELOADS];
04875
04876
04877
04878 static int reload_spill_index[MAX_RELOADS];
04879
04880
04881
04882
04883
04884 static int
04885 reload_reg_free_for_value_p (int start_regno, int regno, int opnum,
04886 enum reload_type type, rtx value, rtx out,
04887 int reloadnum, int ignore_address_reloads)
04888 {
04889 int time1;
04890
04891
04892
04893 int check_earlyclobber = 0;
04894 int i;
04895 int copy = 0;
04896
04897 if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno))
04898 return 0;
04899
04900 if (out == const0_rtx)
04901 {
04902 copy = 1;
04903 out = NULL_RTX;
04904 }
04905
04906
04907
04908
04909
04910
04911
04912
04913
04914
04915
04916
04917
04918
04919
04920
04921 switch (type)
04922 {
04923 case RELOAD_FOR_OTHER_ADDRESS:
04924
04925 time1 = copy ? 0 : 1;
04926 break;
04927 case RELOAD_OTHER:
04928 time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5;
04929 break;
04930
04931
04932
04933
04934
04935
04936 case RELOAD_FOR_INPADDR_ADDRESS:
04937 time1 = opnum * 4 + 2;
04938 break;
04939 case RELOAD_FOR_INPUT_ADDRESS:
04940 time1 = opnum * 4 + 3;
04941 break;
04942 case RELOAD_FOR_INPUT:
04943
04944
04945 time1 = copy ? opnum * 4 + 4 : MAX_RECOG_OPERANDS * 4 + 3;
04946 break;
04947 case RELOAD_FOR_OPADDR_ADDR:
04948
04949
04950 time1 = MAX_RECOG_OPERANDS * 4 + 1;
04951 break;
04952 case RELOAD_FOR_OPERAND_ADDRESS:
04953
04954
04955 time1 = copy ? MAX_RECOG_OPERANDS * 4 + 2 : MAX_RECOG_OPERANDS * 4 + 3;
04956 break;
04957 case RELOAD_FOR_OUTADDR_ADDRESS:
04958 time1 = MAX_RECOG_OPERANDS * 4 + 4 + opnum;
04959 break;
04960 case RELOAD_FOR_OUTPUT_ADDRESS:
04961 time1 = MAX_RECOG_OPERANDS * 4 + 5 + opnum;
04962 break;
04963 default:
04964 time1 = MAX_RECOG_OPERANDS * 5 + 5;
04965 }
04966
04967 for (i = 0; i < n_reloads; i++)
04968 {
04969 rtx reg = rld[i].reg_rtx;
04970 if (reg && REG_P (reg)
04971 && ((unsigned) regno - true_regnum (reg)
04972 <= hard_regno_nregs[REGNO (reg)][GET_MODE (reg)] - (unsigned) 1)
04973 && i != reloadnum)
04974 {
04975 rtx other_input = rld[i].in;
04976
04977
04978
04979
04980 if (true_regnum (reg) != start_regno)
04981 other_input = NULL_RTX;
04982 if (! other_input || ! rtx_equal_p (other_input, value)
04983 || rld[i].out || out)
04984 {
04985 int time2;
04986 switch (rld[i].when_needed)
04987 {
04988 case RELOAD_FOR_OTHER_ADDRESS:
04989 time2 = 0;
04990 break;
04991 case RELOAD_FOR_INPADDR_ADDRESS:
04992
04993
04994
04995
04996
04997
04998 if (type == RELOAD_FOR_INPUT_ADDRESS && reloadnum == i + 1
04999 && ignore_address_reloads
05000
05001
05002
05003 && ! rld[reloadnum].out)
05004 continue;
05005
05006
05007
05008 if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum
05009 && ignore_address_reloads
05010
05011 && ! rld[reloadnum].out)
05012 continue;
05013 time2 = rld[i].opnum * 4 + 2;
05014 break;
05015 case RELOAD_FOR_INPUT_ADDRESS:
05016 if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum
05017 && ignore_address_reloads
05018 && ! rld[reloadnum].out)
05019 continue;
05020 time2 = rld[i].opnum * 4 + 3;
05021 break;
05022 case RELOAD_FOR_INPUT:
05023 time2 = rld[i].opnum * 4 + 4;
05024 check_earlyclobber = 1;
05025 break;
05026
05027
05028 case RELOAD_FOR_OPADDR_ADDR:
05029 if (type == RELOAD_FOR_OPERAND_ADDRESS && reloadnum == i + 1
05030 && ignore_address_reloads
05031 && ! rld[reloadnum].out)
05032 continue;
05033 time2 = MAX_RECOG_OPERANDS * 4 + 1;
05034 break;
05035 case RELOAD_FOR_OPERAND_ADDRESS:
05036 time2 = MAX_RECOG_OPERANDS * 4 + 2;
05037 check_earlyclobber = 1;
05038 break;
05039 case RELOAD_FOR_INSN:
05040 time2 = MAX_RECOG_OPERANDS * 4 + 3;
05041 break;
05042 case RELOAD_FOR_OUTPUT:
05043
05044
05045 time2 = MAX_RECOG_OPERANDS * 4 + 4;
05046 break;
05047
05048
05049
05050 case RELOAD_FOR_OUTADDR_ADDRESS:
05051 if (type == RELOAD_FOR_OUTPUT_ADDRESS && reloadnum == i + 1
05052 && ignore_address_reloads
05053 && ! rld[reloadnum].out)
05054 continue;
05055 time2 = MAX_RECOG_OPERANDS * 4 + 4 + rld[i].opnum;
05056 break;
05057 case RELOAD_FOR_OUTPUT_ADDRESS:
05058 time2 = MAX_RECOG_OPERANDS * 4 + 5 + rld[i].opnum;
05059 break;
05060 case RELOAD_OTHER:
05061
05062
05063 if (! rld[i].in || rtx_equal_p (other_input, value))
05064 {
05065 time2 = MAX_RECOG_OPERANDS * 4 + 4;
05066
05067 if (earlyclobber_operand_p (rld[i].out))
05068 time2 = MAX_RECOG_OPERANDS * 4 + 3;
05069
05070 break;
05071 }
05072 time2 = 1;
05073
05074
05075
05076
05077 if (out)
05078 return 0;
05079 break;
05080 default:
05081 return 0;
05082 }
05083 if ((time1 >= time2
05084 && (! rld[i].in || rld[i].out
05085 || ! rtx_equal_p (other_input, value)))
05086 || (out && rld[reloadnum].out_reg
05087 && time2 >= MAX_RECOG_OPERANDS * 4 + 3))
05088 return 0;
05089 }
05090 }
05091 }
05092
05093
05094 if (check_earlyclobber && out && earlyclobber_operand_p (out))
05095 return 0;
05096
05097 return 1;
05098 }
05099
05100
05101
05102
05103
05104
05105
05106
05107
05108
05109
05110
05111
05112
05113
05114
05115
05116
05117
05118
05119
05120
05121
05122
05123 static int
05124 free_for_value_p (int regno, enum machine_mode mode, int opnum,
05125 enum reload_type type, rtx value, rtx out, int reloadnum,
05126 int ignore_address_reloads)
05127 {
05128 int nregs = hard_regno_nregs[regno][mode];
05129 while (nregs-- > 0)
05130 if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type,
05131 value, out, reloadnum,
05132 ignore_address_reloads))
05133 return 0;
05134 return 1;
05135 }
05136
05137
05138
05139
05140
05141
05142
05143
05144 int
05145 function_invariant_p (rtx x)
05146 {
05147 if (CONSTANT_P (x))
05148 return 1;
05149 if (x == frame_pointer_rtx || x == arg_pointer_rtx)
05150 return 1;
05151 if (GET_CODE (x) == PLUS
05152 && (XEXP (x, 0) == frame_pointer_rtx || XEXP (x, 0) == arg_pointer_rtx)
05153 && CONSTANT_P (XEXP (x, 1)))
05154 return 1;
05155 return 0;
05156 }
05157
05158
05159
05160
05161 static int
05162 conflicts_with_override (rtx x)
05163 {
05164 int i;
05165 for (i = 0; i < n_reloads; i++)
05166 if (reload_override_in[i]
05167 && reg_overlap_mentioned_p (x, reload_override_in[i]))
05168 return 1;
05169 return 0;
05170 }
05171
05172
05173
05174 static void
05175 failed_reload (rtx insn, int r)
05176 {
05177 if (asm_noperands (PATTERN (insn)) < 0)
05178
05179 fatal_insn ("could not find a spill register", insn);
05180
05181
05182
05183 error_for_asm (insn,
05184 "%<asm%> operand constraint incompatible with operand size");
05185 rld[r].in = 0;
05186 rld[r].out = 0;
05187 rld[r].reg_rtx = 0;
05188 rld[r].optional = 1;
05189 rld[r].secondary_p = 1;
05190 }
05191
05192
05193
05194
05195 static int
05196 set_reload_reg (int i, int r)
05197 {
05198 int regno;
05199 rtx reg = spill_reg_rtx[i];
05200
05201 if (reg == 0 || GET_MODE (reg) != rld[r].mode)
05202 spill_reg_rtx[i] = reg
05203 = gen_rtx_REG (rld[r].mode, spill_regs[i]);
05204
05205 regno = true_regnum (reg);
05206
05207
05208
05209 if (HARD_REGNO_MODE_OK (regno, rld[r].mode))
05210 {
05211 enum machine_mode test_mode = VOIDmode;
05212 if (rld[r].in)
05213 test_mode = GET_MODE (rld[r].in);
05214
05215
05216
05217
05218
05219
05220 if (! (rld[r].in != 0 && test_mode != VOIDmode
05221 && ! HARD_REGNO_MODE_OK (regno, test_mode)))
05222 if (! (rld[r].out != 0
05223 && ! HARD_REGNO_MODE_OK (regno, GET_MODE (rld[r].out))))
05224 {
05225
05226 last_spill_reg = i;
05227
05228
05229
05230 mark_reload_reg_in_use (spill_regs[i], rld[r].opnum,
05231 rld[r].when_needed, rld[r].mode);
05232
05233 rld[r].reg_rtx = reg;
05234 reload_spill_index[r] = spill_regs[i];
05235 return 1;
05236 }
05237 }
05238 return 0;
05239 }
05240
05241
05242
05243
05244
05245
05246
05247
05248
05249
05250 static int
05251 allocate_reload_reg (struct insn_chain *chain ATTRIBUTE_UNUSED, int r,
05252 int last_reload)
05253 {
05254 int i, pass, count;
05255
05256
05257
05258
05259
05260
05261
05262
05263
05264
05265
05266
05267
05268
05269 int force_group = rld[r].nregs > 1 && ! last_reload;
05270
05271
05272
05273
05274
05275
05276
05277
05278
05279
05280
05281
05282
05283 for (pass = 0; pass < 2; pass++)
05284 {
05285
05286
05287
05288
05289
05290 i = last_spill_reg;
05291
05292 for (count = 0; count < n_spills; count++)
05293 {
05294 int class = (int) rld[r].class;
05295 int regnum;
05296
05297 i++;
05298 if (i >= n_spills)
05299 i -= n_spills;
05300 regnum = spill_regs[i];
05301
05302 if ((reload_reg_free_p (regnum, rld[r].opnum,
05303 rld[r].when_needed)
05304 || (rld[r].in
05305
05306
05307 && ! TEST_HARD_REG_BIT (reload_reg_used, regnum)
05308 && free_for_value_p (regnum, rld[r].mode, rld[r].opnum,
05309 rld[r].when_needed, rld[r].in,
05310 rld[r].out, r, 1)))
05311 && TEST_HARD_REG_BIT (reg_class_contents[class], regnum)
05312 && HARD_REGNO_MODE_OK (regnum, rld[r].mode)
05313
05314
05315
05316 && (pass
05317 || (TEST_HARD_REG_BIT (reload_reg_used_at_all,
05318 regnum)
05319 && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit,
05320 regnum))))
05321 {
05322 int nr = hard_regno_nregs[regnum][rld[r].mode];
05323
05324
05325
05326 if (force_group)
05327 nr = rld[r].nregs;
05328
05329 if (nr == 1)
05330 {
05331
05332 if (force_group)
05333 continue;
05334 break;
05335 }
05336
05337
05338 while (nr > 1)
05339 {
05340 int regno = regnum + nr - 1;
05341 if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno)
05342 && spill_reg_order[regno] >= 0
05343 && reload_reg_free_p (regno, rld[r].opnum,
05344 rld[r].when_needed)))
05345 break;
05346 nr--;
05347 }
05348 if (nr == 1)
05349 break;
05350 }
05351 }
05352
05353
05354 if (count < n_spills)
05355 break;
05356 }
05357
05358
05359 if (count >= n_spills)
05360 return 0;
05361
05362
05363
05364
05365 return set_reload_reg (i, r);
05366 }
05367
05368
05369
05370
05371
05372 static void
05373 choose_reload_regs_init (struct insn_chain *chain, rtx *save_reload_reg_rtx)
05374 {
05375 int i;
05376
05377 for (i = 0; i < n_reloads; i++)
05378 rld[i].reg_rtx = save_reload_reg_rtx[i];
05379
05380 memset (reload_inherited, 0, MAX_RELOADS);
05381 memset (reload_inheritance_insn, 0, MAX_RELOADS * sizeof (rtx));
05382 memset (reload_override_in, 0, MAX_RELOADS * sizeof (rtx));
05383
05384 CLEAR_HARD_REG_SET (reload_reg_used);
05385 CLEAR_HARD_REG_SET (reload_reg_used_at_all);
05386 CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr);
05387 CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr_reload);
05388 CLEAR_HARD_REG_SET (reload_reg_used_in_insn);
05389 CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr);
05390
05391 CLEAR_HARD_REG_SET (reg_used_in_insn);
05392 {
05393 HARD_REG_SET tmp;
05394 REG_SET_TO_HARD_REG_SET (tmp, &chain->live_throughout);
05395 IOR_HARD_REG_SET (reg_used_in_insn, tmp);
05396 REG_SET_TO_HARD_REG_SET (tmp, &chain->dead_or_set);
05397 IOR_HARD_REG_SET (reg_used_in_insn, tmp);
05398 compute_use_by_pseudos (®_used_in_insn, &chain->live_throughout);
05399 compute_use_by_pseudos (®_used_in_insn, &chain->dead_or_set);
05400 }
05401
05402 for (i = 0; i < reload_n_operands; i++)
05403 {
05404 CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]);
05405 CLEAR_HARD_REG_SET (reload_reg_used_in_input[i]);
05406 CLEAR_HARD_REG_SET (reload_reg_used_in_input_addr[i]);
05407 CLEAR_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i]);
05408 CLEAR_HARD_REG_SET (reload_reg_used_in_output_addr[i]);
05409 CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]);
05410 }
05411
05412 COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs);
05413
05414 CLEAR_HARD_REG_SET (reload_reg_used_for_inherit);
05415
05416 for (i = 0; i < n_reloads; i++)
05417
05418
05419 if (rld[i].reg_rtx)
05420 mark_reload_reg_in_use (REGNO (rld[i].reg_rtx), rld[i].opnum,
05421 rld[i].when_needed, rld[i].mode);
05422 }
05423
05424
05425
05426
05427
05428
05429
05430
05431 static void
05432 choose_reload_regs (struct insn_chain *chain)
05433 {
05434 rtx insn = chain->insn;
05435 int i, j;
05436 unsigned int max_group_size = 1;
05437 enum reg_class group_class = NO_REGS;
05438 int pass, win, inheritance;
05439
05440 rtx save_reload_reg_rtx[MAX_RELOADS];
05441
05442
05443
05444
05445
05446
05447
05448
05449
05450
05451 for (j = 0; j < n_reloads; j++)
05452 {
05453 reload_order[j] = j;
05454 reload_spill_index[j] = -1;
05455
05456 if (rld[j].nregs > 1)
05457 {
05458 max_group_size = MAX (rld[j].nregs, max_group_size);
05459 group_class
05460 = reg_class_superunion[(int) rld[j].class][(int) group_class];
05461 }
05462
05463 save_reload_reg_rtx[j] = rld[j].reg_rtx;
05464 }
05465
05466 if (n_reloads > 1)
05467 qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower);
05468
05469
05470
05471
05472
05473
05474 win = 0;
05475 for (inheritance = optimize > 0; inheritance >= 0; inheritance--)
05476 {
05477 choose_reload_regs_init (chain, save_reload_reg_rtx);
05478
05479
05480
05481
05482
05483
05484
05485
05486
05487
05488
05489
05490
05491
05492
05493
05494
05495
05496
05497 for (j = 0; j < n_reloads; j++)
05498 {
05499 int r = reload_order[j];
05500 rtx search_equiv = NULL_RTX;
05501
05502
05503 if (rld[r].out == 0 && rld[r].in == 0
05504 && ! rld[r].secondary_p)
05505 continue;
05506
05507
05508
05509
05510
05511
05512 if (rld[r].in != 0 && rld[r].reg_rtx != 0
05513 && (rtx_equal_p (rld[r].in, rld[r].reg_rtx)
05514 || (rtx_equal_p (rld[r].out, rld[r].reg_rtx)
05515 && !MEM_P (rld[r].in)
05516 && true_regnum (rld[r].in) < FIRST_PSEUDO_REGISTER)))
05517 continue;
05518
05519 #if 0
05520
05521
05522
05523
05524
05525 if (rld[r].optional != 0)
05526 for (i = 0; i < j; i++)
05527 if ((rld[reload_order[i]].out != 0
05528 || rld[reload_order[i]].in != 0
05529 || rld[reload_order[i]].secondary_p)
05530 && ! rld[reload_order[i]].optional
05531 && rld[reload_order[i]].reg_rtx == 0)
05532 allocate_reload_reg (chain, reload_order[i], 0);
05533 #endif
05534
05535
05536
05537
05538
05539
05540
05541
05542
05543
05544
05545
05546
05547
05548
05549 if (inheritance)
05550 {
05551 int byte = 0;
05552 int regno = -1;
05553 enum machine_mode mode = VOIDmode;
05554
05555 if (rld[r].in == 0)
05556 ;
05557 else if (REG_P (rld[r].in))
05558 {
05559 regno = REGNO (rld[r].in);
05560 mode = GET_MODE (rld[r].in);
05561 }
05562 else if (REG_P (rld[r].in_reg))
05563 {
05564 regno = REGNO (rld[r].in_reg);
05565 mode = GET_MODE (rld[r].in_reg);
05566 }
05567 else if (GET_CODE (rld[r].in_reg) == SUBREG
05568 && REG_P (SUBREG_REG (rld[r].in_reg)))
05569 {
05570 byte = SUBREG_BYTE (rld[r].in_reg);
05571 regno = REGNO (SUBREG_REG (rld[r].in_reg));
05572 if (regno < FIRST_PSEUDO_REGISTER)
05573 regno = subreg_regno (rld[r].in_reg);
05574 mode = GET_MODE (rld[r].in_reg);
05575 }
05576 #ifdef AUTO_INC_DEC
05577 else if (GET_RTX_CLASS (GET_CODE (rld[r].in_reg)) == RTX_AUTOINC
05578 && REG_P (XEXP (rld[r].in_reg, 0)))
05579 {
05580 regno = REGNO (XEXP (rld[r].in_reg, 0));
05581 mode = GET_MODE (XEXP (rld[r].in_reg, 0));
05582 rld[r].out = rld[r].in;
05583 }
05584 #endif
05585 #if 0
05586
05587
05588
05589 else if (GET_CODE (rld[r].in) == SUBREG
05590 && REG_P (SUBREG_REG (rld[r].in)))
05591 regno = subreg_regno (rld[r].in);
05592 #endif
05593
05594 if (regno >= 0 && reg_last_reload_reg[regno] != 0)
05595 {
05596 enum reg_class class = rld[r].class, last_class;
05597 rtx last_reg = reg_last_reload_reg[regno];
05598 enum machine_mode need_mode;
05599
05600 i = REGNO (last_reg);
05601 i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode);
05602 last_class = REGNO_REG_CLASS (i);
05603
05604 if (byte == 0)
05605 need_mode = mode;
05606 else
05607 need_mode
05608 = smallest_mode_for_size (GET_MODE_BITSIZE (mode)
05609 + byte * BITS_PER_UNIT,
05610 GET_MODE_CLASS (mode));
05611
05612 if ((GET_MODE_SIZE (GET_MODE (last_reg))
05613 >= GET_MODE_SIZE (need_mode))
05614 #ifdef CANNOT_CHANGE_MODE_CLASS
05615
05616
05617 && !REG_CANNOT_CHANGE_MODE_P (REGNO (last_reg),
05618 GET_MODE (last_reg),
05619 mode)
05620 #endif
05621 && reg_reloaded_contents[i] == regno
05622 && TEST_HARD_REG_BIT (reg_reloaded_valid, i)
05623 && HARD_REGNO_MODE_OK (i, rld[r].mode)
05624 && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i)
05625
05626
05627
05628
05629 || ((REGISTER_MOVE_COST (mode, last_class, class)
05630 < MEMORY_MOVE_COST (mode, class, 1))
05631 && (secondary_reload_class (1, class, mode,
05632 last_reg)
05633 == NO_REGS)
05634 #ifdef SECONDARY_MEMORY_NEEDED
05635 && ! SECONDARY_MEMORY_NEEDED (last_class, class,
05636 mode)
05637 #endif
05638 ))
05639
05640 && (rld[r].nregs == max_group_size
05641 || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class],
05642 i))
05643 && free_for_value_p (i, rld[r].mode, rld[r].opnum,
05644 rld[r].when_needed, rld[r].in,
05645 const0_rtx, r, 1))
05646 {
05647
05648
05649 int nr = hard_regno_nregs[i][rld[r].mode];
05650 int k;
05651
05652 for (k = 1; k < nr; k++)
05653 if (reg_reloaded_contents[i + k] != regno
05654 || ! TEST_HARD_REG_BIT (reg_reloaded_valid, i + k))
05655 break;
05656
05657 if (k == nr)
05658 {
05659 int i1;
05660 int bad_for_class;
05661
05662 last_reg = (GET_MODE (last_reg) == mode
05663 ? last_reg : gen_rtx_REG (mode, i));
05664
05665 bad_for_class = 0;
05666 for (k = 0; k < nr; k++)
05667 bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
05668 i+k);
05669
05670
05671
05672
05673
05674
05675
05676
05677 for (i1 = 0; i1 < n_earlyclobbers; i1++)
05678 if (reg_overlap_mentioned_for_reload_p
05679 (reg_last_reload_reg[regno],
05680 reload_earlyclobbers[i1]))
05681 break;
05682
05683 if (i1 != n_earlyclobbers
05684 || ! (free_for_value_p (i, rld[r].mode,
05685 rld[r].opnum,
05686 rld[r].when_needed, rld[r].in,
05687 rld[r].out, r, 1))
05688
05689 || (TEST_HARD_REG_BIT (reg_used_in_insn, i)
05690 && rld[r].out
05691 && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i))
05692
05693 || (i == HARD_FRAME_POINTER_REGNUM
05694 && frame_pointer_needed
05695 && rld[r].out)
05696
05697
05698 || (GET_MODE_SIZE (rld[r].mode)
05699 > GET_MODE_SIZE (mode))
05700 || bad_for_class
05701
05702
05703
05704
05705 || (rld[r].out && rld[r].reg_rtx
05706 && rtx_equal_p (rld[r].out, rld[r].reg_rtx)))
05707 {
05708 if (! rld[r].optional)
05709 {
05710 reload_override_in[r] = last_reg;
05711 reload_inheritance_insn[r]
05712 = reg_reloaded_insn[i];
05713 }
05714 }
05715 else
05716 {
05717 int k;
05718
05719
05720
05721 mark_reload_reg_in_use (i,
05722 rld[r].opnum,
05723 rld[r].when_needed,
05724 rld[r].mode);
05725 rld[r].reg_rtx = last_reg;
05726 reload_inherited[r] = 1;
05727 reload_inheritance_insn[r]
05728 = reg_reloaded_insn[i];
05729 reload_spill_index[r] = i;
05730 for (k = 0; k < nr; k++)
05731 SET_HARD_REG_BIT (reload_reg_used_for_inherit,
05732 i + k);
05733 }
05734 }
05735 }
05736 }
05737 }
05738
05739
05740 if (inheritance
05741 && rld[r].in != 0
05742 && ! reload_inherited[r]
05743 && rld[r].out == 0
05744 && (CONSTANT_P (rld[r].in)
05745 || GET_CODE (rld[r].in) == PLUS
05746 || REG_P (rld[r].in)
05747 || MEM_P (rld[r].in))
05748 && (rld[r].nregs == max_group_size
05749 || ! reg_classes_intersect_p (rld[r].class, group_class)))
05750 search_equiv = rld[r].in;
05751
05752
05753 else if (inheritance && rld[r].in == 0 && rld[r].out != 0)
05754 {
05755 rtx set = single_set (insn);
05756
05757 if (set
05758 && rtx_equal_p (rld[r].out, SET_DEST (set))
05759 && CONSTANT_P (SET_SRC (set)))
05760 search_equiv = SET_SRC (set);
05761 }
05762
05763 if (search_equiv)
05764 {
05765 rtx equiv
05766 = find_equiv_reg (search_equiv, insn, rld[r].class,
05767 -1, NULL, 0, rld[r].mode);
05768 int regno = 0;
05769
05770 if (equiv != 0)
05771 {
05772 if (REG_P (equiv))
05773 regno = REGNO (equiv);
05774 else
05775 {
05776
05777
05778
05779
05780 gcc_assert (GET_CODE (equiv) == SUBREG);
05781 regno = subreg_regno (equiv);
05782 equiv = gen_rtx_REG (rld[r].mode, regno);
05783
05784
05785
05786
05787
05788
05789 for (i = regno; i < regno + (int) rld[r].nregs; i++)
05790 if (TEST_HARD_REG_BIT (reload_reg_unavailable, i))
05791 equiv = 0;
05792 }
05793 }
05794
05795
05796
05797 if (equiv != 0)
05798 {
05799 int regs_used = 0;
05800 int bad_for_class = 0;
05801 int max_regno = regno + rld[r].nregs;
05802
05803 for (i = regno; i < max_regno; i++)
05804 {
05805 regs_used |= TEST_HARD_REG_BIT (reload_reg_used_at_all,
05806 i);
05807 bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class],
05808 i);
05809 }
05810
05811 if ((regs_used
05812 && ! free_for_value_p (regno, rld[r].mode,
05813 rld[r].opnum, rld[r].when_needed,
05814 rld[r].in, rld[r].out, r, 1))
05815 || bad_for_class)
05816 equiv = 0;
05817 }
05818
05819 if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode))
05820 equiv = 0;
05821
05822
05823
05824
05825
05826
05827 if (equiv != 0)
05828 for (i = 0; i < n_earlyclobbers; i++)
05829 if (reg_overlap_mentioned_for_reload_p (equiv,
05830 reload_earlyclobbers[i]))
05831 {
05832 if (! rld[r].optional)
05833 reload_override_in[r] = equiv;
05834 equiv = 0;
05835 break;
05836 }
05837
05838
05839
05840
05841
05842
05843
05844 if (equiv != 0)
05845 {
05846 if (regno_clobbered_p (regno, insn, rld[r].mode, 2))
05847 switch (rld[r].when_needed)
05848 {
05849 case RELOAD_FOR_OTHER_ADDRESS:
05850 case RELOAD_FOR_INPADDR_ADDRESS:
05851 case RELOAD_FOR_INPUT_ADDRESS:
05852 case RELOAD_FOR_OPADDR_ADDR:
05853 break;
05854 case RELOAD_OTHER:
05855 case RELOAD_FOR_INPUT:
05856 case RELOAD_FOR_OPERAND_ADDRESS:
05857 if (! rld[r].optional)
05858 reload_override_in[r] = equiv;
05859
05860 default:
05861 equiv = 0;
05862 break;
05863 }
05864 else if (regno_clobbered_p (regno, insn, rld[r].mode, 1))
05865 switch (rld[r].when_needed)
05866 {
05867 case RELOAD_FOR_OTHER_ADDRESS:
05868 case RELOAD_FOR_INPADDR_ADDRESS:
05869 case RELOAD_FOR_INPUT_ADDRESS:
05870 case RELOAD_FOR_OPADDR_ADDR:
05871 case RELOAD_FOR_OPERAND_ADDRESS:
05872 case RELOAD_FOR_INPUT:
05873 break;
05874 case RELOAD_OTHER:
05875 if (! rld[r].optional)
05876 reload_override_in[r] = equiv;
05877
05878 default:
05879 equiv = 0;
05880 break;
05881 }
05882 }
05883
05884
05885
05886 if (equiv != 0
05887 && (regno != HARD_FRAME_POINTER_REGNUM
05888 || !frame_pointer_needed))
05889 {
05890 int nr = hard_regno_nregs[regno][rld[r].mode];
05891 int k;
05892 rld[r].reg_rtx = equiv;
05893 reload_inherited[r] = 1;
05894
05895
05896
05897
05898
05899 if (! TEST_HARD_REG_BIT (reg_reloaded_valid, regno))
05900 spill_reg_store[regno] = NULL_RTX;
05901
05902
05903 for (k = 0; k < nr; k++)
05904 {
05905 i = spill_reg_order[regno + k];
05906 if (i >= 0)
05907 {
05908 mark_reload_reg_in_use (regno, rld[r].opnum,
05909 rld[r].when_needed,
05910 rld[r].mode);
05911 SET_HARD_REG_BIT (reload_reg_used_for_inherit,
05912 regno + k);
05913 }
05914 }
05915 }
05916 }
05917
05918
05919
05920 if (rld[r].reg_rtx != 0 || rld[r].optional != 0)
05921 continue;
05922
05923 #if 0
05924
05925
05926
05927
05928
05929
05930
05931
05932
05933
05934
05935
05936 for (i = j + 1; i < n_reloads; i++)
05937 {
05938 int s = reload_order[i];
05939
05940 if ((rld[s].in == 0 && rld[s].out == 0
05941 && ! rld[s].secondary_p)
05942 || rld[s].optional)
05943 continue;
05944
05945 if ((rld[s].class != rld[r].class
05946 && reg_classes_intersect_p (rld[r].class,
05947 rld[s].class))
05948 || rld[s].nregs < rld[r].nregs)
05949 break;
05950 }
05951
05952 if (i == n_reloads)
05953 continue;
05954
05955 allocate_reload_reg (chain, r, j == n_reloads - 1);
05956 #endif
05957 }
05958
05959
05960
05961 for (j = 0; j < n_reloads; j++)
05962 {
05963 int r = reload_order[j];
05964
05965
05966 if (rld[r].out == 0 && rld[r].in == 0 && ! rld[r].secondary_p)
05967 continue;
05968
05969
05970
05971 if (rld[r].reg_rtx != 0 || rld[r].optional)
05972 continue;
05973
05974 if (! allocate_reload_reg (chain, r, j == n_reloads - 1))
05975 break;
05976 }
05977
05978
05979 if (j == n_reloads)
05980 {
05981 win = 1;
05982 break;
05983 }
05984
05985
05986 }
05987
05988 if (! win)
05989 {
05990
05991
05992 choose_reload_regs_init (chain, save_reload_reg_rtx);
05993
05994
05995
05996 gcc_assert (chain->n_reloads == n_reloads);
05997
05998 for (i = 0; i < n_reloads; i++)
05999 {
06000 if (chain->rld[i].regno < 0 || chain->rld[i].reg_rtx != 0)
06001 continue;
06002 gcc_assert (chain->rld[i].when_needed == rld[i].when_needed);
06003 for (j = 0; j < n_spills; j++)
06004 if (spill_regs[j] == chain->rld[i].regno)
06005 if (! set_reload_reg (j, i))
06006 failed_reload (chain->insn, i);
06007 }
06008 }
06009
06010
06011
06012
06013
06014
06015
06016
06017
06018 for (pass = flag_expensive_optimizations; pass >= 0; pass--)
06019 {
06020 for (j = 0; j < n_reloads; j++)
06021 {
06022 int r = reload_order[j];
06023 rtx check_reg;
06024 if (reload_inherited[r] && rld[r].reg_rtx)
06025 check_reg = rld[r].reg_rtx;
06026 else if (reload_override_in[r]
06027 && (REG_P (reload_override_in[r])
06028 || GET_CODE (reload_override_in[r]) == SUBREG))
06029 check_reg = reload_override_in[r];
06030 else
06031 continue;
06032 if (! free_for_value_p (true_regnum (check_reg), rld[r].mode,
06033 rld[r].opnum, rld[r].when_needed, rld[r].in,
06034 (reload_inherited[r]
06035 ? rld[r].out : const0_rtx),
06036 r, 1))
06037 {
06038 if (pass)
06039 continue;
06040 reload_inherited[r] = 0;
06041 reload_override_in[r] = 0;
06042 }
06043
06044
06045
06046
06047
06048
06049
06050
06051
06052
06053
06054
06055 else if (rld[r].in
06056 && rld[r].out != rld[r].in
06057 && remove_address_replacements (rld[r].in) && pass)
06058 pass = 2;
06059 }
06060 }
06061
06062
06063
06064 for (j = 0; j < n_reloads; j++)
06065 if (reload_override_in[j])
06066 rld[j].in = reload_override_in[j];
06067
06068
06069
06070
06071 for (j = 0; j < n_reloads; j++)
06072 if (rld[j].reg_rtx != 0
06073 && ((rld[j].optional && ! reload_inherited[j])
06074 || (rld[j].in == 0 && rld[j].out == 0
06075 && ! rld[j].secondary_p)))
06076 {
06077 int regno = true_regnum (rld[j].reg_rtx);
06078
06079 if (spill_reg_order[regno] >= 0)
06080 clear_reload_reg_in_use (regno, rld[j].opnum,
06081 rld[j].when_needed, rld[j].mode);
06082 rld[j].reg_rtx = 0;
06083 reload_spill_index[j] = -1;
06084 }
06085
06086
06087 for (j = 0; j < n_reloads; j++)
06088 {
06089 int r = reload_order[j];
06090
06091 i = reload_spill_index[r];
06092
06093
06094
06095
06096 if (rld[r].out_reg != 0 && REG_P (rld[r].out_reg)
06097 && rld[r].reg_rtx != 0)
06098 {
06099 int nregno = REGNO (rld[r].out_reg);
06100 int nr = 1;
06101
06102 if (nregno < FIRST_PSEUDO_REGISTER)
06103 nr = hard_regno_nregs[nregno][rld[r].mode];
06104
06105 while (--nr >= 0)
06106 SET_REGNO_REG_SET (®_has_output_reload,
06107 nregno + nr);
06108
06109 if (i >= 0)
06110 {
06111 nr = hard_regno_nregs[i][rld[r].mode];
06112 while (--nr >= 0)
06113 SET_HARD_REG_BIT (reg_is_output_reload, i + nr);
06114 }
06115
06116 gcc_assert (rld[r].when_needed == RELOAD_OTHER
06117 || rld[r].when_needed == RELOAD_FOR_OUTPUT
06118 || rld[r].when_needed == RELOAD_FOR_INSN);
06119 }
06120 }
06121 }
06122
06123
06124
06125
06126 void
06127 deallocate_reload_reg (int r)
06128 {
06129 int regno;
06130
06131 if (! rld[r].reg_rtx)
06132 return;
06133 regno = true_regnum (rld[r].reg_rtx);
06134 rld[r].reg_rtx = 0;
06135 if (spill_reg_order[regno] >= 0)
06136 clear_reload_reg_in_use (regno, rld[r].opnum, rld[r].when_needed,
06137 rld[r].mode);
06138 reload_spill_index[r] = -1;
06139 }
06140
06141
06142
06143
06144
06145
06146
06147
06148
06149
06150
06151
06152
06153
06154 static void
06155 merge_assigned_reloads (rtx insn)
06156 {
06157 int i, j;
06158
06159
06160
06161
06162
06163 for (i = 0; i < n_reloads; i++)
06164 {
06165 int conflicting_input = 0;
06166 int max_input_address_opnum = -1;
06167 int min_conflicting_input_opnum = MAX_RECOG_OPERANDS;
06168
06169 if (rld[i].in == 0 || rld[i].when_needed == RELOAD_OTHER
06170 || rld[i].out != 0 || rld[i].reg_rtx == 0
06171 || reg_set_p (rld[i].reg_rtx, insn))
06172 continue;
06173
06174
06175
06176
06177
06178
06179
06180 for (j = 0; j < n_reloads; j++)
06181 {
06182 if (i == j || rld[j].reg_rtx == 0
06183 || ! reg_overlap_mentioned_p (rld[j].reg_rtx,
06184 rld[i].reg_rtx))
06185 continue;
06186
06187 if (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
06188 && rld[j].opnum > max_input_address_opnum)
06189 max_input_address_opnum = rld[j].opnum;
06190
06191
06192
06193
06194
06195
06196 if (! rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx)
06197 || rld[j].out != 0 || rld[j].in == 0
06198 || ! rtx_equal_p (rld[i].in, rld[j].in))
06199 {
06200 if (rld[j].when_needed != RELOAD_FOR_INPUT
06201 || ((rld[i].when_needed != RELOAD_FOR_INPUT_ADDRESS
06202 || rld[i].opnum > rld[j].opnum)
06203 && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS))
06204 break;
06205 conflicting_input = 1;
06206 if (min_conflicting_input_opnum > rld[j].opnum)
06207 min_conflicting_input_opnum = rld[j].opnum;
06208 }
06209 }
06210
06211
06212
06213
06214 if (j == n_reloads
06215 && max_input_address_opnum <= min_conflicting_input_opnum)
06216 {
06217 gcc_assert (rld[i].when_needed != RELOAD_FOR_OUTPUT);
06218
06219 for (j = 0; j < n_reloads; j++)
06220 if (i != j && rld[j].reg_rtx != 0
06221 && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx)
06222 && (! conflicting_input
06223 || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
06224 || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS))
06225 {
06226 rld[i].when_needed = RELOAD_OTHER;
06227 rld[j].in = 0;
06228 reload_spill_index[j] = -1;
06229 transfer_replacements (i, j);
06230 }
06231
06232
06233
06234
06235
06236
06237
06238
06239
06240
06241
06242 if (rld[i].when_needed == RELOAD_OTHER)
06243 for (j = 0; j < n_reloads; j++)
06244 if (rld[j].in != 0
06245 && rld[j].when_needed != RELOAD_OTHER
06246 && rld[j].when_needed != RELOAD_FOR_OTHER_ADDRESS
06247 && rld[j].when_needed != RELOAD_FOR_OUTPUT_ADDRESS
06248 && (! conflicting_input
06249 || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
06250 || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
06251 && reg_overlap_mentioned_for_reload_p (rld[j].in,
06252 rld[i].in))
06253 {
06254 int k;
06255
06256 rld[j].when_needed
06257 = ((rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS
06258 || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS)
06259 ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER);
06260
06261
06262
06263
06264
06265 if (rld[j].reg_rtx)
06266 for (k = 0; k < j; k++)
06267 gcc_assert (rld[k].in == 0 || rld[k].reg_rtx == 0
06268 || rld[k].when_needed != rld[j].when_needed
06269 || !rtx_equal_p (rld[k].reg_rtx,
06270 rld[j].reg_rtx)
06271 || rtx_equal_p (rld[k].in,
06272 rld[j].in));
06273 }
06274 }
06275 }
06276 }
06277
06278
06279 static rtx input_reload_insns[MAX_RECOG_OPERANDS];
06280 static rtx other_input_address_reload_insns = 0;
06281 static rtx other_input_reload_insns = 0;
06282 static rtx input_address_reload_insns[MAX_RECOG_OPERANDS];
06283 static rtx inpaddr_address_reload_insns[MAX_RECOG_OPERANDS];
06284 static rtx output_reload_insns[MAX_RECOG_OPERANDS];
06285 static rtx output_address_reload_insns[MAX_RECOG_OPERANDS];
06286 static rtx outaddr_address_reload_insns[MAX_RECOG_OPERANDS];
06287 static rtx operand_reload_insns = 0;
06288 static rtx other_operand_reload_insns = 0;
06289 static rtx other_output_reload_insns[MAX_RECOG_OPERANDS];
06290
06291
06292 static rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER];
06293 static HARD_REG_SET reg_reloaded_died;
06294
06295
06296
06297
06298
06299 static bool
06300 reload_adjust_reg_for_temp (rtx *reload_reg, rtx alt_reload_reg,
06301 enum reg_class new_class,
06302 enum machine_mode new_mode)
06303
06304 {
06305 rtx reg;
06306
06307 for (reg = *reload_reg; reg; reg = alt_reload_reg, alt_reload_reg = 0)
06308 {
06309 unsigned regno = REGNO (reg);
06310
06311 if (!TEST_HARD_REG_BIT (reg_class_contents[(int) new_class], regno))
06312 continue;
06313 if (GET_MODE (reg) != new_mode)
06314 {
06315 if (!HARD_REGNO_MODE_OK (regno, new_mode))
06316 continue;
06317 if (hard_regno_nregs[regno][new_mode]
06318 > hard_regno_nregs[regno][GET_MODE (reg)])
06319 continue;
06320 reg = reload_adjust_reg_for_mode (reg, new_mode);
06321 }
06322 *reload_reg = reg;
06323 return true;
06324 }
06325 return false;
06326 }
06327
06328
06329
06330
06331
06332 static bool
06333 reload_adjust_reg_for_icode (rtx *reload_reg, rtx alt_reload_reg,
06334 enum insn_code icode)
06335
06336 {
06337 enum reg_class new_class = scratch_reload_class (icode);
06338 enum machine_mode new_mode = insn_data[(int) icode].operand[2].mode;
06339
06340 return reload_adjust_reg_for_temp (reload_reg, alt_reload_reg,
06341 new_class, new_mode);
06342 }
06343
06344
06345
06346
06347 static void
06348 emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
06349 rtx old, int j)
06350 {
06351 rtx insn = chain->insn;
06352 rtx reloadreg = rl->reg_rtx;
06353 rtx oldequiv_reg = 0;
06354 rtx oldequiv = 0;
06355 int special = 0;
06356 enum machine_mode mode;
06357 rtx *where;
06358
06359
06360
06361
06362
06363
06364
06365
06366
06367
06368
06369
06370
06371
06372
06373
06374
06375
06376
06377
06378
06379
06380
06381
06382
06383
06384
06385
06386
06387
06388
06389
06390
06391 mode = GET_MODE (old);
06392 if (mode == VOIDmode)
06393 mode = rl->inmode;
06394
06395
06396
06397
06398
06399 if (reload_override_in[j]
06400 && REG_P (rl->in_reg))
06401 {
06402 oldequiv = old;
06403 old = rl->in_reg;
06404 }
06405 if (oldequiv == 0)
06406 oldequiv = old;
06407 else if (REG_P (oldequiv))
06408 oldequiv_reg = oldequiv;
06409 else if (GET_CODE (oldequiv) == SUBREG)
06410 oldequiv_reg = SUBREG_REG (oldequiv);
06411
06412
06413
06414
06415
06416 if (optimize && REG_P (oldequiv)
06417 && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
06418 && spill_reg_store[REGNO (oldequiv)]
06419 && REG_P (old)
06420 && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)])
06421 || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
06422 rl->out_reg)))
06423 delete_output_reload (insn, j, REGNO (oldequiv));
06424
06425
06426
06427
06428
06429
06430
06431 if (GET_MODE (reloadreg) != mode)
06432 reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
06433 while (GET_CODE (oldequiv) == SUBREG && GET_MODE (oldequiv) != mode)
06434 oldequiv = SUBREG_REG (oldequiv);
06435 if (GET_MODE (oldequiv) != VOIDmode
06436 && mode != GET_MODE (oldequiv))
06437 oldequiv = gen_lowpart_SUBREG (mode, oldequiv);
06438
06439
06440 switch (rl->when_needed)
06441 {
06442 case RELOAD_OTHER:
06443 where = &other_input_reload_insns;
06444 break;
06445 case RELOAD_FOR_INPUT:
06446 where = &input_reload_insns[rl->opnum];
06447 break;
06448 case RELOAD_FOR_INPUT_ADDRESS:
06449 where = &input_address_reload_insns[rl->opnum];
06450 break;
06451 case RELOAD_FOR_INPADDR_ADDRESS:
06452 where = &inpaddr_address_reload_insns[rl->opnum];
06453 break;
06454 case RELOAD_FOR_OUTPUT_ADDRESS:
06455 where = &output_address_reload_insns[rl->opnum];
06456 break;
06457 case RELOAD_FOR_OUTADDR_ADDRESS:
06458 where = &outaddr_address_reload_insns[rl->opnum];
06459 break;
06460 case RELOAD_FOR_OPERAND_ADDRESS:
06461 where = &operand_reload_insns;
06462 break;
06463 case RELOAD_FOR_OPADDR_ADDR:
06464 where = &other_operand_reload_insns;
06465 break;
06466 case RELOAD_FOR_OTHER_ADDRESS:
06467 where = &other_input_address_reload_insns;
06468 break;
06469 default:
06470 gcc_unreachable ();
06471 }
06472
06473 push_to_sequence (*where);
06474
06475
06476 if (rl->out && ! rl->out_reg)
06477 {
06478
06479
06480
06481 gcc_assert (rl->secondary_in_reload < 0);
06482
06483 if (reload_inherited[j])
06484 oldequiv = reloadreg;
06485
06486 old = XEXP (rl->in_reg, 0);
06487
06488 if (optimize && REG_P (oldequiv)
06489 && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER
06490 && spill_reg_store[REGNO (oldequiv)]
06491 && REG_P (old)
06492 && (dead_or_set_p (insn,
06493 spill_reg_stored_to[REGNO (oldequiv)])
06494 || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)],
06495 old)))
06496 delete_output_reload (insn, j, REGNO (oldequiv));
06497
06498
06499 special = 1;
06500
06501 new_spill_reg_store[REGNO (reloadreg)]
06502 = inc_for_reload (reloadreg, oldequiv, rl->out,
06503 rl->inc);
06504 }
06505
06506
06507
06508
06509
06510 else if (optimize && REG_P (old)
06511 && REGNO (old) >= FIRST_PSEUDO_REGISTER
06512 && dead_or_set_p (insn, old)
06513
06514
06515 && ! conflicts_with_override (reloadreg)
06516 && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum,
06517 rl->when_needed, old, rl->out, j, 0))
06518 {
06519 rtx temp = PREV_INSN (insn);
06520 while (temp && NOTE_P (temp))
06521 temp = PREV_INSN (temp);
06522 if (temp
06523 && NONJUMP_INSN_P (temp)
06524 && GET_CODE (PATTERN (temp)) == SET
06525 && SET_DEST (PATTERN (temp)) == old
06526
06527 && asm_noperands (PATTERN (temp)) < 0
06528
06529
06530 && count_occurrences (PATTERN (insn), old, 0) == 1)
06531 {
06532 rtx old = SET_DEST (PATTERN (temp));
06533
06534 SET_DEST (PATTERN (temp)) = reloadreg;
06535
06536
06537 extract_insn (temp);
06538 if (constrain_operands (1))
06539 {
06540
06541
06542
06543
06544 if (REG_P (SET_SRC (PATTERN (temp)))
06545 && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
06546 {
06547 spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
06548 spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0;
06549 }
06550
06551
06552
06553 if (REG_N_DEATHS (REGNO (old)) == 1
06554 && REG_N_SETS (REGNO (old)) == 1)
06555 {
06556 reg_renumber[REGNO (old)] = REGNO (rl->reg_rtx);
06557 alter_reg (REGNO (old), -1);
06558 }
06559 special = 1;
06560 }
06561 else
06562 {
06563 SET_DEST (PATTERN (temp)) = old;
06564 }
06565 }
06566 }
06567
06568
06569
06570
06571
06572
06573
06574
06575
06576
06577
06578
06579
06580
06581 if (! special && rl->secondary_in_reload >= 0)
06582 {
06583 rtx second_reload_reg = 0;
06584 rtx third_reload_reg = 0;
06585 int secondary_reload = rl->secondary_in_reload;
06586 rtx real_oldequiv = oldequiv;
06587 rtx real_old = old;
06588 rtx tmp;
06589 enum insn_code icode;
06590 enum insn_code tertiary_icode = CODE_FOR_nothing;
06591
06592
06593
06594
06595
06596
06597
06598
06599
06600
06601
06602
06603
06604
06605 tmp = oldequiv;
06606 if (GET_CODE (tmp) == SUBREG)
06607 tmp = SUBREG_REG (tmp);
06608 if (REG_P (tmp)
06609 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
06610 && (reg_equiv_memory_loc[REGNO (tmp)] != 0
06611 || reg_equiv_constant[REGNO (tmp)] != 0))
06612 {
06613 if (! reg_equiv_mem[REGNO (tmp)]
06614 || num_not_at_initial_offset
06615 || GET_CODE (oldequiv) == SUBREG)
06616 real_oldequiv = rl->in;
06617 else
06618 real_oldequiv = reg_equiv_mem[REGNO (tmp)];
06619 }
06620
06621 tmp = old;
06622 if (GET_CODE (tmp) == SUBREG)
06623 tmp = SUBREG_REG (tmp);
06624 if (REG_P (tmp)
06625 && REGNO (tmp) >= FIRST_PSEUDO_REGISTER
06626 && (reg_equiv_memory_loc[REGNO (tmp)] != 0
06627 || reg_equiv_constant[REGNO (tmp)] != 0))
06628 {
06629 if (! reg_equiv_mem[REGNO (tmp)]
06630 || num_not_at_initial_offset
06631 || GET_CODE (old) == SUBREG)
06632 real_old = rl->in;
06633 else
06634 real_old = reg_equiv_mem[REGNO (tmp)];
06635 }
06636
06637 second_reload_reg = rld[secondary_reload].reg_rtx;
06638 if (rld[secondary_reload].secondary_in_reload >= 0)
06639 {
06640 int tertiary_reload = rld[secondary_reload].secondary_in_reload;
06641
06642 third_reload_reg = rld[tertiary_reload].reg_rtx;
06643 tertiary_icode = rld[secondary_reload].secondary_in_icode;
06644
06645 gcc_assert (rld[tertiary_reload].secondary_in_reload < 0);
06646 }
06647 icode = rl->secondary_in_icode;
06648
06649 if ((old != oldequiv && ! rtx_equal_p (old, oldequiv))
06650 || (rl->in != 0 && rl->out != 0))
06651 {
06652 secondary_reload_info sri, sri2;
06653 enum reg_class new_class, new_t_class;
06654
06655 sri.icode = CODE_FOR_nothing;
06656 sri.prev_sri = NULL;
06657 new_class = targetm.secondary_reload (1, real_oldequiv, rl->class,
06658 mode, &sri);
06659
06660 if (new_class == NO_REGS && sri.icode == CODE_FOR_nothing)
06661 second_reload_reg = 0;
06662 else if (new_class == NO_REGS)
06663 {
06664 if (reload_adjust_reg_for_icode (&second_reload_reg,
06665 third_reload_reg, sri.icode))
06666 icode = sri.icode, third_reload_reg = 0;
06667 else
06668 oldequiv = old, real_oldequiv = real_old;
06669 }
06670 else if (sri.icode != CODE_FOR_nothing)
06671
06672 gcc_unreachable ();
06673 else
06674 {
06675 sri2.icode = CODE_FOR_nothing;
06676 sri2.prev_sri = &sri;
06677 new_t_class = targetm.secondary_reload (1, real_oldequiv,
06678 new_class, mode, &sri);
06679 if (new_t_class == NO_REGS && sri2.icode == CODE_FOR_nothing)
06680 {
06681 if (reload_adjust_reg_for_temp (&second_reload_reg,
06682 third_reload_reg,
06683 new_class, mode))
06684 third_reload_reg = 0, tertiary_icode = sri2.icode;
06685 else
06686 oldequiv = old, real_oldequiv = real_old;
06687 }
06688 else if (new_t_class == NO_REGS && sri2.icode != CODE_FOR_nothing)
06689 {
06690 rtx intermediate = second_reload_reg;
06691
06692 if (reload_adjust_reg_for_temp (&intermediate, NULL,
06693 new_class, mode)
06694 && reload_adjust_reg_for_icode (&third_reload_reg, NULL,
06695 sri2.icode))
06696 {
06697 second_reload_reg = intermediate;
06698 tertiary_icode = sri2.icode;
06699 }
06700 else
06701 oldequiv = old, real_oldequiv = real_old;
06702 }
06703 else if (new_t_class != NO_REGS && sri2.icode == CODE_FOR_nothing)
06704 {
06705 rtx intermediate = second_reload_reg;
06706
06707 if (reload_adjust_reg_for_temp (&intermediate, NULL,
06708 new_class, mode)
06709 && reload_adjust_reg_for_temp (&third_reload_reg, NULL,
06710 new_t_class, mode))
06711 {
06712 second_reload_reg = intermediate;
06713 tertiary_icode = sri2.icode;
06714 }
06715 else
06716 oldequiv = old, real_oldequiv = real_old;
06717 }
06718 else
06719
06720 oldequiv = old, real_oldequiv = real_old;
06721 }
06722 }
06723
06724
06725
06726
06727
06728
06729
06730
06731 if (second_reload_reg)
06732 {
06733 if (icode != CODE_FOR_nothing)
06734 {
06735
06736 gcc_assert (!third_reload_reg);
06737
06738 emit_insn (GEN_FCN (icode) (reloadreg, real_oldequiv,
06739 second_reload_reg));
06740 special = 1;
06741 }
06742 else
06743 {
06744
06745
06746 if (tertiary_icode != CODE_FOR_nothing)
06747 {
06748 emit_insn ((GEN_FCN (tertiary_icode)
06749 (second_reload_reg, real_oldequiv,
06750 third_reload_reg)));
06751 }
06752 else if (third_reload_reg)
06753 {
06754 gen_reload (third_reload_reg, real_oldequiv,
06755 rl->opnum,
06756 rl->when_needed);
06757 gen_reload (second_reload_reg, third_reload_reg,
06758 rl->opnum,
06759 rl->when_needed);
06760 }
06761 else
06762 gen_reload (second_reload_reg, real_oldequiv,
06763 rl->opnum,
06764 rl->when_needed);
06765
06766 oldequiv = second_reload_reg;
06767 }
06768 }
06769 }
06770
06771 if (! special && ! rtx_equal_p (reloadreg, oldequiv))
06772 {
06773 rtx real_oldequiv = oldequiv;
06774
06775 if ((REG_P (oldequiv)
06776 && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER
06777 && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0
06778 || reg_equiv_constant[REGNO (oldequiv)] != 0))
06779 || (GET_CODE (oldequiv) == SUBREG
06780 && REG_P (SUBREG_REG (oldequiv))
06781 && (REGNO (SUBREG_REG (oldequiv))
06782 >= FIRST_PSEUDO_REGISTER)
06783 && ((reg_equiv_memory_loc
06784 [REGNO (SUBREG_REG (oldequiv))] != 0)
06785 || (reg_equiv_constant
06786 [REGNO (SUBREG_REG (oldequiv))] != 0)))
06787 || (CONSTANT_P (oldequiv)
06788 && (PREFERRED_RELOAD_CLASS (oldequiv,
06789 REGNO_REG_CLASS (REGNO (reloadreg)))
06790 == NO_REGS)))
06791 real_oldequiv = rl->in;
06792 gen_reload (reloadreg, real_oldequiv, rl->opnum,
06793 rl->when_needed);
06794 }
06795
06796 if (flag_non_call_exceptions)
06797 copy_eh_notes (insn, get_insns ());
06798
06799
06800 *where = get_insns ();
06801 end_sequence ();
06802
06803
06804
06805 if (oldequiv_reg)
06806 reload_override_in[j] = oldequiv;
06807 }
06808
06809
06810
06811 static void
06812 emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
06813 int j)
06814 {
06815 rtx reloadreg = rl->reg_rtx;
06816 rtx insn = chain->insn;
06817 int special = 0;
06818 rtx old = rl->out;
06819 enum machine_mode mode = GET_MODE (old);
06820 rtx p;
06821
06822 if (rl->when_needed == RELOAD_OTHER)
06823 start_sequence ();
06824 else
06825 push_to_sequence (output_reload_insns[rl->opnum]);
06826
06827
06828
06829
06830 if (mode == VOIDmode)
06831 {
06832
06833 if (asm_noperands (PATTERN (insn)) < 0)
06834
06835 fatal_insn ("VOIDmode on an output", insn);
06836 error_for_asm (insn, "output operand is constant in %<asm%>");
06837
06838 mode = word_mode;
06839 old = gen_rtx_REG (mode, REGNO (reloadreg));
06840 }
06841
06842 if (GET_MODE (reloadreg) != mode)
06843 reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
06844
06845
06846
06847
06848
06849 if (rl->secondary_out_reload >= 0)
06850 {
06851 rtx real_old = old;
06852 int secondary_reload = rl->secondary_out_reload;
06853 int tertiary_reload = rld[secondary_reload].secondary_out_reload;
06854
06855 if (REG_P (old) && REGNO (old) >= FIRST_PSEUDO_REGISTER
06856 && reg_equiv_mem[REGNO (old)] != 0)
06857 real_old = reg_equiv_mem[REGNO (old)];
06858
06859 if (secondary_reload_class (0, rl->class, mode, real_old) != NO_REGS)
06860 {
06861 rtx second_reloadreg = reloadreg;
06862 reloadreg = rld[secondary_reload].reg_rtx;
06863
06864
06865
06866 if (rl->secondary_out_icode != CODE_FOR_nothing)
06867 {
06868
06869 gcc_assert (tertiary_reload < 0);
06870
06871 emit_insn ((GEN_FCN (rl->secondary_out_icode)
06872 (real_old, second_reloadreg, reloadreg)));
06873 special = 1;
06874 }
06875 else
06876 {
06877
06878
06879
06880 enum insn_code tertiary_icode
06881 = rld[secondary_reload].secondary_out_icode;
06882
06883
06884 gcc_assert (tertiary_reload < 0
06885 || rld[tertiary_reload].secondary_out_reload < 0);
06886
06887 if (GET_MODE (reloadreg) != mode)
06888 reloadreg = reload_adjust_reg_for_mode (reloadreg, mode);
06889
06890 if (tertiary_icode != CODE_FOR_nothing)
06891 {
06892 rtx third_reloadreg = rld[tertiary_reload].reg_rtx;
06893 rtx tem;
06894
06895
06896
06897
06898
06899
06900
06901
06902 if (GET_CODE (real_old) == SUBREG
06903 && (GET_MODE_SIZE (GET_MODE (real_old))
06904 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (real_old))))
06905 && 0 != (tem = gen_lowpart_common
06906 (GET_MODE (SUBREG_REG (real_old)),
06907 reloadreg)))
06908 real_old = SUBREG_REG (real_old), reloadreg = tem;
06909
06910 gen_reload (reloadreg, second_reloadreg,
06911 rl->opnum, rl->when_needed);
06912 emit_insn ((GEN_FCN (tertiary_icode)
06913 (real_old, reloadreg, third_reloadreg)));
06914 special = 1;
06915 }
06916
06917 else
06918 {
06919
06920
06921
06922 gen_reload (reloadreg, second_reloadreg,
06923 rl->opnum, rl->when_needed);
06924 if (tertiary_reload >= 0)
06925 {
06926 rtx third_reloadreg = rld[tertiary_reload].reg_rtx;
06927
06928 gen_reload (third_reloadreg, reloadreg,
06929 rl->opnum, rl->when_needed);
06930 reloadreg = third_reloadreg;
06931 }
06932 }
06933 }
06934 }
06935 }
06936
06937
06938 if (! special)
06939 {
06940 rtx set;
06941
06942
06943
06944 if (! flag_expensive_optimizations
06945 || !REG_P (old)
06946 || !(set = single_set (insn))
06947 || rtx_equal_p (old, SET_DEST (set))
06948 || !reg_mentioned_p (old, SET_SRC (set))
06949 || !((REGNO (old) < FIRST_PSEUDO_REGISTER)
06950 && regno_clobbered_p (REGNO (old), insn, rl->mode, 0)))
06951 gen_reload (old, reloadreg, rl->opnum,
06952 rl->when_needed);
06953 }
06954
06955
06956 for (p = get_insns (); p; p = NEXT_INSN (p))
06957 if (INSN_P (p))
06958 {
06959 rtx pat = PATTERN (p);
06960
06961
06962
06963
06964
06965 note_stores (pat, forget_old_reloads_1, NULL);
06966
06967 if (reg_mentioned_p (rl->reg_rtx, pat))
06968 {
06969 rtx set = single_set (insn);
06970 if (reload_spill_index[j] < 0
06971 && set
06972 && SET_SRC (set) == rl->reg_rtx)
06973 {
06974 int src = REGNO (SET_SRC (set));
06975
06976 reload_spill_index[j] = src;
06977 SET_HARD_REG_BIT (reg_is_output_reload, src);
06978 if (find_regno_note (insn, REG_DEAD, src))
06979 SET_HARD_REG_BIT (reg_reloaded_died, src);
06980 }
06981 if (REGNO (rl->reg_rtx) < FIRST_PSEUDO_REGISTER)
06982 {
06983 int s = rl->secondary_out_reload;
06984 set = single_set (p);
06985
06986
06987
06988 if (s >= 0 && set == NULL_RTX)
06989
06990
06991
06992 ;
06993 else if (s >= 0
06994 && SET_SRC (set) == rl->reg_rtx
06995 && SET_DEST (set) == rld[s].reg_rtx)
06996 {
06997
06998
06999
07000
07001 rtx s_reg = rld[s].reg_rtx;
07002 rtx next = NEXT_INSN (p);
07003 rld[s].out = rl->out;
07004 rld[s].out_reg = rl->out_reg;
07005 set = single_set (next);
07006 if (set && SET_SRC (set) == s_reg
07007 && ! new_spill_reg_store[REGNO (s_reg)])
07008 {
07009 SET_HARD_REG_BIT (reg_is_output_reload,
07010 REGNO (s_reg));
07011 new_spill_reg_store[REGNO (s_reg)] = next;
07012 }
07013 }
07014 else
07015 new_spill_reg_store[REGNO (rl->reg_rtx)] = p;
07016 }
07017 }
07018 }
07019
07020 if (rl->when_needed == RELOAD_OTHER)
07021 {
07022 emit_insn (other_output_reload_insns[rl->opnum]);
07023 other_output_reload_insns[rl->opnum] = get_insns ();
07024 }
07025 else
07026 output_reload_insns[rl->opnum] = get_insns ();
07027
07028 if (flag_non_call_exceptions)
07029 copy_eh_notes (insn, get_insns ());
07030
07031 end_sequence ();
07032 }
07033
07034
07035
07036 static void
07037 do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
07038 {
07039 rtx insn = chain->insn;
07040 rtx old = (rl->in && MEM_P (rl->in)
07041 ? rl->in_reg : rl->in);
07042
07043 if (old != 0
07044
07045
07046 && (! reload_inherited[j] || (rl->out && ! rl->out_reg))
07047 && ! rtx_equal_p (rl->reg_rtx, old)
07048 && rl->reg_rtx != 0)
07049 emit_input_reload_insns (chain, rld + j, old, j);
07050
07051
07052
07053
07054 if (optimize && reload_inherited[j] && rl->in
07055 && MEM_P (rl->in)
07056 && MEM_P (rl->in_reg)
07057 && reload_spill_index[j] >= 0
07058 && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j]))
07059 rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]];
07060
07061
07062
07063
07064
07065 if (optimize
07066
07067
07068
07069 && rl->when_needed == RELOAD_FOR_INPUT
07070 && (reload_inherited[j] || reload_override_in[j])
07071 && rl->reg_rtx
07072 && REG_P (rl->reg_rtx)
07073 && spill_reg_store[REGNO (rl->reg_rtx)] != 0
07074 #if 0
07075
07076
07077
07078 && (REGNO (spill_reg_stored_to[REGNO (rl->reg_rtx)])
07079 >= FIRST_PSEUDO_REGISTER)
07080 #endif
07081
07082
07083
07084 && (dead_or_set_p (insn,
07085 spill_reg_stored_to[REGNO (rl->reg_rtx)])
07086 || rtx_equal_p (spill_reg_stored_to[REGNO (rl->reg_rtx)],
07087 rl->out_reg)))
07088 delete_output_reload (insn, j, REGNO (rl->reg_rtx));
07089 }
07090
07091
07092
07093
07094
07095 static void
07096 do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
07097 {
07098 rtx note, old;
07099 rtx insn = chain->insn;
07100
07101
07102
07103 rtx pseudo = rl->out_reg;
07104
07105 if (pseudo
07106 && optimize
07107 && REG_P (pseudo)
07108 && ! rtx_equal_p (rl->in_reg, pseudo)
07109 && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER
07110 && reg_last_reload_reg[REGNO (pseudo)])
07111 {
07112 int pseudo_no = REGNO (pseudo);
07113 int last_regno = REGNO (reg_last_reload_reg[pseudo_no]);
07114
07115
07116
07117
07118 if (TEST_HARD_REG_BIT (reg_reloaded_valid, last_regno)
07119 && reg_reloaded_contents[last_regno] == pseudo_no
07120 && spill_reg_store[last_regno]
07121 && rtx_equal_p (pseudo, spill_reg_stored_to[last_regno]))
07122 delete_output_reload (insn, j, last_regno);
07123 }
07124
07125 old = rl->out_reg;
07126 if (old == 0
07127 || rl->reg_rtx == old
07128 || rl->reg_rtx == 0)
07129 return;
07130
07131
07132
07133
07134 if ((REG_P (old) || GET_CODE (old) == SCRATCH)
07135 && (note = find_reg_note (insn, REG_UNUSED, old)) != 0)
07136 {
07137 XEXP (note, 0) = rl->reg_rtx;
07138 return;
07139 }
07140
07141 else if (GET_CODE (old) == SUBREG
07142 && REG_P (SUBREG_REG (old))
07143 && 0 != (note = find_reg_note (insn, REG_UNUSED,
07144 SUBREG_REG (old))))
07145 {
07146 XEXP (note, 0) = gen_lowpart_common (GET_MODE (old),
07147 rl->reg_rtx);
07148 return;
07149 }
07150 else if (GET_CODE (old) == SCRATCH)
07151
07152
07153 return;
07154
07155
07156 gcc_assert (NONJUMP_INSN_P (insn));
07157
07158 emit_output_reload_insns (chain, rld + j, j);
07159 }
07160
07161
07162
07163
07164
07165
07166
07167 static bool
07168 inherit_piecemeal_p (int r ATTRIBUTE_UNUSED, int regno ATTRIBUTE_UNUSED)
07169 {
07170 #ifdef CANNOT_CHANGE_MODE_CLASS
07171 return (!REG_CANNOT_CHANGE_MODE_P (reload_spill_index[r],
07172 GET_MODE (rld[r].reg_rtx),
07173 reg_raw_mode[reload_spill_index[r]])
07174 && !REG_CANNOT_CHANGE_MODE_P (regno,
07175 GET_MODE (rld[r].reg_rtx),
07176 reg_raw_mode[regno]));
07177 #else
07178 return true;
07179 #endif
07180 }
07181
07182
07183
07184 static void
07185 emit_reload_insns (struct insn_chain *chain)
07186 {
07187 rtx insn = chain->insn;
07188
07189 int j;
07190
07191 CLEAR_HARD_REG_SET (reg_reloaded_died);
07192
07193 for (j = 0; j < reload_n_operands; j++)
07194 input_reload_insns[j] = input_address_reload_insns[j]
07195 = inpaddr_address_reload_insns[j]
07196 = output_reload_insns[j] = output_address_reload_insns[j]
07197 = outaddr_address_reload_insns[j]
07198 = other_output_reload_insns[j] = 0;
07199 other_input_address_reload_insns = 0;
07200 other_input_reload_insns = 0;
07201 operand_reload_insns = 0;
07202 other_operand_reload_insns = 0;
07203
07204
07205 if (dump_file)
07206 {
07207 fprintf (dump_file, "\nReloads for insn # %d\n", INSN_UID (insn));
07208 debug_reload_to_stream (dump_file);
07209 }
07210
07211
07212
07213
07214
07215
07216 for (j = 0; j < n_reloads; j++)
07217 {
07218 if (rld[j].reg_rtx
07219 && REGNO (rld[j].reg_rtx) < FIRST_PSEUDO_REGISTER)
07220 new_spill_reg_store[REGNO (rld[j].reg_rtx)] = 0;
07221
07222 do_input_reload (chain, rld + j, j);
07223 do_output_reload (chain, rld + j, j);
07224 }
07225
07226
07227
07228
07229
07230
07231
07232
07233
07234
07235
07236
07237
07238
07239
07240
07241
07242
07243
07244
07245
07246
07247
07248
07249
07250 emit_insn_before (other_input_address_reload_insns, insn);
07251 emit_insn_before (other_input_reload_insns, insn);
07252
07253 for (j = 0; j < reload_n_operands; j++)
07254 {
07255 emit_insn_before (inpaddr_address_reload_insns[j], insn);
07256 emit_insn_before (input_address_reload_insns[j], insn);
07257 emit_insn_before (input_reload_insns[j], insn);
07258 }
07259
07260 emit_insn_before (other_operand_reload_insns, insn);
07261 emit_insn_before (operand_reload_insns, insn);
07262
07263 for (j = 0; j < reload_n_operands; j++)
07264 {
07265 rtx x = emit_insn_after (outaddr_address_reload_insns[j], insn);
07266 x = emit_insn_after (output_address_reload_insns[j], x);
07267 x = emit_insn_after (output_reload_insns[j], x);
07268 emit_insn_after (other_output_reload_insns[j], x);
07269 }
07270
07271
07272
07273
07274
07275
07276
07277
07278 for (j = 0; j < n_reloads; j++)
07279 {
07280 int r = reload_order[j];
07281 int i = reload_spill_index[r];
07282
07283
07284
07285
07286
07287 if (rld[r].in_reg != 0
07288 && ! (reload_inherited[r] || reload_override_in[r]))
07289 {
07290 rtx reg = rld[r].in_reg;
07291
07292 if (GET_CODE (reg) == SUBREG)
07293 reg = SUBREG_REG (reg);
07294
07295 if (REG_P (reg)
07296 && REGNO (reg) >= FIRST_PSEUDO_REGISTER
07297 && !REGNO_REG_SET_P (®_has_output_reload, REGNO (reg)))
07298 {
07299 int nregno = REGNO (reg);
07300
07301 if (reg_last_reload_reg[nregno])
07302 {
07303 int last_regno = REGNO (reg_last_reload_reg[nregno]);
07304
07305 if (reg_reloaded_contents[last_regno] == nregno)
07306 spill_reg_store[last_regno] = 0;
07307 }
07308 }
07309 }
07310
07311
07312
07313
07314
07315 if (i >= 0 && rld[r].reg_rtx != 0)
07316 {
07317 int nr = hard_regno_nregs[i][GET_MODE (rld[r].reg_rtx)];
07318 int k;
07319 int part_reaches_end = 0;
07320 int all_reaches_end = 1;
07321
07322
07323
07324 for (k = 0; k < nr; k++)
07325 {
07326 if (reload_reg_reaches_end_p (i + k, rld[r].opnum,
07327 rld[r].when_needed))
07328 part_reaches_end = 1;
07329 else
07330 all_reaches_end = 0;
07331 }
07332
07333
07334
07335 if (all_reaches_end)
07336 {
07337
07338
07339
07340 for (k = 0; k < nr; k++)
07341 {
07342 CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
07343 CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
07344 }
07345
07346
07347 if (rld[r].out != 0
07348 && (REG_P (rld[r].out)
07349 #ifdef AUTO_INC_DEC
07350 || ! rld[r].out_reg
07351 #endif
07352 || REG_P (rld[r].out_reg)))
07353 {
07354 rtx out = (REG_P (rld[r].out)
07355 ? rld[r].out
07356 : rld[r].out_reg
07357 ? rld[r].out_reg
07358 : XEXP (rld[r].in_reg, 0));
07359 int nregno = REGNO (out);
07360 int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
07361 : hard_regno_nregs[nregno]
07362 [GET_MODE (rld[r].reg_rtx)]);
07363 bool piecemeal;
07364
07365 spill_reg_store[i] = new_spill_reg_store[i];
07366 spill_reg_stored_to[i] = out;
07367 reg_last_reload_reg[nregno] = rld[r].reg_rtx;
07368
07369 piecemeal = (nregno < FIRST_PSEUDO_REGISTER
07370 && nr == nnr
07371 && inherit_piecemeal_p (r, nregno));
07372
07373
07374
07375
07376
07377
07378
07379 if (nregno < FIRST_PSEUDO_REGISTER)
07380 for (k = 1; k < nnr; k++)
07381 reg_last_reload_reg[nregno + k]
07382 = (piecemeal
07383 ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
07384 : 0);
07385
07386
07387 for (k = 0; k < nr; k++)
07388 {
07389 CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
07390 reg_reloaded_contents[i + k]
07391 = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
07392 ? nregno
07393 : nregno + k);
07394 reg_reloaded_insn[i + k] = insn;
07395 SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
07396 if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (out)))
07397 SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
07398 }
07399 }
07400
07401
07402
07403
07404 else if (rld[r].out_reg == 0
07405 && rld[r].in != 0
07406 && ((REG_P (rld[r].in)
07407 && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER
07408 && !REGNO_REG_SET_P (®_has_output_reload,
07409 REGNO (rld[r].in)))
07410 || (REG_P (rld[r].in_reg)
07411 && !REGNO_REG_SET_P (®_has_output_reload,
07412 REGNO (rld[r].in_reg))))
07413 && ! reg_set_p (rld[r].reg_rtx, PATTERN (insn)))
07414 {
07415 int nregno;
07416 int nnr;
07417 rtx in;
07418 bool piecemeal;
07419
07420 if (REG_P (rld[r].in)
07421 && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
07422 in = rld[r].in;
07423 else if (REG_P (rld[r].in_reg))
07424 in = rld[r].in_reg;
07425 else
07426 in = XEXP (rld[r].in_reg, 0);
07427 nregno = REGNO (in);
07428
07429 nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
07430 : hard_regno_nregs[nregno]
07431 [GET_MODE (rld[r].reg_rtx)]);
07432
07433 reg_last_reload_reg[nregno] = rld[r].reg_rtx;
07434
07435 piecemeal = (nregno < FIRST_PSEUDO_REGISTER
07436 && nr == nnr
07437 && inherit_piecemeal_p (r, nregno));
07438
07439 if (nregno < FIRST_PSEUDO_REGISTER)
07440 for (k = 1; k < nnr; k++)
07441 reg_last_reload_reg[nregno + k]
07442 = (piecemeal
07443 ? regno_reg_rtx[REGNO (rld[r].reg_rtx) + k]
07444 : 0);
07445
07446
07447
07448
07449
07450 if (! reload_inherited[r]
07451 || (rld[r].out && ! rld[r].out_reg))
07452 spill_reg_store[i] = 0;
07453
07454 for (k = 0; k < nr; k++)
07455 {
07456 CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k);
07457 reg_reloaded_contents[i + k]
07458 = (nregno >= FIRST_PSEUDO_REGISTER || !piecemeal
07459 ? nregno
07460 : nregno + k);
07461 reg_reloaded_insn[i + k] = insn;
07462 SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
07463 if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (in)))
07464 SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
07465 }
07466 }
07467 }
07468
07469
07470
07471 else if (part_reaches_end)
07472 {
07473 for (k = 0; k < nr; k++)
07474 if (reload_reg_reaches_end_p (i + k,
07475 rld[r].opnum,
07476 rld[r].when_needed))
07477 CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
07478 }
07479 }
07480
07481
07482
07483
07484
07485
07486
07487
07488
07489
07490
07491 if (i < 0
07492 && ((rld[r].out != 0
07493 && (REG_P (rld[r].out)
07494 || (MEM_P (rld[r].out)
07495 && REG_P (rld[r].out_reg))))
07496 || (rld[r].out == 0 && rld[r].out_reg
07497 && REG_P (rld[r].out_reg))))
07498 {
07499 rtx out = ((rld[r].out && REG_P (rld[r].out))
07500 ? rld[r].out : rld[r].out_reg);
07501 int nregno = REGNO (out);
07502 if (nregno >= FIRST_PSEUDO_REGISTER)
07503 {
07504 rtx src_reg, store_insn = NULL_RTX;
07505
07506 reg_last_reload_reg[nregno] = 0;
07507
07508
07509
07510
07511 src_reg = rld[r].reg_rtx;
07512
07513
07514
07515 if (! src_reg)
07516 {
07517 rtx set = single_set (insn);
07518 if (set && SET_DEST (set) == rld[r].out)
07519 {
07520 int k;
07521
07522 src_reg = SET_SRC (set);
07523 store_insn = insn;
07524 for (k = 0; k < n_reloads; k++)
07525 {
07526 if (rld[k].in == src_reg)
07527 {
07528 src_reg = rld[k].reg_rtx;
07529 break;
07530 }
07531 }
07532 }
07533 }
07534 else
07535 store_insn = new_spill_reg_store[REGNO (src_reg)];
07536 if (src_reg && REG_P (src_reg)
07537 && REGNO (src_reg) < FIRST_PSEUDO_REGISTER)
07538 {
07539 int src_regno = REGNO (src_reg);
07540 int nr = hard_regno_nregs[src_regno][rld[r].mode];
07541
07542
07543
07544
07545 rtx note = find_regno_note (insn, REG_DEAD, src_regno);
07546 if (! note && store_insn)
07547 note = find_regno_note (store_insn, REG_DEAD, src_regno);
07548 while (nr-- > 0)
07549 {
07550 spill_reg_store[src_regno + nr] = store_insn;
07551 spill_reg_stored_to[src_regno + nr] = out;
07552 reg_reloaded_contents[src_regno + nr] = nregno;
07553 reg_reloaded_insn[src_regno + nr] = store_insn;
07554 CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr);
07555 SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr);
07556 if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + nr,
07557 GET_MODE (src_reg)))
07558 SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
07559 src_regno + nr);
07560 SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr);
07561 if (note)
07562 SET_HARD_REG_BIT (reg_reloaded_died, src_regno);
07563 else
07564 CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno);
07565 }
07566 reg_last_reload_reg[nregno] = src_reg;
07567
07568
07569
07570 SET_REGNO_REG_SET (®_has_output_reload,
07571 nregno);
07572 }
07573 }
07574 else
07575 {
07576 int num_regs = hard_regno_nregs[nregno][GET_MODE (out)];
07577
07578 while (num_regs-- > 0)
07579 reg_last_reload_reg[nregno + num_regs] = 0;
07580 }
07581 }
07582 }
07583 IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died);
07584 }
07585
07586
07587
07588
07589 static rtx
07590 emit_insn_if_valid_for_reload (rtx insn)
07591 {
07592 rtx last = get_last_insn ();
07593 int code;
07594
07595 insn = emit_insn (insn);
07596 code = recog_memoized (insn);
07597
07598 if (code >= 0)
07599 {
07600 extract_insn (insn);
07601
07602
07603
07604 if (constrain_operands (1))
07605 return insn;
07606 }
07607
07608 delete_insns_since (last);
07609 return NULL;
07610 }
07611
07612
07613
07614
07615
07616
07617
07618 static rtx
07619 gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
07620 {
07621 rtx last = get_last_insn ();
07622 rtx tem;
07623
07624
07625
07626 if (GET_CODE (in) == SUBREG
07627 && (GET_MODE_SIZE (GET_MODE (in))
07628 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in))))
07629 && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0)
07630 in = SUBREG_REG (in), out = tem;
07631 else if (GET_CODE (out) == SUBREG
07632 && (GET_MODE_SIZE (GET_MODE (out))
07633 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out))))
07634 && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0)
07635 out = SUBREG_REG (out), in = tem;
07636
07637
07638
07639
07640
07641
07642
07643
07644
07645
07646
07647
07648
07649
07650
07651
07652
07653
07654
07655
07656
07657
07658
07659
07660
07661
07662
07663
07664
07665
07666
07667
07668
07669 if (GET_CODE (in) == PLUS
07670 && (REG_P (XEXP (in, 0))
07671 || GET_CODE (XEXP (in, 0)) == SUBREG
07672 || MEM_P (XEXP (in, 0)))
07673 && (REG_P (XEXP (in, 1))
07674 || GET_CODE (XEXP (in, 1)) == SUBREG
07675 || CONSTANT_P (XEXP (in, 1))
07676 || MEM_P (XEXP (in, 1))))
07677 {
07678
07679
07680
07681
07682
07683
07684
07685
07686
07687
07688
07689
07690
07691 rtx op0, op1, tem, insn;
07692 int code;
07693
07694 op0 = find_replacement (&XEXP (in, 0));
07695 op1 = find_replacement (&XEXP (in, 1));
07696
07697
07698
07699
07700
07701
07702
07703
07704 if (REG_P (XEXP (in, 1))
07705 && REGNO (out) == REGNO (XEXP (in, 1)))
07706 tem = op0, op0 = op1, op1 = tem;
07707
07708 if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
07709 in = gen_rtx_PLUS (GET_MODE (in), op0, op1);
07710
07711 insn = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
07712 if (insn)
07713 return insn;
07714
07715
07716
07717
07718
07719
07720
07721
07722
07723
07724
07725
07726
07727
07728
07729
07730 code = (int) add_optab->handlers[(int) GET_MODE (out)].insn_code;
07731
07732 if (CONSTANT_P (op1) || MEM_P (op1) || GET_CODE (op1) == SUBREG
07733 || (REG_P (op1)
07734 && REGNO (op1) >= FIRST_PSEUDO_REGISTER)
07735 || (code != CODE_FOR_nothing
07736 && ! ((*insn_data[code].operand[2].predicate)
07737 (op1, insn_data[code].operand[2].mode))))
07738 tem = op0, op0 = op1, op1 = tem;
07739
07740 gen_reload (out, op0, opnum, type);
07741
07742
07743
07744
07745
07746 if (rtx_equal_p (op0, op1))
07747 op1 = out;
07748
07749 insn = emit_insn_if_valid_for_reload (gen_add2_insn (out, op1));
07750 if (insn)
07751 {
07752
07753 REG_NOTES (insn)
07754 = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn));
07755 return insn;
07756 }
07757
07758
07759
07760
07761 gen_reload (out, op1, opnum, type);
07762 insn = emit_insn (gen_add2_insn (out, op0));
07763 REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn));
07764 }
07765
07766 #ifdef SECONDARY_MEMORY_NEEDED
07767
07768 else if ((REG_P (in) || GET_CODE (in) == SUBREG)
07769 && reg_or_subregno (in) < FIRST_PSEUDO_REGISTER
07770 && (REG_P (out) || GET_CODE (out) == SUBREG)
07771 && reg_or_subregno (out) < FIRST_PSEUDO_REGISTER
07772 && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (reg_or_subregno (in)),
07773 REGNO_REG_CLASS (reg_or_subregno (out)),
07774 GET_MODE (out)))
07775 {
07776
07777 rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type);
07778
07779 if (GET_MODE (loc) != GET_MODE (out))
07780 out = gen_rtx_REG (GET_MODE (loc), REGNO (out));
07781
07782 if (GET_MODE (loc) != GET_MODE (in))
07783 in = gen_rtx_REG (GET_MODE (loc), REGNO (in));
07784
07785 gen_reload (loc, in, opnum, type);
07786 gen_reload (out, loc, opnum, type);
07787 }
07788 #endif
07789 else if (REG_P (out) && UNARY_P (in))
07790 {
07791 rtx insn;
07792 rtx op1;
07793 rtx out_moded;
07794 rtx set;
07795
07796 op1 = find_replacement (&XEXP (in, 0));
07797 if (op1 != XEXP (in, 0))
07798 in = gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in), op1);
07799
07800
07801 set = emit_insn_if_valid_for_reload (gen_rtx_SET (VOIDmode, out, in));
07802 if (set)
07803 return set;
07804
07805
07806
07807
07808
07809 if (GET_MODE (op1) != GET_MODE (out))
07810 out_moded = gen_rtx_REG (GET_MODE (op1), REGNO (out));
07811 else
07812 out_moded = out;
07813
07814 gen_reload (out_moded, op1, opnum, type);
07815
07816 insn
07817 = gen_rtx_SET (VOIDmode, out,
07818 gen_rtx_fmt_e (GET_CODE (in), GET_MODE (in),
07819 out_moded));
07820 insn = emit_insn_if_valid_for_reload (insn);
07821 if (insn)
07822 {
07823 REG_NOTES (insn)
07824 = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn));
07825 return insn;
07826 }
07827
07828 fatal_insn ("Failure trying to reload:", set);
07829 }
07830
07831 else if (OBJECT_P (in) || GET_CODE (in) == SUBREG)
07832 {
07833 tem = emit_insn (gen_move_insn (out, in));
07834
07835 mark_jump_label (in, tem, 0);
07836 }
07837
07838 #ifdef HAVE_reload_load_address
07839 else if (HAVE_reload_load_address)
07840 emit_insn (gen_reload_load_address (out, in));
07841 #endif
07842
07843
07844 else
07845 emit_insn (gen_rtx_SET (VOIDmode, out, in));
07846
07847
07848
07849
07850
07851
07852
07853 return last ? NEXT_INSN (last) : get_insns ();
07854 }
07855
07856
07857
07858
07859
07860
07861
07862
07863
07864
07865 static void
07866 delete_output_reload (rtx insn, int j, int last_reload_reg)
07867 {
07868 rtx output_reload_insn = spill_reg_store[last_reload_reg];
07869 rtx reg = spill_reg_stored_to[last_reload_reg];
07870 int k;
07871 int n_occurrences;
07872 int n_inherited = 0;
07873 rtx i1;
07874 rtx substed;
07875
07876
07877
07878 if (INSN_DELETED_P (output_reload_insn))
07879 return;
07880
07881
07882
07883 while (GET_CODE (reg) == SUBREG)
07884 reg = SUBREG_REG (reg);
07885 substed = reg_equiv_memory_loc[REGNO (reg)];
07886
07887
07888
07889 for (k = n_reloads - 1; k >= 0; k--)
07890 {
07891 rtx reg2 = rld[k].in;
07892 if (! reg2)
07893 continue;
07894 if (MEM_P (reg2) || reload_override_in[k])
07895 reg2 = rld[k].in_reg;
07896 #ifdef AUTO_INC_DEC
07897 if (rld[k].out && ! rld[k].out_reg)
07898 reg2 = XEXP (rld[k].in_reg, 0);
07899 #endif
07900 while (GET_CODE (reg2) == SUBREG)
07901 reg2 = SUBREG_REG (reg2);
07902 if (rtx_equal_p (reg2, reg))
07903 {
07904 if (reload_inherited[k] || reload_override_in[k] || k == j)
07905 {
07906 n_inherited++;
07907 reg2 = rld[k].out_reg;
07908 if (! reg2)
07909 continue;
07910 while (GET_CODE (reg2) == SUBREG)
07911 reg2 = XEXP (reg2, 0);
07912 if (rtx_equal_p (reg2, reg))
07913 n_inherited++;
07914 }
07915 else
07916 return;
07917 }
07918 }
07919 n_occurrences = count_occurrences (PATTERN (insn), reg, 0);
07920 if (substed)
07921 n_occurrences += count_occurrences (PATTERN (insn),
07922 eliminate_regs (substed, 0,
07923 NULL_RTX), 0);
07924 for (i1 = reg_equiv_alt_mem_list [REGNO (reg)]; i1; i1 = XEXP (i1, 1))
07925 {
07926 gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
07927 n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);
07928 }
07929 if (n_occurrences > n_inherited)
07930 return;
07931
07932
07933
07934
07935
07936
07937 for (i1 = NEXT_INSN (output_reload_insn);
07938 i1 != insn; i1 = NEXT_INSN (i1))
07939 {
07940 if (NOTE_INSN_BASIC_BLOCK_P (i1))
07941 return;
07942 if ((NONJUMP_INSN_P (i1) || CALL_P (i1))
07943 && reg_mentioned_p (reg, PATTERN (i1)))
07944 {
07945
07946
07947 while (NONJUMP_INSN_P (i1) && GET_CODE (PATTERN (i1)) == USE)
07948 {
07949 n_occurrences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0;
07950 i1 = NEXT_INSN (i1);
07951 }
07952 if (n_occurrences <= n_inherited && i1 == insn)
07953 break;
07954 return;
07955 }
07956 }
07957
07958
07959 for (k = hard_regno_nregs[last_reload_reg][GET_MODE (reg)]; k-- > 0; )
07960 {
07961 spill_reg_store[last_reload_reg + k] = 0;
07962 spill_reg_stored_to[last_reload_reg + k] = 0;
07963 }
07964
07965
07966
07967
07968
07969
07970
07971
07972
07973 if (rld[j].out != rld[j].in
07974 && REG_N_DEATHS (REGNO (reg)) == 1
07975 && REG_N_SETS (REGNO (reg)) == 1
07976 && REG_BASIC_BLOCK (REGNO (reg)) >= 0
07977 && find_regno_note (insn, REG_DEAD, REGNO (reg)))
07978 {
07979 rtx i2;
07980
07981
07982
07983
07984
07985 for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2))
07986 {
07987 rtx set = single_set (i2);
07988
07989
07990
07991 if (set != 0 && SET_DEST (set) == reg)
07992 continue;
07993 if (LABEL_P (i2)
07994 || JUMP_P (i2))
07995 break;
07996 if ((NONJUMP_INSN_P (i2) || CALL_P (i2))
07997 && reg_mentioned_p (reg, PATTERN (i2)))
07998 {
07999
08000
08001 delete_address_reloads (output_reload_insn, insn);
08002 delete_insn (output_reload_insn);
08003 return;
08004 }
08005 }
08006
08007
08008
08009 for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2))
08010 {
08011 rtx set = single_set (i2);
08012
08013 if (set != 0 && SET_DEST (set) == reg)
08014 {
08015 delete_address_reloads (i2, insn);
08016 delete_insn (i2);
08017 }
08018 if (LABEL_P (i2)
08019 || JUMP_P (i2))
08020 break;
08021 }
08022
08023
08024 reg_renumber[REGNO (reg)] = REGNO (rld[j].reg_rtx);
08025 alter_reg (REGNO (reg), -1);
08026 }
08027 else
08028 {
08029 delete_address_reloads (output_reload_insn, insn);
08030 delete_insn (output_reload_insn);
08031 }
08032 }
08033
08034
08035
08036
08037 static void
08038 delete_address_reloads (rtx dead_insn, rtx current_insn)
08039 {
08040 rtx set = single_set (dead_insn);
08041 rtx set2, dst, prev, next;
08042 if (set)
08043 {
08044 rtx dst = SET_DEST (set);
08045 if (MEM_P (dst))
08046 delete_address_reloads_1 (dead_insn, XEXP (dst, 0), current_insn);
08047 }
08048
08049
08050 prev = PREV_INSN (dead_insn);
08051 next = NEXT_INSN (dead_insn);
08052 if (! prev || ! next)
08053 return;
08054 set = single_set (next);
08055 set2 = single_set (prev);
08056 if (! set || ! set2
08057 || GET_CODE (SET_SRC (set)) != PLUS || GET_CODE (SET_SRC (set2)) != PLUS
08058 || GET_CODE (XEXP (SET_SRC (set), 1)) != CONST_INT
08059 || GET_CODE (XEXP (SET_SRC (set2), 1)) != CONST_INT)
08060 return;
08061 dst = SET_DEST (set);
08062 if (! rtx_equal_p (dst, SET_DEST (set2))
08063 || ! rtx_equal_p (dst, XEXP (SET_SRC (set), 0))
08064 || ! rtx_equal_p (dst, XEXP (SET_SRC (set2), 0))
08065 || (INTVAL (XEXP (SET_SRC (set), 1))
08066 != -INTVAL (XEXP (SET_SRC (set2), 1))))
08067 return;
08068 delete_related_insns (prev);
08069 delete_related_insns (next);
08070 }
08071
08072
08073 static void
08074 delete_address_reloads_1 (rtx dead_insn, rtx x, rtx current_insn)
08075 {
08076 rtx prev, set, dst, i2;
08077 int i, j;
08078 enum rtx_code code = GET_CODE (x);
08079
08080 if (code != REG)
08081 {
08082 const char *fmt = GET_RTX_FORMAT (code);
08083 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
08084 {
08085 if (fmt[i] == 'e')
08086 delete_address_reloads_1 (dead_insn, XEXP (x, i), current_insn);
08087 else if (fmt[i] == 'E')
08088 {
08089 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
08090 delete_address_reloads_1 (dead_insn, XVECEXP (x, i, j),
08091 current_insn);
08092 }
08093 }
08094 return;
08095 }
08096
08097 if (spill_reg_order[REGNO (x)] < 0)
08098 return;
08099
08100
08101
08102 for (prev = PREV_INSN (dead_insn); prev; prev = PREV_INSN (prev))
08103 {
08104 code = GET_CODE (prev);
08105 if (code == CODE_LABEL || code == JUMP_INSN)
08106 return;
08107 if (!INSN_P (prev))
08108 continue;
08109 if (reg_set_p (x, PATTERN (prev)))
08110 break;
08111 if (reg_referenced_p (x, PATTERN (prev)))
08112 return;
08113 }
08114 if (! prev || INSN_UID (prev) < reload_first_uid)
08115 return;
08116
08117 set = single_set (prev);
08118 if (! set)
08119 return;
08120 dst = SET_DEST (set);
08121 if (!REG_P (dst)
08122 || ! rtx_equal_p (dst, x))
08123 return;
08124 if (! reg_set_p (dst, PATTERN (dead_insn)))
08125 {
08126
08127
08128 for (i2 = NEXT_INSN (dead_insn); i2; i2 = NEXT_INSN (i2))
08129 {
08130 if (LABEL_P (i2))
08131 break;
08132 if (! INSN_P (i2))
08133 continue;
08134 if (reg_referenced_p (dst, PATTERN (i2)))
08135 {
08136
08137
08138
08139
08140 if (i2 == current_insn)
08141 {
08142 for (j = n_reloads - 1; j >= 0; j--)
08143 if ((rld[j].reg_rtx == dst && reload_inherited[j])
08144 || reload_override_in[j] == dst)
08145 return;
08146 for (j = n_reloads - 1; j >= 0; j--)
08147 if (rld[j].in && rld[j].reg_rtx == dst)
08148 break;
08149 if (j >= 0)
08150 break;
08151 }
08152 return;
08153 }
08154 if (JUMP_P (i2))
08155 break;
08156
08157
08158
08159 if (i2 == current_insn)
08160 {
08161 for (j = n_reloads - 1; j >= 0; j--)
08162 if ((rld[j].reg_rtx == dst && reload_inherited[j])
08163 || reload_override_in[j] == dst)
08164 return;
08165
08166
08167
08168
08169
08170 }
08171 if (reg_set_p (dst, PATTERN (i2)))
08172 break;
08173 }
08174 }
08175 delete_address_reloads_1 (prev, SET_SRC (set), current_insn);
08176 reg_reloaded_contents[REGNO (dst)] = -1;
08177 delete_insn (prev);
08178 }
08179
08180
08181
08182
08183
08184
08185
08186
08187
08188
08189
08190
08191 static rtx
08192 inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
08193 {
08194
08195 rtx incloc = find_replacement (&XEXP (value, 0));
08196
08197 int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC
08198 || GET_CODE (value) == POST_MODIFY);
08199 rtx last;
08200 rtx inc;
08201 rtx add_insn;
08202 int code;
08203 rtx store;
08204 rtx real_in = in == value ? incloc : in;
08205
08206
08207
08208
08209
08210 if (REG_P (incloc))
08211 reg_last_reload_reg[REGNO (incloc)] = 0;
08212
08213 if (GET_CODE (value) == PRE_MODIFY || GET_CODE (value) == POST_MODIFY)
08214 {
08215 gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS);
08216 inc = find_replacement (&XEXP (XEXP (value, 1), 1));
08217 }
08218 else
08219 {
08220 if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC)
08221 inc_amount = -inc_amount;
08222
08223 inc = GEN_INT (inc_amount);
08224 }
08225
08226
08227 if (post && real_in != reloadreg)
08228 emit_insn (gen_move_insn (reloadreg, real_in));
08229
08230 if (in == value)
08231 {
08232
08233
08234
08235 last = get_last_insn ();
08236 add_insn = emit_insn (gen_rtx_SET (VOIDmode, incloc,
08237 gen_rtx_PLUS (GET_MODE (incloc),
08238 incloc, inc)));
08239
08240 code = recog_memoized (add_insn);
08241 if (code >= 0)
08242 {
08243 extract_insn (add_insn);
08244 if (constrain_operands (1))
08245 {
08246
08247
08248
08249
08250 if (! post)
08251 emit_insn (gen_move_insn (reloadreg, incloc));
08252
08253 return add_insn;
08254 }
08255 }
08256 delete_insns_since (last);
08257 }
08258
08259
08260
08261
08262
08263
08264 if (! post)
08265 {
08266 if (in != reloadreg)
08267 emit_insn (gen_move_insn (reloadreg, real_in));
08268 emit_insn (gen_add2_insn (reloadreg, inc));
08269 store = emit_insn (gen_move_insn (incloc, reloadreg));
08270 }
08271 else
08272 {
08273
08274
08275
08276
08277
08278
08279
08280
08281
08282 emit_insn (gen_add2_insn (reloadreg, inc));
08283 store = emit_insn (gen_move_insn (incloc, reloadreg));
08284 if (GET_CODE (inc) == CONST_INT)
08285 emit_insn (gen_add2_insn (reloadreg, GEN_INT (-INTVAL(inc))));
08286 else
08287 emit_insn (gen_sub2_insn (reloadreg, inc));
08288 }
08289
08290 return store;
08291 }
08292
08293 #ifdef AUTO_INC_DEC
08294 static void
08295 add_auto_inc_notes (rtx insn, rtx x)
08296 {
08297 enum rtx_code code = GET_CODE (x);
08298 const char *fmt;
08299 int i, j;
08300
08301 if (code == MEM && auto_inc_p (XEXP (x, 0)))
08302 {
08303 REG_NOTES (insn)
08304 = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn));
08305 return;
08306 }
08307
08308
08309 fmt = GET_RTX_FORMAT (code);
08310 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
08311 {
08312 if (fmt[i] == 'e')
08313 add_auto_inc_notes (insn, XEXP (x, i));
08314 else if (fmt[i] == 'E')
08315 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
08316 add_auto_inc_notes (insn, XVECEXP (x, i, j));
08317 }
08318 }
08319 #endif
08320
08321
08322 static void
08323 copy_eh_notes (rtx insn, rtx x)
08324 {
08325 rtx eh_note = find_reg_note (insn, REG_EH_REGION, NULL_RTX);
08326 if (eh_note)
08327 {
08328 for (; x != 0; x = NEXT_INSN (x))
08329 {
08330 if (may_trap_p (PATTERN (x)))
08331 REG_NOTES (x)
08332 = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (eh_note, 0),
08333 REG_NOTES (x));
08334 }
08335 }
08336 }
08337
08338
08339
08340
08341
08342
08343
08344 void
08345 fixup_abnormal_edges (void)
08346 {
08347 bool inserted = false;
08348 basic_block bb;
08349
08350 FOR_EACH_BB (bb)
08351 {
08352 edge e;
08353 edge_iterator ei;
08354
08355
08356
08357 FOR_EACH_EDGE (e, ei, bb->succs)
08358 {
08359 if (e->flags & EDGE_ABNORMAL_CALL)
08360 break;
08361 if ((e->flags & (EDGE_ABNORMAL | EDGE_EH))
08362 == (EDGE_ABNORMAL | EDGE_EH))
08363 break;
08364 }
08365 if (e && !CALL_P (BB_END (bb))
08366 && !can_throw_internal (BB_END (bb)))
08367 {
08368 rtx insn;
08369
08370
08371
08372 insn = BB_END (bb);
08373 while ((NONJUMP_INSN_P (insn) || NOTE_P (insn))
08374 && !can_throw_internal (insn)
08375 && insn != BB_HEAD (bb))
08376 insn = PREV_INSN (insn);
08377
08378 if (CALL_P (insn) || can_throw_internal (insn))
08379 {
08380 rtx stop, next;
08381
08382 stop = NEXT_INSN (BB_END (bb));
08383 BB_END (bb) = insn;
08384 insn = NEXT_INSN (insn);
08385
08386 FOR_EACH_EDGE (e, ei, bb->succs)
08387 if (e->flags & EDGE_FALLTHRU)
08388 break;
08389
08390 while (insn && insn != stop)
08391 {
08392 next = NEXT_INSN (insn);
08393 if (INSN_P (insn))
08394 {
08395 delete_insn (insn);
08396
08397
08398
08399
08400
08401
08402 if (GET_CODE (PATTERN (insn)) != USE)
08403 {
08404
08405 INSN_DELETED_P (insn) = 0;
08406 PREV_INSN (insn) = NULL_RTX;
08407 NEXT_INSN (insn) = NULL_RTX;
08408
08409 insert_insn_on_edge (insn, e);
08410 inserted = true;
08411 }
08412 }
08413 insn = next;
08414 }
08415 }
08416
08417
08418
08419
08420
08421 else
08422 purge_dead_edges (bb);
08423 }
08424 }
08425
08426
08427 if (flag_non_call_exceptions)
08428 {
08429 sbitmap blocks;
08430 blocks = sbitmap_alloc (last_basic_block);
08431 sbitmap_ones (blocks);
08432 find_many_sub_basic_blocks (blocks);
08433 }
08434
08435 if (inserted)
08436 commit_edge_insertions ();
08437
08438 #ifdef ENABLE_CHECKING
08439
08440
08441
08442 verify_flow_info ();
08443 #endif
08444 }