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