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