reload1.c revision 107590
118334Speter/* Reload pseudo regs into hard regs for insns that require hard regs. 290075Sobrien Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 390075Sobrien 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 418334Speter 590075SobrienThis file is part of GCC. 618334Speter 790075SobrienGCC is free software; you can redistribute it and/or modify it under 890075Sobrienthe terms of the GNU General Public License as published by the Free 990075SobrienSoftware Foundation; either version 2, or (at your option) any later 1090075Sobrienversion. 1118334Speter 1290075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1390075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1490075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1590075Sobrienfor more details. 1618334Speter 1718334SpeterYou should have received a copy of the GNU General Public License 1890075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 1990075SobrienSoftware Foundation, 59 Temple Place - Suite 330, Boston, MA 2090075Sobrien02111-1307, USA. */ 2118334Speter 2218334Speter#include "config.h" 2350397Sobrien#include "system.h" 2450397Sobrien 2550397Sobrien#include "machmode.h" 2650397Sobrien#include "hard-reg-set.h" 2718334Speter#include "rtl.h" 2890075Sobrien#include "tm_p.h" 2918334Speter#include "obstack.h" 3018334Speter#include "insn-config.h" 3118334Speter#include "flags.h" 3290075Sobrien#include "function.h" 3318334Speter#include "expr.h" 3490075Sobrien#include "optabs.h" 3518334Speter#include "regs.h" 3652284Sobrien#include "basic-block.h" 3718334Speter#include "reload.h" 3818334Speter#include "recog.h" 3918334Speter#include "output.h" 4090075Sobrien#include "cselib.h" 4118334Speter#include "real.h" 4250397Sobrien#include "toplev.h" 4390075Sobrien#include "except.h" 4496263Sobrien#include "tree.h" 4518334Speter 4618334Speter/* This file contains the reload pass of the compiler, which is 4718334Speter run after register allocation has been done. It checks that 4818334Speter each insn is valid (operands required to be in registers really 4918334Speter are in registers of the proper class) and fixes up invalid ones 5018334Speter by copying values temporarily into registers for the insns 5118334Speter that need them. 5218334Speter 5318334Speter The results of register allocation are described by the vector 5418334Speter reg_renumber; the insns still contain pseudo regs, but reg_renumber 5518334Speter can be used to find which hard reg, if any, a pseudo reg is in. 5618334Speter 5718334Speter The technique we always use is to free up a few hard regs that are 5818334Speter called ``reload regs'', and for each place where a pseudo reg 5918334Speter must be in a hard reg, copy it temporarily into one of the reload regs. 6018334Speter 6152284Sobrien Reload regs are allocated locally for every instruction that needs 6252284Sobrien reloads. When there are pseudos which are allocated to a register that 6352284Sobrien has been chosen as a reload reg, such pseudos must be ``spilled''. 6452284Sobrien This means that they go to other hard regs, or to stack slots if no other 6518334Speter available hard regs can be found. Spilling can invalidate more 6618334Speter insns, requiring additional need for reloads, so we must keep checking 6718334Speter until the process stabilizes. 6818334Speter 6918334Speter For machines with different classes of registers, we must keep track 7018334Speter of the register class needed for each reload, and make sure that 7118334Speter we allocate enough reload registers of each class. 7218334Speter 7318334Speter The file reload.c contains the code that checks one insn for 7418334Speter validity and reports the reloads that it needs. This file 7518334Speter is in charge of scanning the entire rtl code, accumulating the 7618334Speter reload needs, spilling, assigning reload registers to use for 7718334Speter fixing up each insn, and generating the new insns to copy values 7818334Speter into the reload registers. */ 7918334Speter 8018334Speter#ifndef REGISTER_MOVE_COST 8190075Sobrien#define REGISTER_MOVE_COST(m, x, y) 2 8218334Speter#endif 8390075Sobrien 8490075Sobrien#ifndef LOCAL_REGNO 8590075Sobrien#define LOCAL_REGNO(REGNO) 0 8690075Sobrien#endif 8718334Speter 8818334Speter/* During reload_as_needed, element N contains a REG rtx for the hard reg 8950397Sobrien into which reg N has been reloaded (perhaps for a previous insn). */ 9018334Speterstatic rtx *reg_last_reload_reg; 9118334Speter 9218334Speter/* Elt N nonzero if reg_last_reload_reg[N] has been set in this insn 9318334Speter for an output reload that stores into reg N. */ 9418334Speterstatic char *reg_has_output_reload; 9518334Speter 9618334Speter/* Indicates which hard regs are reload-registers for an output reload 9718334Speter in the current insn. */ 9818334Speterstatic HARD_REG_SET reg_is_output_reload; 9918334Speter 10018334Speter/* Element N is the constant value to which pseudo reg N is equivalent, 10118334Speter or zero if pseudo reg N is not equivalent to a constant. 10218334Speter find_reloads looks at this in order to replace pseudo reg N 10318334Speter with the constant it stands for. */ 10418334Speterrtx *reg_equiv_constant; 10518334Speter 10618334Speter/* Element N is a memory location to which pseudo reg N is equivalent, 10718334Speter prior to any register elimination (such as frame pointer to stack 10818334Speter pointer). Depending on whether or not it is a valid address, this value 10918334Speter is transferred to either reg_equiv_address or reg_equiv_mem. */ 11018334Speterrtx *reg_equiv_memory_loc; 11118334Speter 11218334Speter/* Element N is the address of stack slot to which pseudo reg N is equivalent. 11318334Speter This is used when the address is not valid as a memory address 11418334Speter (because its displacement is too big for the machine.) */ 11518334Speterrtx *reg_equiv_address; 11618334Speter 11718334Speter/* Element N is the memory slot to which pseudo reg N is equivalent, 11818334Speter or zero if pseudo reg N is not equivalent to a memory slot. */ 11918334Speterrtx *reg_equiv_mem; 12018334Speter 12118334Speter/* Widest width in which each pseudo reg is referred to (via subreg). */ 12290075Sobrienstatic unsigned int *reg_max_ref_width; 12318334Speter 12452284Sobrien/* Element N is the list of insns that initialized reg N from its equivalent 12518334Speter constant or memory slot. */ 12618334Speterstatic rtx *reg_equiv_init; 12718334Speter 12852284Sobrien/* Vector to remember old contents of reg_renumber before spilling. */ 12952284Sobrienstatic short *reg_old_renumber; 13052284Sobrien 13150397Sobrien/* During reload_as_needed, element N contains the last pseudo regno reloaded 13252284Sobrien into hard register N. If that pseudo reg occupied more than one register, 13318334Speter reg_reloaded_contents points to that pseudo for each spill register in 13418334Speter use; all of these must remain set for an inheritance to occur. */ 13518334Speterstatic int reg_reloaded_contents[FIRST_PSEUDO_REGISTER]; 13618334Speter 13718334Speter/* During reload_as_needed, element N contains the insn for which 13850397Sobrien hard register N was last used. Its contents are significant only 13950397Sobrien when reg_reloaded_valid is set for this register. */ 14018334Speterstatic rtx reg_reloaded_insn[FIRST_PSEUDO_REGISTER]; 14118334Speter 14250397Sobrien/* Indicate if reg_reloaded_insn / reg_reloaded_contents is valid */ 14350397Sobrienstatic HARD_REG_SET reg_reloaded_valid; 14450397Sobrien/* Indicate if the register was dead at the end of the reload. 14550397Sobrien This is only valid if reg_reloaded_contents is set and valid. */ 14650397Sobrienstatic HARD_REG_SET reg_reloaded_dead; 14750397Sobrien 14818334Speter/* Number of spill-regs so far; number of valid elements of spill_regs. */ 14918334Speterstatic int n_spills; 15018334Speter 15118334Speter/* In parallel with spill_regs, contains REG rtx's for those regs. 15218334Speter Holds the last rtx used for any given reg, or 0 if it has never 15318334Speter been used for spilling yet. This rtx is reused, provided it has 15418334Speter the proper mode. */ 15518334Speterstatic rtx spill_reg_rtx[FIRST_PSEUDO_REGISTER]; 15618334Speter 15718334Speter/* In parallel with spill_regs, contains nonzero for a spill reg 15818334Speter that was stored after the last time it was used. 15918334Speter The precise value is the insn generated to do the store. */ 16018334Speterstatic rtx spill_reg_store[FIRST_PSEUDO_REGISTER]; 16118334Speter 16252284Sobrien/* This is the register that was stored with spill_reg_store. This is a 16352284Sobrien copy of reload_out / reload_out_reg when the value was stored; if 16452284Sobrien reload_out is a MEM, spill_reg_stored_to will be set to reload_out_reg. */ 16552284Sobrienstatic rtx spill_reg_stored_to[FIRST_PSEUDO_REGISTER]; 16652284Sobrien 16718334Speter/* This table is the inverse mapping of spill_regs: 16818334Speter indexed by hard reg number, 16918334Speter it contains the position of that reg in spill_regs, 17090075Sobrien or -1 for something that is not in spill_regs. 17152284Sobrien 17252284Sobrien ?!? This is no longer accurate. */ 17318334Speterstatic short spill_reg_order[FIRST_PSEUDO_REGISTER]; 17418334Speter 17552284Sobrien/* This reg set indicates registers that can't be used as spill registers for 17652284Sobrien the currently processed insn. These are the hard registers which are live 17752284Sobrien during the insn, but not allocated to pseudos, as well as fixed 17852284Sobrien registers. */ 17952284Sobrienstatic HARD_REG_SET bad_spill_regs; 18018334Speter 18152284Sobrien/* These are the hard registers that can't be used as spill register for any 18252284Sobrien insn. This includes registers used for user variables and registers that 18352284Sobrien we can't eliminate. A register that appears in this set also can't be used 18452284Sobrien to retry register allocation. */ 18552284Sobrienstatic HARD_REG_SET bad_spill_regs_global; 18618334Speter 18752284Sobrien/* Describes order of use of registers for reloading 18852284Sobrien of spilled pseudo-registers. `n_spills' is the number of 18952284Sobrien elements that are actually valid; new ones are added at the end. 19018334Speter 19152284Sobrien Both spill_regs and spill_reg_order are used on two occasions: 19252284Sobrien once during find_reload_regs, where they keep track of the spill registers 19352284Sobrien for a single insn, but also during reload_as_needed where they show all 19452284Sobrien the registers ever used by reload. For the latter case, the information 19552284Sobrien is calculated during finish_spills. */ 19618334Speterstatic short spill_regs[FIRST_PSEUDO_REGISTER]; 19718334Speter 19852284Sobrien/* This vector of reg sets indicates, for each pseudo, which hard registers 19952284Sobrien may not be used for retrying global allocation because the register was 20052284Sobrien formerly spilled from one of them. If we allowed reallocating a pseudo to 20152284Sobrien a register that it was already allocated to, reload might not 20252284Sobrien terminate. */ 20352284Sobrienstatic HARD_REG_SET *pseudo_previous_regs; 20450397Sobrien 20552284Sobrien/* This vector of reg sets indicates, for each pseudo, which hard 20652284Sobrien registers may not be used for retrying global allocation because they 20752284Sobrien are used as spill registers during one of the insns in which the 20852284Sobrien pseudo is live. */ 20952284Sobrienstatic HARD_REG_SET *pseudo_forbidden_regs; 21050397Sobrien 21152284Sobrien/* All hard regs that have been used as spill registers for any insn are 21252284Sobrien marked in this set. */ 21352284Sobrienstatic HARD_REG_SET used_spill_regs; 21452284Sobrien 21518334Speter/* Index of last register assigned as a spill register. We allocate in 21618334Speter a round-robin fashion. */ 21718334Speterstatic int last_spill_reg; 21818334Speter 21918334Speter/* Nonzero if indirect addressing is supported on the machine; this means 22018334Speter that spilling (REG n) does not require reloading it into a register in 22118334Speter order to do (MEM (REG n)) or (MEM (PLUS (REG n) (CONST_INT c))). The 22218334Speter value indicates the level of indirect addressing supported, e.g., two 22318334Speter means that (MEM (MEM (REG n))) is also valid if (REG n) does not get 22418334Speter a hard register. */ 22518334Speterstatic char spill_indirect_levels; 22618334Speter 22718334Speter/* Nonzero if indirect addressing is supported when the innermost MEM is 22818334Speter of the form (MEM (SYMBOL_REF sym)). It is assumed that the level to 22990075Sobrien which these are valid is the same as spill_indirect_levels, above. */ 23018334Speterchar indirect_symref_ok; 23118334Speter 23218334Speter/* Nonzero if an address (plus (reg frame_pointer) (reg ...)) is valid. */ 23318334Speterchar double_reg_address_ok; 23418334Speter 23518334Speter/* Record the stack slot for each spilled hard register. */ 23618334Speterstatic rtx spill_stack_slot[FIRST_PSEUDO_REGISTER]; 23718334Speter 23818334Speter/* Width allocated so far for that stack slot. */ 23990075Sobrienstatic unsigned int spill_stack_slot_width[FIRST_PSEUDO_REGISTER]; 24018334Speter 24152284Sobrien/* Record which pseudos needed to be spilled. */ 24290075Sobrienstatic regset_head spilled_pseudos; 24318334Speter 24490075Sobrien/* Used for communication between order_regs_for_reload and count_pseudo. 24590075Sobrien Used to avoid counting one pseudo twice. */ 24690075Sobrienstatic regset_head pseudos_counted; 24790075Sobrien 24818334Speter/* First uid used by insns created by reload in this function. 24918334Speter Used in find_equiv_reg. */ 25018334Speterint reload_first_uid; 25118334Speter 25218334Speter/* Flag set by local-alloc or global-alloc if anything is live in 25318334Speter a call-clobbered reg across calls. */ 25418334Speterint caller_save_needed; 25518334Speter 25618334Speter/* Set to 1 while reload_as_needed is operating. 25718334Speter Required by some machines to handle any generated moves differently. */ 25818334Speterint reload_in_progress = 0; 25918334Speter 26018334Speter/* These arrays record the insn_code of insns that may be needed to 26118334Speter perform input and output reloads of special objects. They provide a 26218334Speter place to pass a scratch register. */ 26318334Speterenum insn_code reload_in_optab[NUM_MACHINE_MODES]; 26418334Speterenum insn_code reload_out_optab[NUM_MACHINE_MODES]; 26518334Speter 26618334Speter/* This obstack is used for allocation of rtl during register elimination. 26718334Speter The allocated storage can be freed once find_reloads has processed the 26818334Speter insn. */ 26952284Sobrienstruct obstack reload_obstack; 27018334Speter 27152284Sobrien/* Points to the beginning of the reload_obstack. All insn_chain structures 27252284Sobrien are allocated first. */ 27352284Sobrienchar *reload_startobj; 27452284Sobrien 27552284Sobrien/* The point after all insn_chain structures. Used to quickly deallocate 27690075Sobrien memory allocated in copy_reloads during calculate_needs_all_insns. */ 27718334Speterchar *reload_firstobj; 27818334Speter 27990075Sobrien/* This points before all local rtl generated by register elimination. 28090075Sobrien Used to quickly free all memory after processing one insn. */ 28190075Sobrienstatic char *reload_insn_firstobj; 28290075Sobrien 28318334Speter#define obstack_chunk_alloc xmalloc 28418334Speter#define obstack_chunk_free free 28518334Speter 28652284Sobrien/* List of insn_chain instructions, one for every insn that reload needs to 28752284Sobrien examine. */ 28852284Sobrienstruct insn_chain *reload_insn_chain; 28952284Sobrien 29052284Sobrien#ifdef TREE_CODE 29152284Sobrienextern tree current_function_decl; 29252284Sobrien#else 29352284Sobrienextern union tree_node *current_function_decl; 29452284Sobrien#endif 29552284Sobrien 29652284Sobrien/* List of all insns needing reloads. */ 29752284Sobrienstatic struct insn_chain *insns_need_reload; 29818334Speter 29918334Speter/* This structure is used to record information about register eliminations. 30018334Speter Each array entry describes one possible way of eliminating a register 30118334Speter in favor of another. If there is more than one way of eliminating a 30218334Speter particular register, the most preferred should be specified first. */ 30318334Speter 30452284Sobrienstruct elim_table 30518334Speter{ 30650397Sobrien int from; /* Register number to be eliminated. */ 30750397Sobrien int to; /* Register number used as replacement. */ 30850397Sobrien int initial_offset; /* Initial difference between values. */ 30950397Sobrien int can_eliminate; /* Non-zero if this elimination can be done. */ 31018334Speter int can_eliminate_previous; /* Value of CAN_ELIMINATE in previous scan over 31150397Sobrien insns made by reload. */ 31250397Sobrien int offset; /* Current offset between the two regs. */ 31350397Sobrien int previous_offset; /* Offset at end of previous insn. */ 31450397Sobrien int ref_outside_mem; /* "to" has been referenced outside a MEM. */ 31518334Speter rtx from_rtx; /* REG rtx for the register to be eliminated. 31618334Speter We cannot simply compare the number since 31718334Speter we might then spuriously replace a hard 31818334Speter register corresponding to a pseudo 31950397Sobrien assigned to the reg to be eliminated. */ 32050397Sobrien rtx to_rtx; /* REG rtx for the replacement. */ 32152284Sobrien}; 32218334Speter 32390075Sobrienstatic struct elim_table *reg_eliminate = 0; 32452284Sobrien 32552284Sobrien/* This is an intermediate structure to initialize the table. It has 32690075Sobrien exactly the members provided by ELIMINABLE_REGS. */ 32790075Sobrienstatic const struct elim_table_1 32852284Sobrien{ 32990075Sobrien const int from; 33090075Sobrien const int to; 33152284Sobrien} reg_eliminate_1[] = 33252284Sobrien 33318334Speter/* If a set of eliminable registers was specified, define the table from it. 33418334Speter Otherwise, default to the normal case of the frame pointer being 33518334Speter replaced by the stack pointer. */ 33618334Speter 33718334Speter#ifdef ELIMINABLE_REGS 33818334Speter ELIMINABLE_REGS; 33918334Speter#else 34018334Speter {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}; 34118334Speter#endif 34218334Speter 34390075Sobrien#define NUM_ELIMINABLE_REGS ARRAY_SIZE (reg_eliminate_1) 34418334Speter 34518334Speter/* Record the number of pending eliminations that have an offset not equal 34618334Speter to their initial offset. If non-zero, we use a new copy of each 34718334Speter replacement result in any insns encountered. */ 34852284Sobrienint num_not_at_initial_offset; 34918334Speter 35018334Speter/* Count the number of registers that we may be able to eliminate. */ 35118334Speterstatic int num_eliminable; 35252284Sobrien/* And the number of registers that are equivalent to a constant that 35352284Sobrien can be eliminated to frame_pointer / arg_pointer + constant. */ 35452284Sobrienstatic int num_eliminable_invariants; 35518334Speter 35618334Speter/* For each label, we record the offset of each elimination. If we reach 35718334Speter a label by more than one path and an offset differs, we cannot do the 35818334Speter elimination. This information is indexed by the number of the label. 35918334Speter The first table is an array of flags that records whether we have yet 36018334Speter encountered a label and the second table is an array of arrays, one 36118334Speter entry in the latter array for each elimination. */ 36218334Speter 36318334Speterstatic char *offsets_known_at; 36418334Speterstatic int (*offsets_at)[NUM_ELIMINABLE_REGS]; 36518334Speter 36618334Speter/* Number of labels in the current function. */ 36718334Speter 36818334Speterstatic int num_labels; 36918334Speter 37090075Sobrienstatic void replace_pseudos_in_call_usage PARAMS ((rtx *, 37190075Sobrien enum machine_mode, 37290075Sobrien rtx)); 37390075Sobrienstatic void maybe_fix_stack_asms PARAMS ((void)); 37490075Sobrienstatic void copy_reloads PARAMS ((struct insn_chain *)); 37590075Sobrienstatic void calculate_needs_all_insns PARAMS ((int)); 37690075Sobrienstatic int find_reg PARAMS ((struct insn_chain *, int)); 37790075Sobrienstatic void find_reload_regs PARAMS ((struct insn_chain *)); 37890075Sobrienstatic void select_reload_regs PARAMS ((void)); 37990075Sobrienstatic void delete_caller_save_insns PARAMS ((void)); 38052284Sobrien 38190075Sobrienstatic void spill_failure PARAMS ((rtx, enum reg_class)); 38290075Sobrienstatic void count_spilled_pseudo PARAMS ((int, int, int)); 38390075Sobrienstatic void delete_dead_insn PARAMS ((rtx)); 38490075Sobrienstatic void alter_reg PARAMS ((int, int)); 38590075Sobrienstatic void set_label_offsets PARAMS ((rtx, rtx, int)); 38690075Sobrienstatic void check_eliminable_occurrences PARAMS ((rtx)); 38790075Sobrienstatic void elimination_effects PARAMS ((rtx, enum machine_mode)); 38890075Sobrienstatic int eliminate_regs_in_insn PARAMS ((rtx, int)); 38990075Sobrienstatic void update_eliminable_offsets PARAMS ((void)); 39090075Sobrienstatic void mark_not_eliminable PARAMS ((rtx, rtx, void *)); 39190075Sobrienstatic void set_initial_elim_offsets PARAMS ((void)); 39290075Sobrienstatic void verify_initial_elim_offsets PARAMS ((void)); 39390075Sobrienstatic void set_initial_label_offsets PARAMS ((void)); 39490075Sobrienstatic void set_offsets_for_label PARAMS ((rtx)); 39590075Sobrienstatic void init_elim_table PARAMS ((void)); 39690075Sobrienstatic void update_eliminables PARAMS ((HARD_REG_SET *)); 39790075Sobrienstatic void spill_hard_reg PARAMS ((unsigned int, int)); 39890075Sobrienstatic int finish_spills PARAMS ((int)); 39990075Sobrienstatic void ior_hard_reg_set PARAMS ((HARD_REG_SET *, HARD_REG_SET *)); 40090075Sobrienstatic void scan_paradoxical_subregs PARAMS ((rtx)); 40190075Sobrienstatic void count_pseudo PARAMS ((int)); 40290075Sobrienstatic void order_regs_for_reload PARAMS ((struct insn_chain *)); 40390075Sobrienstatic void reload_as_needed PARAMS ((int)); 40490075Sobrienstatic void forget_old_reloads_1 PARAMS ((rtx, rtx, void *)); 40590075Sobrienstatic int reload_reg_class_lower PARAMS ((const PTR, const PTR)); 40690075Sobrienstatic void mark_reload_reg_in_use PARAMS ((unsigned int, int, 40790075Sobrien enum reload_type, 40890075Sobrien enum machine_mode)); 40990075Sobrienstatic void clear_reload_reg_in_use PARAMS ((unsigned int, int, 41090075Sobrien enum reload_type, 41190075Sobrien enum machine_mode)); 41290075Sobrienstatic int reload_reg_free_p PARAMS ((unsigned int, int, 41390075Sobrien enum reload_type)); 41490075Sobrienstatic int reload_reg_free_for_value_p PARAMS ((int, int, int, 41590075Sobrien enum reload_type, 41690075Sobrien rtx, rtx, int, int)); 41790075Sobrienstatic int free_for_value_p PARAMS ((int, enum machine_mode, int, 41890075Sobrien enum reload_type, rtx, rtx, 41990075Sobrien int, int)); 42090075Sobrienstatic int reload_reg_reaches_end_p PARAMS ((unsigned int, int, 42190075Sobrien enum reload_type)); 42290075Sobrienstatic int allocate_reload_reg PARAMS ((struct insn_chain *, int, 42390075Sobrien int)); 42490075Sobrienstatic int conflicts_with_override PARAMS ((rtx)); 42590075Sobrienstatic void failed_reload PARAMS ((rtx, int)); 42690075Sobrienstatic int set_reload_reg PARAMS ((int, int)); 42790075Sobrienstatic void choose_reload_regs_init PARAMS ((struct insn_chain *, rtx *)); 42890075Sobrienstatic void choose_reload_regs PARAMS ((struct insn_chain *)); 42990075Sobrienstatic void merge_assigned_reloads PARAMS ((rtx)); 43090075Sobrienstatic void emit_input_reload_insns PARAMS ((struct insn_chain *, 43190075Sobrien struct reload *, rtx, int)); 43290075Sobrienstatic void emit_output_reload_insns PARAMS ((struct insn_chain *, 43390075Sobrien struct reload *, int)); 43490075Sobrienstatic void do_input_reload PARAMS ((struct insn_chain *, 43590075Sobrien struct reload *, int)); 43690075Sobrienstatic void do_output_reload PARAMS ((struct insn_chain *, 43790075Sobrien struct reload *, int)); 43890075Sobrienstatic void emit_reload_insns PARAMS ((struct insn_chain *)); 43990075Sobrienstatic void delete_output_reload PARAMS ((rtx, int, int)); 44090075Sobrienstatic void delete_address_reloads PARAMS ((rtx, rtx)); 44190075Sobrienstatic void delete_address_reloads_1 PARAMS ((rtx, rtx, rtx)); 44290075Sobrienstatic rtx inc_for_reload PARAMS ((rtx, rtx, rtx, int)); 44390075Sobrienstatic void reload_cse_regs_1 PARAMS ((rtx)); 44490075Sobrienstatic int reload_cse_noop_set_p PARAMS ((rtx)); 44590075Sobrienstatic int reload_cse_simplify_set PARAMS ((rtx, rtx)); 44690075Sobrienstatic int reload_cse_simplify_operands PARAMS ((rtx)); 44790075Sobrienstatic void reload_combine PARAMS ((void)); 44890075Sobrienstatic void reload_combine_note_use PARAMS ((rtx *, rtx)); 44990075Sobrienstatic void reload_combine_note_store PARAMS ((rtx, rtx, void *)); 45090075Sobrienstatic void reload_cse_move2add PARAMS ((rtx)); 45190075Sobrienstatic void move2add_note_store PARAMS ((rtx, rtx, void *)); 45252284Sobrien#ifdef AUTO_INC_DEC 45390075Sobrienstatic void add_auto_inc_notes PARAMS ((rtx, rtx)); 45452284Sobrien#endif 45590075Sobrienstatic void copy_eh_notes PARAMS ((rtx, rtx)); 45690075Sobrienstatic HOST_WIDE_INT sext_for_mode PARAMS ((enum machine_mode, 45790075Sobrien HOST_WIDE_INT)); 45890075Sobrienstatic void failed_reload PARAMS ((rtx, int)); 45990075Sobrienstatic int set_reload_reg PARAMS ((int, int)); 46090075Sobrienstatic void reload_cse_delete_noop_set PARAMS ((rtx, rtx)); 46190075Sobrienstatic void reload_cse_simplify PARAMS ((rtx)); 46296263Sobrienvoid fixup_abnormal_edges PARAMS ((void)); 46390075Sobrienextern void dump_needs PARAMS ((struct insn_chain *)); 46418334Speter 46518334Speter/* Initialize the reload pass once per compilation. */ 46618334Speter 46718334Spetervoid 46818334Speterinit_reload () 46918334Speter{ 47090075Sobrien int i; 47118334Speter 47218334Speter /* Often (MEM (REG n)) is still valid even if (REG n) is put on the stack. 47318334Speter Set spill_indirect_levels to the number of levels such addressing is 47418334Speter permitted, zero if it is not permitted at all. */ 47518334Speter 47690075Sobrien rtx tem 47750397Sobrien = gen_rtx_MEM (Pmode, 47850397Sobrien gen_rtx_PLUS (Pmode, 47990075Sobrien gen_rtx_REG (Pmode, 48090075Sobrien LAST_VIRTUAL_REGISTER + 1), 48150397Sobrien GEN_INT (4))); 48218334Speter spill_indirect_levels = 0; 48318334Speter 48418334Speter while (memory_address_p (QImode, tem)) 48518334Speter { 48618334Speter spill_indirect_levels++; 48750397Sobrien tem = gen_rtx_MEM (Pmode, tem); 48818334Speter } 48918334Speter 49018334Speter /* See if indirect addressing is valid for (MEM (SYMBOL_REF ...)). */ 49118334Speter 49250397Sobrien tem = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "foo")); 49318334Speter indirect_symref_ok = memory_address_p (QImode, tem); 49418334Speter 49518334Speter /* See if reg+reg is a valid (and offsettable) address. */ 49618334Speter 49718334Speter for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 49818334Speter { 49950397Sobrien tem = gen_rtx_PLUS (Pmode, 50050397Sobrien gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM), 50150397Sobrien gen_rtx_REG (Pmode, i)); 50290075Sobrien 50318334Speter /* This way, we make sure that reg+reg is an offsettable address. */ 50418334Speter tem = plus_constant (tem, 4); 50518334Speter 50618334Speter if (memory_address_p (QImode, tem)) 50718334Speter { 50818334Speter double_reg_address_ok = 1; 50918334Speter break; 51018334Speter } 51118334Speter } 51218334Speter 51350397Sobrien /* Initialize obstack for our rtl allocation. */ 51418334Speter gcc_obstack_init (&reload_obstack); 51552284Sobrien reload_startobj = (char *) obstack_alloc (&reload_obstack, 0); 51690075Sobrien 51790075Sobrien INIT_REG_SET (&spilled_pseudos); 51890075Sobrien INIT_REG_SET (&pseudos_counted); 51952284Sobrien} 52050397Sobrien 52152284Sobrien/* List of insn chains that are currently unused. */ 52252284Sobrienstatic struct insn_chain *unused_insn_chains = 0; 52350397Sobrien 52452284Sobrien/* Allocate an empty insn_chain structure. */ 52552284Sobrienstruct insn_chain * 52652284Sobriennew_insn_chain () 52752284Sobrien{ 52852284Sobrien struct insn_chain *c; 52950397Sobrien 53052284Sobrien if (unused_insn_chains == 0) 53152284Sobrien { 53252284Sobrien c = (struct insn_chain *) 53352284Sobrien obstack_alloc (&reload_obstack, sizeof (struct insn_chain)); 53490075Sobrien INIT_REG_SET (&c->live_throughout); 53590075Sobrien INIT_REG_SET (&c->dead_or_set); 53650397Sobrien } 53752284Sobrien else 53852284Sobrien { 53952284Sobrien c = unused_insn_chains; 54052284Sobrien unused_insn_chains = c->next; 54152284Sobrien } 54252284Sobrien c->is_caller_save_insn = 0; 54352284Sobrien c->need_operand_change = 0; 54452284Sobrien c->need_reload = 0; 54552284Sobrien c->need_elim = 0; 54652284Sobrien return c; 54718334Speter} 54818334Speter 54952284Sobrien/* Small utility function to set all regs in hard reg set TO which are 55052284Sobrien allocated to pseudos in regset FROM. */ 55190075Sobrien 55252284Sobrienvoid 55352284Sobriencompute_use_by_pseudos (to, from) 55452284Sobrien HARD_REG_SET *to; 55552284Sobrien regset from; 55652284Sobrien{ 55790075Sobrien unsigned int regno; 55890075Sobrien 55952284Sobrien EXECUTE_IF_SET_IN_REG_SET 56052284Sobrien (from, FIRST_PSEUDO_REGISTER, regno, 56152284Sobrien { 56252284Sobrien int r = reg_renumber[regno]; 56352284Sobrien int nregs; 56490075Sobrien 56552284Sobrien if (r < 0) 56652284Sobrien { 56752284Sobrien /* reload_combine uses the information from 56852284Sobrien BASIC_BLOCK->global_live_at_start, which might still 56952284Sobrien contain registers that have not actually been allocated 57052284Sobrien since they have an equivalence. */ 57152284Sobrien if (! reload_completed) 57252284Sobrien abort (); 57352284Sobrien } 57452284Sobrien else 57552284Sobrien { 57652284Sobrien nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (regno)); 57752284Sobrien while (nregs-- > 0) 57852284Sobrien SET_HARD_REG_BIT (*to, r + nregs); 57952284Sobrien } 58052284Sobrien }); 58152284Sobrien} 58290075Sobrien 58390075Sobrien/* Replace all pseudos found in LOC with their corresponding 58490075Sobrien equivalences. */ 58590075Sobrien 58690075Sobrienstatic void 58790075Sobrienreplace_pseudos_in_call_usage (loc, mem_mode, usage) 58890075Sobrien rtx *loc; 58990075Sobrien enum machine_mode mem_mode; 59090075Sobrien rtx usage; 59190075Sobrien{ 59290075Sobrien rtx x = *loc; 59390075Sobrien enum rtx_code code; 59490075Sobrien const char *fmt; 59590075Sobrien int i, j; 59690075Sobrien 59790075Sobrien if (! x) 59890075Sobrien return; 59990075Sobrien 60090075Sobrien code = GET_CODE (x); 60190075Sobrien if (code == REG) 60290075Sobrien { 60390075Sobrien unsigned int regno = REGNO (x); 60490075Sobrien 60590075Sobrien if (regno < FIRST_PSEUDO_REGISTER) 60690075Sobrien return; 60790075Sobrien 60890075Sobrien x = eliminate_regs (x, mem_mode, usage); 60990075Sobrien if (x != *loc) 61090075Sobrien { 61190075Sobrien *loc = x; 61290075Sobrien replace_pseudos_in_call_usage (loc, mem_mode, usage); 61390075Sobrien return; 61490075Sobrien } 61590075Sobrien 61690075Sobrien if (reg_equiv_constant[regno]) 61790075Sobrien *loc = reg_equiv_constant[regno]; 61890075Sobrien else if (reg_equiv_mem[regno]) 61990075Sobrien *loc = reg_equiv_mem[regno]; 62090075Sobrien else if (reg_equiv_address[regno]) 62190075Sobrien *loc = gen_rtx_MEM (GET_MODE (x), reg_equiv_address[regno]); 62290075Sobrien else if (GET_CODE (regno_reg_rtx[regno]) != REG 62390075Sobrien || REGNO (regno_reg_rtx[regno]) != regno) 62490075Sobrien *loc = regno_reg_rtx[regno]; 62590075Sobrien else 62690075Sobrien abort (); 62790075Sobrien 62890075Sobrien return; 62990075Sobrien } 63090075Sobrien else if (code == MEM) 63190075Sobrien { 63290075Sobrien replace_pseudos_in_call_usage (& XEXP (x, 0), GET_MODE (x), usage); 63390075Sobrien return; 63490075Sobrien } 63590075Sobrien 63690075Sobrien /* Process each of our operands recursively. */ 63790075Sobrien fmt = GET_RTX_FORMAT (code); 63890075Sobrien for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 63990075Sobrien if (*fmt == 'e') 64090075Sobrien replace_pseudos_in_call_usage (&XEXP (x, i), mem_mode, usage); 64190075Sobrien else if (*fmt == 'E') 64290075Sobrien for (j = 0; j < XVECLEN (x, i); j++) 64390075Sobrien replace_pseudos_in_call_usage (& XVECEXP (x, i, j), mem_mode, usage); 64490075Sobrien} 64590075Sobrien 64652284Sobrien 64752284Sobrien/* Global variables used by reload and its subroutines. */ 64852284Sobrien 64952284Sobrien/* Set during calculate_needs if an insn needs register elimination. */ 65052284Sobrienstatic int something_needs_elimination; 65152284Sobrien/* Set during calculate_needs if an insn needs an operand changed. */ 65252284Sobrienint something_needs_operands_changed; 65352284Sobrien 65452284Sobrien/* Nonzero means we couldn't get enough spill regs. */ 65552284Sobrienstatic int failure; 65652284Sobrien 65718334Speter/* Main entry point for the reload pass. 65818334Speter 65918334Speter FIRST is the first insn of the function being compiled. 66018334Speter 66118334Speter GLOBAL nonzero means we were called from global_alloc 66218334Speter and should attempt to reallocate any pseudoregs that we 66318334Speter displace from hard regs we will use for reloads. 66418334Speter If GLOBAL is zero, we do not have enough information to do that, 66518334Speter so any pseudo reg that is spilled must go to the stack. 66618334Speter 66718334Speter Return value is nonzero if reload failed 66818334Speter and we must not do any more for this function. */ 66918334Speter 67018334Speterint 67190075Sobrienreload (first, global) 67218334Speter rtx first; 67318334Speter int global; 67418334Speter{ 67590075Sobrien int i; 67690075Sobrien rtx insn; 67790075Sobrien struct elim_table *ep; 67818334Speter 67950397Sobrien /* The two pointers used to track the true location of the memory used 68050397Sobrien for label offsets. */ 68190075Sobrien char *real_known_ptr = NULL; 68250397Sobrien int (*real_at_ptr)[NUM_ELIMINABLE_REGS]; 68350397Sobrien 68452284Sobrien /* Make sure even insns with volatile mem refs are recognizable. */ 68552284Sobrien init_recog (); 68618334Speter 68752284Sobrien failure = 0; 68818334Speter 68952284Sobrien reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0); 69018334Speter 69152284Sobrien /* Make sure that the last insn in the chain 69252284Sobrien is not something that needs reloading. */ 69390075Sobrien emit_note (NULL, NOTE_INSN_DELETED); 69418334Speter 69518334Speter /* Enable find_equiv_reg to distinguish insns made by reload. */ 69618334Speter reload_first_uid = get_max_uid (); 69718334Speter 69818334Speter#ifdef SECONDARY_MEMORY_NEEDED 69918334Speter /* Initialize the secondary memory table. */ 70018334Speter clear_secondary_mem (); 70118334Speter#endif 70218334Speter 70318334Speter /* We don't have a stack slot for any spill reg yet. */ 70490075Sobrien memset ((char *) spill_stack_slot, 0, sizeof spill_stack_slot); 70590075Sobrien memset ((char *) spill_stack_slot_width, 0, sizeof spill_stack_slot_width); 70618334Speter 70718334Speter /* Initialize the save area information for caller-save, in case some 70818334Speter are needed. */ 70918334Speter init_save_areas (); 71018334Speter 71118334Speter /* Compute which hard registers are now in use 71218334Speter as homes for pseudo registers. 71318334Speter This is done here rather than (eg) in global_alloc 71418334Speter because this point is reached even if not optimizing. */ 71518334Speter for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 71618334Speter mark_home_live (i); 71718334Speter 71850397Sobrien /* A function that receives a nonlocal goto must save all call-saved 71950397Sobrien registers. */ 72050397Sobrien if (current_function_has_nonlocal_label) 72150397Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 72290075Sobrien if (! call_used_regs[i] && ! fixed_regs[i] && ! LOCAL_REGNO (i)) 72390075Sobrien regs_ever_live[i] = 1; 72450397Sobrien 72518334Speter /* Find all the pseudo registers that didn't get hard regs 72618334Speter but do have known equivalent constants or memory slots. 72718334Speter These include parameters (known equivalent to parameter slots) 72818334Speter and cse'd or loop-moved constant memory addresses. 72918334Speter 73018334Speter Record constant equivalents in reg_equiv_constant 73118334Speter so they will be substituted by find_reloads. 73218334Speter Record memory equivalents in reg_mem_equiv so they can 73318334Speter be substituted eventually by altering the REG-rtx's. */ 73418334Speter 73590075Sobrien reg_equiv_constant = (rtx *) xcalloc (max_regno, sizeof (rtx)); 73690075Sobrien reg_equiv_mem = (rtx *) xcalloc (max_regno, sizeof (rtx)); 73790075Sobrien reg_equiv_init = (rtx *) xcalloc (max_regno, sizeof (rtx)); 73890075Sobrien reg_equiv_address = (rtx *) xcalloc (max_regno, sizeof (rtx)); 73990075Sobrien reg_max_ref_width = (unsigned int *) xcalloc (max_regno, sizeof (int)); 74090075Sobrien reg_old_renumber = (short *) xcalloc (max_regno, sizeof (short)); 74190075Sobrien memcpy (reg_old_renumber, reg_renumber, max_regno * sizeof (short)); 74252284Sobrien pseudo_forbidden_regs 74352284Sobrien = (HARD_REG_SET *) xmalloc (max_regno * sizeof (HARD_REG_SET)); 74452284Sobrien pseudo_previous_regs 74590075Sobrien = (HARD_REG_SET *) xcalloc (max_regno, sizeof (HARD_REG_SET)); 74618334Speter 74752284Sobrien CLEAR_HARD_REG_SET (bad_spill_regs_global); 74818334Speter 74918334Speter /* Look for REG_EQUIV notes; record what each pseudo is equivalent to. 75018334Speter Also find all paradoxical subregs and find largest such for each pseudo. 75118334Speter On machines with small register classes, record hard registers that 75290075Sobrien are used for user variables. These can never be used for spills. 75390075Sobrien Also look for a "constant" REG_SETJMP. This means that all 75450397Sobrien caller-saved registers must be marked live. */ 75518334Speter 75652284Sobrien num_eliminable_invariants = 0; 75718334Speter for (insn = first; insn; insn = NEXT_INSN (insn)) 75818334Speter { 75918334Speter rtx set = single_set (insn); 76018334Speter 76190075Sobrien /* We may introduce USEs that we want to remove at the end, so 76290075Sobrien we'll mark them with QImode. Make sure there are no 76390075Sobrien previously-marked insns left by say regmove. */ 76490075Sobrien if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE 76590075Sobrien && GET_MODE (insn) != VOIDmode) 76690075Sobrien PUT_MODE (insn, VOIDmode); 76790075Sobrien 76890075Sobrien if (GET_CODE (insn) == CALL_INSN 76990075Sobrien && find_reg_note (insn, REG_SETJMP, NULL)) 77050397Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 77150397Sobrien if (! call_used_regs[i]) 77250397Sobrien regs_ever_live[i] = 1; 77350397Sobrien 77418334Speter if (set != 0 && GET_CODE (SET_DEST (set)) == REG) 77518334Speter { 77618334Speter rtx note = find_reg_note (insn, REG_EQUIV, NULL_RTX); 77718334Speter if (note 77818334Speter#ifdef LEGITIMATE_PIC_OPERAND_P 77952284Sobrien && (! function_invariant_p (XEXP (note, 0)) 78052284Sobrien || ! flag_pic 78190075Sobrien /* A function invariant is often CONSTANT_P but may 78290075Sobrien include a register. We promise to only pass 78390075Sobrien CONSTANT_P objects to LEGITIMATE_PIC_OPERAND_P. */ 78490075Sobrien || (CONSTANT_P (XEXP (note, 0)) 78590075Sobrien && LEGITIMATE_PIC_OPERAND_P (XEXP (note, 0)))) 78618334Speter#endif 78718334Speter ) 78818334Speter { 78918334Speter rtx x = XEXP (note, 0); 79018334Speter i = REGNO (SET_DEST (set)); 79118334Speter if (i > LAST_VIRTUAL_REGISTER) 79218334Speter { 79396263Sobrien /* It can happen that a REG_EQUIV note contains a MEM 79496263Sobrien that is not a legitimate memory operand. As later 79596263Sobrien stages of reload assume that all addresses found 79696263Sobrien in the reg_equiv_* arrays were originally legitimate, 79796263Sobrien we ignore such REG_EQUIV notes. */ 79896263Sobrien if (memory_operand (x, VOIDmode)) 79950397Sobrien { 80090075Sobrien /* Always unshare the equivalence, so we can 80190075Sobrien substitute into this insn without touching the 80290075Sobrien equivalence. */ 80390075Sobrien reg_equiv_memory_loc[i] = copy_rtx (x); 80450397Sobrien } 80552284Sobrien else if (function_invariant_p (x)) 80618334Speter { 80752284Sobrien if (GET_CODE (x) == PLUS) 80852284Sobrien { 80952284Sobrien /* This is PLUS of frame pointer and a constant, 81052284Sobrien and might be shared. Unshare it. */ 81152284Sobrien reg_equiv_constant[i] = copy_rtx (x); 81252284Sobrien num_eliminable_invariants++; 81352284Sobrien } 81452284Sobrien else if (x == frame_pointer_rtx 81552284Sobrien || x == arg_pointer_rtx) 81652284Sobrien { 81752284Sobrien reg_equiv_constant[i] = x; 81852284Sobrien num_eliminable_invariants++; 81952284Sobrien } 82052284Sobrien else if (LEGITIMATE_CONSTANT_P (x)) 82118334Speter reg_equiv_constant[i] = x; 82218334Speter else 82318334Speter reg_equiv_memory_loc[i] 82418334Speter = force_const_mem (GET_MODE (SET_DEST (set)), x); 82518334Speter } 82618334Speter else 82718334Speter continue; 82818334Speter 82918334Speter /* If this register is being made equivalent to a MEM 83018334Speter and the MEM is not SET_SRC, the equivalencing insn 83118334Speter is one with the MEM as a SET_DEST and it occurs later. 83218334Speter So don't mark this insn now. */ 83318334Speter if (GET_CODE (x) != MEM 83418334Speter || rtx_equal_p (SET_SRC (set), x)) 83552284Sobrien reg_equiv_init[i] 83652284Sobrien = gen_rtx_INSN_LIST (VOIDmode, insn, reg_equiv_init[i]); 83718334Speter } 83818334Speter } 83918334Speter } 84018334Speter 84118334Speter /* If this insn is setting a MEM from a register equivalent to it, 84218334Speter this is the equivalencing insn. */ 84318334Speter else if (set && GET_CODE (SET_DEST (set)) == MEM 84418334Speter && GET_CODE (SET_SRC (set)) == REG 84518334Speter && reg_equiv_memory_loc[REGNO (SET_SRC (set))] 84618334Speter && rtx_equal_p (SET_DEST (set), 84718334Speter reg_equiv_memory_loc[REGNO (SET_SRC (set))])) 84852284Sobrien reg_equiv_init[REGNO (SET_SRC (set))] 84952284Sobrien = gen_rtx_INSN_LIST (VOIDmode, insn, 85052284Sobrien reg_equiv_init[REGNO (SET_SRC (set))]); 85118334Speter 85290075Sobrien if (INSN_P (insn)) 85318334Speter scan_paradoxical_subregs (PATTERN (insn)); 85418334Speter } 85518334Speter 85652284Sobrien init_elim_table (); 85718334Speter 85818334Speter num_labels = max_label_num () - get_first_label_num (); 85918334Speter 86018334Speter /* Allocate the tables used to store offset information at labels. */ 86150397Sobrien /* We used to use alloca here, but the size of what it would try to 86250397Sobrien allocate would occasionally cause it to exceed the stack limit and 86350397Sobrien cause a core dump. */ 86450397Sobrien real_known_ptr = xmalloc (num_labels); 86550397Sobrien real_at_ptr 86618334Speter = (int (*)[NUM_ELIMINABLE_REGS]) 86750397Sobrien xmalloc (num_labels * NUM_ELIMINABLE_REGS * sizeof (int)); 86818334Speter 86950397Sobrien offsets_known_at = real_known_ptr - get_first_label_num (); 87050397Sobrien offsets_at 87150397Sobrien = (int (*)[NUM_ELIMINABLE_REGS]) (real_at_ptr - get_first_label_num ()); 87218334Speter 87318334Speter /* Alter each pseudo-reg rtx to contain its hard reg number. 87418334Speter Assign stack slots to the pseudos that lack hard regs or equivalents. 87518334Speter Do not touch virtual registers. */ 87618334Speter 87718334Speter for (i = LAST_VIRTUAL_REGISTER + 1; i < max_regno; i++) 87818334Speter alter_reg (i, -1); 87918334Speter 88018334Speter /* If we have some registers we think can be eliminated, scan all insns to 88118334Speter see if there is an insn that sets one of these registers to something 88218334Speter other than itself plus a constant. If so, the register cannot be 88318334Speter eliminated. Doing this scan here eliminates an extra pass through the 88418334Speter main reload loop in the most common case where register elimination 88518334Speter cannot be done. */ 88618334Speter for (insn = first; insn && num_eliminable; insn = NEXT_INSN (insn)) 88718334Speter if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN 88818334Speter || GET_CODE (insn) == CALL_INSN) 88990075Sobrien note_stores (PATTERN (insn), mark_not_eliminable, NULL); 89018334Speter 89152284Sobrien maybe_fix_stack_asms (); 89218334Speter 89352284Sobrien insns_need_reload = 0; 89452284Sobrien something_needs_elimination = 0; 89590075Sobrien 89618334Speter /* Initialize to -1, which means take the first spill register. */ 89718334Speter last_spill_reg = -1; 89818334Speter 89918334Speter /* Spill any hard regs that we know we can't eliminate. */ 90052284Sobrien CLEAR_HARD_REG_SET (used_spill_regs); 90118334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 90218334Speter if (! ep->can_eliminate) 90390075Sobrien spill_hard_reg (ep->from, 1); 90418334Speter 90518334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 90618334Speter if (frame_pointer_needed) 90790075Sobrien spill_hard_reg (HARD_FRAME_POINTER_REGNUM, 1); 90818334Speter#endif 90990075Sobrien finish_spills (global); 91018334Speter 91152284Sobrien /* From now on, we may need to generate moves differently. We may also 91252284Sobrien allow modifications of insns which cause them to not be recognized. 91352284Sobrien Any such modifications will be cleaned up during reload itself. */ 91418334Speter reload_in_progress = 1; 91518334Speter 91618334Speter /* This loop scans the entire function each go-round 91718334Speter and repeats until one repetition spills no additional hard regs. */ 91852284Sobrien for (;;) 91918334Speter { 92052284Sobrien int something_changed; 92152284Sobrien int did_spill; 92218334Speter 92350397Sobrien HOST_WIDE_INT starting_frame_size; 92418334Speter 92590075Sobrien /* Round size of stack frame to stack_alignment_needed. This must be done 92650397Sobrien here because the stack size may be a part of the offset computation 92750397Sobrien for register elimination, and there might have been new stack slots 92890075Sobrien created in the last iteration of this loop. */ 92990075Sobrien if (cfun->stack_alignment_needed) 93090075Sobrien assign_stack_local (BLKmode, 0, cfun->stack_alignment_needed); 93150397Sobrien 93250397Sobrien starting_frame_size = get_frame_size (); 93350397Sobrien 93452284Sobrien set_initial_elim_offsets (); 93552284Sobrien set_initial_label_offsets (); 93618334Speter 93718334Speter /* For each pseudo register that has an equivalent location defined, 93818334Speter try to eliminate any eliminable registers (such as the frame pointer) 93918334Speter assuming initial offsets for the replacement register, which 94018334Speter is the normal case. 94118334Speter 94218334Speter If the resulting location is directly addressable, substitute 94318334Speter the MEM we just got directly for the old REG. 94418334Speter 94518334Speter If it is not addressable but is a constant or the sum of a hard reg 94618334Speter and constant, it is probably not addressable because the constant is 94718334Speter out of range, in that case record the address; we will generate 94818334Speter hairy code to compute the address in a register each time it is 94918334Speter needed. Similarly if it is a hard register, but one that is not 95018334Speter valid as an address register. 95118334Speter 95218334Speter If the location is not addressable, but does not have one of the 95318334Speter above forms, assign a stack slot. We have to do this to avoid the 95418334Speter potential of producing lots of reloads if, e.g., a location involves 95518334Speter a pseudo that didn't get a hard register and has an equivalent memory 95618334Speter location that also involves a pseudo that didn't get a hard register. 95718334Speter 95818334Speter Perhaps at some point we will improve reload_when_needed handling 95918334Speter so this problem goes away. But that's very hairy. */ 96018334Speter 96118334Speter for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 96218334Speter if (reg_renumber[i] < 0 && reg_equiv_memory_loc[i]) 96318334Speter { 96418334Speter rtx x = eliminate_regs (reg_equiv_memory_loc[i], 0, NULL_RTX); 96518334Speter 96618334Speter if (strict_memory_address_p (GET_MODE (regno_reg_rtx[i]), 96718334Speter XEXP (x, 0))) 96818334Speter reg_equiv_mem[i] = x, reg_equiv_address[i] = 0; 96918334Speter else if (CONSTANT_P (XEXP (x, 0)) 97018334Speter || (GET_CODE (XEXP (x, 0)) == REG 97118334Speter && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER) 97218334Speter || (GET_CODE (XEXP (x, 0)) == PLUS 97318334Speter && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG 97418334Speter && (REGNO (XEXP (XEXP (x, 0), 0)) 97518334Speter < FIRST_PSEUDO_REGISTER) 97618334Speter && CONSTANT_P (XEXP (XEXP (x, 0), 1)))) 97718334Speter reg_equiv_address[i] = XEXP (x, 0), reg_equiv_mem[i] = 0; 97818334Speter else 97918334Speter { 98018334Speter /* Make a new stack slot. Then indicate that something 98118334Speter changed so we go back and recompute offsets for 98218334Speter eliminable registers because the allocation of memory 98318334Speter below might change some offset. reg_equiv_{mem,address} 98418334Speter will be set up for this pseudo on the next pass around 98518334Speter the loop. */ 98618334Speter reg_equiv_memory_loc[i] = 0; 98718334Speter reg_equiv_init[i] = 0; 98818334Speter alter_reg (i, -1); 98918334Speter } 99018334Speter } 99118334Speter 99252284Sobrien if (caller_save_needed) 99352284Sobrien setup_save_areas (); 99452284Sobrien 99552284Sobrien /* If we allocated another stack slot, redo elimination bookkeeping. */ 99652284Sobrien if (starting_frame_size != get_frame_size ()) 99718334Speter continue; 99818334Speter 99952284Sobrien if (caller_save_needed) 100018334Speter { 100152284Sobrien save_call_clobbered_regs (); 100252284Sobrien /* That might have allocated new insn_chain structures. */ 100352284Sobrien reload_firstobj = (char *) obstack_alloc (&reload_obstack, 0); 100418334Speter } 100518334Speter 100652284Sobrien calculate_needs_all_insns (global); 100718334Speter 100890075Sobrien CLEAR_REG_SET (&spilled_pseudos); 100952284Sobrien did_spill = 0; 101018334Speter 101152284Sobrien something_changed = 0; 101218334Speter 101352284Sobrien /* If we allocated any new memory locations, make another pass 101452284Sobrien since it might have changed elimination offsets. */ 101552284Sobrien if (starting_frame_size != get_frame_size ()) 101652284Sobrien something_changed = 1; 101718334Speter 101852284Sobrien { 101952284Sobrien HARD_REG_SET to_spill; 102052284Sobrien CLEAR_HARD_REG_SET (to_spill); 102152284Sobrien update_eliminables (&to_spill); 102252284Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 102352284Sobrien if (TEST_HARD_REG_BIT (to_spill, i)) 102418334Speter { 102590075Sobrien spill_hard_reg (i, 1); 102652284Sobrien did_spill = 1; 102718334Speter 102852284Sobrien /* Regardless of the state of spills, if we previously had 102952284Sobrien a register that we thought we could eliminate, but no can 103052284Sobrien not eliminate, we must run another pass. 103118334Speter 103252284Sobrien Consider pseudos which have an entry in reg_equiv_* which 103352284Sobrien reference an eliminable register. We must make another pass 103452284Sobrien to update reg_equiv_* so that we do not substitute in the 103552284Sobrien old value from when we thought the elimination could be 103652284Sobrien performed. */ 103752284Sobrien something_changed = 1; 103852284Sobrien } 103952284Sobrien } 104018334Speter 104190075Sobrien select_reload_regs (); 104252284Sobrien if (failure) 104352284Sobrien goto failed; 104418334Speter 104552284Sobrien if (insns_need_reload != 0 || did_spill) 104690075Sobrien something_changed |= finish_spills (global); 104718334Speter 104852284Sobrien if (! something_changed) 104952284Sobrien break; 105018334Speter 105152284Sobrien if (caller_save_needed) 105252284Sobrien delete_caller_save_insns (); 105390075Sobrien 105490075Sobrien obstack_free (&reload_obstack, reload_firstobj); 105552284Sobrien } 105618334Speter 105752284Sobrien /* If global-alloc was run, notify it of any register eliminations we have 105852284Sobrien done. */ 105952284Sobrien if (global) 106052284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 106152284Sobrien if (ep->can_eliminate) 106252284Sobrien mark_elimination (ep->from, ep->to); 106352284Sobrien 106452284Sobrien /* If a pseudo has no hard reg, delete the insns that made the equivalence. 106552284Sobrien If that insn didn't set the register (i.e., it copied the register to 106652284Sobrien memory), just delete that insn instead of the equivalencing insn plus 106752284Sobrien anything now dead. If we call delete_dead_insn on that insn, we may 106852284Sobrien delete the insn that actually sets the register if the register dies 106952284Sobrien there and that is incorrect. */ 107052284Sobrien 107152284Sobrien for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 107252284Sobrien { 107352284Sobrien if (reg_renumber[i] < 0 && reg_equiv_init[i] != 0) 107452284Sobrien { 107552284Sobrien rtx list; 107652284Sobrien for (list = reg_equiv_init[i]; list; list = XEXP (list, 1)) 107752284Sobrien { 107852284Sobrien rtx equiv_insn = XEXP (list, 0); 107990075Sobrien 108090075Sobrien /* If we already deleted the insn or if it may trap, we can't 108190075Sobrien delete it. The latter case shouldn't happen, but can 108290075Sobrien if an insn has a variable address, gets a REG_EH_REGION 108390075Sobrien note added to it, and then gets converted into an load 108490075Sobrien from a constant address. */ 108590075Sobrien if (GET_CODE (equiv_insn) == NOTE 108690075Sobrien || can_throw_internal (equiv_insn)) 108790075Sobrien ; 108890075Sobrien else if (reg_set_p (regno_reg_rtx[i], PATTERN (equiv_insn))) 108952284Sobrien delete_dead_insn (equiv_insn); 109052284Sobrien else 109118334Speter { 109252284Sobrien PUT_CODE (equiv_insn, NOTE); 109352284Sobrien NOTE_SOURCE_FILE (equiv_insn) = 0; 109452284Sobrien NOTE_LINE_NUMBER (equiv_insn) = NOTE_INSN_DELETED; 109518334Speter } 109652284Sobrien } 109752284Sobrien } 109852284Sobrien } 109918334Speter 110052284Sobrien /* Use the reload registers where necessary 110152284Sobrien by generating move instructions to move the must-be-register 110252284Sobrien values into or out of the reload registers. */ 110318334Speter 110452284Sobrien if (insns_need_reload != 0 || something_needs_elimination 110552284Sobrien || something_needs_operands_changed) 110652284Sobrien { 110790075Sobrien HOST_WIDE_INT old_frame_size = get_frame_size (); 110818334Speter 110952284Sobrien reload_as_needed (global); 111018334Speter 111152284Sobrien if (old_frame_size != get_frame_size ()) 111252284Sobrien abort (); 111318334Speter 111452284Sobrien if (num_eliminable) 111552284Sobrien verify_initial_elim_offsets (); 111652284Sobrien } 111718334Speter 111852284Sobrien /* If we were able to eliminate the frame pointer, show that it is no 111952284Sobrien longer live at the start of any basic block. If it ls live by 112052284Sobrien virtue of being in a pseudo, that pseudo will be marked live 112152284Sobrien and hence the frame pointer will be known to be live via that 112252284Sobrien pseudo. */ 112318334Speter 112452284Sobrien if (! frame_pointer_needed) 112552284Sobrien for (i = 0; i < n_basic_blocks; i++) 112652284Sobrien CLEAR_REGNO_REG_SET (BASIC_BLOCK (i)->global_live_at_start, 112752284Sobrien HARD_FRAME_POINTER_REGNUM); 112818334Speter 112952284Sobrien /* Come here (with failure set nonzero) if we can't get enough spill regs 113052284Sobrien and we decide not to abort about it. */ 113152284Sobrien failed: 113218334Speter 113390075Sobrien CLEAR_REG_SET (&spilled_pseudos); 113452284Sobrien reload_in_progress = 0; 113518334Speter 113652284Sobrien /* Now eliminate all pseudo regs by modifying them into 113752284Sobrien their equivalent memory references. 113852284Sobrien The REG-rtx's for the pseudos are modified in place, 113952284Sobrien so all insns that used to refer to them now refer to memory. 114018334Speter 114152284Sobrien For a reg that has a reg_equiv_address, all those insns 114252284Sobrien were changed by reloading so that no insns refer to it any longer; 114352284Sobrien but the DECL_RTL of a variable decl may refer to it, 114452284Sobrien and if so this causes the debugging info to mention the variable. */ 114518334Speter 114652284Sobrien for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 114752284Sobrien { 114852284Sobrien rtx addr = 0; 114918334Speter 115052284Sobrien if (reg_equiv_mem[i]) 115152284Sobrien addr = XEXP (reg_equiv_mem[i], 0); 115218334Speter 115352284Sobrien if (reg_equiv_address[i]) 115452284Sobrien addr = reg_equiv_address[i]; 115518334Speter 115652284Sobrien if (addr) 115752284Sobrien { 115852284Sobrien if (reg_renumber[i] < 0) 115952284Sobrien { 116052284Sobrien rtx reg = regno_reg_rtx[i]; 116190075Sobrien 116290075Sobrien PUT_CODE (reg, MEM); 116352284Sobrien XEXP (reg, 0) = addr; 116452284Sobrien REG_USERVAR_P (reg) = 0; 116590075Sobrien if (reg_equiv_memory_loc[i]) 116690075Sobrien MEM_COPY_ATTRIBUTES (reg, reg_equiv_memory_loc[i]); 116790075Sobrien else 116890075Sobrien { 116990075Sobrien RTX_UNCHANGING_P (reg) = MEM_IN_STRUCT_P (reg) 117090075Sobrien = MEM_SCALAR_P (reg) = 0; 117190075Sobrien MEM_ATTRS (reg) = 0; 117290075Sobrien } 117352284Sobrien } 117452284Sobrien else if (reg_equiv_mem[i]) 117552284Sobrien XEXP (reg_equiv_mem[i], 0) = addr; 117652284Sobrien } 117752284Sobrien } 117818334Speter 117952284Sobrien /* We must set reload_completed now since the cleanup_subreg_operands call 118052284Sobrien below will re-recognize each insn and reload may have generated insns 118152284Sobrien which are only valid during and after reload. */ 118252284Sobrien reload_completed = 1; 118318334Speter 118490075Sobrien /* Make a pass over all the insns and delete all USEs which we inserted 118590075Sobrien only to tag a REG_EQUAL note on them. Remove all REG_DEAD and REG_UNUSED 118690075Sobrien notes. Delete all CLOBBER insns that don't refer to the return value 118790075Sobrien and simplify (subreg (reg)) operands. Also remove all REG_RETVAL and 118890075Sobrien REG_LIBCALL notes since they are no longer useful or accurate. Strip 118990075Sobrien and regenerate REG_INC notes that may have been moved around. */ 119018334Speter 119152284Sobrien for (insn = first; insn; insn = NEXT_INSN (insn)) 119290075Sobrien if (INSN_P (insn)) 119352284Sobrien { 119452284Sobrien rtx *pnote; 119518334Speter 119690075Sobrien if (GET_CODE (insn) == CALL_INSN) 119790075Sobrien replace_pseudos_in_call_usage (& CALL_INSN_FUNCTION_USAGE (insn), 119890075Sobrien VOIDmode, 119990075Sobrien CALL_INSN_FUNCTION_USAGE (insn)); 120090075Sobrien 120152284Sobrien if ((GET_CODE (PATTERN (insn)) == USE 120290075Sobrien /* We mark with QImode USEs introduced by reload itself. */ 120390075Sobrien && (GET_MODE (insn) == QImode 120490075Sobrien || find_reg_note (insn, REG_EQUAL, NULL_RTX))) 120590075Sobrien || (GET_CODE (PATTERN (insn)) == CLOBBER 120690075Sobrien && (GET_CODE (XEXP (PATTERN (insn), 0)) != REG 120790075Sobrien || ! REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0))))) 120852284Sobrien { 120990075Sobrien delete_insn (insn); 121052284Sobrien continue; 121152284Sobrien } 121218334Speter 121352284Sobrien pnote = ®_NOTES (insn); 121452284Sobrien while (*pnote != 0) 121552284Sobrien { 121652284Sobrien if (REG_NOTE_KIND (*pnote) == REG_DEAD 121752284Sobrien || REG_NOTE_KIND (*pnote) == REG_UNUSED 121852284Sobrien || REG_NOTE_KIND (*pnote) == REG_INC 121952284Sobrien || REG_NOTE_KIND (*pnote) == REG_RETVAL 122052284Sobrien || REG_NOTE_KIND (*pnote) == REG_LIBCALL) 122152284Sobrien *pnote = XEXP (*pnote, 1); 122252284Sobrien else 122352284Sobrien pnote = &XEXP (*pnote, 1); 122452284Sobrien } 122518334Speter 122652284Sobrien#ifdef AUTO_INC_DEC 122752284Sobrien add_auto_inc_notes (insn, PATTERN (insn)); 122852284Sobrien#endif 122918334Speter 123052284Sobrien /* And simplify (subreg (reg)) if it appears as an operand. */ 123152284Sobrien cleanup_subreg_operands (insn); 123252284Sobrien } 123318334Speter 123452284Sobrien /* If we are doing stack checking, give a warning if this function's 123552284Sobrien frame size is larger than we expect. */ 123652284Sobrien if (flag_stack_check && ! STACK_CHECK_BUILTIN) 123752284Sobrien { 123852284Sobrien HOST_WIDE_INT size = get_frame_size () + STACK_CHECK_FIXED_FRAME_SIZE; 123990075Sobrien static int verbose_warned = 0; 124090075Sobrien 124152284Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 124252284Sobrien if (regs_ever_live[i] && ! fixed_regs[i] && call_used_regs[i]) 124352284Sobrien size += UNITS_PER_WORD; 124418334Speter 124552284Sobrien if (size > STACK_CHECK_MAX_FRAME_SIZE) 124690075Sobrien { 124752284Sobrien warning ("frame size too large for reliable stack checking"); 124852284Sobrien if (! verbose_warned) 124952284Sobrien { 125052284Sobrien warning ("try reducing the number of local variables"); 125152284Sobrien verbose_warned = 1; 125252284Sobrien } 125352284Sobrien } 125452284Sobrien } 125518334Speter 125652284Sobrien /* Indicate that we no longer have known memory locations or constants. */ 125752284Sobrien if (reg_equiv_constant) 125852284Sobrien free (reg_equiv_constant); 125952284Sobrien reg_equiv_constant = 0; 126052284Sobrien if (reg_equiv_memory_loc) 126152284Sobrien free (reg_equiv_memory_loc); 126252284Sobrien reg_equiv_memory_loc = 0; 126318334Speter 126452284Sobrien if (real_known_ptr) 126552284Sobrien free (real_known_ptr); 126652284Sobrien if (real_at_ptr) 126752284Sobrien free (real_at_ptr); 126818334Speter 126952284Sobrien free (reg_equiv_mem); 127052284Sobrien free (reg_equiv_init); 127152284Sobrien free (reg_equiv_address); 127252284Sobrien free (reg_max_ref_width); 127352284Sobrien free (reg_old_renumber); 127452284Sobrien free (pseudo_previous_regs); 127552284Sobrien free (pseudo_forbidden_regs); 127618334Speter 127752284Sobrien CLEAR_HARD_REG_SET (used_spill_regs); 127852284Sobrien for (i = 0; i < n_spills; i++) 127952284Sobrien SET_HARD_REG_BIT (used_spill_regs, spill_regs[i]); 128018334Speter 128152284Sobrien /* Free all the insn_chain structures at once. */ 128252284Sobrien obstack_free (&reload_obstack, reload_startobj); 128352284Sobrien unused_insn_chains = 0; 128490075Sobrien fixup_abnormal_edges (); 128518334Speter 128696263Sobrien /* Replacing pseudos with their memory equivalents might have 128796263Sobrien created shared rtx. Subsequent passes would get confused 128896263Sobrien by this, so unshare everything here. */ 128996263Sobrien unshare_all_rtl_again (first); 129096263Sobrien 129152284Sobrien return failure; 129252284Sobrien} 129318334Speter 129452284Sobrien/* Yet another special case. Unfortunately, reg-stack forces people to 129552284Sobrien write incorrect clobbers in asm statements. These clobbers must not 129652284Sobrien cause the register to appear in bad_spill_regs, otherwise we'll call 129752284Sobrien fatal_insn later. We clear the corresponding regnos in the live 129852284Sobrien register sets to avoid this. 129952284Sobrien The whole thing is rather sick, I'm afraid. */ 130090075Sobrien 130152284Sobrienstatic void 130252284Sobrienmaybe_fix_stack_asms () 130352284Sobrien{ 130452284Sobrien#ifdef STACK_REGS 130590075Sobrien const char *constraints[MAX_RECOG_OPERANDS]; 130652284Sobrien enum machine_mode operand_mode[MAX_RECOG_OPERANDS]; 130752284Sobrien struct insn_chain *chain; 130818334Speter 130952284Sobrien for (chain = reload_insn_chain; chain != 0; chain = chain->next) 131052284Sobrien { 131152284Sobrien int i, noperands; 131252284Sobrien HARD_REG_SET clobbered, allowed; 131352284Sobrien rtx pat; 131418334Speter 131590075Sobrien if (! INSN_P (chain->insn) 131652284Sobrien || (noperands = asm_noperands (PATTERN (chain->insn))) < 0) 131752284Sobrien continue; 131852284Sobrien pat = PATTERN (chain->insn); 131952284Sobrien if (GET_CODE (pat) != PARALLEL) 132052284Sobrien continue; 132118334Speter 132252284Sobrien CLEAR_HARD_REG_SET (clobbered); 132352284Sobrien CLEAR_HARD_REG_SET (allowed); 132418334Speter 132552284Sobrien /* First, make a mask of all stack regs that are clobbered. */ 132652284Sobrien for (i = 0; i < XVECLEN (pat, 0); i++) 132752284Sobrien { 132852284Sobrien rtx t = XVECEXP (pat, 0, i); 132952284Sobrien if (GET_CODE (t) == CLOBBER && STACK_REG_P (XEXP (t, 0))) 133052284Sobrien SET_HARD_REG_BIT (clobbered, REGNO (XEXP (t, 0))); 133152284Sobrien } 133218334Speter 133352284Sobrien /* Get the operand values and constraints out of the insn. */ 133490075Sobrien decode_asm_operands (pat, recog_data.operand, recog_data.operand_loc, 133552284Sobrien constraints, operand_mode); 133618334Speter 133752284Sobrien /* For every operand, see what registers are allowed. */ 133852284Sobrien for (i = 0; i < noperands; i++) 133952284Sobrien { 134090075Sobrien const char *p = constraints[i]; 134152284Sobrien /* For every alternative, we compute the class of registers allowed 134252284Sobrien for reloading in CLS, and merge its contents into the reg set 134352284Sobrien ALLOWED. */ 134452284Sobrien int cls = (int) NO_REGS; 134518334Speter 134652284Sobrien for (;;) 134752284Sobrien { 134852284Sobrien char c = *p++; 134918334Speter 135052284Sobrien if (c == '\0' || c == ',' || c == '#') 135152284Sobrien { 135252284Sobrien /* End of one alternative - mark the regs in the current 135352284Sobrien class, and reset the class. */ 135452284Sobrien IOR_HARD_REG_SET (allowed, reg_class_contents[cls]); 135552284Sobrien cls = NO_REGS; 135652284Sobrien if (c == '#') 135752284Sobrien do { 135852284Sobrien c = *p++; 135952284Sobrien } while (c != '\0' && c != ','); 136052284Sobrien if (c == '\0') 136152284Sobrien break; 136252284Sobrien continue; 136352284Sobrien } 136418334Speter 136552284Sobrien switch (c) 136652284Sobrien { 136752284Sobrien case '=': case '+': case '*': case '%': case '?': case '!': 136852284Sobrien case '0': case '1': case '2': case '3': case '4': case 'm': 136952284Sobrien case '<': case '>': case 'V': case 'o': case '&': case 'E': 137052284Sobrien case 'F': case 's': case 'i': case 'n': case 'X': case 'I': 137152284Sobrien case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': 137252284Sobrien case 'P': 137352284Sobrien break; 137418334Speter 137552284Sobrien case 'p': 137690075Sobrien cls = (int) reg_class_subunion[cls] 137790075Sobrien [(int) MODE_BASE_REG_CLASS (VOIDmode)]; 137852284Sobrien break; 137918334Speter 138052284Sobrien case 'g': 138152284Sobrien case 'r': 138252284Sobrien cls = (int) reg_class_subunion[cls][(int) GENERAL_REGS]; 138352284Sobrien break; 138418334Speter 138552284Sobrien default: 138652284Sobrien cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)]; 138790075Sobrien 138818334Speter } 138952284Sobrien } 139052284Sobrien } 139152284Sobrien /* Those of the registers which are clobbered, but allowed by the 139252284Sobrien constraints, must be usable as reload registers. So clear them 139352284Sobrien out of the life information. */ 139452284Sobrien AND_HARD_REG_SET (allowed, clobbered); 139552284Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 139652284Sobrien if (TEST_HARD_REG_BIT (allowed, i)) 139752284Sobrien { 139890075Sobrien CLEAR_REGNO_REG_SET (&chain->live_throughout, i); 139990075Sobrien CLEAR_REGNO_REG_SET (&chain->dead_or_set, i); 140052284Sobrien } 140152284Sobrien } 140218334Speter 140352284Sobrien#endif 140452284Sobrien} 140590075Sobrien 140690075Sobrien/* Copy the global variables n_reloads and rld into the corresponding elts 140790075Sobrien of CHAIN. */ 140890075Sobrienstatic void 140990075Sobriencopy_reloads (chain) 141090075Sobrien struct insn_chain *chain; 141190075Sobrien{ 141290075Sobrien chain->n_reloads = n_reloads; 141390075Sobrien chain->rld 141490075Sobrien = (struct reload *) obstack_alloc (&reload_obstack, 141590075Sobrien n_reloads * sizeof (struct reload)); 141690075Sobrien memcpy (chain->rld, rld, n_reloads * sizeof (struct reload)); 141790075Sobrien reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0); 141890075Sobrien} 141918334Speter 142052284Sobrien/* Walk the chain of insns, and determine for each whether it needs reloads 142152284Sobrien and/or eliminations. Build the corresponding insns_need_reload list, and 142252284Sobrien set something_needs_elimination as appropriate. */ 142352284Sobrienstatic void 142452284Sobriencalculate_needs_all_insns (global) 142552284Sobrien int global; 142652284Sobrien{ 142752284Sobrien struct insn_chain **pprev_reload = &insns_need_reload; 142890075Sobrien struct insn_chain *chain, *next = 0; 142918334Speter 143052284Sobrien something_needs_elimination = 0; 143118334Speter 143290075Sobrien reload_insn_firstobj = (char *) obstack_alloc (&reload_obstack, 0); 143390075Sobrien for (chain = reload_insn_chain; chain != 0; chain = next) 143452284Sobrien { 143590075Sobrien rtx insn = chain->insn; 143618334Speter 143790075Sobrien next = chain->next; 143818334Speter 143990075Sobrien /* Clear out the shortcuts. */ 144090075Sobrien chain->n_reloads = 0; 144190075Sobrien chain->need_elim = 0; 144290075Sobrien chain->need_reload = 0; 144390075Sobrien chain->need_operand_change = 0; 144490075Sobrien 144552284Sobrien /* If this is a label, a JUMP_INSN, or has REG_NOTES (which might 144652284Sobrien include REG_LABEL), we need to see what effects this has on the 144752284Sobrien known offsets at labels. */ 144818334Speter 144952284Sobrien if (GET_CODE (insn) == CODE_LABEL || GET_CODE (insn) == JUMP_INSN 145090075Sobrien || (INSN_P (insn) && REG_NOTES (insn) != 0)) 145152284Sobrien set_label_offsets (insn, insn, 0); 145218334Speter 145390075Sobrien if (INSN_P (insn)) 145452284Sobrien { 145552284Sobrien rtx old_body = PATTERN (insn); 145652284Sobrien int old_code = INSN_CODE (insn); 145752284Sobrien rtx old_notes = REG_NOTES (insn); 145852284Sobrien int did_elimination = 0; 145952284Sobrien int operands_changed = 0; 146052284Sobrien rtx set = single_set (insn); 146118334Speter 146252284Sobrien /* Skip insns that only set an equivalence. */ 146352284Sobrien if (set && GET_CODE (SET_DEST (set)) == REG 146452284Sobrien && reg_renumber[REGNO (SET_DEST (set))] < 0 146552284Sobrien && reg_equiv_constant[REGNO (SET_DEST (set))]) 146690075Sobrien continue; 146718334Speter 146852284Sobrien /* If needed, eliminate any eliminable registers. */ 146952284Sobrien if (num_eliminable || num_eliminable_invariants) 147052284Sobrien did_elimination = eliminate_regs_in_insn (insn, 0); 147118334Speter 147252284Sobrien /* Analyze the instruction. */ 147352284Sobrien operands_changed = find_reloads (insn, 0, spill_indirect_levels, 147452284Sobrien global, spill_reg_order); 147518334Speter 147652284Sobrien /* If a no-op set needs more than one reload, this is likely 147752284Sobrien to be something that needs input address reloads. We 147852284Sobrien can't get rid of this cleanly later, and it is of no use 147952284Sobrien anyway, so discard it now. 148052284Sobrien We only do this when expensive_optimizations is enabled, 148152284Sobrien since this complements reload inheritance / output 148252284Sobrien reload deletion, and it can make debugging harder. */ 148352284Sobrien if (flag_expensive_optimizations && n_reloads > 1) 148452284Sobrien { 148552284Sobrien rtx set = single_set (insn); 148652284Sobrien if (set 148752284Sobrien && SET_SRC (set) == SET_DEST (set) 148852284Sobrien && GET_CODE (SET_SRC (set)) == REG 148952284Sobrien && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER) 149018334Speter { 149190075Sobrien delete_insn (insn); 149290075Sobrien /* Delete it from the reload chain */ 149390075Sobrien if (chain->prev) 149490075Sobrien chain->prev->next = next; 149590075Sobrien else 149690075Sobrien reload_insn_chain = next; 149790075Sobrien if (next) 149890075Sobrien next->prev = chain->prev; 149990075Sobrien chain->next = unused_insn_chains; 150090075Sobrien unused_insn_chains = chain; 150152284Sobrien continue; 150218334Speter } 150318334Speter } 150452284Sobrien if (num_eliminable) 150552284Sobrien update_eliminable_offsets (); 150618334Speter 150752284Sobrien /* Remember for later shortcuts which insns had any reloads or 150852284Sobrien register eliminations. */ 150952284Sobrien chain->need_elim = did_elimination; 151052284Sobrien chain->need_reload = n_reloads > 0; 151152284Sobrien chain->need_operand_change = operands_changed; 151218334Speter 151352284Sobrien /* Discard any register replacements done. */ 151452284Sobrien if (did_elimination) 151552284Sobrien { 151690075Sobrien obstack_free (&reload_obstack, reload_insn_firstobj); 151752284Sobrien PATTERN (insn) = old_body; 151852284Sobrien INSN_CODE (insn) = old_code; 151952284Sobrien REG_NOTES (insn) = old_notes; 152052284Sobrien something_needs_elimination = 1; 152152284Sobrien } 152218334Speter 152352284Sobrien something_needs_operands_changed |= operands_changed; 152418334Speter 152552284Sobrien if (n_reloads != 0) 152650397Sobrien { 152790075Sobrien copy_reloads (chain); 152852284Sobrien *pprev_reload = chain; 152952284Sobrien pprev_reload = &chain->next_need_reload; 153050397Sobrien } 153118334Speter } 153252284Sobrien } 153352284Sobrien *pprev_reload = 0; 153452284Sobrien} 153590075Sobrien 153690075Sobrien/* Comparison function for qsort to decide which of two reloads 153790075Sobrien should be handled first. *P1 and *P2 are the reload numbers. */ 153818334Speter 153990075Sobrienstatic int 154090075Sobrienreload_reg_class_lower (r1p, r2p) 154190075Sobrien const PTR r1p; 154290075Sobrien const PTR r2p; 154390075Sobrien{ 154490075Sobrien int r1 = *(const short *) r1p, r2 = *(const short *) r2p; 154590075Sobrien int t; 154618334Speter 154790075Sobrien /* Consider required reloads before optional ones. */ 154890075Sobrien t = rld[r1].optional - rld[r2].optional; 154990075Sobrien if (t != 0) 155090075Sobrien return t; 155118334Speter 155290075Sobrien /* Count all solitary classes before non-solitary ones. */ 155390075Sobrien t = ((reg_class_size[(int) rld[r2].class] == 1) 155490075Sobrien - (reg_class_size[(int) rld[r1].class] == 1)); 155590075Sobrien if (t != 0) 155690075Sobrien return t; 155718334Speter 155890075Sobrien /* Aside from solitaires, consider all multi-reg groups first. */ 155990075Sobrien t = rld[r2].nregs - rld[r1].nregs; 156090075Sobrien if (t != 0) 156190075Sobrien return t; 156218334Speter 156390075Sobrien /* Consider reloads in order of increasing reg-class number. */ 156490075Sobrien t = (int) rld[r1].class - (int) rld[r2].class; 156590075Sobrien if (t != 0) 156690075Sobrien return t; 156718334Speter 156890075Sobrien /* If reloads are equally urgent, sort by reload number, 156990075Sobrien so that the results of qsort leave nothing to chance. */ 157090075Sobrien return r1 - r2; 157190075Sobrien} 157290075Sobrien 157390075Sobrien/* The cost of spilling each hard reg. */ 157490075Sobrienstatic int spill_cost[FIRST_PSEUDO_REGISTER]; 157518334Speter 157690075Sobrien/* When spilling multiple hard registers, we use SPILL_COST for the first 157790075Sobrien spilled hard reg and SPILL_ADD_COST for subsequent regs. SPILL_ADD_COST 157890075Sobrien only the first hard reg for a multi-reg pseudo. */ 157990075Sobrienstatic int spill_add_cost[FIRST_PSEUDO_REGISTER]; 158018334Speter 158190075Sobrien/* Update the spill cost arrays, considering that pseudo REG is live. */ 158218334Speter 158390075Sobrienstatic void 158490075Sobriencount_pseudo (reg) 158590075Sobrien int reg; 158690075Sobrien{ 158790075Sobrien int freq = REG_FREQ (reg); 158890075Sobrien int r = reg_renumber[reg]; 158990075Sobrien int nregs; 159018334Speter 159190075Sobrien if (REGNO_REG_SET_P (&pseudos_counted, reg) 159290075Sobrien || REGNO_REG_SET_P (&spilled_pseudos, reg)) 159390075Sobrien return; 159452284Sobrien 159590075Sobrien SET_REGNO_REG_SET (&pseudos_counted, reg); 159652284Sobrien 159790075Sobrien if (r < 0) 159890075Sobrien abort (); 159918334Speter 160090075Sobrien spill_add_cost[r] += freq; 160118334Speter 160290075Sobrien nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg)); 160390075Sobrien while (nregs-- > 0) 160490075Sobrien spill_cost[r + nregs] += freq; 160590075Sobrien} 160618334Speter 160790075Sobrien/* Calculate the SPILL_COST and SPILL_ADD_COST arrays and determine the 160890075Sobrien contents of BAD_SPILL_REGS for the insn described by CHAIN. */ 160918334Speter 161090075Sobrienstatic void 161190075Sobrienorder_regs_for_reload (chain) 161290075Sobrien struct insn_chain *chain; 161390075Sobrien{ 161490075Sobrien int i; 161590075Sobrien HARD_REG_SET used_by_pseudos; 161690075Sobrien HARD_REG_SET used_by_pseudos2; 161718334Speter 161890075Sobrien COPY_HARD_REG_SET (bad_spill_regs, fixed_reg_set); 161918334Speter 162090075Sobrien memset (spill_cost, 0, sizeof spill_cost); 162190075Sobrien memset (spill_add_cost, 0, sizeof spill_add_cost); 162218334Speter 162390075Sobrien /* Count number of uses of each hard reg by pseudo regs allocated to it 162490075Sobrien and then order them by decreasing use. First exclude hard registers 162590075Sobrien that are live in or across this insn. */ 162652284Sobrien 162790075Sobrien REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout); 162890075Sobrien REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set); 162990075Sobrien IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos); 163090075Sobrien IOR_HARD_REG_SET (bad_spill_regs, used_by_pseudos2); 163152284Sobrien 163290075Sobrien /* Now find out which pseudos are allocated to it, and update 163390075Sobrien hard_reg_n_uses. */ 163490075Sobrien CLEAR_REG_SET (&pseudos_counted); 163518334Speter 163690075Sobrien EXECUTE_IF_SET_IN_REG_SET 163790075Sobrien (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, 163890075Sobrien { 163990075Sobrien count_pseudo (i); 164090075Sobrien }); 164190075Sobrien EXECUTE_IF_SET_IN_REG_SET 164290075Sobrien (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, 164390075Sobrien { 164490075Sobrien count_pseudo (i); 164590075Sobrien }); 164690075Sobrien CLEAR_REG_SET (&pseudos_counted); 164790075Sobrien} 164890075Sobrien 164990075Sobrien/* Vector of reload-numbers showing the order in which the reloads should 165090075Sobrien be processed. */ 165190075Sobrienstatic short reload_order[MAX_RELOADS]; 165218334Speter 165390075Sobrien/* This is used to keep track of the spill regs used in one insn. */ 165490075Sobrienstatic HARD_REG_SET used_spill_regs_local; 165518334Speter 165690075Sobrien/* We decided to spill hard register SPILLED, which has a size of 165790075Sobrien SPILLED_NREGS. Determine how pseudo REG, which is live during the insn, 165890075Sobrien is affected. We will add it to SPILLED_PSEUDOS if necessary, and we will 165990075Sobrien update SPILL_COST/SPILL_ADD_COST. */ 166018334Speter 166190075Sobrienstatic void 166290075Sobriencount_spilled_pseudo (spilled, spilled_nregs, reg) 166390075Sobrien int spilled, spilled_nregs, reg; 166490075Sobrien{ 166590075Sobrien int r = reg_renumber[reg]; 166690075Sobrien int nregs = HARD_REGNO_NREGS (r, PSEUDO_REGNO_MODE (reg)); 166718334Speter 166890075Sobrien if (REGNO_REG_SET_P (&spilled_pseudos, reg) 166990075Sobrien || spilled + spilled_nregs <= r || r + nregs <= spilled) 167090075Sobrien return; 167118334Speter 167290075Sobrien SET_REGNO_REG_SET (&spilled_pseudos, reg); 167318334Speter 167490075Sobrien spill_add_cost[r] -= REG_FREQ (reg); 167590075Sobrien while (nregs-- > 0) 167690075Sobrien spill_cost[r + nregs] -= REG_FREQ (reg); 167790075Sobrien} 167818334Speter 167990075Sobrien/* Find reload register to use for reload number ORDER. */ 168018334Speter 168190075Sobrienstatic int 168290075Sobrienfind_reg (chain, order) 168390075Sobrien struct insn_chain *chain; 168490075Sobrien int order; 168590075Sobrien{ 168690075Sobrien int rnum = reload_order[order]; 168790075Sobrien struct reload *rl = rld + rnum; 168890075Sobrien int best_cost = INT_MAX; 168990075Sobrien int best_reg = -1; 169090075Sobrien unsigned int i, j; 169190075Sobrien int k; 169290075Sobrien HARD_REG_SET not_usable; 169390075Sobrien HARD_REG_SET used_by_other_reload; 169418334Speter 169590075Sobrien COPY_HARD_REG_SET (not_usable, bad_spill_regs); 169690075Sobrien IOR_HARD_REG_SET (not_usable, bad_spill_regs_global); 169790075Sobrien IOR_COMPL_HARD_REG_SET (not_usable, reg_class_contents[rl->class]); 169818334Speter 169990075Sobrien CLEAR_HARD_REG_SET (used_by_other_reload); 170090075Sobrien for (k = 0; k < order; k++) 170190075Sobrien { 170290075Sobrien int other = reload_order[k]; 170318334Speter 170490075Sobrien if (rld[other].regno >= 0 && reloads_conflict (other, rnum)) 170590075Sobrien for (j = 0; j < rld[other].nregs; j++) 170690075Sobrien SET_HARD_REG_BIT (used_by_other_reload, rld[other].regno + j); 170790075Sobrien } 170818334Speter 170952284Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 171052284Sobrien { 171190075Sobrien unsigned int regno = i; 171218334Speter 171390075Sobrien if (! TEST_HARD_REG_BIT (not_usable, regno) 171490075Sobrien && ! TEST_HARD_REG_BIT (used_by_other_reload, regno) 171590075Sobrien && HARD_REGNO_MODE_OK (regno, rl->mode)) 171652284Sobrien { 171790075Sobrien int this_cost = spill_cost[regno]; 171890075Sobrien int ok = 1; 171990075Sobrien unsigned int this_nregs = HARD_REGNO_NREGS (regno, rl->mode); 172018334Speter 172190075Sobrien for (j = 1; j < this_nregs; j++) 172218334Speter { 172390075Sobrien this_cost += spill_add_cost[regno + j]; 172490075Sobrien if ((TEST_HARD_REG_BIT (not_usable, regno + j)) 172590075Sobrien || TEST_HARD_REG_BIT (used_by_other_reload, regno + j)) 172690075Sobrien ok = 0; 172752284Sobrien } 172890075Sobrien if (! ok) 172990075Sobrien continue; 173090075Sobrien if (rl->in && GET_CODE (rl->in) == REG && REGNO (rl->in) == regno) 173190075Sobrien this_cost--; 173290075Sobrien if (rl->out && GET_CODE (rl->out) == REG && REGNO (rl->out) == regno) 173390075Sobrien this_cost--; 173490075Sobrien if (this_cost < best_cost 173590075Sobrien /* Among registers with equal cost, prefer caller-saved ones, or 173690075Sobrien use REG_ALLOC_ORDER if it is defined. */ 173790075Sobrien || (this_cost == best_cost 173890075Sobrien#ifdef REG_ALLOC_ORDER 173990075Sobrien && (inv_reg_alloc_order[regno] 174090075Sobrien < inv_reg_alloc_order[best_reg]) 174190075Sobrien#else 174290075Sobrien && call_used_regs[regno] 174390075Sobrien && ! call_used_regs[best_reg] 174490075Sobrien#endif 174590075Sobrien )) 174690075Sobrien { 174790075Sobrien best_reg = regno; 174890075Sobrien best_cost = this_cost; 174990075Sobrien } 175052284Sobrien } 175152284Sobrien } 175290075Sobrien if (best_reg == -1) 175390075Sobrien return 0; 175418334Speter 175590075Sobrien if (rtl_dump_file) 175690075Sobrien fprintf (rtl_dump_file, "Using reg %d for reload %d\n", best_reg, rnum); 175718334Speter 175890075Sobrien rl->nregs = HARD_REGNO_NREGS (best_reg, rl->mode); 175990075Sobrien rl->regno = best_reg; 176018334Speter 176190075Sobrien EXECUTE_IF_SET_IN_REG_SET 176290075Sobrien (&chain->live_throughout, FIRST_PSEUDO_REGISTER, j, 176390075Sobrien { 176490075Sobrien count_spilled_pseudo (best_reg, rl->nregs, j); 176590075Sobrien }); 176618334Speter 176790075Sobrien EXECUTE_IF_SET_IN_REG_SET 176890075Sobrien (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, j, 176990075Sobrien { 177090075Sobrien count_spilled_pseudo (best_reg, rl->nregs, j); 177190075Sobrien }); 177218334Speter 177390075Sobrien for (i = 0; i < rl->nregs; i++) 177452284Sobrien { 177590075Sobrien if (spill_cost[best_reg + i] != 0 177690075Sobrien || spill_add_cost[best_reg + i] != 0) 177790075Sobrien abort (); 177890075Sobrien SET_HARD_REG_BIT (used_spill_regs_local, best_reg + i); 177918334Speter } 178090075Sobrien return 1; 178152284Sobrien} 178218334Speter 178352284Sobrien/* Find more reload regs to satisfy the remaining need of an insn, which 178452284Sobrien is given by CHAIN. 178552284Sobrien Do it by ascending class number, since otherwise a reg 178652284Sobrien might be spilled for a big class and might fail to count 178790075Sobrien for a smaller class even though it belongs to that class. */ 178818334Speter 178952284Sobrienstatic void 179090075Sobrienfind_reload_regs (chain) 179152284Sobrien struct insn_chain *chain; 179252284Sobrien{ 179390075Sobrien int i; 179418334Speter 179590075Sobrien /* In order to be certain of getting the registers we need, 179690075Sobrien we must sort the reloads into order of increasing register class. 179790075Sobrien Then our grabbing of reload registers will parallel the process 179890075Sobrien that provided the reload registers. */ 179990075Sobrien for (i = 0; i < chain->n_reloads; i++) 180018334Speter { 180190075Sobrien /* Show whether this reload already has a hard reg. */ 180290075Sobrien if (chain->rld[i].reg_rtx) 180352284Sobrien { 180490075Sobrien int regno = REGNO (chain->rld[i].reg_rtx); 180590075Sobrien chain->rld[i].regno = regno; 180690075Sobrien chain->rld[i].nregs 180790075Sobrien = HARD_REGNO_NREGS (regno, GET_MODE (chain->rld[i].reg_rtx)); 180818334Speter } 180990075Sobrien else 181090075Sobrien chain->rld[i].regno = -1; 181190075Sobrien reload_order[i] = i; 181290075Sobrien } 181350397Sobrien 181490075Sobrien n_reloads = chain->n_reloads; 181590075Sobrien memcpy (rld, chain->rld, n_reloads * sizeof (struct reload)); 181650397Sobrien 181790075Sobrien CLEAR_HARD_REG_SET (used_spill_regs_local); 181850397Sobrien 181990075Sobrien if (rtl_dump_file) 182090075Sobrien fprintf (rtl_dump_file, "Spilling for insn %d.\n", INSN_UID (chain->insn)); 182152284Sobrien 182290075Sobrien qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower); 182352284Sobrien 182490075Sobrien /* Compute the order of preference for hard registers to spill. */ 182552284Sobrien 182690075Sobrien order_regs_for_reload (chain); 182752284Sobrien 182890075Sobrien for (i = 0; i < n_reloads; i++) 182990075Sobrien { 183090075Sobrien int r = reload_order[i]; 183152284Sobrien 183290075Sobrien /* Ignore reloads that got marked inoperative. */ 183390075Sobrien if ((rld[r].out != 0 || rld[r].in != 0 || rld[r].secondary_p) 183490075Sobrien && ! rld[r].optional 183590075Sobrien && rld[r].regno == -1) 183690075Sobrien if (! find_reg (chain, i)) 183790075Sobrien { 183890075Sobrien spill_failure (chain->insn, rld[r].class); 183990075Sobrien failure = 1; 184052284Sobrien return; 184190075Sobrien } 184218334Speter } 184318334Speter 184490075Sobrien COPY_HARD_REG_SET (chain->used_spill_regs, used_spill_regs_local); 184590075Sobrien IOR_HARD_REG_SET (used_spill_regs, used_spill_regs_local); 184690075Sobrien 184790075Sobrien memcpy (chain->rld, rld, n_reloads * sizeof (struct reload)); 184852284Sobrien} 184918334Speter 185090075Sobrienstatic void 185190075Sobrienselect_reload_regs () 185252284Sobrien{ 185390075Sobrien struct insn_chain *chain; 185418334Speter 185590075Sobrien /* Try to satisfy the needs for each insn. */ 185690075Sobrien for (chain = insns_need_reload; chain != 0; 185790075Sobrien chain = chain->next_need_reload) 185890075Sobrien find_reload_regs (chain); 185952284Sobrien} 186052284Sobrien 186152284Sobrien/* Delete all insns that were inserted by emit_caller_save_insns during 186252284Sobrien this iteration. */ 186352284Sobrienstatic void 186452284Sobriendelete_caller_save_insns () 186552284Sobrien{ 186652284Sobrien struct insn_chain *c = reload_insn_chain; 186718334Speter 186852284Sobrien while (c != 0) 186952284Sobrien { 187052284Sobrien while (c != 0 && c->is_caller_save_insn) 187152284Sobrien { 187252284Sobrien struct insn_chain *next = c->next; 187352284Sobrien rtx insn = c->insn; 187450397Sobrien 187552284Sobrien if (c == reload_insn_chain) 187652284Sobrien reload_insn_chain = next; 187790075Sobrien delete_insn (insn); 187818334Speter 187952284Sobrien if (next) 188052284Sobrien next->prev = c->prev; 188152284Sobrien if (c->prev) 188252284Sobrien c->prev->next = next; 188352284Sobrien c->next = unused_insn_chains; 188452284Sobrien unused_insn_chains = c; 188552284Sobrien c = next; 188652284Sobrien } 188752284Sobrien if (c != 0) 188852284Sobrien c = c->next; 188952284Sobrien } 189018334Speter} 189118334Speter 189218334Speter/* Handle the failure to find a register to spill. 189318334Speter INSN should be one of the insns which needed this particular spill reg. */ 189418334Speter 189518334Speterstatic void 189690075Sobrienspill_failure (insn, class) 189718334Speter rtx insn; 189890075Sobrien enum reg_class class; 189918334Speter{ 190090075Sobrien static const char *const reg_class_names[] = REG_CLASS_NAMES; 190118334Speter if (asm_noperands (PATTERN (insn)) >= 0) 190290075Sobrien error_for_asm (insn, "can't find a register in class `%s' while reloading `asm'", 190390075Sobrien reg_class_names[class]); 190418334Speter else 190552284Sobrien { 190690075Sobrien error ("unable to find a register to spill in class `%s'", 190790075Sobrien reg_class_names[class]); 190890075Sobrien fatal_insn ("this is the insn:", insn); 190952284Sobrien } 191018334Speter} 191118334Speter 191218334Speter/* Delete an unneeded INSN and any previous insns who sole purpose is loading 191318334Speter data that is dead in INSN. */ 191418334Speter 191518334Speterstatic void 191618334Speterdelete_dead_insn (insn) 191718334Speter rtx insn; 191818334Speter{ 191918334Speter rtx prev = prev_real_insn (insn); 192018334Speter rtx prev_dest; 192118334Speter 192218334Speter /* If the previous insn sets a register that dies in our insn, delete it 192318334Speter too. */ 192418334Speter if (prev && GET_CODE (PATTERN (prev)) == SET 192518334Speter && (prev_dest = SET_DEST (PATTERN (prev)), GET_CODE (prev_dest) == REG) 192618334Speter && reg_mentioned_p (prev_dest, PATTERN (insn)) 192750397Sobrien && find_regno_note (insn, REG_DEAD, REGNO (prev_dest)) 192850397Sobrien && ! side_effects_p (SET_SRC (PATTERN (prev)))) 192918334Speter delete_dead_insn (prev); 193018334Speter 193118334Speter PUT_CODE (insn, NOTE); 193218334Speter NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; 193318334Speter NOTE_SOURCE_FILE (insn) = 0; 193418334Speter} 193518334Speter 193618334Speter/* Modify the home of pseudo-reg I. 193718334Speter The new home is present in reg_renumber[I]. 193818334Speter 193918334Speter FROM_REG may be the hard reg that the pseudo-reg is being spilled from; 194018334Speter or it may be -1, meaning there is none or it is not relevant. 194118334Speter This is used so that all pseudos spilled from a given hard reg 194218334Speter can share one stack slot. */ 194318334Speter 194418334Speterstatic void 194518334Speteralter_reg (i, from_reg) 194690075Sobrien int i; 194718334Speter int from_reg; 194818334Speter{ 194918334Speter /* When outputting an inline function, this can happen 195018334Speter for a reg that isn't actually used. */ 195118334Speter if (regno_reg_rtx[i] == 0) 195218334Speter return; 195318334Speter 195418334Speter /* If the reg got changed to a MEM at rtl-generation time, 195518334Speter ignore it. */ 195618334Speter if (GET_CODE (regno_reg_rtx[i]) != REG) 195718334Speter return; 195818334Speter 195918334Speter /* Modify the reg-rtx to contain the new hard reg 196018334Speter number or else to contain its pseudo reg number. */ 196118334Speter REGNO (regno_reg_rtx[i]) 196218334Speter = reg_renumber[i] >= 0 ? reg_renumber[i] : i; 196318334Speter 196418334Speter /* If we have a pseudo that is needed but has no hard reg or equivalent, 196518334Speter allocate a stack slot for it. */ 196618334Speter 196718334Speter if (reg_renumber[i] < 0 196850397Sobrien && REG_N_REFS (i) > 0 196918334Speter && reg_equiv_constant[i] == 0 197018334Speter && reg_equiv_memory_loc[i] == 0) 197118334Speter { 197290075Sobrien rtx x; 197390075Sobrien unsigned int inherent_size = PSEUDO_REGNO_BYTES (i); 197490075Sobrien unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]); 197518334Speter int adjust = 0; 197618334Speter 197718334Speter /* Each pseudo reg has an inherent size which comes from its own mode, 197818334Speter and a total size which provides room for paradoxical subregs 197918334Speter which refer to the pseudo reg in wider modes. 198018334Speter 198118334Speter We can use a slot already allocated if it provides both 198218334Speter enough inherent space and enough total space. 198318334Speter Otherwise, we allocate a new slot, making sure that it has no less 198418334Speter inherent space, and no less total space, then the previous slot. */ 198518334Speter if (from_reg == -1) 198618334Speter { 198718334Speter /* No known place to spill from => no slot to reuse. */ 198850397Sobrien x = assign_stack_local (GET_MODE (regno_reg_rtx[i]), total_size, 198950397Sobrien inherent_size == total_size ? 0 : -1); 199018334Speter if (BYTES_BIG_ENDIAN) 199118334Speter /* Cancel the big-endian correction done in assign_stack_local. 199218334Speter Get the address of the beginning of the slot. 199318334Speter This is so we can do a big-endian correction unconditionally 199418334Speter below. */ 199518334Speter adjust = inherent_size - total_size; 199618334Speter 199718334Speter RTX_UNCHANGING_P (x) = RTX_UNCHANGING_P (regno_reg_rtx[i]); 199890075Sobrien 199990075Sobrien /* Nothing can alias this slot except this pseudo. */ 200090075Sobrien set_mem_alias_set (x, new_alias_set ()); 200118334Speter } 200290075Sobrien 200318334Speter /* Reuse a stack slot if possible. */ 200418334Speter else if (spill_stack_slot[from_reg] != 0 200518334Speter && spill_stack_slot_width[from_reg] >= total_size 200618334Speter && (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg])) 200718334Speter >= inherent_size)) 200818334Speter x = spill_stack_slot[from_reg]; 200990075Sobrien 201018334Speter /* Allocate a bigger slot. */ 201118334Speter else 201218334Speter { 201318334Speter /* Compute maximum size needed, both for inherent size 201418334Speter and for total size. */ 201518334Speter enum machine_mode mode = GET_MODE (regno_reg_rtx[i]); 201618334Speter rtx stack_slot; 201790075Sobrien 201818334Speter if (spill_stack_slot[from_reg]) 201918334Speter { 202018334Speter if (GET_MODE_SIZE (GET_MODE (spill_stack_slot[from_reg])) 202118334Speter > inherent_size) 202218334Speter mode = GET_MODE (spill_stack_slot[from_reg]); 202318334Speter if (spill_stack_slot_width[from_reg] > total_size) 202418334Speter total_size = spill_stack_slot_width[from_reg]; 202518334Speter } 202690075Sobrien 202718334Speter /* Make a slot with that size. */ 202850397Sobrien x = assign_stack_local (mode, total_size, 202950397Sobrien inherent_size == total_size ? 0 : -1); 203018334Speter stack_slot = x; 203190075Sobrien 203290075Sobrien /* All pseudos mapped to this slot can alias each other. */ 203390075Sobrien if (spill_stack_slot[from_reg]) 203490075Sobrien set_mem_alias_set (x, MEM_ALIAS_SET (spill_stack_slot[from_reg])); 203590075Sobrien else 203690075Sobrien set_mem_alias_set (x, new_alias_set ()); 203790075Sobrien 203818334Speter if (BYTES_BIG_ENDIAN) 203918334Speter { 204018334Speter /* Cancel the big-endian correction done in assign_stack_local. 204118334Speter Get the address of the beginning of the slot. 204218334Speter This is so we can do a big-endian correction unconditionally 204318334Speter below. */ 204418334Speter adjust = GET_MODE_SIZE (mode) - total_size; 204518334Speter if (adjust) 204690075Sobrien stack_slot 204790075Sobrien = adjust_address_nv (x, mode_for_size (total_size 204850397Sobrien * BITS_PER_UNIT, 204950397Sobrien MODE_INT, 1), 205090075Sobrien adjust); 205118334Speter } 205290075Sobrien 205318334Speter spill_stack_slot[from_reg] = stack_slot; 205418334Speter spill_stack_slot_width[from_reg] = total_size; 205518334Speter } 205618334Speter 205718334Speter /* On a big endian machine, the "address" of the slot 205818334Speter is the address of the low part that fits its inherent mode. */ 205918334Speter if (BYTES_BIG_ENDIAN && inherent_size < total_size) 206018334Speter adjust += (total_size - inherent_size); 206118334Speter 206218334Speter /* If we have any adjustment to make, or if the stack slot is the 206318334Speter wrong mode, make a new stack slot. */ 206490075Sobrien x = adjust_address_nv (x, GET_MODE (regno_reg_rtx[i]), adjust); 206590075Sobrien 206690075Sobrien /* If we have a decl for the original register, set it for the 206790075Sobrien memory. If this is a shared MEM, make a copy. */ 206890075Sobrien if (REGNO_DECL (i)) 206918334Speter { 207096263Sobrien rtx decl = DECL_RTL_IF_SET (REGNO_DECL (i)); 207150397Sobrien 207296263Sobrien /* We can do this only for the DECLs home pseudo, not for 207396263Sobrien any copies of it, since otherwise when the stack slot 207496263Sobrien is reused, nonoverlapping_memrefs_p might think they 207596263Sobrien cannot overlap. */ 207696263Sobrien if (decl && GET_CODE (decl) == REG && REGNO (decl) == (unsigned) i) 207796263Sobrien { 207896263Sobrien if (from_reg != -1 && spill_stack_slot[from_reg] == x) 207996263Sobrien x = copy_rtx (x); 208096263Sobrien 208196263Sobrien set_mem_expr (x, REGNO_DECL (i)); 208296263Sobrien } 208318334Speter } 208418334Speter 208590075Sobrien /* Save the stack slot for later. */ 208618334Speter reg_equiv_memory_loc[i] = x; 208718334Speter } 208818334Speter} 208918334Speter 209018334Speter/* Mark the slots in regs_ever_live for the hard regs 209118334Speter used by pseudo-reg number REGNO. */ 209218334Speter 209318334Spetervoid 209418334Spetermark_home_live (regno) 209518334Speter int regno; 209618334Speter{ 209790075Sobrien int i, lim; 209890075Sobrien 209918334Speter i = reg_renumber[regno]; 210018334Speter if (i < 0) 210118334Speter return; 210218334Speter lim = i + HARD_REGNO_NREGS (i, PSEUDO_REGNO_MODE (regno)); 210318334Speter while (i < lim) 210418334Speter regs_ever_live[i++] = 1; 210518334Speter} 210618334Speter 210718334Speter/* This function handles the tracking of elimination offsets around branches. 210818334Speter 210918334Speter X is a piece of RTL being scanned. 211018334Speter 211118334Speter INSN is the insn that it came from, if any. 211218334Speter 211318334Speter INITIAL_P is non-zero if we are to set the offset to be the initial 211418334Speter offset and zero if we are setting the offset of the label to be the 211518334Speter current offset. */ 211618334Speter 211718334Speterstatic void 211818334Speterset_label_offsets (x, insn, initial_p) 211918334Speter rtx x; 212018334Speter rtx insn; 212118334Speter int initial_p; 212218334Speter{ 212318334Speter enum rtx_code code = GET_CODE (x); 212418334Speter rtx tem; 212552284Sobrien unsigned int i; 212618334Speter struct elim_table *p; 212718334Speter 212818334Speter switch (code) 212918334Speter { 213018334Speter case LABEL_REF: 213118334Speter if (LABEL_REF_NONLOCAL_P (x)) 213218334Speter return; 213318334Speter 213418334Speter x = XEXP (x, 0); 213518334Speter 213650397Sobrien /* ... fall through ... */ 213718334Speter 213818334Speter case CODE_LABEL: 213918334Speter /* If we know nothing about this label, set the desired offsets. Note 214018334Speter that this sets the offset at a label to be the offset before a label 214118334Speter if we don't know anything about the label. This is not correct for 214218334Speter the label after a BARRIER, but is the best guess we can make. If 214318334Speter we guessed wrong, we will suppress an elimination that might have 214418334Speter been possible had we been able to guess correctly. */ 214518334Speter 214618334Speter if (! offsets_known_at[CODE_LABEL_NUMBER (x)]) 214718334Speter { 214818334Speter for (i = 0; i < NUM_ELIMINABLE_REGS; i++) 214918334Speter offsets_at[CODE_LABEL_NUMBER (x)][i] 215018334Speter = (initial_p ? reg_eliminate[i].initial_offset 215118334Speter : reg_eliminate[i].offset); 215218334Speter offsets_known_at[CODE_LABEL_NUMBER (x)] = 1; 215318334Speter } 215418334Speter 215518334Speter /* Otherwise, if this is the definition of a label and it is 215618334Speter preceded by a BARRIER, set our offsets to the known offset of 215718334Speter that label. */ 215818334Speter 215918334Speter else if (x == insn 216018334Speter && (tem = prev_nonnote_insn (insn)) != 0 216118334Speter && GET_CODE (tem) == BARRIER) 216252284Sobrien set_offsets_for_label (insn); 216318334Speter else 216418334Speter /* If neither of the above cases is true, compare each offset 216518334Speter with those previously recorded and suppress any eliminations 216618334Speter where the offsets disagree. */ 216718334Speter 216818334Speter for (i = 0; i < NUM_ELIMINABLE_REGS; i++) 216918334Speter if (offsets_at[CODE_LABEL_NUMBER (x)][i] 217018334Speter != (initial_p ? reg_eliminate[i].initial_offset 217118334Speter : reg_eliminate[i].offset)) 217218334Speter reg_eliminate[i].can_eliminate = 0; 217318334Speter 217418334Speter return; 217518334Speter 217618334Speter case JUMP_INSN: 217718334Speter set_label_offsets (PATTERN (insn), insn, initial_p); 217818334Speter 217950397Sobrien /* ... fall through ... */ 218018334Speter 218118334Speter case INSN: 218218334Speter case CALL_INSN: 218318334Speter /* Any labels mentioned in REG_LABEL notes can be branched to indirectly 218418334Speter and hence must have all eliminations at their initial offsets. */ 218518334Speter for (tem = REG_NOTES (x); tem; tem = XEXP (tem, 1)) 218618334Speter if (REG_NOTE_KIND (tem) == REG_LABEL) 218718334Speter set_label_offsets (XEXP (tem, 0), insn, 1); 218818334Speter return; 218918334Speter 219090075Sobrien case PARALLEL: 219118334Speter case ADDR_VEC: 219218334Speter case ADDR_DIFF_VEC: 219390075Sobrien /* Each of the labels in the parallel or address vector must be 219490075Sobrien at their initial offsets. We want the first field for PARALLEL 219590075Sobrien and ADDR_VEC and the second field for ADDR_DIFF_VEC. */ 219618334Speter 219752284Sobrien for (i = 0; i < (unsigned) XVECLEN (x, code == ADDR_DIFF_VEC); i++) 219818334Speter set_label_offsets (XVECEXP (x, code == ADDR_DIFF_VEC, i), 219918334Speter insn, initial_p); 220018334Speter return; 220118334Speter 220218334Speter case SET: 220318334Speter /* We only care about setting PC. If the source is not RETURN, 220418334Speter IF_THEN_ELSE, or a label, disable any eliminations not at 220518334Speter their initial offsets. Similarly if any arm of the IF_THEN_ELSE 220618334Speter isn't one of those possibilities. For branches to a label, 220718334Speter call ourselves recursively. 220818334Speter 220918334Speter Note that this can disable elimination unnecessarily when we have 221018334Speter a non-local goto since it will look like a non-constant jump to 221118334Speter someplace in the current function. This isn't a significant 221218334Speter problem since such jumps will normally be when all elimination 221318334Speter pairs are back to their initial offsets. */ 221418334Speter 221518334Speter if (SET_DEST (x) != pc_rtx) 221618334Speter return; 221718334Speter 221818334Speter switch (GET_CODE (SET_SRC (x))) 221918334Speter { 222018334Speter case PC: 222118334Speter case RETURN: 222218334Speter return; 222318334Speter 222418334Speter case LABEL_REF: 222518334Speter set_label_offsets (XEXP (SET_SRC (x), 0), insn, initial_p); 222618334Speter return; 222718334Speter 222818334Speter case IF_THEN_ELSE: 222918334Speter tem = XEXP (SET_SRC (x), 1); 223018334Speter if (GET_CODE (tem) == LABEL_REF) 223118334Speter set_label_offsets (XEXP (tem, 0), insn, initial_p); 223218334Speter else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN) 223318334Speter break; 223418334Speter 223518334Speter tem = XEXP (SET_SRC (x), 2); 223618334Speter if (GET_CODE (tem) == LABEL_REF) 223718334Speter set_label_offsets (XEXP (tem, 0), insn, initial_p); 223818334Speter else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN) 223918334Speter break; 224018334Speter return; 224150397Sobrien 224250397Sobrien default: 224350397Sobrien break; 224418334Speter } 224518334Speter 224618334Speter /* If we reach here, all eliminations must be at their initial 224718334Speter offset because we are doing a jump to a variable address. */ 224818334Speter for (p = reg_eliminate; p < ®_eliminate[NUM_ELIMINABLE_REGS]; p++) 224918334Speter if (p->offset != p->initial_offset) 225018334Speter p->can_eliminate = 0; 225150397Sobrien break; 225290075Sobrien 225350397Sobrien default: 225450397Sobrien break; 225518334Speter } 225618334Speter} 225718334Speter 225818334Speter/* Scan X and replace any eliminable registers (such as fp) with a 225918334Speter replacement (such as sp), plus an offset. 226018334Speter 226118334Speter MEM_MODE is the mode of an enclosing MEM. We need this to know how 226218334Speter much to adjust a register for, e.g., PRE_DEC. Also, if we are inside a 226318334Speter MEM, we are allowed to replace a sum of a register and the constant zero 226418334Speter with the register, which we cannot do outside a MEM. In addition, we need 226518334Speter to record the fact that a register is referenced outside a MEM. 226618334Speter 226718334Speter If INSN is an insn, it is the insn containing X. If we replace a REG 226818334Speter in a SET_DEST with an equivalent MEM and INSN is non-zero, write a 226918334Speter CLOBBER of the pseudo after INSN so find_equiv_regs will know that 227050397Sobrien the REG is being modified. 227118334Speter 227218334Speter Alternatively, INSN may be a note (an EXPR_LIST or INSN_LIST). 227318334Speter That's used when we eliminate in expressions stored in notes. 227418334Speter This means, do not set ref_outside_mem even if the reference 227518334Speter is outside of MEMs. 227618334Speter 227718334Speter REG_EQUIV_MEM and REG_EQUIV_ADDRESS contain address that have had 227818334Speter replacements done assuming all offsets are at their initial values. If 227918334Speter they are not, or if REG_EQUIV_ADDRESS is nonzero for a pseudo we 228018334Speter encounter, return the actual location so that find_reloads will do 228118334Speter the proper thing. */ 228218334Speter 228318334Speterrtx 228418334Spetereliminate_regs (x, mem_mode, insn) 228518334Speter rtx x; 228618334Speter enum machine_mode mem_mode; 228718334Speter rtx insn; 228818334Speter{ 228918334Speter enum rtx_code code = GET_CODE (x); 229018334Speter struct elim_table *ep; 229118334Speter int regno; 229218334Speter rtx new; 229318334Speter int i, j; 229490075Sobrien const char *fmt; 229518334Speter int copied = 0; 229618334Speter 229752284Sobrien if (! current_function_decl) 229852284Sobrien return x; 229952284Sobrien 230018334Speter switch (code) 230118334Speter { 230218334Speter case CONST_INT: 230318334Speter case CONST_DOUBLE: 230496263Sobrien case CONST_VECTOR: 230518334Speter case CONST: 230618334Speter case SYMBOL_REF: 230718334Speter case CODE_LABEL: 230818334Speter case PC: 230918334Speter case CC0: 231018334Speter case ASM_INPUT: 231118334Speter case ADDR_VEC: 231218334Speter case ADDR_DIFF_VEC: 231318334Speter case RETURN: 231418334Speter return x; 231518334Speter 231650397Sobrien case ADDRESSOF: 231750397Sobrien /* This is only for the benefit of the debugging backends, which call 231850397Sobrien eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are 231950397Sobrien removed after CSE. */ 232050397Sobrien new = eliminate_regs (XEXP (x, 0), 0, insn); 232150397Sobrien if (GET_CODE (new) == MEM) 232250397Sobrien return XEXP (new, 0); 232350397Sobrien return x; 232450397Sobrien 232518334Speter case REG: 232618334Speter regno = REGNO (x); 232718334Speter 232818334Speter /* First handle the case where we encounter a bare register that 232918334Speter is eliminable. Replace it with a PLUS. */ 233018334Speter if (regno < FIRST_PSEUDO_REGISTER) 233118334Speter { 233218334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 233318334Speter ep++) 233418334Speter if (ep->from_rtx == x && ep->can_eliminate) 233590075Sobrien return plus_constant (ep->to_rtx, ep->previous_offset); 233618334Speter 233718334Speter } 233890075Sobrien else if (reg_renumber && reg_renumber[regno] < 0 233990075Sobrien && reg_equiv_constant && reg_equiv_constant[regno] 234052284Sobrien && ! CONSTANT_P (reg_equiv_constant[regno])) 234152284Sobrien return eliminate_regs (copy_rtx (reg_equiv_constant[regno]), 234252284Sobrien mem_mode, insn); 234318334Speter return x; 234418334Speter 234590075Sobrien /* You might think handling MINUS in a manner similar to PLUS is a 234690075Sobrien good idea. It is not. It has been tried multiple times and every 234790075Sobrien time the change has had to have been reverted. 234890075Sobrien 234990075Sobrien Other parts of reload know a PLUS is special (gen_reload for example) 235090075Sobrien and require special code to handle code a reloaded PLUS operand. 235190075Sobrien 235290075Sobrien Also consider backends where the flags register is clobbered by a 235390075Sobrien MINUS, but we can emit a PLUS that does not clobber flags (ia32, 235490075Sobrien lea instruction comes to mind). If we try to reload a MINUS, we 235590075Sobrien may kill the flags register that was holding a useful value. 235690075Sobrien 235790075Sobrien So, please before trying to handle MINUS, consider reload as a 235890075Sobrien whole instead of this little section as well as the backend issues. */ 235918334Speter case PLUS: 236018334Speter /* If this is the sum of an eliminable register and a constant, rework 236190075Sobrien the sum. */ 236218334Speter if (GET_CODE (XEXP (x, 0)) == REG 236318334Speter && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER 236418334Speter && CONSTANT_P (XEXP (x, 1))) 236518334Speter { 236618334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 236718334Speter ep++) 236818334Speter if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate) 236918334Speter { 237018334Speter /* The only time we want to replace a PLUS with a REG (this 237118334Speter occurs when the constant operand of the PLUS is the negative 237218334Speter of the offset) is when we are inside a MEM. We won't want 237318334Speter to do so at other times because that would change the 237418334Speter structure of the insn in a way that reload can't handle. 237518334Speter We special-case the commonest situation in 237618334Speter eliminate_regs_in_insn, so just replace a PLUS with a 237718334Speter PLUS here, unless inside a MEM. */ 237818334Speter if (mem_mode != 0 && GET_CODE (XEXP (x, 1)) == CONST_INT 237918334Speter && INTVAL (XEXP (x, 1)) == - ep->previous_offset) 238018334Speter return ep->to_rtx; 238118334Speter else 238250397Sobrien return gen_rtx_PLUS (Pmode, ep->to_rtx, 238350397Sobrien plus_constant (XEXP (x, 1), 238450397Sobrien ep->previous_offset)); 238518334Speter } 238618334Speter 238718334Speter /* If the register is not eliminable, we are done since the other 238818334Speter operand is a constant. */ 238918334Speter return x; 239018334Speter } 239118334Speter 239218334Speter /* If this is part of an address, we want to bring any constant to the 239318334Speter outermost PLUS. We will do this by doing register replacement in 239418334Speter our operands and seeing if a constant shows up in one of them. 239518334Speter 239690075Sobrien Note that there is no risk of modifying the structure of the insn, 239790075Sobrien since we only get called for its operands, thus we are either 239890075Sobrien modifying the address inside a MEM, or something like an address 239990075Sobrien operand of a load-address insn. */ 240018334Speter 240118334Speter { 240218334Speter rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn); 240318334Speter rtx new1 = eliminate_regs (XEXP (x, 1), mem_mode, insn); 240418334Speter 240590075Sobrien if (reg_renumber && (new0 != XEXP (x, 0) || new1 != XEXP (x, 1))) 240618334Speter { 240718334Speter /* If one side is a PLUS and the other side is a pseudo that 240818334Speter didn't get a hard register but has a reg_equiv_constant, 240918334Speter we must replace the constant here since it may no longer 241018334Speter be in the position of any operand. */ 241118334Speter if (GET_CODE (new0) == PLUS && GET_CODE (new1) == REG 241218334Speter && REGNO (new1) >= FIRST_PSEUDO_REGISTER 241318334Speter && reg_renumber[REGNO (new1)] < 0 241418334Speter && reg_equiv_constant != 0 241518334Speter && reg_equiv_constant[REGNO (new1)] != 0) 241618334Speter new1 = reg_equiv_constant[REGNO (new1)]; 241718334Speter else if (GET_CODE (new1) == PLUS && GET_CODE (new0) == REG 241818334Speter && REGNO (new0) >= FIRST_PSEUDO_REGISTER 241918334Speter && reg_renumber[REGNO (new0)] < 0 242018334Speter && reg_equiv_constant[REGNO (new0)] != 0) 242118334Speter new0 = reg_equiv_constant[REGNO (new0)]; 242218334Speter 242318334Speter new = form_sum (new0, new1); 242418334Speter 242518334Speter /* As above, if we are not inside a MEM we do not want to 242618334Speter turn a PLUS into something else. We might try to do so here 242718334Speter for an addition of 0 if we aren't optimizing. */ 242818334Speter if (! mem_mode && GET_CODE (new) != PLUS) 242950397Sobrien return gen_rtx_PLUS (GET_MODE (x), new, const0_rtx); 243018334Speter else 243118334Speter return new; 243218334Speter } 243318334Speter } 243418334Speter return x; 243518334Speter 243618334Speter case MULT: 243790075Sobrien /* If this is the product of an eliminable register and a 243818334Speter constant, apply the distribute law and move the constant out 243918334Speter so that we have (plus (mult ..) ..). This is needed in order 244018334Speter to keep load-address insns valid. This case is pathological. 244118334Speter We ignore the possibility of overflow here. */ 244218334Speter if (GET_CODE (XEXP (x, 0)) == REG 244318334Speter && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER 244418334Speter && GET_CODE (XEXP (x, 1)) == CONST_INT) 244518334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 244618334Speter ep++) 244718334Speter if (ep->from_rtx == XEXP (x, 0) && ep->can_eliminate) 244818334Speter { 244918334Speter if (! mem_mode 245018334Speter /* Refs inside notes don't count for this purpose. */ 245118334Speter && ! (insn != 0 && (GET_CODE (insn) == EXPR_LIST 245218334Speter || GET_CODE (insn) == INSN_LIST))) 245318334Speter ep->ref_outside_mem = 1; 245418334Speter 245518334Speter return 245650397Sobrien plus_constant (gen_rtx_MULT (Pmode, ep->to_rtx, XEXP (x, 1)), 245718334Speter ep->previous_offset * INTVAL (XEXP (x, 1))); 245818334Speter } 245918334Speter 246050397Sobrien /* ... fall through ... */ 246118334Speter 246218334Speter case CALL: 246318334Speter case COMPARE: 246490075Sobrien /* See comments before PLUS about handling MINUS. */ 246518334Speter case MINUS: 246618334Speter case DIV: case UDIV: 246718334Speter case MOD: case UMOD: 246818334Speter case AND: case IOR: case XOR: 246918334Speter case ROTATERT: case ROTATE: 247018334Speter case ASHIFTRT: case LSHIFTRT: case ASHIFT: 247118334Speter case NE: case EQ: 247218334Speter case GE: case GT: case GEU: case GTU: 247318334Speter case LE: case LT: case LEU: case LTU: 247418334Speter { 247518334Speter rtx new0 = eliminate_regs (XEXP (x, 0), mem_mode, insn); 247618334Speter rtx new1 247718334Speter = XEXP (x, 1) ? eliminate_regs (XEXP (x, 1), mem_mode, insn) : 0; 247818334Speter 247918334Speter if (new0 != XEXP (x, 0) || new1 != XEXP (x, 1)) 248050397Sobrien return gen_rtx_fmt_ee (code, GET_MODE (x), new0, new1); 248118334Speter } 248218334Speter return x; 248318334Speter 248418334Speter case EXPR_LIST: 248518334Speter /* If we have something in XEXP (x, 0), the usual case, eliminate it. */ 248618334Speter if (XEXP (x, 0)) 248718334Speter { 248818334Speter new = eliminate_regs (XEXP (x, 0), mem_mode, insn); 248918334Speter if (new != XEXP (x, 0)) 249052284Sobrien { 249152284Sobrien /* If this is a REG_DEAD note, it is not valid anymore. 249252284Sobrien Using the eliminated version could result in creating a 249352284Sobrien REG_DEAD note for the stack or frame pointer. */ 249452284Sobrien if (GET_MODE (x) == REG_DEAD) 249552284Sobrien return (XEXP (x, 1) 249652284Sobrien ? eliminate_regs (XEXP (x, 1), mem_mode, insn) 249752284Sobrien : NULL_RTX); 249852284Sobrien 249952284Sobrien x = gen_rtx_EXPR_LIST (REG_NOTE_KIND (x), new, XEXP (x, 1)); 250052284Sobrien } 250118334Speter } 250218334Speter 250350397Sobrien /* ... fall through ... */ 250418334Speter 250518334Speter case INSN_LIST: 250618334Speter /* Now do eliminations in the rest of the chain. If this was 250718334Speter an EXPR_LIST, this might result in allocating more memory than is 250818334Speter strictly needed, but it simplifies the code. */ 250918334Speter if (XEXP (x, 1)) 251018334Speter { 251118334Speter new = eliminate_regs (XEXP (x, 1), mem_mode, insn); 251218334Speter if (new != XEXP (x, 1)) 251390075Sobrien return 251490075Sobrien gen_rtx_fmt_ee (GET_CODE (x), GET_MODE (x), XEXP (x, 0), new); 251518334Speter } 251618334Speter return x; 251718334Speter 251818334Speter case PRE_INC: 251918334Speter case POST_INC: 252018334Speter case PRE_DEC: 252118334Speter case POST_DEC: 252218334Speter case STRICT_LOW_PART: 252318334Speter case NEG: case NOT: 252418334Speter case SIGN_EXTEND: case ZERO_EXTEND: 252518334Speter case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: 252618334Speter case FLOAT: case FIX: 252718334Speter case UNSIGNED_FIX: case UNSIGNED_FLOAT: 252818334Speter case ABS: 252918334Speter case SQRT: 253018334Speter case FFS: 253118334Speter new = eliminate_regs (XEXP (x, 0), mem_mode, insn); 253218334Speter if (new != XEXP (x, 0)) 253350397Sobrien return gen_rtx_fmt_e (code, GET_MODE (x), new); 253418334Speter return x; 253518334Speter 253618334Speter case SUBREG: 253790075Sobrien /* Similar to above processing, but preserve SUBREG_BYTE. 253818334Speter Convert (subreg (mem)) to (mem) if not paradoxical. 253918334Speter Also, if we have a non-paradoxical (subreg (pseudo)) and the 254018334Speter pseudo didn't get a hard reg, we must replace this with the 254118334Speter eliminated version of the memory location because push_reloads 254218334Speter may do the replacement in certain circumstances. */ 254318334Speter if (GET_CODE (SUBREG_REG (x)) == REG 254418334Speter && (GET_MODE_SIZE (GET_MODE (x)) 254518334Speter <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 254618334Speter && reg_equiv_memory_loc != 0 254718334Speter && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0) 254818334Speter { 254952284Sobrien new = SUBREG_REG (x); 255018334Speter } 255118334Speter else 255218334Speter new = eliminate_regs (SUBREG_REG (x), mem_mode, insn); 255318334Speter 255490075Sobrien if (new != SUBREG_REG (x)) 255518334Speter { 255650397Sobrien int x_size = GET_MODE_SIZE (GET_MODE (x)); 255750397Sobrien int new_size = GET_MODE_SIZE (GET_MODE (new)); 255850397Sobrien 255918334Speter if (GET_CODE (new) == MEM 256050397Sobrien && ((x_size < new_size 256150397Sobrien#ifdef WORD_REGISTER_OPERATIONS 256250397Sobrien /* On these machines, combine can create rtl of the form 256350397Sobrien (set (subreg:m1 (reg:m2 R) 0) ...) 256490075Sobrien where m1 < m2, and expects something interesting to 256550397Sobrien happen to the entire word. Moreover, it will use the 256650397Sobrien (reg:m2 R) later, expecting all bits to be preserved. 256790075Sobrien So if the number of words is the same, preserve the 256850397Sobrien subreg so that push_reloads can see it. */ 256990075Sobrien && ! ((x_size - 1) / UNITS_PER_WORD 257090075Sobrien == (new_size -1 ) / UNITS_PER_WORD) 257118334Speter#endif 257250397Sobrien ) 257390075Sobrien || x_size == new_size) 257418334Speter ) 257596263Sobrien return adjust_address_nv (new, GET_MODE (x), SUBREG_BYTE (x)); 257690075Sobrien else 257790075Sobrien return gen_rtx_SUBREG (GET_MODE (x), new, SUBREG_BYTE (x)); 257890075Sobrien } 257918334Speter 258090075Sobrien return x; 258118334Speter 258290075Sobrien case MEM: 258390075Sobrien /* This is only for the benefit of the debugging backends, which call 258490075Sobrien eliminate_regs on DECL_RTL; any ADDRESSOFs in the actual insns are 258590075Sobrien removed after CSE. */ 258690075Sobrien if (GET_CODE (XEXP (x, 0)) == ADDRESSOF) 258790075Sobrien return eliminate_regs (XEXP (XEXP (x, 0), 0), 0, insn); 258890075Sobrien 258990075Sobrien /* Our only special processing is to pass the mode of the MEM to our 259090075Sobrien recursive call and copy the flags. While we are here, handle this 259190075Sobrien case more efficiently. */ 259290075Sobrien return 259390075Sobrien replace_equiv_address_nv (x, 259490075Sobrien eliminate_regs (XEXP (x, 0), 259590075Sobrien GET_MODE (x), insn)); 259690075Sobrien 259790075Sobrien case USE: 259890075Sobrien /* Handle insn_list USE that a call to a pure function may generate. */ 259990075Sobrien new = eliminate_regs (XEXP (x, 0), 0, insn); 260090075Sobrien if (new != XEXP (x, 0)) 260190075Sobrien return gen_rtx_USE (GET_MODE (x), new); 260290075Sobrien return x; 260390075Sobrien 260490075Sobrien case CLOBBER: 260590075Sobrien case ASM_OPERANDS: 260690075Sobrien case SET: 260790075Sobrien abort (); 260890075Sobrien 260990075Sobrien default: 261090075Sobrien break; 261190075Sobrien } 261290075Sobrien 261390075Sobrien /* Process each of our operands recursively. If any have changed, make a 261490075Sobrien copy of the rtx. */ 261590075Sobrien fmt = GET_RTX_FORMAT (code); 261690075Sobrien for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 261790075Sobrien { 261890075Sobrien if (*fmt == 'e') 261990075Sobrien { 262090075Sobrien new = eliminate_regs (XEXP (x, i), mem_mode, insn); 262190075Sobrien if (new != XEXP (x, i) && ! copied) 262290075Sobrien { 262390075Sobrien rtx new_x = rtx_alloc (code); 262490075Sobrien memcpy (new_x, x, 262590075Sobrien (sizeof (*new_x) - sizeof (new_x->fld) 262690075Sobrien + sizeof (new_x->fld[0]) * GET_RTX_LENGTH (code))); 262790075Sobrien x = new_x; 262890075Sobrien copied = 1; 262918334Speter } 263090075Sobrien XEXP (x, i) = new; 263118334Speter } 263290075Sobrien else if (*fmt == 'E') 263390075Sobrien { 263490075Sobrien int copied_vec = 0; 263590075Sobrien for (j = 0; j < XVECLEN (x, i); j++) 263690075Sobrien { 263790075Sobrien new = eliminate_regs (XVECEXP (x, i, j), mem_mode, insn); 263890075Sobrien if (new != XVECEXP (x, i, j) && ! copied_vec) 263990075Sobrien { 264090075Sobrien rtvec new_v = gen_rtvec_v (XVECLEN (x, i), 264190075Sobrien XVEC (x, i)->elem); 264290075Sobrien if (! copied) 264390075Sobrien { 264490075Sobrien rtx new_x = rtx_alloc (code); 264590075Sobrien memcpy (new_x, x, 264690075Sobrien (sizeof (*new_x) - sizeof (new_x->fld) 264790075Sobrien + (sizeof (new_x->fld[0]) 264890075Sobrien * GET_RTX_LENGTH (code)))); 264990075Sobrien x = new_x; 265090075Sobrien copied = 1; 265190075Sobrien } 265290075Sobrien XVEC (x, i) = new_v; 265390075Sobrien copied_vec = 1; 265490075Sobrien } 265590075Sobrien XVECEXP (x, i, j) = new; 265690075Sobrien } 265790075Sobrien } 265890075Sobrien } 265918334Speter 266090075Sobrien return x; 266190075Sobrien} 266218334Speter 266390075Sobrien/* Scan rtx X for modifications of elimination target registers. Update 266490075Sobrien the table of eliminables to reflect the changed state. MEM_MODE is 266590075Sobrien the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM. */ 266690075Sobrien 266790075Sobrienstatic void 266890075Sobrienelimination_effects (x, mem_mode) 266990075Sobrien rtx x; 267090075Sobrien enum machine_mode mem_mode; 267190075Sobrien 267290075Sobrien{ 267390075Sobrien enum rtx_code code = GET_CODE (x); 267490075Sobrien struct elim_table *ep; 267590075Sobrien int regno; 267690075Sobrien int i, j; 267790075Sobrien const char *fmt; 267890075Sobrien 267990075Sobrien switch (code) 268090075Sobrien { 268190075Sobrien case CONST_INT: 268290075Sobrien case CONST_DOUBLE: 268396263Sobrien case CONST_VECTOR: 268490075Sobrien case CONST: 268590075Sobrien case SYMBOL_REF: 268690075Sobrien case CODE_LABEL: 268790075Sobrien case PC: 268890075Sobrien case CC0: 268990075Sobrien case ASM_INPUT: 269090075Sobrien case ADDR_VEC: 269190075Sobrien case ADDR_DIFF_VEC: 269290075Sobrien case RETURN: 269390075Sobrien return; 269490075Sobrien 269590075Sobrien case ADDRESSOF: 269690075Sobrien abort (); 269790075Sobrien 269890075Sobrien case REG: 269990075Sobrien regno = REGNO (x); 270090075Sobrien 270190075Sobrien /* First handle the case where we encounter a bare register that 270290075Sobrien is eliminable. Replace it with a PLUS. */ 270390075Sobrien if (regno < FIRST_PSEUDO_REGISTER) 270490075Sobrien { 270590075Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 270690075Sobrien ep++) 270790075Sobrien if (ep->from_rtx == x && ep->can_eliminate) 270890075Sobrien { 270990075Sobrien if (! mem_mode) 271090075Sobrien ep->ref_outside_mem = 1; 271190075Sobrien return; 271290075Sobrien } 271390075Sobrien 271490075Sobrien } 271590075Sobrien else if (reg_renumber[regno] < 0 && reg_equiv_constant 271690075Sobrien && reg_equiv_constant[regno] 271790075Sobrien && ! function_invariant_p (reg_equiv_constant[regno])) 271890075Sobrien elimination_effects (reg_equiv_constant[regno], mem_mode); 271990075Sobrien return; 272090075Sobrien 272190075Sobrien case PRE_INC: 272290075Sobrien case POST_INC: 272390075Sobrien case PRE_DEC: 272490075Sobrien case POST_DEC: 272590075Sobrien case POST_MODIFY: 272690075Sobrien case PRE_MODIFY: 272790075Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 272890075Sobrien if (ep->to_rtx == XEXP (x, 0)) 272990075Sobrien { 273090075Sobrien int size = GET_MODE_SIZE (mem_mode); 273190075Sobrien 273290075Sobrien /* If more bytes than MEM_MODE are pushed, account for them. */ 273390075Sobrien#ifdef PUSH_ROUNDING 273490075Sobrien if (ep->to_rtx == stack_pointer_rtx) 273590075Sobrien size = PUSH_ROUNDING (size); 273690075Sobrien#endif 273790075Sobrien if (code == PRE_DEC || code == POST_DEC) 273890075Sobrien ep->offset += size; 273990075Sobrien else if (code == PRE_INC || code == POST_INC) 274090075Sobrien ep->offset -= size; 274190075Sobrien else if ((code == PRE_MODIFY || code == POST_MODIFY) 274290075Sobrien && GET_CODE (XEXP (x, 1)) == PLUS 274390075Sobrien && XEXP (x, 0) == XEXP (XEXP (x, 1), 0) 274490075Sobrien && CONSTANT_P (XEXP (XEXP (x, 1), 1))) 274590075Sobrien ep->offset -= INTVAL (XEXP (XEXP (x, 1), 1)); 274690075Sobrien } 274790075Sobrien 274890075Sobrien /* These two aren't unary operators. */ 274990075Sobrien if (code == POST_MODIFY || code == PRE_MODIFY) 275090075Sobrien break; 275190075Sobrien 275290075Sobrien /* Fall through to generic unary operation case. */ 275390075Sobrien case STRICT_LOW_PART: 275490075Sobrien case NEG: case NOT: 275590075Sobrien case SIGN_EXTEND: case ZERO_EXTEND: 275690075Sobrien case TRUNCATE: case FLOAT_EXTEND: case FLOAT_TRUNCATE: 275790075Sobrien case FLOAT: case FIX: 275890075Sobrien case UNSIGNED_FIX: case UNSIGNED_FLOAT: 275990075Sobrien case ABS: 276090075Sobrien case SQRT: 276190075Sobrien case FFS: 276290075Sobrien elimination_effects (XEXP (x, 0), mem_mode); 276390075Sobrien return; 276490075Sobrien 276590075Sobrien case SUBREG: 276690075Sobrien if (GET_CODE (SUBREG_REG (x)) == REG 276790075Sobrien && (GET_MODE_SIZE (GET_MODE (x)) 276890075Sobrien <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 276990075Sobrien && reg_equiv_memory_loc != 0 277090075Sobrien && reg_equiv_memory_loc[REGNO (SUBREG_REG (x))] != 0) 277190075Sobrien return; 277290075Sobrien 277390075Sobrien elimination_effects (SUBREG_REG (x), mem_mode); 277490075Sobrien return; 277590075Sobrien 277650397Sobrien case USE: 277750397Sobrien /* If using a register that is the source of an eliminate we still 277850397Sobrien think can be performed, note it cannot be performed since we don't 277950397Sobrien know how this register is used. */ 278050397Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 278150397Sobrien if (ep->from_rtx == XEXP (x, 0)) 278250397Sobrien ep->can_eliminate = 0; 278350397Sobrien 278490075Sobrien elimination_effects (XEXP (x, 0), mem_mode); 278590075Sobrien return; 278650397Sobrien 278718334Speter case CLOBBER: 278818334Speter /* If clobbering a register that is the replacement register for an 278918334Speter elimination we still think can be performed, note that it cannot 279018334Speter be performed. Otherwise, we need not be concerned about it. */ 279118334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 279218334Speter if (ep->to_rtx == XEXP (x, 0)) 279318334Speter ep->can_eliminate = 0; 279418334Speter 279590075Sobrien elimination_effects (XEXP (x, 0), mem_mode); 279690075Sobrien return; 279718334Speter 279818334Speter case SET: 279918334Speter /* Check for setting a register that we know about. */ 280018334Speter if (GET_CODE (SET_DEST (x)) == REG) 280118334Speter { 280218334Speter /* See if this is setting the replacement register for an 280318334Speter elimination. 280418334Speter 280518334Speter If DEST is the hard frame pointer, we do nothing because we 280618334Speter assume that all assignments to the frame pointer are for 280718334Speter non-local gotos and are being done at a time when they are valid 280818334Speter and do not disturb anything else. Some machines want to 280918334Speter eliminate a fake argument pointer (or even a fake frame pointer) 281018334Speter with either the real frame or the stack pointer. Assignments to 281118334Speter the hard frame pointer must not prevent this elimination. */ 281218334Speter 281318334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 281418334Speter ep++) 281518334Speter if (ep->to_rtx == SET_DEST (x) 281618334Speter && SET_DEST (x) != hard_frame_pointer_rtx) 281718334Speter { 281818334Speter /* If it is being incremented, adjust the offset. Otherwise, 281918334Speter this elimination can't be done. */ 282018334Speter rtx src = SET_SRC (x); 282118334Speter 282218334Speter if (GET_CODE (src) == PLUS 282318334Speter && XEXP (src, 0) == SET_DEST (x) 282418334Speter && GET_CODE (XEXP (src, 1)) == CONST_INT) 282518334Speter ep->offset -= INTVAL (XEXP (src, 1)); 282618334Speter else 282718334Speter ep->can_eliminate = 0; 282818334Speter } 282918334Speter } 283018334Speter 283190075Sobrien elimination_effects (SET_DEST (x), 0); 283290075Sobrien elimination_effects (SET_SRC (x), 0); 283390075Sobrien return; 283418334Speter 283518334Speter case MEM: 283650397Sobrien if (GET_CODE (XEXP (x, 0)) == ADDRESSOF) 283790075Sobrien abort (); 283850397Sobrien 283918334Speter /* Our only special processing is to pass the mode of the MEM to our 284090075Sobrien recursive call. */ 284190075Sobrien elimination_effects (XEXP (x, 0), GET_MODE (x)); 284290075Sobrien return; 284390075Sobrien 284450397Sobrien default: 284550397Sobrien break; 284618334Speter } 284718334Speter 284818334Speter fmt = GET_RTX_FORMAT (code); 284918334Speter for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 285018334Speter { 285118334Speter if (*fmt == 'e') 285290075Sobrien elimination_effects (XEXP (x, i), mem_mode); 285318334Speter else if (*fmt == 'E') 285490075Sobrien for (j = 0; j < XVECLEN (x, i); j++) 285590075Sobrien elimination_effects (XVECEXP (x, i, j), mem_mode); 285690075Sobrien } 285790075Sobrien} 285890075Sobrien 285990075Sobrien/* Descend through rtx X and verify that no references to eliminable registers 286090075Sobrien remain. If any do remain, mark the involved register as not 286190075Sobrien eliminable. */ 286290075Sobrien 286390075Sobrienstatic void 286490075Sobriencheck_eliminable_occurrences (x) 286590075Sobrien rtx x; 286690075Sobrien{ 286790075Sobrien const char *fmt; 286890075Sobrien int i; 286990075Sobrien enum rtx_code code; 287090075Sobrien 287190075Sobrien if (x == 0) 287290075Sobrien return; 287390075Sobrien 287490075Sobrien code = GET_CODE (x); 287590075Sobrien 287690075Sobrien if (code == REG && REGNO (x) < FIRST_PSEUDO_REGISTER) 287790075Sobrien { 287890075Sobrien struct elim_table *ep; 287990075Sobrien 288090075Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 288190075Sobrien if (ep->from_rtx == x && ep->can_eliminate) 288290075Sobrien ep->can_eliminate = 0; 288390075Sobrien return; 288490075Sobrien } 288590075Sobrien 288690075Sobrien fmt = GET_RTX_FORMAT (code); 288790075Sobrien for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) 288890075Sobrien { 288990075Sobrien if (*fmt == 'e') 289090075Sobrien check_eliminable_occurrences (XEXP (x, i)); 289190075Sobrien else if (*fmt == 'E') 289218334Speter { 289390075Sobrien int j; 289418334Speter for (j = 0; j < XVECLEN (x, i); j++) 289590075Sobrien check_eliminable_occurrences (XVECEXP (x, i, j)); 289618334Speter } 289718334Speter } 289818334Speter} 289918334Speter 290018334Speter/* Scan INSN and eliminate all eliminable registers in it. 290118334Speter 290218334Speter If REPLACE is nonzero, do the replacement destructively. Also 290318334Speter delete the insn as dead it if it is setting an eliminable register. 290418334Speter 290518334Speter If REPLACE is zero, do all our allocations in reload_obstack. 290618334Speter 290718334Speter If no eliminations were done and this insn doesn't require any elimination 290818334Speter processing (these are not identical conditions: it might be updating sp, 290918334Speter but not referencing fp; this needs to be seen during reload_as_needed so 291018334Speter that the offset between fp and sp can be taken into consideration), zero 291118334Speter is returned. Otherwise, 1 is returned. */ 291218334Speter 291318334Speterstatic int 291418334Spetereliminate_regs_in_insn (insn, replace) 291518334Speter rtx insn; 291618334Speter int replace; 291718334Speter{ 291890075Sobrien int icode = recog_memoized (insn); 291918334Speter rtx old_body = PATTERN (insn); 292090075Sobrien int insn_is_asm = asm_noperands (old_body) >= 0; 292118334Speter rtx old_set = single_set (insn); 292218334Speter rtx new_body; 292318334Speter int val = 0; 292490075Sobrien int i, any_changes; 292590075Sobrien rtx substed_operand[MAX_RECOG_OPERANDS]; 292690075Sobrien rtx orig_operand[MAX_RECOG_OPERANDS]; 292718334Speter struct elim_table *ep; 292818334Speter 292990075Sobrien if (! insn_is_asm && icode < 0) 293090075Sobrien { 293190075Sobrien if (GET_CODE (PATTERN (insn)) == USE 293290075Sobrien || GET_CODE (PATTERN (insn)) == CLOBBER 293390075Sobrien || GET_CODE (PATTERN (insn)) == ADDR_VEC 293490075Sobrien || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC 293590075Sobrien || GET_CODE (PATTERN (insn)) == ASM_INPUT) 293690075Sobrien return 0; 293790075Sobrien abort (); 293890075Sobrien } 293918334Speter 294018334Speter if (old_set != 0 && GET_CODE (SET_DEST (old_set)) == REG 294118334Speter && REGNO (SET_DEST (old_set)) < FIRST_PSEUDO_REGISTER) 294218334Speter { 294318334Speter /* Check for setting an eliminable register. */ 294418334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 294518334Speter if (ep->from_rtx == SET_DEST (old_set) && ep->can_eliminate) 294618334Speter { 294718334Speter#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 294818334Speter /* If this is setting the frame pointer register to the 294918334Speter hardware frame pointer register and this is an elimination 295018334Speter that will be done (tested above), this insn is really 295118334Speter adjusting the frame pointer downward to compensate for 295218334Speter the adjustment done before a nonlocal goto. */ 295318334Speter if (ep->from == FRAME_POINTER_REGNUM 295418334Speter && ep->to == HARD_FRAME_POINTER_REGNUM) 295518334Speter { 295690075Sobrien rtx base = SET_SRC (old_set); 295790075Sobrien rtx base_insn = insn; 295890075Sobrien int offset = 0; 295918334Speter 296090075Sobrien while (base != ep->to_rtx) 296150397Sobrien { 296290075Sobrien rtx prev_insn, prev_set; 296390075Sobrien 296490075Sobrien if (GET_CODE (base) == PLUS 296590075Sobrien && GET_CODE (XEXP (base, 1)) == CONST_INT) 296690075Sobrien { 296790075Sobrien offset += INTVAL (XEXP (base, 1)); 296890075Sobrien base = XEXP (base, 0); 296990075Sobrien } 297090075Sobrien else if ((prev_insn = prev_nonnote_insn (base_insn)) != 0 297190075Sobrien && (prev_set = single_set (prev_insn)) != 0 297290075Sobrien && rtx_equal_p (SET_DEST (prev_set), base)) 297390075Sobrien { 297490075Sobrien base = SET_SRC (prev_set); 297590075Sobrien base_insn = prev_insn; 297690075Sobrien } 297790075Sobrien else 297890075Sobrien break; 297950397Sobrien } 298018334Speter 298190075Sobrien if (base == ep->to_rtx) 298218334Speter { 298390075Sobrien rtx src 298490075Sobrien = plus_constant (ep->to_rtx, offset - ep->offset); 298590075Sobrien 298690075Sobrien new_body = old_body; 298790075Sobrien if (! replace) 298818334Speter { 298990075Sobrien new_body = copy_insn (old_body); 299090075Sobrien if (REG_NOTES (insn)) 299190075Sobrien REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn)); 299290075Sobrien } 299390075Sobrien PATTERN (insn) = new_body; 299490075Sobrien old_set = single_set (insn); 299518334Speter 299690075Sobrien /* First see if this insn remains valid when we 299790075Sobrien make the change. If not, keep the INSN_CODE 299890075Sobrien the same and let reload fit it up. */ 299990075Sobrien validate_change (insn, &SET_SRC (old_set), src, 1); 300090075Sobrien validate_change (insn, &SET_DEST (old_set), 300190075Sobrien ep->to_rtx, 1); 300290075Sobrien if (! apply_change_group ()) 300390075Sobrien { 300490075Sobrien SET_SRC (old_set) = src; 300590075Sobrien SET_DEST (old_set) = ep->to_rtx; 300618334Speter } 300718334Speter 300818334Speter val = 1; 300918334Speter goto done; 301018334Speter } 301118334Speter } 301218334Speter#endif 301318334Speter 301418334Speter /* In this case this insn isn't serving a useful purpose. We 301518334Speter will delete it in reload_as_needed once we know that this 301618334Speter elimination is, in fact, being done. 301718334Speter 301818334Speter If REPLACE isn't set, we can't delete this insn, but needn't 301918334Speter process it since it won't be used unless something changes. */ 302018334Speter if (replace) 302190075Sobrien { 302290075Sobrien delete_dead_insn (insn); 302390075Sobrien return 1; 302490075Sobrien } 302518334Speter val = 1; 302618334Speter goto done; 302718334Speter } 302890075Sobrien } 302918334Speter 303090075Sobrien /* We allow one special case which happens to work on all machines we 303190075Sobrien currently support: a single set with the source being a PLUS of an 303290075Sobrien eliminable register and a constant. */ 303390075Sobrien if (old_set 303490075Sobrien && GET_CODE (SET_DEST (old_set)) == REG 303590075Sobrien && GET_CODE (SET_SRC (old_set)) == PLUS 303690075Sobrien && GET_CODE (XEXP (SET_SRC (old_set), 0)) == REG 303790075Sobrien && GET_CODE (XEXP (SET_SRC (old_set), 1)) == CONST_INT 303890075Sobrien && REGNO (XEXP (SET_SRC (old_set), 0)) < FIRST_PSEUDO_REGISTER) 303990075Sobrien { 304090075Sobrien rtx reg = XEXP (SET_SRC (old_set), 0); 304190075Sobrien int offset = INTVAL (XEXP (SET_SRC (old_set), 1)); 304218334Speter 304390075Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 304490075Sobrien if (ep->from_rtx == reg && ep->can_eliminate) 304590075Sobrien { 304690075Sobrien offset += ep->offset; 304718334Speter 304890075Sobrien if (offset == 0) 304990075Sobrien { 305090075Sobrien int num_clobbers; 305190075Sobrien /* We assume here that if we need a PARALLEL with 305290075Sobrien CLOBBERs for this assignment, we can do with the 305390075Sobrien MATCH_SCRATCHes that add_clobbers allocates. 305490075Sobrien There's not much we can do if that doesn't work. */ 305590075Sobrien PATTERN (insn) = gen_rtx_SET (VOIDmode, 305690075Sobrien SET_DEST (old_set), 305790075Sobrien ep->to_rtx); 305890075Sobrien num_clobbers = 0; 305990075Sobrien INSN_CODE (insn) = recog (PATTERN (insn), insn, &num_clobbers); 306090075Sobrien if (num_clobbers) 306190075Sobrien { 306290075Sobrien rtvec vec = rtvec_alloc (num_clobbers + 1); 306390075Sobrien 306490075Sobrien vec->elem[0] = PATTERN (insn); 306590075Sobrien PATTERN (insn) = gen_rtx_PARALLEL (VOIDmode, vec); 306690075Sobrien add_clobbers (PATTERN (insn), INSN_CODE (insn)); 306790075Sobrien } 306890075Sobrien if (INSN_CODE (insn) < 0) 306990075Sobrien abort (); 307090075Sobrien } 307190075Sobrien else 307290075Sobrien { 307390075Sobrien new_body = old_body; 307490075Sobrien if (! replace) 307590075Sobrien { 307690075Sobrien new_body = copy_insn (old_body); 307790075Sobrien if (REG_NOTES (insn)) 307890075Sobrien REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn)); 307990075Sobrien } 308090075Sobrien PATTERN (insn) = new_body; 308190075Sobrien old_set = single_set (insn); 308290075Sobrien 308390075Sobrien XEXP (SET_SRC (old_set), 0) = ep->to_rtx; 308490075Sobrien XEXP (SET_SRC (old_set), 1) = GEN_INT (offset); 308590075Sobrien } 308690075Sobrien val = 1; 308790075Sobrien /* This can't have an effect on elimination offsets, so skip right 308890075Sobrien to the end. */ 308990075Sobrien goto done; 309090075Sobrien } 309190075Sobrien } 309290075Sobrien 309390075Sobrien /* Determine the effects of this insn on elimination offsets. */ 309490075Sobrien elimination_effects (old_body, 0); 309590075Sobrien 309690075Sobrien /* Eliminate all eliminable registers occurring in operands that 309790075Sobrien can be handled by reload. */ 309890075Sobrien extract_insn (insn); 309990075Sobrien any_changes = 0; 310090075Sobrien for (i = 0; i < recog_data.n_operands; i++) 310190075Sobrien { 310290075Sobrien orig_operand[i] = recog_data.operand[i]; 310390075Sobrien substed_operand[i] = recog_data.operand[i]; 310490075Sobrien 310590075Sobrien /* For an asm statement, every operand is eliminable. */ 310690075Sobrien if (insn_is_asm || insn_data[icode].operand[i].eliminable) 310790075Sobrien { 310890075Sobrien /* Check for setting a register that we know about. */ 310990075Sobrien if (recog_data.operand_type[i] != OP_IN 311090075Sobrien && GET_CODE (orig_operand[i]) == REG) 311118334Speter { 311290075Sobrien /* If we are assigning to a register that can be eliminated, it 311390075Sobrien must be as part of a PARALLEL, since the code above handles 311490075Sobrien single SETs. We must indicate that we can no longer 311590075Sobrien eliminate this reg. */ 311690075Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; 311790075Sobrien ep++) 311890075Sobrien if (ep->from_rtx == orig_operand[i] && ep->can_eliminate) 311990075Sobrien ep->can_eliminate = 0; 312090075Sobrien } 312118334Speter 312290075Sobrien substed_operand[i] = eliminate_regs (recog_data.operand[i], 0, 312390075Sobrien replace ? insn : NULL_RTX); 312490075Sobrien if (substed_operand[i] != orig_operand[i]) 312590075Sobrien val = any_changes = 1; 312690075Sobrien /* Terminate the search in check_eliminable_occurrences at 312790075Sobrien this point. */ 312890075Sobrien *recog_data.operand_loc[i] = 0; 312990075Sobrien 313090075Sobrien /* If an output operand changed from a REG to a MEM and INSN is an 313190075Sobrien insn, write a CLOBBER insn. */ 313290075Sobrien if (recog_data.operand_type[i] != OP_IN 313390075Sobrien && GET_CODE (orig_operand[i]) == REG 313490075Sobrien && GET_CODE (substed_operand[i]) == MEM 313590075Sobrien && replace) 313690075Sobrien emit_insn_after (gen_rtx_CLOBBER (VOIDmode, orig_operand[i]), 313790075Sobrien insn); 313890075Sobrien } 313918334Speter } 314018334Speter 314190075Sobrien for (i = 0; i < recog_data.n_dups; i++) 314290075Sobrien *recog_data.dup_loc[i] 314390075Sobrien = *recog_data.operand_loc[(int) recog_data.dup_num[i]]; 314418334Speter 314590075Sobrien /* If any eliminable remain, they aren't eliminable anymore. */ 314690075Sobrien check_eliminable_occurrences (old_body); 314718334Speter 314890075Sobrien /* Substitute the operands; the new values are in the substed_operand 314990075Sobrien array. */ 315090075Sobrien for (i = 0; i < recog_data.n_operands; i++) 315190075Sobrien *recog_data.operand_loc[i] = substed_operand[i]; 315290075Sobrien for (i = 0; i < recog_data.n_dups; i++) 315390075Sobrien *recog_data.dup_loc[i] = substed_operand[(int) recog_data.dup_num[i]]; 315490075Sobrien 315590075Sobrien /* If we are replacing a body that was a (set X (plus Y Z)), try to 315618334Speter re-recognize the insn. We do this in case we had a simple addition 315718334Speter but now can do this as a load-address. This saves an insn in this 315890075Sobrien common case. 315990075Sobrien If re-recognition fails, the old insn code number will still be used, 316090075Sobrien and some register operands may have changed into PLUS expressions. 316190075Sobrien These will be handled by find_reloads by loading them into a register 316290075Sobrien again. */ 316318334Speter 316490075Sobrien if (val) 316518334Speter { 316618334Speter /* If we aren't replacing things permanently and we changed something, 316718334Speter make another copy to ensure that all the RTL is new. Otherwise 316818334Speter things can go wrong if find_reload swaps commutative operands 316950397Sobrien and one is inside RTL that has been copied while the other is not. */ 317090075Sobrien new_body = old_body; 317190075Sobrien if (! replace) 317290075Sobrien { 317390075Sobrien new_body = copy_insn (old_body); 317490075Sobrien if (REG_NOTES (insn)) 317590075Sobrien REG_NOTES (insn) = copy_insn_1 (REG_NOTES (insn)); 317690075Sobrien } 317790075Sobrien PATTERN (insn) = new_body; 317818334Speter 317918334Speter /* If we had a move insn but now we don't, rerecognize it. This will 318018334Speter cause spurious re-recognition if the old move had a PARALLEL since 318118334Speter the new one still will, but we can't call single_set without 318218334Speter having put NEW_BODY into the insn and the re-recognition won't 318318334Speter hurt in this rare case. */ 318490075Sobrien /* ??? Why this huge if statement - why don't we just rerecognize the 318590075Sobrien thing always? */ 318690075Sobrien if (! insn_is_asm 318790075Sobrien && old_set != 0 318818334Speter && ((GET_CODE (SET_SRC (old_set)) == REG 318918334Speter && (GET_CODE (new_body) != SET 319018334Speter || GET_CODE (SET_SRC (new_body)) != REG)) 319118334Speter /* If this was a load from or store to memory, compare 319290075Sobrien the MEM in recog_data.operand to the one in the insn. 319390075Sobrien If they are not equal, then rerecognize the insn. */ 319418334Speter || (old_set != 0 319518334Speter && ((GET_CODE (SET_SRC (old_set)) == MEM 319690075Sobrien && SET_SRC (old_set) != recog_data.operand[1]) 319718334Speter || (GET_CODE (SET_DEST (old_set)) == MEM 319890075Sobrien && SET_DEST (old_set) != recog_data.operand[0]))) 319918334Speter /* If this was an add insn before, rerecognize. */ 320018334Speter || GET_CODE (SET_SRC (old_set)) == PLUS)) 320118334Speter { 320290075Sobrien int new_icode = recog (PATTERN (insn), insn, 0); 320390075Sobrien if (new_icode < 0) 320490075Sobrien INSN_CODE (insn) = icode; 320518334Speter } 320690075Sobrien } 320718334Speter 320890075Sobrien /* Restore the old body. If there were any changes to it, we made a copy 320990075Sobrien of it while the changes were still in place, so we'll correctly return 321090075Sobrien a modified insn below. */ 321190075Sobrien if (! replace) 321290075Sobrien { 321390075Sobrien /* Restore the old body. */ 321490075Sobrien for (i = 0; i < recog_data.n_operands; i++) 321590075Sobrien *recog_data.operand_loc[i] = orig_operand[i]; 321690075Sobrien for (i = 0; i < recog_data.n_dups; i++) 321790075Sobrien *recog_data.dup_loc[i] = orig_operand[(int) recog_data.dup_num[i]]; 321818334Speter } 321918334Speter 322090075Sobrien /* Update all elimination pairs to reflect the status after the current 322190075Sobrien insn. The changes we make were determined by the earlier call to 322290075Sobrien elimination_effects. 322318334Speter 322418334Speter We also detect a cases where register elimination cannot be done, 322518334Speter namely, if a register would be both changed and referenced outside a MEM 322618334Speter in the resulting insn since such an insn is often undefined and, even if 322718334Speter not, we cannot know what meaning will be given to it. Note that it is 322818334Speter valid to have a register used in an address in an insn that changes it 322918334Speter (presumably with a pre- or post-increment or decrement). 323018334Speter 323118334Speter If anything changes, return nonzero. */ 323218334Speter 323318334Speter for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 323418334Speter { 323518334Speter if (ep->previous_offset != ep->offset && ep->ref_outside_mem) 323618334Speter ep->can_eliminate = 0; 323718334Speter 323818334Speter ep->ref_outside_mem = 0; 323918334Speter 324018334Speter if (ep->previous_offset != ep->offset) 324118334Speter val = 1; 324218334Speter } 324318334Speter 324418334Speter done: 324518334Speter /* If we changed something, perform elimination in REG_NOTES. This is 324618334Speter needed even when REPLACE is zero because a REG_DEAD note might refer 324718334Speter to a register that we eliminate and could cause a different number 324818334Speter of spill registers to be needed in the final reload pass than in 324918334Speter the pre-passes. */ 325018334Speter if (val && REG_NOTES (insn) != 0) 325118334Speter REG_NOTES (insn) = eliminate_regs (REG_NOTES (insn), 0, REG_NOTES (insn)); 325218334Speter 325318334Speter return val; 325418334Speter} 325518334Speter 325652284Sobrien/* Loop through all elimination pairs. 325752284Sobrien Recalculate the number not at initial offset. 325852284Sobrien 325952284Sobrien Compute the maximum offset (minimum offset if the stack does not 326052284Sobrien grow downward) for each elimination pair. */ 326152284Sobrien 326252284Sobrienstatic void 326352284Sobrienupdate_eliminable_offsets () 326452284Sobrien{ 326552284Sobrien struct elim_table *ep; 326652284Sobrien 326752284Sobrien num_not_at_initial_offset = 0; 326852284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 326952284Sobrien { 327052284Sobrien ep->previous_offset = ep->offset; 327152284Sobrien if (ep->can_eliminate && ep->offset != ep->initial_offset) 327252284Sobrien num_not_at_initial_offset++; 327352284Sobrien } 327452284Sobrien} 327552284Sobrien 327618334Speter/* Given X, a SET or CLOBBER of DEST, if DEST is the target of a register 327718334Speter replacement we currently believe is valid, mark it as not eliminable if X 327818334Speter modifies DEST in any way other than by adding a constant integer to it. 327918334Speter 328018334Speter If DEST is the frame pointer, we do nothing because we assume that 328118334Speter all assignments to the hard frame pointer are nonlocal gotos and are being 328218334Speter done at a time when they are valid and do not disturb anything else. 328318334Speter Some machines want to eliminate a fake argument pointer with either the 328418334Speter frame or stack pointer. Assignments to the hard frame pointer must not 328518334Speter prevent this elimination. 328618334Speter 328718334Speter Called via note_stores from reload before starting its passes to scan 328818334Speter the insns of the function. */ 328918334Speter 329018334Speterstatic void 329190075Sobrienmark_not_eliminable (dest, x, data) 329218334Speter rtx dest; 329318334Speter rtx x; 329490075Sobrien void *data ATTRIBUTE_UNUSED; 329518334Speter{ 329690075Sobrien unsigned int i; 329718334Speter 329818334Speter /* A SUBREG of a hard register here is just changing its mode. We should 329918334Speter not see a SUBREG of an eliminable hard register, but check just in 330018334Speter case. */ 330118334Speter if (GET_CODE (dest) == SUBREG) 330218334Speter dest = SUBREG_REG (dest); 330318334Speter 330418334Speter if (dest == hard_frame_pointer_rtx) 330518334Speter return; 330618334Speter 330718334Speter for (i = 0; i < NUM_ELIMINABLE_REGS; i++) 330818334Speter if (reg_eliminate[i].can_eliminate && dest == reg_eliminate[i].to_rtx 330918334Speter && (GET_CODE (x) != SET 331018334Speter || GET_CODE (SET_SRC (x)) != PLUS 331118334Speter || XEXP (SET_SRC (x), 0) != dest 331218334Speter || GET_CODE (XEXP (SET_SRC (x), 1)) != CONST_INT)) 331318334Speter { 331418334Speter reg_eliminate[i].can_eliminate_previous 331518334Speter = reg_eliminate[i].can_eliminate = 0; 331618334Speter num_eliminable--; 331718334Speter } 331818334Speter} 331952284Sobrien 332052284Sobrien/* Verify that the initial elimination offsets did not change since the 332152284Sobrien last call to set_initial_elim_offsets. This is used to catch cases 332252284Sobrien where something illegal happened during reload_as_needed that could 332352284Sobrien cause incorrect code to be generated if we did not check for it. */ 332490075Sobrien 332552284Sobrienstatic void 332652284Sobrienverify_initial_elim_offsets () 332752284Sobrien{ 332852284Sobrien int t; 332952284Sobrien 333052284Sobrien#ifdef ELIMINABLE_REGS 333152284Sobrien struct elim_table *ep; 333252284Sobrien 333352284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 333452284Sobrien { 333552284Sobrien INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, t); 333652284Sobrien if (t != ep->initial_offset) 333752284Sobrien abort (); 333852284Sobrien } 333952284Sobrien#else 334052284Sobrien INITIAL_FRAME_POINTER_OFFSET (t); 334152284Sobrien if (t != reg_eliminate[0].initial_offset) 334252284Sobrien abort (); 334390075Sobrien#endif 334452284Sobrien} 334552284Sobrien 334652284Sobrien/* Reset all offsets on eliminable registers to their initial values. */ 334790075Sobrien 334852284Sobrienstatic void 334952284Sobrienset_initial_elim_offsets () 335052284Sobrien{ 335152284Sobrien struct elim_table *ep = reg_eliminate; 335252284Sobrien 335352284Sobrien#ifdef ELIMINABLE_REGS 335452284Sobrien for (; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 335552284Sobrien { 335652284Sobrien INITIAL_ELIMINATION_OFFSET (ep->from, ep->to, ep->initial_offset); 335752284Sobrien ep->previous_offset = ep->offset = ep->initial_offset; 335852284Sobrien } 335952284Sobrien#else 336052284Sobrien INITIAL_FRAME_POINTER_OFFSET (ep->initial_offset); 336152284Sobrien ep->previous_offset = ep->offset = ep->initial_offset; 336252284Sobrien#endif 336352284Sobrien 336452284Sobrien num_not_at_initial_offset = 0; 336552284Sobrien} 336652284Sobrien 336752284Sobrien/* Initialize the known label offsets. 336852284Sobrien Set a known offset for each forced label to be at the initial offset 336952284Sobrien of each elimination. We do this because we assume that all 337052284Sobrien computed jumps occur from a location where each elimination is 337152284Sobrien at its initial offset. 337252284Sobrien For all other labels, show that we don't know the offsets. */ 337352284Sobrien 337452284Sobrienstatic void 337552284Sobrienset_initial_label_offsets () 337652284Sobrien{ 337752284Sobrien rtx x; 337890075Sobrien memset ((char *) &offsets_known_at[get_first_label_num ()], 0, num_labels); 337952284Sobrien 338052284Sobrien for (x = forced_labels; x; x = XEXP (x, 1)) 338152284Sobrien if (XEXP (x, 0)) 338252284Sobrien set_label_offsets (XEXP (x, 0), NULL_RTX, 1); 338352284Sobrien} 338452284Sobrien 338552284Sobrien/* Set all elimination offsets to the known values for the code label given 338652284Sobrien by INSN. */ 338790075Sobrien 338852284Sobrienstatic void 338952284Sobrienset_offsets_for_label (insn) 339052284Sobrien rtx insn; 339152284Sobrien{ 339252284Sobrien unsigned int i; 339352284Sobrien int label_nr = CODE_LABEL_NUMBER (insn); 339452284Sobrien struct elim_table *ep; 339552284Sobrien 339652284Sobrien num_not_at_initial_offset = 0; 339752284Sobrien for (i = 0, ep = reg_eliminate; i < NUM_ELIMINABLE_REGS; ep++, i++) 339852284Sobrien { 339952284Sobrien ep->offset = ep->previous_offset = offsets_at[label_nr][i]; 340052284Sobrien if (ep->can_eliminate && ep->offset != ep->initial_offset) 340152284Sobrien num_not_at_initial_offset++; 340252284Sobrien } 340352284Sobrien} 340452284Sobrien 340552284Sobrien/* See if anything that happened changes which eliminations are valid. 340652284Sobrien For example, on the Sparc, whether or not the frame pointer can 340752284Sobrien be eliminated can depend on what registers have been used. We need 340852284Sobrien not check some conditions again (such as flag_omit_frame_pointer) 340952284Sobrien since they can't have changed. */ 341052284Sobrien 341152284Sobrienstatic void 341252284Sobrienupdate_eliminables (pset) 341352284Sobrien HARD_REG_SET *pset; 341452284Sobrien{ 341552284Sobrien#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 341652284Sobrien int previous_frame_pointer_needed = frame_pointer_needed; 341752284Sobrien#endif 341852284Sobrien struct elim_table *ep; 341952284Sobrien 342052284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 342152284Sobrien if ((ep->from == HARD_FRAME_POINTER_REGNUM && FRAME_POINTER_REQUIRED) 342252284Sobrien#ifdef ELIMINABLE_REGS 342352284Sobrien || ! CAN_ELIMINATE (ep->from, ep->to) 342452284Sobrien#endif 342552284Sobrien ) 342652284Sobrien ep->can_eliminate = 0; 342752284Sobrien 342852284Sobrien /* Look for the case where we have discovered that we can't replace 342952284Sobrien register A with register B and that means that we will now be 343052284Sobrien trying to replace register A with register C. This means we can 343152284Sobrien no longer replace register C with register B and we need to disable 343252284Sobrien such an elimination, if it exists. This occurs often with A == ap, 343352284Sobrien B == sp, and C == fp. */ 343452284Sobrien 343552284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 343652284Sobrien { 343752284Sobrien struct elim_table *op; 343890075Sobrien int new_to = -1; 343952284Sobrien 344052284Sobrien if (! ep->can_eliminate && ep->can_eliminate_previous) 344152284Sobrien { 344252284Sobrien /* Find the current elimination for ep->from, if there is a 344352284Sobrien new one. */ 344452284Sobrien for (op = reg_eliminate; 344552284Sobrien op < ®_eliminate[NUM_ELIMINABLE_REGS]; op++) 344652284Sobrien if (op->from == ep->from && op->can_eliminate) 344752284Sobrien { 344852284Sobrien new_to = op->to; 344952284Sobrien break; 345052284Sobrien } 345152284Sobrien 345252284Sobrien /* See if there is an elimination of NEW_TO -> EP->TO. If so, 345352284Sobrien disable it. */ 345452284Sobrien for (op = reg_eliminate; 345552284Sobrien op < ®_eliminate[NUM_ELIMINABLE_REGS]; op++) 345652284Sobrien if (op->from == new_to && op->to == ep->to) 345752284Sobrien op->can_eliminate = 0; 345852284Sobrien } 345952284Sobrien } 346052284Sobrien 346152284Sobrien /* See if any registers that we thought we could eliminate the previous 346252284Sobrien time are no longer eliminable. If so, something has changed and we 346352284Sobrien must spill the register. Also, recompute the number of eliminable 346452284Sobrien registers and see if the frame pointer is needed; it is if there is 346552284Sobrien no elimination of the frame pointer that we can perform. */ 346652284Sobrien 346752284Sobrien frame_pointer_needed = 1; 346852284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 346952284Sobrien { 347052284Sobrien if (ep->can_eliminate && ep->from == FRAME_POINTER_REGNUM 347152284Sobrien && ep->to != HARD_FRAME_POINTER_REGNUM) 347252284Sobrien frame_pointer_needed = 0; 347352284Sobrien 347452284Sobrien if (! ep->can_eliminate && ep->can_eliminate_previous) 347552284Sobrien { 347652284Sobrien ep->can_eliminate_previous = 0; 347752284Sobrien SET_HARD_REG_BIT (*pset, ep->from); 347852284Sobrien num_eliminable--; 347952284Sobrien } 348052284Sobrien } 348152284Sobrien 348252284Sobrien#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM 348352284Sobrien /* If we didn't need a frame pointer last time, but we do now, spill 348452284Sobrien the hard frame pointer. */ 348552284Sobrien if (frame_pointer_needed && ! previous_frame_pointer_needed) 348652284Sobrien SET_HARD_REG_BIT (*pset, HARD_FRAME_POINTER_REGNUM); 348752284Sobrien#endif 348852284Sobrien} 348952284Sobrien 349052284Sobrien/* Initialize the table of registers to eliminate. */ 349190075Sobrien 349252284Sobrienstatic void 349352284Sobrieninit_elim_table () 349452284Sobrien{ 349552284Sobrien struct elim_table *ep; 349652284Sobrien#ifdef ELIMINABLE_REGS 349790075Sobrien const struct elim_table_1 *ep1; 349852284Sobrien#endif 349952284Sobrien 350052284Sobrien if (!reg_eliminate) 350190075Sobrien reg_eliminate = (struct elim_table *) 350290075Sobrien xcalloc (sizeof (struct elim_table), NUM_ELIMINABLE_REGS); 350390075Sobrien 350452284Sobrien /* Does this function require a frame pointer? */ 350552284Sobrien 350652284Sobrien frame_pointer_needed = (! flag_omit_frame_pointer 350752284Sobrien#ifdef EXIT_IGNORE_STACK 350852284Sobrien /* ?? If EXIT_IGNORE_STACK is set, we will not save 350952284Sobrien and restore sp for alloca. So we can't eliminate 351052284Sobrien the frame pointer in that case. At some point, 351152284Sobrien we should improve this by emitting the 351252284Sobrien sp-adjusting insns for this case. */ 351352284Sobrien || (current_function_calls_alloca 351452284Sobrien && EXIT_IGNORE_STACK) 351552284Sobrien#endif 351652284Sobrien || FRAME_POINTER_REQUIRED); 351752284Sobrien 351852284Sobrien num_eliminable = 0; 351952284Sobrien 352052284Sobrien#ifdef ELIMINABLE_REGS 352152284Sobrien for (ep = reg_eliminate, ep1 = reg_eliminate_1; 352252284Sobrien ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++, ep1++) 352352284Sobrien { 352452284Sobrien ep->from = ep1->from; 352552284Sobrien ep->to = ep1->to; 352652284Sobrien ep->can_eliminate = ep->can_eliminate_previous 352752284Sobrien = (CAN_ELIMINATE (ep->from, ep->to) 352852284Sobrien && ! (ep->to == STACK_POINTER_REGNUM && frame_pointer_needed)); 352952284Sobrien } 353052284Sobrien#else 353152284Sobrien reg_eliminate[0].from = reg_eliminate_1[0].from; 353252284Sobrien reg_eliminate[0].to = reg_eliminate_1[0].to; 353352284Sobrien reg_eliminate[0].can_eliminate = reg_eliminate[0].can_eliminate_previous 353452284Sobrien = ! frame_pointer_needed; 353552284Sobrien#endif 353652284Sobrien 353752284Sobrien /* Count the number of eliminable registers and build the FROM and TO 353852284Sobrien REG rtx's. Note that code in gen_rtx will cause, e.g., 353952284Sobrien gen_rtx (REG, Pmode, STACK_POINTER_REGNUM) to equal stack_pointer_rtx. 354052284Sobrien We depend on this. */ 354152284Sobrien for (ep = reg_eliminate; ep < ®_eliminate[NUM_ELIMINABLE_REGS]; ep++) 354252284Sobrien { 354352284Sobrien num_eliminable += ep->can_eliminate; 354452284Sobrien ep->from_rtx = gen_rtx_REG (Pmode, ep->from); 354552284Sobrien ep->to_rtx = gen_rtx_REG (Pmode, ep->to); 354652284Sobrien } 354752284Sobrien} 354818334Speter 354918334Speter/* Kick all pseudos out of hard register REGNO. 355018334Speter 355118334Speter If CANT_ELIMINATE is nonzero, it means that we are doing this spill 355218334Speter because we found we can't eliminate some register. In the case, no pseudos 355318334Speter are allowed to be in the register, even if they are only in a block that 355418334Speter doesn't require spill registers, unlike the case when we are spilling this 355518334Speter hard reg to produce another spill register. 355618334Speter 355718334Speter Return nonzero if any pseudos needed to be kicked out. */ 355818334Speter 355952284Sobrienstatic void 356090075Sobrienspill_hard_reg (regno, cant_eliminate) 356190075Sobrien unsigned int regno; 356218334Speter int cant_eliminate; 356318334Speter{ 356490075Sobrien int i; 356518334Speter 356618334Speter if (cant_eliminate) 356752284Sobrien { 356852284Sobrien SET_HARD_REG_BIT (bad_spill_regs_global, regno); 356952284Sobrien regs_ever_live[regno] = 1; 357052284Sobrien } 357118334Speter 357218334Speter /* Spill every pseudo reg that was allocated to this reg 357318334Speter or to something that overlaps this reg. */ 357418334Speter 357518334Speter for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 357618334Speter if (reg_renumber[i] >= 0 357790075Sobrien && (unsigned int) reg_renumber[i] <= regno 357890075Sobrien && ((unsigned int) reg_renumber[i] 357990075Sobrien + HARD_REGNO_NREGS ((unsigned int) reg_renumber[i], 358018334Speter PSEUDO_REGNO_MODE (i)) 358118334Speter > regno)) 358290075Sobrien SET_REGNO_REG_SET (&spilled_pseudos, i); 358352284Sobrien} 358418334Speter 358552284Sobrien/* I'm getting weird preprocessor errors if I use IOR_HARD_REG_SET 358652284Sobrien from within EXECUTE_IF_SET_IN_REG_SET. Hence this awkwardness. */ 358790075Sobrien 358852284Sobrienstatic void 358952284Sobrienior_hard_reg_set (set1, set2) 359052284Sobrien HARD_REG_SET *set1, *set2; 359152284Sobrien{ 359252284Sobrien IOR_HARD_REG_SET (*set1, *set2); 359352284Sobrien} 359490075Sobrien 359552284Sobrien/* After find_reload_regs has been run for all insn that need reloads, 359652284Sobrien and/or spill_hard_regs was called, this function is used to actually 359752284Sobrien spill pseudo registers and try to reallocate them. It also sets up the 359852284Sobrien spill_regs array for use by choose_reload_regs. */ 359918334Speter 360052284Sobrienstatic int 360190075Sobrienfinish_spills (global) 360252284Sobrien int global; 360352284Sobrien{ 360452284Sobrien struct insn_chain *chain; 360552284Sobrien int something_changed = 0; 360652284Sobrien int i; 360718334Speter 360852284Sobrien /* Build the spill_regs array for the function. */ 360952284Sobrien /* If there are some registers still to eliminate and one of the spill regs 361052284Sobrien wasn't ever used before, additional stack space may have to be 361152284Sobrien allocated to store this register. Thus, we may have changed the offset 361252284Sobrien between the stack and frame pointers, so mark that something has changed. 361318334Speter 361452284Sobrien One might think that we need only set VAL to 1 if this is a call-used 361552284Sobrien register. However, the set of registers that must be saved by the 361652284Sobrien prologue is not identical to the call-used set. For example, the 361752284Sobrien register used by the call insn for the return PC is a call-used register, 361852284Sobrien but must be saved by the prologue. */ 361952284Sobrien 362052284Sobrien n_spills = 0; 362152284Sobrien for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) 362252284Sobrien if (TEST_HARD_REG_BIT (used_spill_regs, i)) 362352284Sobrien { 362452284Sobrien spill_reg_order[i] = n_spills; 362552284Sobrien spill_regs[n_spills++] = i; 362652284Sobrien if (num_eliminable && ! regs_ever_live[i]) 362752284Sobrien something_changed = 1; 362852284Sobrien regs_ever_live[i] = 1; 362952284Sobrien } 363052284Sobrien else 363152284Sobrien spill_reg_order[i] = -1; 363252284Sobrien 363390075Sobrien EXECUTE_IF_SET_IN_REG_SET 363490075Sobrien (&spilled_pseudos, FIRST_PSEUDO_REGISTER, i, 363590075Sobrien { 363690075Sobrien /* Record the current hard register the pseudo is allocated to in 363790075Sobrien pseudo_previous_regs so we avoid reallocating it to the same 363890075Sobrien hard reg in a later pass. */ 363990075Sobrien if (reg_renumber[i] < 0) 364090075Sobrien abort (); 364118334Speter 364290075Sobrien SET_HARD_REG_BIT (pseudo_previous_regs[i], reg_renumber[i]); 364390075Sobrien /* Mark it as no longer having a hard register home. */ 364490075Sobrien reg_renumber[i] = -1; 364590075Sobrien /* We will need to scan everything again. */ 364690075Sobrien something_changed = 1; 364790075Sobrien }); 364890075Sobrien 364952284Sobrien /* Retry global register allocation if possible. */ 365052284Sobrien if (global) 365152284Sobrien { 365290075Sobrien memset ((char *) pseudo_forbidden_regs, 0, max_regno * sizeof (HARD_REG_SET)); 365352284Sobrien /* For every insn that needs reloads, set the registers used as spill 365452284Sobrien regs in pseudo_forbidden_regs for every pseudo live across the 365552284Sobrien insn. */ 365652284Sobrien for (chain = insns_need_reload; chain; chain = chain->next_need_reload) 365752284Sobrien { 365852284Sobrien EXECUTE_IF_SET_IN_REG_SET 365990075Sobrien (&chain->live_throughout, FIRST_PSEUDO_REGISTER, i, 366052284Sobrien { 366152284Sobrien ior_hard_reg_set (pseudo_forbidden_regs + i, 366252284Sobrien &chain->used_spill_regs); 366352284Sobrien }); 366452284Sobrien EXECUTE_IF_SET_IN_REG_SET 366590075Sobrien (&chain->dead_or_set, FIRST_PSEUDO_REGISTER, i, 366652284Sobrien { 366752284Sobrien ior_hard_reg_set (pseudo_forbidden_regs + i, 366852284Sobrien &chain->used_spill_regs); 366952284Sobrien }); 367052284Sobrien } 367152284Sobrien 367252284Sobrien /* Retry allocating the spilled pseudos. For each reg, merge the 367352284Sobrien various reg sets that indicate which hard regs can't be used, 367452284Sobrien and call retry_global_alloc. 367590075Sobrien We change spill_pseudos here to only contain pseudos that did not 367652284Sobrien get a new hard register. */ 367752284Sobrien for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 367852284Sobrien if (reg_old_renumber[i] != reg_renumber[i]) 367918334Speter { 368052284Sobrien HARD_REG_SET forbidden; 368152284Sobrien COPY_HARD_REG_SET (forbidden, bad_spill_regs_global); 368252284Sobrien IOR_HARD_REG_SET (forbidden, pseudo_forbidden_regs[i]); 368352284Sobrien IOR_HARD_REG_SET (forbidden, pseudo_previous_regs[i]); 368452284Sobrien retry_global_alloc (i, forbidden); 368552284Sobrien if (reg_renumber[i] >= 0) 368690075Sobrien CLEAR_REGNO_REG_SET (&spilled_pseudos, i); 368718334Speter } 368852284Sobrien } 368952284Sobrien 369052284Sobrien /* Fix up the register information in the insn chain. 369152284Sobrien This involves deleting those of the spilled pseudos which did not get 369252284Sobrien a new hard register home from the live_{before,after} sets. */ 369352284Sobrien for (chain = reload_insn_chain; chain; chain = chain->next) 369418334Speter { 369552284Sobrien HARD_REG_SET used_by_pseudos; 369652284Sobrien HARD_REG_SET used_by_pseudos2; 369752284Sobrien 369890075Sobrien AND_COMPL_REG_SET (&chain->live_throughout, &spilled_pseudos); 369990075Sobrien AND_COMPL_REG_SET (&chain->dead_or_set, &spilled_pseudos); 370052284Sobrien 370152284Sobrien /* Mark any unallocated hard regs as available for spills. That 370252284Sobrien makes inheritance work somewhat better. */ 370352284Sobrien if (chain->need_reload) 370418334Speter { 370590075Sobrien REG_SET_TO_HARD_REG_SET (used_by_pseudos, &chain->live_throughout); 370690075Sobrien REG_SET_TO_HARD_REG_SET (used_by_pseudos2, &chain->dead_or_set); 370752284Sobrien IOR_HARD_REG_SET (used_by_pseudos, used_by_pseudos2); 370818334Speter 370952284Sobrien /* Save the old value for the sanity test below. */ 371052284Sobrien COPY_HARD_REG_SET (used_by_pseudos2, chain->used_spill_regs); 371118334Speter 371290075Sobrien compute_use_by_pseudos (&used_by_pseudos, &chain->live_throughout); 371390075Sobrien compute_use_by_pseudos (&used_by_pseudos, &chain->dead_or_set); 371452284Sobrien COMPL_HARD_REG_SET (chain->used_spill_regs, used_by_pseudos); 371552284Sobrien AND_HARD_REG_SET (chain->used_spill_regs, used_spill_regs); 371652284Sobrien 371752284Sobrien /* Make sure we only enlarge the set. */ 371852284Sobrien GO_IF_HARD_REG_SUBSET (used_by_pseudos2, chain->used_spill_regs, ok); 371952284Sobrien abort (); 372052284Sobrien ok:; 372118334Speter } 372218334Speter } 372318334Speter 372452284Sobrien /* Let alter_reg modify the reg rtx's for the modified pseudos. */ 372552284Sobrien for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 372652284Sobrien { 372752284Sobrien int regno = reg_renumber[i]; 372852284Sobrien if (reg_old_renumber[i] == regno) 372952284Sobrien continue; 373090075Sobrien 373152284Sobrien alter_reg (i, reg_old_renumber[i]); 373252284Sobrien reg_old_renumber[i] = regno; 373390075Sobrien if (rtl_dump_file) 373452284Sobrien { 373552284Sobrien if (regno == -1) 373690075Sobrien fprintf (rtl_dump_file, " Register %d now on stack.\n\n", i); 373752284Sobrien else 373890075Sobrien fprintf (rtl_dump_file, " Register %d now in %d.\n\n", 373952284Sobrien i, reg_renumber[i]); 374052284Sobrien } 374152284Sobrien } 374252284Sobrien 374318334Speter return something_changed; 374418334Speter} 374518334Speter 374690075Sobrien/* Find all paradoxical subregs within X and update reg_max_ref_width. 374718334Speter Also mark any hard registers used to store user variables as 374818334Speter forbidden from being used for spill registers. */ 374918334Speter 375018334Speterstatic void 375118334Speterscan_paradoxical_subregs (x) 375290075Sobrien rtx x; 375318334Speter{ 375490075Sobrien int i; 375590075Sobrien const char *fmt; 375690075Sobrien enum rtx_code code = GET_CODE (x); 375718334Speter 375818334Speter switch (code) 375918334Speter { 376018334Speter case REG: 376152284Sobrien#if 0 376250397Sobrien if (SMALL_REGISTER_CLASSES && REGNO (x) < FIRST_PSEUDO_REGISTER 376350397Sobrien && REG_USERVAR_P (x)) 376452284Sobrien SET_HARD_REG_BIT (bad_spill_regs_global, REGNO (x)); 376552284Sobrien#endif 376618334Speter return; 376718334Speter 376818334Speter case CONST_INT: 376918334Speter case CONST: 377018334Speter case SYMBOL_REF: 377118334Speter case LABEL_REF: 377218334Speter case CONST_DOUBLE: 377396263Sobrien case CONST_VECTOR: /* shouldn't happen, but just in case. */ 377418334Speter case CC0: 377518334Speter case PC: 377618334Speter case USE: 377718334Speter case CLOBBER: 377818334Speter return; 377918334Speter 378018334Speter case SUBREG: 378118334Speter if (GET_CODE (SUBREG_REG (x)) == REG 378218334Speter && GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)))) 378318334Speter reg_max_ref_width[REGNO (SUBREG_REG (x))] 378418334Speter = GET_MODE_SIZE (GET_MODE (x)); 378518334Speter return; 378690075Sobrien 378750397Sobrien default: 378850397Sobrien break; 378918334Speter } 379018334Speter 379118334Speter fmt = GET_RTX_FORMAT (code); 379218334Speter for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 379318334Speter { 379418334Speter if (fmt[i] == 'e') 379518334Speter scan_paradoxical_subregs (XEXP (x, i)); 379618334Speter else if (fmt[i] == 'E') 379718334Speter { 379890075Sobrien int j; 379990075Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 380018334Speter scan_paradoxical_subregs (XVECEXP (x, i, j)); 380118334Speter } 380218334Speter } 380318334Speter} 380418334Speter 380518334Speter/* Reload pseudo-registers into hard regs around each insn as needed. 380618334Speter Additional register load insns are output before the insn that needs it 380718334Speter and perhaps store insns after insns that modify the reloaded pseudo reg. 380818334Speter 380918334Speter reg_last_reload_reg and reg_reloaded_contents keep track of 381018334Speter which registers are already available in reload registers. 381118334Speter We update these for the reloads that we perform, 381218334Speter as the insns are scanned. */ 381318334Speter 381418334Speterstatic void 381552284Sobrienreload_as_needed (live_known) 381618334Speter int live_known; 381718334Speter{ 381852284Sobrien struct insn_chain *chain; 381990075Sobrien#if defined (AUTO_INC_DEC) 382090075Sobrien int i; 382152284Sobrien#endif 382218334Speter rtx x; 382318334Speter 382490075Sobrien memset ((char *) spill_reg_rtx, 0, sizeof spill_reg_rtx); 382590075Sobrien memset ((char *) spill_reg_store, 0, sizeof spill_reg_store); 382690075Sobrien reg_last_reload_reg = (rtx *) xcalloc (max_regno, sizeof (rtx)); 382790075Sobrien reg_has_output_reload = (char *) xmalloc (max_regno); 382850397Sobrien CLEAR_HARD_REG_SET (reg_reloaded_valid); 382918334Speter 383052284Sobrien set_initial_elim_offsets (); 383118334Speter 383252284Sobrien for (chain = reload_insn_chain; chain; chain = chain->next) 383318334Speter { 383452284Sobrien rtx prev; 383552284Sobrien rtx insn = chain->insn; 383652284Sobrien rtx old_next = NEXT_INSN (insn); 383718334Speter 383818334Speter /* If we pass a label, copy the offsets from the label information 383918334Speter into the current offsets of each elimination. */ 384018334Speter if (GET_CODE (insn) == CODE_LABEL) 384152284Sobrien set_offsets_for_label (insn); 384218334Speter 384390075Sobrien else if (INSN_P (insn)) 384418334Speter { 384518334Speter rtx oldpat = PATTERN (insn); 384618334Speter 384718334Speter /* If this is a USE and CLOBBER of a MEM, ensure that any 384818334Speter references to eliminable registers have been removed. */ 384918334Speter 385018334Speter if ((GET_CODE (PATTERN (insn)) == USE 385118334Speter || GET_CODE (PATTERN (insn)) == CLOBBER) 385218334Speter && GET_CODE (XEXP (PATTERN (insn), 0)) == MEM) 385318334Speter XEXP (XEXP (PATTERN (insn), 0), 0) 385418334Speter = eliminate_regs (XEXP (XEXP (PATTERN (insn), 0), 0), 385550397Sobrien GET_MODE (XEXP (PATTERN (insn), 0)), 385650397Sobrien NULL_RTX); 385718334Speter 385818334Speter /* If we need to do register elimination processing, do so. 385918334Speter This might delete the insn, in which case we are done. */ 386052284Sobrien if ((num_eliminable || num_eliminable_invariants) && chain->need_elim) 386118334Speter { 386218334Speter eliminate_regs_in_insn (insn, 1); 386318334Speter if (GET_CODE (insn) == NOTE) 386418334Speter { 386552284Sobrien update_eliminable_offsets (); 386618334Speter continue; 386718334Speter } 386818334Speter } 386918334Speter 387052284Sobrien /* If need_elim is nonzero but need_reload is zero, one might think 387152284Sobrien that we could simply set n_reloads to 0. However, find_reloads 387252284Sobrien could have done some manipulation of the insn (such as swapping 387352284Sobrien commutative operands), and these manipulations are lost during 387452284Sobrien the first pass for every insn that needs register elimination. 387552284Sobrien So the actions of find_reloads must be redone here. */ 387652284Sobrien 387752284Sobrien if (! chain->need_elim && ! chain->need_reload 387852284Sobrien && ! chain->need_operand_change) 387918334Speter n_reloads = 0; 388018334Speter /* First find the pseudo regs that must be reloaded for this insn. 388118334Speter This info is returned in the tables reload_... (see reload.h). 388218334Speter Also modify the body of INSN by substituting RELOAD 388318334Speter rtx's for those pseudo regs. */ 388418334Speter else 388518334Speter { 388690075Sobrien memset (reg_has_output_reload, 0, max_regno); 388718334Speter CLEAR_HARD_REG_SET (reg_is_output_reload); 388818334Speter 388918334Speter find_reloads (insn, 1, spill_indirect_levels, live_known, 389018334Speter spill_reg_order); 389118334Speter } 389218334Speter 389318334Speter if (n_reloads > 0) 389418334Speter { 389552284Sobrien rtx next = NEXT_INSN (insn); 389618334Speter rtx p; 389718334Speter 389852284Sobrien prev = PREV_INSN (insn); 389918334Speter 390018334Speter /* Now compute which reload regs to reload them into. Perhaps 390118334Speter reusing reload regs from previous insns, or else output 390218334Speter load insns to reload them. Maybe output store insns too. 390318334Speter Record the choices of reload reg in reload_reg_rtx. */ 390452284Sobrien choose_reload_regs (chain); 390518334Speter 390690075Sobrien /* Merge any reloads that we didn't combine for fear of 390718334Speter increasing the number of spill registers needed but now 390818334Speter discover can be safely merged. */ 390950397Sobrien if (SMALL_REGISTER_CLASSES) 391050397Sobrien merge_assigned_reloads (insn); 391118334Speter 391218334Speter /* Generate the insns to reload operands into or out of 391318334Speter their reload regs. */ 391452284Sobrien emit_reload_insns (chain); 391518334Speter 391618334Speter /* Substitute the chosen reload regs from reload_reg_rtx 391718334Speter into the insn's body (or perhaps into the bodies of other 391818334Speter load and store insn that we just made for reloading 391918334Speter and that we moved the structure into). */ 392090075Sobrien subst_reloads (insn); 392118334Speter 392218334Speter /* If this was an ASM, make sure that all the reload insns 392318334Speter we have generated are valid. If not, give an error 392418334Speter and delete them. */ 392518334Speter 392618334Speter if (asm_noperands (PATTERN (insn)) >= 0) 392718334Speter for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p)) 392890075Sobrien if (p != insn && INSN_P (p) 392918334Speter && (recog_memoized (p) < 0 393052284Sobrien || (extract_insn (p), ! constrain_operands (1)))) 393118334Speter { 393218334Speter error_for_asm (insn, 393318334Speter "`asm' operand requires impossible reload"); 393490075Sobrien delete_insn (p); 393518334Speter } 393618334Speter } 393790075Sobrien 393890075Sobrien if (num_eliminable && chain->need_elim) 393990075Sobrien update_eliminable_offsets (); 394090075Sobrien 394118334Speter /* Any previously reloaded spilled pseudo reg, stored in this insn, 394218334Speter is no longer validly lying around to save a future reload. 394318334Speter Note that this does not detect pseudos that were reloaded 394418334Speter for this insn in order to be stored in 394518334Speter (obeying register constraints). That is correct; such reload 394618334Speter registers ARE still valid. */ 394790075Sobrien note_stores (oldpat, forget_old_reloads_1, NULL); 394818334Speter 394918334Speter /* There may have been CLOBBER insns placed after INSN. So scan 395018334Speter between INSN and NEXT and use them to forget old reloads. */ 395152284Sobrien for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x)) 395218334Speter if (GET_CODE (x) == INSN && GET_CODE (PATTERN (x)) == CLOBBER) 395390075Sobrien note_stores (PATTERN (x), forget_old_reloads_1, NULL); 395418334Speter 395518334Speter#ifdef AUTO_INC_DEC 395618334Speter /* Likewise for regs altered by auto-increment in this insn. 395752284Sobrien REG_INC notes have been changed by reloading: 395852284Sobrien find_reloads_address_1 records substitutions for them, 395952284Sobrien which have been performed by subst_reloads above. */ 396052284Sobrien for (i = n_reloads - 1; i >= 0; i--) 396152284Sobrien { 396290075Sobrien rtx in_reg = rld[i].in_reg; 396352284Sobrien if (in_reg) 396452284Sobrien { 396552284Sobrien enum rtx_code code = GET_CODE (in_reg); 396652284Sobrien /* PRE_INC / PRE_DEC will have the reload register ending up 396752284Sobrien with the same value as the stack slot, but that doesn't 396852284Sobrien hold true for POST_INC / POST_DEC. Either we have to 396952284Sobrien convert the memory access to a true POST_INC / POST_DEC, 397052284Sobrien or we can't use the reload register for inheritance. */ 397152284Sobrien if ((code == POST_INC || code == POST_DEC) 397252284Sobrien && TEST_HARD_REG_BIT (reg_reloaded_valid, 397390075Sobrien REGNO (rld[i].reg_rtx)) 397452284Sobrien /* Make sure it is the inc/dec pseudo, and not 397552284Sobrien some other (e.g. output operand) pseudo. */ 397690075Sobrien && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)] 397752284Sobrien == REGNO (XEXP (in_reg, 0)))) 397890075Sobrien 397952284Sobrien { 398090075Sobrien rtx reload_reg = rld[i].reg_rtx; 398152284Sobrien enum machine_mode mode = GET_MODE (reload_reg); 398252284Sobrien int n = 0; 398352284Sobrien rtx p; 398452284Sobrien 398552284Sobrien for (p = PREV_INSN (old_next); p != prev; p = PREV_INSN (p)) 398652284Sobrien { 398752284Sobrien /* We really want to ignore REG_INC notes here, so 398852284Sobrien use PATTERN (p) as argument to reg_set_p . */ 398952284Sobrien if (reg_set_p (reload_reg, PATTERN (p))) 399052284Sobrien break; 399190075Sobrien n = count_occurrences (PATTERN (p), reload_reg, 0); 399252284Sobrien if (! n) 399352284Sobrien continue; 399452284Sobrien if (n == 1) 399552284Sobrien { 399652284Sobrien n = validate_replace_rtx (reload_reg, 399752284Sobrien gen_rtx (code, mode, 399852284Sobrien reload_reg), 399952284Sobrien p); 400052284Sobrien 400152284Sobrien /* We must also verify that the constraints 400252284Sobrien are met after the replacement. */ 400352284Sobrien extract_insn (p); 400452284Sobrien if (n) 400552284Sobrien n = constrain_operands (1); 400652284Sobrien else 400752284Sobrien break; 400852284Sobrien 400952284Sobrien /* If the constraints were not met, then 401052284Sobrien undo the replacement. */ 401152284Sobrien if (!n) 401252284Sobrien { 401352284Sobrien validate_replace_rtx (gen_rtx (code, mode, 401452284Sobrien reload_reg), 401552284Sobrien reload_reg, p); 401652284Sobrien break; 401752284Sobrien } 401890075Sobrien 401952284Sobrien } 402052284Sobrien break; 402152284Sobrien } 402252284Sobrien if (n == 1) 402352284Sobrien { 402452284Sobrien REG_NOTES (p) 402552284Sobrien = gen_rtx_EXPR_LIST (REG_INC, reload_reg, 402652284Sobrien REG_NOTES (p)); 402752284Sobrien /* Mark this as having an output reload so that the 402852284Sobrien REG_INC processing code below won't invalidate 402952284Sobrien the reload for inheritance. */ 403052284Sobrien SET_HARD_REG_BIT (reg_is_output_reload, 403152284Sobrien REGNO (reload_reg)); 403252284Sobrien reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1; 403352284Sobrien } 403452284Sobrien else 403590075Sobrien forget_old_reloads_1 (XEXP (in_reg, 0), NULL_RTX, 403690075Sobrien NULL); 403752284Sobrien } 403852284Sobrien else if ((code == PRE_INC || code == PRE_DEC) 403952284Sobrien && TEST_HARD_REG_BIT (reg_reloaded_valid, 404090075Sobrien REGNO (rld[i].reg_rtx)) 404152284Sobrien /* Make sure it is the inc/dec pseudo, and not 404252284Sobrien some other (e.g. output operand) pseudo. */ 404390075Sobrien && (reg_reloaded_contents[REGNO (rld[i].reg_rtx)] 404452284Sobrien == REGNO (XEXP (in_reg, 0)))) 404552284Sobrien { 404652284Sobrien SET_HARD_REG_BIT (reg_is_output_reload, 404790075Sobrien REGNO (rld[i].reg_rtx)); 404852284Sobrien reg_has_output_reload[REGNO (XEXP (in_reg, 0))] = 1; 404952284Sobrien } 405052284Sobrien } 405152284Sobrien } 405252284Sobrien /* If a pseudo that got a hard register is auto-incremented, 405352284Sobrien we must purge records of copying it into pseudos without 405452284Sobrien hard registers. */ 405518334Speter for (x = REG_NOTES (insn); x; x = XEXP (x, 1)) 405618334Speter if (REG_NOTE_KIND (x) == REG_INC) 405718334Speter { 405818334Speter /* See if this pseudo reg was reloaded in this insn. 405918334Speter If so, its last-reload info is still valid 406018334Speter because it is based on this insn's reload. */ 406118334Speter for (i = 0; i < n_reloads; i++) 406290075Sobrien if (rld[i].out == XEXP (x, 0)) 406318334Speter break; 406418334Speter 406518334Speter if (i == n_reloads) 406690075Sobrien forget_old_reloads_1 (XEXP (x, 0), NULL_RTX, NULL); 406718334Speter } 406818334Speter#endif 406918334Speter } 407018334Speter /* A reload reg's contents are unknown after a label. */ 407118334Speter if (GET_CODE (insn) == CODE_LABEL) 407250397Sobrien CLEAR_HARD_REG_SET (reg_reloaded_valid); 407318334Speter 407418334Speter /* Don't assume a reload reg is still good after a call insn 407518334Speter if it is a call-used reg. */ 407618334Speter else if (GET_CODE (insn) == CALL_INSN) 407790075Sobrien AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set); 407890075Sobrien } 407918334Speter 408090075Sobrien /* Clean up. */ 408190075Sobrien free (reg_last_reload_reg); 408290075Sobrien free (reg_has_output_reload); 408318334Speter} 408418334Speter 408518334Speter/* Discard all record of any value reloaded from X, 408618334Speter or reloaded in X from someplace else; 408718334Speter unless X is an output reload reg of the current insn. 408818334Speter 408918334Speter X may be a hard reg (the reload reg) 409018334Speter or it may be a pseudo reg that was reloaded from. */ 409118334Speter 409218334Speterstatic void 409390075Sobrienforget_old_reloads_1 (x, ignored, data) 409418334Speter rtx x; 409550397Sobrien rtx ignored ATTRIBUTE_UNUSED; 409690075Sobrien void *data ATTRIBUTE_UNUSED; 409718334Speter{ 409890075Sobrien unsigned int regno; 409990075Sobrien unsigned int nr; 410052284Sobrien int offset = 0; 410118334Speter 410290075Sobrien /* note_stores does give us subregs of hard regs, 410390075Sobrien subreg_regno_offset will abort if it is not a hard reg. */ 410418334Speter while (GET_CODE (x) == SUBREG) 410518334Speter { 410690075Sobrien offset += subreg_regno_offset (REGNO (SUBREG_REG (x)), 410790075Sobrien GET_MODE (SUBREG_REG (x)), 410890075Sobrien SUBREG_BYTE (x), 410990075Sobrien GET_MODE (x)); 411018334Speter x = SUBREG_REG (x); 411118334Speter } 411218334Speter 411318334Speter if (GET_CODE (x) != REG) 411418334Speter return; 411518334Speter 411652284Sobrien regno = REGNO (x) + offset; 411718334Speter 411818334Speter if (regno >= FIRST_PSEUDO_REGISTER) 411918334Speter nr = 1; 412018334Speter else 412118334Speter { 412290075Sobrien unsigned int i; 412390075Sobrien 412452284Sobrien nr = HARD_REGNO_NREGS (regno, GET_MODE (x)); 412518334Speter /* Storing into a spilled-reg invalidates its contents. 412618334Speter This can happen if a block-local pseudo is allocated to that reg 412718334Speter and it wasn't spilled because this block's total need is 0. 412818334Speter Then some insn might have an optional reload and use this reg. */ 412918334Speter for (i = 0; i < nr; i++) 413050397Sobrien /* But don't do this if the reg actually serves as an output 413150397Sobrien reload reg in the current instruction. */ 413250397Sobrien if (n_reloads == 0 413350397Sobrien || ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i)) 413470635Sobrien { 413570635Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i); 413670635Sobrien spill_reg_store[regno + i] = 0; 413770635Sobrien } 413818334Speter } 413918334Speter 414018334Speter /* Since value of X has changed, 414118334Speter forget any value previously copied from it. */ 414218334Speter 414318334Speter while (nr-- > 0) 414418334Speter /* But don't forget a copy if this is the output reload 414518334Speter that establishes the copy's validity. */ 414618334Speter if (n_reloads == 0 || reg_has_output_reload[regno + nr] == 0) 414718334Speter reg_last_reload_reg[regno + nr] = 0; 414818334Speter} 414918334Speter 415018334Speter/* The following HARD_REG_SETs indicate when each hard register is 415118334Speter used for a reload of various parts of the current insn. */ 415218334Speter 415370635Sobrien/* If reg is unavailable for all reloads. */ 415470635Sobrienstatic HARD_REG_SET reload_reg_unavailable; 415518334Speter/* If reg is in use as a reload reg for a RELOAD_OTHER reload. */ 415618334Speterstatic HARD_REG_SET reload_reg_used; 415718334Speter/* If reg is in use for a RELOAD_FOR_INPUT_ADDRESS reload for operand I. */ 415818334Speterstatic HARD_REG_SET reload_reg_used_in_input_addr[MAX_RECOG_OPERANDS]; 415950397Sobrien/* If reg is in use for a RELOAD_FOR_INPADDR_ADDRESS reload for operand I. */ 416050397Sobrienstatic HARD_REG_SET reload_reg_used_in_inpaddr_addr[MAX_RECOG_OPERANDS]; 416118334Speter/* If reg is in use for a RELOAD_FOR_OUTPUT_ADDRESS reload for operand I. */ 416218334Speterstatic HARD_REG_SET reload_reg_used_in_output_addr[MAX_RECOG_OPERANDS]; 416350397Sobrien/* If reg is in use for a RELOAD_FOR_OUTADDR_ADDRESS reload for operand I. */ 416450397Sobrienstatic HARD_REG_SET reload_reg_used_in_outaddr_addr[MAX_RECOG_OPERANDS]; 416518334Speter/* If reg is in use for a RELOAD_FOR_INPUT reload for operand I. */ 416618334Speterstatic HARD_REG_SET reload_reg_used_in_input[MAX_RECOG_OPERANDS]; 416718334Speter/* If reg is in use for a RELOAD_FOR_OUTPUT reload for operand I. */ 416818334Speterstatic HARD_REG_SET reload_reg_used_in_output[MAX_RECOG_OPERANDS]; 416918334Speter/* If reg is in use for a RELOAD_FOR_OPERAND_ADDRESS reload. */ 417018334Speterstatic HARD_REG_SET reload_reg_used_in_op_addr; 417118334Speter/* If reg is in use for a RELOAD_FOR_OPADDR_ADDR reload. */ 417218334Speterstatic HARD_REG_SET reload_reg_used_in_op_addr_reload; 417318334Speter/* If reg is in use for a RELOAD_FOR_INSN reload. */ 417418334Speterstatic HARD_REG_SET reload_reg_used_in_insn; 417518334Speter/* If reg is in use for a RELOAD_FOR_OTHER_ADDRESS reload. */ 417618334Speterstatic HARD_REG_SET reload_reg_used_in_other_addr; 417718334Speter 417818334Speter/* If reg is in use as a reload reg for any sort of reload. */ 417918334Speterstatic HARD_REG_SET reload_reg_used_at_all; 418018334Speter 418118334Speter/* If reg is use as an inherited reload. We just mark the first register 418218334Speter in the group. */ 418318334Speterstatic HARD_REG_SET reload_reg_used_for_inherit; 418418334Speter 418552284Sobrien/* Records which hard regs are used in any way, either as explicit use or 418652284Sobrien by being allocated to a pseudo during any point of the current insn. */ 418752284Sobrienstatic HARD_REG_SET reg_used_in_insn; 418852284Sobrien 418918334Speter/* Mark reg REGNO as in use for a reload of the sort spec'd by OPNUM and 419018334Speter TYPE. MODE is used to indicate how many consecutive regs are 419118334Speter actually used. */ 419218334Speter 419318334Speterstatic void 419418334Spetermark_reload_reg_in_use (regno, opnum, type, mode) 419590075Sobrien unsigned int regno; 419618334Speter int opnum; 419718334Speter enum reload_type type; 419818334Speter enum machine_mode mode; 419918334Speter{ 420090075Sobrien unsigned int nregs = HARD_REGNO_NREGS (regno, mode); 420190075Sobrien unsigned int i; 420218334Speter 420318334Speter for (i = regno; i < nregs + regno; i++) 420418334Speter { 420518334Speter switch (type) 420618334Speter { 420718334Speter case RELOAD_OTHER: 420818334Speter SET_HARD_REG_BIT (reload_reg_used, i); 420918334Speter break; 421018334Speter 421118334Speter case RELOAD_FOR_INPUT_ADDRESS: 421218334Speter SET_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], i); 421318334Speter break; 421418334Speter 421550397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 421650397Sobrien SET_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], i); 421750397Sobrien break; 421850397Sobrien 421918334Speter case RELOAD_FOR_OUTPUT_ADDRESS: 422018334Speter SET_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], i); 422118334Speter break; 422218334Speter 422350397Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 422450397Sobrien SET_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], i); 422550397Sobrien break; 422650397Sobrien 422718334Speter case RELOAD_FOR_OPERAND_ADDRESS: 422818334Speter SET_HARD_REG_BIT (reload_reg_used_in_op_addr, i); 422918334Speter break; 423018334Speter 423118334Speter case RELOAD_FOR_OPADDR_ADDR: 423218334Speter SET_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, i); 423318334Speter break; 423418334Speter 423518334Speter case RELOAD_FOR_OTHER_ADDRESS: 423618334Speter SET_HARD_REG_BIT (reload_reg_used_in_other_addr, i); 423718334Speter break; 423818334Speter 423918334Speter case RELOAD_FOR_INPUT: 424018334Speter SET_HARD_REG_BIT (reload_reg_used_in_input[opnum], i); 424118334Speter break; 424218334Speter 424318334Speter case RELOAD_FOR_OUTPUT: 424418334Speter SET_HARD_REG_BIT (reload_reg_used_in_output[opnum], i); 424518334Speter break; 424618334Speter 424718334Speter case RELOAD_FOR_INSN: 424818334Speter SET_HARD_REG_BIT (reload_reg_used_in_insn, i); 424918334Speter break; 425018334Speter } 425118334Speter 425218334Speter SET_HARD_REG_BIT (reload_reg_used_at_all, i); 425318334Speter } 425418334Speter} 425518334Speter 425618334Speter/* Similarly, but show REGNO is no longer in use for a reload. */ 425718334Speter 425818334Speterstatic void 425918334Speterclear_reload_reg_in_use (regno, opnum, type, mode) 426090075Sobrien unsigned int regno; 426118334Speter int opnum; 426218334Speter enum reload_type type; 426318334Speter enum machine_mode mode; 426418334Speter{ 426590075Sobrien unsigned int nregs = HARD_REGNO_NREGS (regno, mode); 426690075Sobrien unsigned int start_regno, end_regno, r; 426718334Speter int i; 426852284Sobrien /* A complication is that for some reload types, inheritance might 426952284Sobrien allow multiple reloads of the same types to share a reload register. 427052284Sobrien We set check_opnum if we have to check only reloads with the same 427152284Sobrien operand number, and check_any if we have to check all reloads. */ 427252284Sobrien int check_opnum = 0; 427352284Sobrien int check_any = 0; 427452284Sobrien HARD_REG_SET *used_in_set; 427518334Speter 427652284Sobrien switch (type) 427718334Speter { 427852284Sobrien case RELOAD_OTHER: 427952284Sobrien used_in_set = &reload_reg_used; 428052284Sobrien break; 428118334Speter 428252284Sobrien case RELOAD_FOR_INPUT_ADDRESS: 428352284Sobrien used_in_set = &reload_reg_used_in_input_addr[opnum]; 428452284Sobrien break; 428518334Speter 428652284Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 428752284Sobrien check_opnum = 1; 428852284Sobrien used_in_set = &reload_reg_used_in_inpaddr_addr[opnum]; 428952284Sobrien break; 429050397Sobrien 429152284Sobrien case RELOAD_FOR_OUTPUT_ADDRESS: 429252284Sobrien used_in_set = &reload_reg_used_in_output_addr[opnum]; 429352284Sobrien break; 429418334Speter 429552284Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 429652284Sobrien check_opnum = 1; 429752284Sobrien used_in_set = &reload_reg_used_in_outaddr_addr[opnum]; 429852284Sobrien break; 429950397Sobrien 430052284Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 430152284Sobrien used_in_set = &reload_reg_used_in_op_addr; 430252284Sobrien break; 430318334Speter 430452284Sobrien case RELOAD_FOR_OPADDR_ADDR: 430552284Sobrien check_any = 1; 430652284Sobrien used_in_set = &reload_reg_used_in_op_addr_reload; 430752284Sobrien break; 430818334Speter 430952284Sobrien case RELOAD_FOR_OTHER_ADDRESS: 431052284Sobrien used_in_set = &reload_reg_used_in_other_addr; 431152284Sobrien check_any = 1; 431252284Sobrien break; 431318334Speter 431452284Sobrien case RELOAD_FOR_INPUT: 431552284Sobrien used_in_set = &reload_reg_used_in_input[opnum]; 431652284Sobrien break; 431718334Speter 431852284Sobrien case RELOAD_FOR_OUTPUT: 431952284Sobrien used_in_set = &reload_reg_used_in_output[opnum]; 432052284Sobrien break; 432118334Speter 432252284Sobrien case RELOAD_FOR_INSN: 432352284Sobrien used_in_set = &reload_reg_used_in_insn; 432452284Sobrien break; 432552284Sobrien default: 432652284Sobrien abort (); 432752284Sobrien } 432852284Sobrien /* We resolve conflicts with remaining reloads of the same type by 432952284Sobrien excluding the intervals of of reload registers by them from the 433052284Sobrien interval of freed reload registers. Since we only keep track of 433152284Sobrien one set of interval bounds, we might have to exclude somewhat 433290075Sobrien more than what would be necessary if we used a HARD_REG_SET here. 433352284Sobrien But this should only happen very infrequently, so there should 433452284Sobrien be no reason to worry about it. */ 433590075Sobrien 433652284Sobrien start_regno = regno; 433752284Sobrien end_regno = regno + nregs; 433852284Sobrien if (check_opnum || check_any) 433952284Sobrien { 434052284Sobrien for (i = n_reloads - 1; i >= 0; i--) 434152284Sobrien { 434290075Sobrien if (rld[i].when_needed == type 434390075Sobrien && (check_any || rld[i].opnum == opnum) 434490075Sobrien && rld[i].reg_rtx) 434552284Sobrien { 434690075Sobrien unsigned int conflict_start = true_regnum (rld[i].reg_rtx); 434790075Sobrien unsigned int conflict_end 434852284Sobrien = (conflict_start 434990075Sobrien + HARD_REGNO_NREGS (conflict_start, rld[i].mode)); 435052284Sobrien 435152284Sobrien /* If there is an overlap with the first to-be-freed register, 435252284Sobrien adjust the interval start. */ 435352284Sobrien if (conflict_start <= start_regno && conflict_end > start_regno) 435452284Sobrien start_regno = conflict_end; 435552284Sobrien /* Otherwise, if there is a conflict with one of the other 435652284Sobrien to-be-freed registers, adjust the interval end. */ 435752284Sobrien if (conflict_start > start_regno && conflict_start < end_regno) 435852284Sobrien end_regno = conflict_start; 435952284Sobrien } 436018334Speter } 436118334Speter } 436290075Sobrien 436390075Sobrien for (r = start_regno; r < end_regno; r++) 436490075Sobrien CLEAR_HARD_REG_BIT (*used_in_set, r); 436518334Speter} 436618334Speter 436718334Speter/* 1 if reg REGNO is free as a reload reg for a reload of the sort 436818334Speter specified by OPNUM and TYPE. */ 436918334Speter 437018334Speterstatic int 437118334Speterreload_reg_free_p (regno, opnum, type) 437290075Sobrien unsigned int regno; 437318334Speter int opnum; 437418334Speter enum reload_type type; 437518334Speter{ 437618334Speter int i; 437718334Speter 437890075Sobrien /* In use for a RELOAD_OTHER means it's not available for anything. */ 437970635Sobrien if (TEST_HARD_REG_BIT (reload_reg_used, regno) 438070635Sobrien || TEST_HARD_REG_BIT (reload_reg_unavailable, regno)) 438118334Speter return 0; 438218334Speter 438318334Speter switch (type) 438418334Speter { 438518334Speter case RELOAD_OTHER: 438650397Sobrien /* In use for anything means we can't use it for RELOAD_OTHER. */ 438750397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno) 438818334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) 438918334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)) 439018334Speter return 0; 439118334Speter 439218334Speter for (i = 0; i < reload_n_operands; i++) 439318334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno) 439450397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno) 439518334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 439650397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno) 439718334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno) 439818334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 439918334Speter return 0; 440018334Speter 440118334Speter return 1; 440218334Speter 440318334Speter case RELOAD_FOR_INPUT: 440418334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 440518334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)) 440618334Speter return 0; 440718334Speter 440818334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)) 440918334Speter return 0; 441018334Speter 441118334Speter /* If it is used for some other input, can't use it. */ 441218334Speter for (i = 0; i < reload_n_operands; i++) 441318334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 441418334Speter return 0; 441518334Speter 441618334Speter /* If it is used in a later operand's address, can't use it. */ 441718334Speter for (i = opnum + 1; i < reload_n_operands; i++) 441850397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno) 441950397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)) 442018334Speter return 0; 442118334Speter 442218334Speter return 1; 442318334Speter 442418334Speter case RELOAD_FOR_INPUT_ADDRESS: 442518334Speter /* Can't use a register if it is used for an input address for this 442618334Speter operand or used as an input in an earlier one. */ 442750397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[opnum], regno) 442850397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno)) 442918334Speter return 0; 443018334Speter 443118334Speter for (i = 0; i < opnum; i++) 443218334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 443318334Speter return 0; 443418334Speter 443518334Speter return 1; 443618334Speter 443750397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 443850397Sobrien /* Can't use a register if it is used for an input address 443990075Sobrien for this operand or used as an input in an earlier 444090075Sobrien one. */ 444150397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[opnum], regno)) 444250397Sobrien return 0; 444350397Sobrien 444450397Sobrien for (i = 0; i < opnum; i++) 444550397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 444650397Sobrien return 0; 444750397Sobrien 444850397Sobrien return 1; 444950397Sobrien 445018334Speter case RELOAD_FOR_OUTPUT_ADDRESS: 445118334Speter /* Can't use a register if it is used for an output address for this 445290075Sobrien operand or used as an output in this or a later operand. Note 445390075Sobrien that multiple output operands are emitted in reverse order, so 445490075Sobrien the conflicting ones are those with lower indices. */ 445518334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[opnum], regno)) 445618334Speter return 0; 445718334Speter 445890075Sobrien for (i = 0; i <= opnum; i++) 445918334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 446018334Speter return 0; 446118334Speter 446218334Speter return 1; 446318334Speter 446450397Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 446550397Sobrien /* Can't use a register if it is used for an output address 446690075Sobrien for this operand or used as an output in this or a 446790075Sobrien later operand. Note that multiple output operands are 446890075Sobrien emitted in reverse order, so the conflicting ones are 446990075Sobrien those with lower indices. */ 447050397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[opnum], regno)) 447150397Sobrien return 0; 447250397Sobrien 447390075Sobrien for (i = 0; i <= opnum; i++) 447450397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 447550397Sobrien return 0; 447650397Sobrien 447750397Sobrien return 1; 447850397Sobrien 447918334Speter case RELOAD_FOR_OPERAND_ADDRESS: 448018334Speter for (i = 0; i < reload_n_operands; i++) 448118334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 448218334Speter return 0; 448318334Speter 448418334Speter return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 448518334Speter && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)); 448618334Speter 448718334Speter case RELOAD_FOR_OPADDR_ADDR: 448818334Speter for (i = 0; i < reload_n_operands; i++) 448990075Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 449090075Sobrien return 0; 449118334Speter 449218334Speter return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)); 449318334Speter 449418334Speter case RELOAD_FOR_OUTPUT: 449518334Speter /* This cannot share a register with RELOAD_FOR_INSN reloads, other 449690075Sobrien outputs, or an operand address for this or an earlier output. 449790075Sobrien Note that multiple output operands are emitted in reverse order, 449890075Sobrien so the conflicting ones are those with higher indices. */ 449918334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno)) 450018334Speter return 0; 450118334Speter 450218334Speter for (i = 0; i < reload_n_operands; i++) 450318334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 450418334Speter return 0; 450518334Speter 450690075Sobrien for (i = opnum; i < reload_n_operands; i++) 450750397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 450850397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)) 450918334Speter return 0; 451018334Speter 451118334Speter return 1; 451218334Speter 451318334Speter case RELOAD_FOR_INSN: 451418334Speter for (i = 0; i < reload_n_operands; i++) 451518334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno) 451618334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 451718334Speter return 0; 451818334Speter 451918334Speter return (! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 452018334Speter && ! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno)); 452118334Speter 452218334Speter case RELOAD_FOR_OTHER_ADDRESS: 452318334Speter return ! TEST_HARD_REG_BIT (reload_reg_used_in_other_addr, regno); 452418334Speter } 452518334Speter abort (); 452618334Speter} 452718334Speter 452818334Speter/* Return 1 if the value in reload reg REGNO, as used by a reload 452918334Speter needed for the part of the insn specified by OPNUM and TYPE, 453018334Speter is still available in REGNO at the end of the insn. 453118334Speter 453218334Speter We can assume that the reload reg was already tested for availability 453318334Speter at the time it is needed, and we should not check this again, 453418334Speter in case the reg has already been marked in use. */ 453518334Speter 453618334Speterstatic int 453718334Speterreload_reg_reaches_end_p (regno, opnum, type) 453890075Sobrien unsigned int regno; 453918334Speter int opnum; 454018334Speter enum reload_type type; 454118334Speter{ 454218334Speter int i; 454318334Speter 454418334Speter switch (type) 454518334Speter { 454618334Speter case RELOAD_OTHER: 454718334Speter /* Since a RELOAD_OTHER reload claims the reg for the entire insn, 454818334Speter its value must reach the end. */ 454918334Speter return 1; 455018334Speter 455118334Speter /* If this use is for part of the insn, 455290075Sobrien its value reaches if no subsequent part uses the same register. 455318334Speter Just like the above function, don't try to do this with lots 455418334Speter of fallthroughs. */ 455518334Speter 455618334Speter case RELOAD_FOR_OTHER_ADDRESS: 455718334Speter /* Here we check for everything else, since these don't conflict 455818334Speter with anything else and everything comes later. */ 455918334Speter 456018334Speter for (i = 0; i < reload_n_operands; i++) 456118334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 456250397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno) 456318334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno) 456418334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno) 456550397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno) 456618334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 456718334Speter return 0; 456818334Speter 456918334Speter return (! TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) 457018334Speter && ! TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 457118334Speter && ! TEST_HARD_REG_BIT (reload_reg_used, regno)); 457218334Speter 457318334Speter case RELOAD_FOR_INPUT_ADDRESS: 457450397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 457518334Speter /* Similar, except that we check only for this and subsequent inputs 457618334Speter and the address of only subsequent inputs and we do not need 457718334Speter to check for RELOAD_OTHER objects since they are known not to 457818334Speter conflict. */ 457918334Speter 458018334Speter for (i = opnum; i < reload_n_operands; i++) 458118334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 458218334Speter return 0; 458318334Speter 458418334Speter for (i = opnum + 1; i < reload_n_operands; i++) 458550397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno) 458650397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno)) 458718334Speter return 0; 458818334Speter 458918334Speter for (i = 0; i < reload_n_operands; i++) 459018334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 459150397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno) 459218334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 459318334Speter return 0; 459418334Speter 459518334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_op_addr_reload, regno)) 459618334Speter return 0; 459718334Speter 459890075Sobrien return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) 459990075Sobrien && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 460090075Sobrien && !TEST_HARD_REG_BIT (reload_reg_used, regno)); 460118334Speter 460218334Speter case RELOAD_FOR_INPUT: 460318334Speter /* Similar to input address, except we start at the next operand for 460490075Sobrien both input and input address and we do not check for 460518334Speter RELOAD_FOR_OPERAND_ADDRESS and RELOAD_FOR_INSN since these 460618334Speter would conflict. */ 460718334Speter 460818334Speter for (i = opnum + 1; i < reload_n_operands; i++) 460918334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_input_addr[i], regno) 461050397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_inpaddr_addr[i], regno) 461118334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_input[i], regno)) 461218334Speter return 0; 461318334Speter 461450397Sobrien /* ... fall through ... */ 461518334Speter 461618334Speter case RELOAD_FOR_OPERAND_ADDRESS: 461718334Speter /* Check outputs and their addresses. */ 461818334Speter 461918334Speter for (i = 0; i < reload_n_operands; i++) 462018334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 462150397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno) 462218334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 462318334Speter return 0; 462418334Speter 462590075Sobrien return (!TEST_HARD_REG_BIT (reload_reg_used, regno)); 462618334Speter 462718334Speter case RELOAD_FOR_OPADDR_ADDR: 462818334Speter for (i = 0; i < reload_n_operands; i++) 462918334Speter if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 463050397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno) 463118334Speter || TEST_HARD_REG_BIT (reload_reg_used_in_output[i], regno)) 463218334Speter return 0; 463318334Speter 463490075Sobrien return (!TEST_HARD_REG_BIT (reload_reg_used_in_op_addr, regno) 463590075Sobrien && !TEST_HARD_REG_BIT (reload_reg_used_in_insn, regno) 463690075Sobrien && !TEST_HARD_REG_BIT (reload_reg_used, regno)); 463718334Speter 463818334Speter case RELOAD_FOR_INSN: 463918334Speter /* These conflict with other outputs with RELOAD_OTHER. So 464018334Speter we need only check for output addresses. */ 464118334Speter 464290075Sobrien opnum = reload_n_operands; 464318334Speter 464450397Sobrien /* ... fall through ... */ 464518334Speter 464618334Speter case RELOAD_FOR_OUTPUT: 464718334Speter case RELOAD_FOR_OUTPUT_ADDRESS: 464850397Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 464918334Speter /* We already know these can't conflict with a later output. So the 465090075Sobrien only thing to check are later output addresses. 465190075Sobrien Note that multiple output operands are emitted in reverse order, 465290075Sobrien so the conflicting ones are those with lower indices. */ 465390075Sobrien for (i = 0; i < opnum; i++) 465450397Sobrien if (TEST_HARD_REG_BIT (reload_reg_used_in_output_addr[i], regno) 465550397Sobrien || TEST_HARD_REG_BIT (reload_reg_used_in_outaddr_addr[i], regno)) 465618334Speter return 0; 465718334Speter 465818334Speter return 1; 465918334Speter } 466018334Speter 466118334Speter abort (); 466218334Speter} 466318334Speter 466418334Speter/* Return 1 if the reloads denoted by R1 and R2 cannot share a register. 466518334Speter Return 0 otherwise. 466618334Speter 466718334Speter This function uses the same algorithm as reload_reg_free_p above. */ 466818334Speter 466950397Sobrienint 467018334Speterreloads_conflict (r1, r2) 467118334Speter int r1, r2; 467218334Speter{ 467390075Sobrien enum reload_type r1_type = rld[r1].when_needed; 467490075Sobrien enum reload_type r2_type = rld[r2].when_needed; 467590075Sobrien int r1_opnum = rld[r1].opnum; 467690075Sobrien int r2_opnum = rld[r2].opnum; 467718334Speter 467850397Sobrien /* RELOAD_OTHER conflicts with everything. */ 467950397Sobrien if (r2_type == RELOAD_OTHER) 468018334Speter return 1; 468118334Speter 468218334Speter /* Otherwise, check conflicts differently for each type. */ 468318334Speter 468418334Speter switch (r1_type) 468518334Speter { 468618334Speter case RELOAD_FOR_INPUT: 468790075Sobrien return (r2_type == RELOAD_FOR_INSN 468818334Speter || r2_type == RELOAD_FOR_OPERAND_ADDRESS 468918334Speter || r2_type == RELOAD_FOR_OPADDR_ADDR 469018334Speter || r2_type == RELOAD_FOR_INPUT 469150397Sobrien || ((r2_type == RELOAD_FOR_INPUT_ADDRESS 469250397Sobrien || r2_type == RELOAD_FOR_INPADDR_ADDRESS) 469350397Sobrien && r2_opnum > r1_opnum)); 469418334Speter 469518334Speter case RELOAD_FOR_INPUT_ADDRESS: 469618334Speter return ((r2_type == RELOAD_FOR_INPUT_ADDRESS && r1_opnum == r2_opnum) 469718334Speter || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum)); 469818334Speter 469950397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 470050397Sobrien return ((r2_type == RELOAD_FOR_INPADDR_ADDRESS && r1_opnum == r2_opnum) 470150397Sobrien || (r2_type == RELOAD_FOR_INPUT && r2_opnum < r1_opnum)); 470250397Sobrien 470318334Speter case RELOAD_FOR_OUTPUT_ADDRESS: 470418334Speter return ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS && r2_opnum == r1_opnum) 470590075Sobrien || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum)); 470618334Speter 470750397Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 470850397Sobrien return ((r2_type == RELOAD_FOR_OUTADDR_ADDRESS && r2_opnum == r1_opnum) 470990075Sobrien || (r2_type == RELOAD_FOR_OUTPUT && r2_opnum <= r1_opnum)); 471050397Sobrien 471118334Speter case RELOAD_FOR_OPERAND_ADDRESS: 471218334Speter return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_INSN 471318334Speter || r2_type == RELOAD_FOR_OPERAND_ADDRESS); 471418334Speter 471518334Speter case RELOAD_FOR_OPADDR_ADDR: 471690075Sobrien return (r2_type == RELOAD_FOR_INPUT 471718334Speter || r2_type == RELOAD_FOR_OPADDR_ADDR); 471818334Speter 471918334Speter case RELOAD_FOR_OUTPUT: 472018334Speter return (r2_type == RELOAD_FOR_INSN || r2_type == RELOAD_FOR_OUTPUT 472150397Sobrien || ((r2_type == RELOAD_FOR_OUTPUT_ADDRESS 472250397Sobrien || r2_type == RELOAD_FOR_OUTADDR_ADDRESS) 472390075Sobrien && r2_opnum >= r1_opnum)); 472418334Speter 472518334Speter case RELOAD_FOR_INSN: 472618334Speter return (r2_type == RELOAD_FOR_INPUT || r2_type == RELOAD_FOR_OUTPUT 472718334Speter || r2_type == RELOAD_FOR_INSN 472818334Speter || r2_type == RELOAD_FOR_OPERAND_ADDRESS); 472918334Speter 473018334Speter case RELOAD_FOR_OTHER_ADDRESS: 473118334Speter return r2_type == RELOAD_FOR_OTHER_ADDRESS; 473218334Speter 473318334Speter case RELOAD_OTHER: 473450397Sobrien return 1; 473518334Speter 473618334Speter default: 473718334Speter abort (); 473818334Speter } 473918334Speter} 474018334Speter 474118334Speter/* Indexed by reload number, 1 if incoming value 474218334Speter inherited from previous insns. */ 474318334Speterchar reload_inherited[MAX_RELOADS]; 474418334Speter 474518334Speter/* For an inherited reload, this is the insn the reload was inherited from, 474618334Speter if we know it. Otherwise, this is 0. */ 474718334Speterrtx reload_inheritance_insn[MAX_RELOADS]; 474818334Speter 474918334Speter/* If non-zero, this is a place to get the value of the reload, 475018334Speter rather than using reload_in. */ 475118334Speterrtx reload_override_in[MAX_RELOADS]; 475218334Speter 475350397Sobrien/* For each reload, the hard register number of the register used, 475450397Sobrien or -1 if we did not need a register for this reload. */ 475518334Speterint reload_spill_index[MAX_RELOADS]; 475618334Speter 475790075Sobrien/* Subroutine of free_for_value_p, used to check a single register. 475890075Sobrien START_REGNO is the starting regno of the full reload register 475990075Sobrien (possibly comprising multiple hard registers) that we are considering. */ 476050397Sobrien 476150397Sobrienstatic int 476290075Sobrienreload_reg_free_for_value_p (start_regno, regno, opnum, type, value, out, 476390075Sobrien reloadnum, ignore_address_reloads) 476490075Sobrien int start_regno, regno; 476550397Sobrien int opnum; 476650397Sobrien enum reload_type type; 476750397Sobrien rtx value, out; 476850397Sobrien int reloadnum; 476952284Sobrien int ignore_address_reloads; 477050397Sobrien{ 477150397Sobrien int time1; 477270635Sobrien /* Set if we see an input reload that must not share its reload register 477370635Sobrien with any new earlyclobber, but might otherwise share the reload 477470635Sobrien register with an output or input-output reload. */ 477570635Sobrien int check_earlyclobber = 0; 477650397Sobrien int i; 477752284Sobrien int copy = 0; 477850397Sobrien 477970635Sobrien if (TEST_HARD_REG_BIT (reload_reg_unavailable, regno)) 478057844Sobrien return 0; 478157844Sobrien 478252284Sobrien if (out == const0_rtx) 478352284Sobrien { 478452284Sobrien copy = 1; 478552284Sobrien out = NULL_RTX; 478652284Sobrien } 478752284Sobrien 478850397Sobrien /* We use some pseudo 'time' value to check if the lifetimes of the 478950397Sobrien new register use would overlap with the one of a previous reload 479050397Sobrien that is not read-only or uses a different value. 479150397Sobrien The 'time' used doesn't have to be linear in any shape or form, just 479250397Sobrien monotonic. 479350397Sobrien Some reload types use different 'buckets' for each operand. 479450397Sobrien So there are MAX_RECOG_OPERANDS different time values for each 479550397Sobrien such reload type. 479650397Sobrien We compute TIME1 as the time when the register for the prospective 479750397Sobrien new reload ceases to be live, and TIME2 for each existing 479850397Sobrien reload as the time when that the reload register of that reload 479950397Sobrien becomes live. 480050397Sobrien Where there is little to be gained by exact lifetime calculations, 480150397Sobrien we just make conservative assumptions, i.e. a longer lifetime; 480250397Sobrien this is done in the 'default:' cases. */ 480350397Sobrien switch (type) 480450397Sobrien { 480550397Sobrien case RELOAD_FOR_OTHER_ADDRESS: 480670635Sobrien /* RELOAD_FOR_OTHER_ADDRESS conflicts with RELOAD_OTHER reloads. */ 480770635Sobrien time1 = copy ? 0 : 1; 480850397Sobrien break; 480952284Sobrien case RELOAD_OTHER: 481052284Sobrien time1 = copy ? 1 : MAX_RECOG_OPERANDS * 5 + 5; 481152284Sobrien break; 481290075Sobrien /* For each input, we may have a sequence of RELOAD_FOR_INPADDR_ADDRESS, 481390075Sobrien RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_INPUT. By adding 0 / 1 / 2 , 481490075Sobrien respectively, to the time values for these, we get distinct time 481590075Sobrien values. To get distinct time values for each operand, we have to 481690075Sobrien multiply opnum by at least three. We round that up to four because 481790075Sobrien multiply by four is often cheaper. */ 481850397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 481952284Sobrien time1 = opnum * 4 + 2; 482050397Sobrien break; 482150397Sobrien case RELOAD_FOR_INPUT_ADDRESS: 482252284Sobrien time1 = opnum * 4 + 3; 482350397Sobrien break; 482450397Sobrien case RELOAD_FOR_INPUT: 482552284Sobrien /* All RELOAD_FOR_INPUT reloads remain live till the instruction 482652284Sobrien executes (inclusive). */ 482752284Sobrien time1 = copy ? opnum * 4 + 4 : MAX_RECOG_OPERANDS * 4 + 3; 482850397Sobrien break; 482952284Sobrien case RELOAD_FOR_OPADDR_ADDR: 483090075Sobrien /* opnum * 4 + 4 483190075Sobrien <= (MAX_RECOG_OPERANDS - 1) * 4 + 4 == MAX_RECOG_OPERANDS * 4 */ 483252284Sobrien time1 = MAX_RECOG_OPERANDS * 4 + 1; 483352284Sobrien break; 483452284Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 483552284Sobrien /* RELOAD_FOR_OPERAND_ADDRESS reloads are live even while the insn 483652284Sobrien is executed. */ 483752284Sobrien time1 = copy ? MAX_RECOG_OPERANDS * 4 + 2 : MAX_RECOG_OPERANDS * 4 + 3; 483852284Sobrien break; 483952284Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 484052284Sobrien time1 = MAX_RECOG_OPERANDS * 4 + 4 + opnum; 484152284Sobrien break; 484250397Sobrien case RELOAD_FOR_OUTPUT_ADDRESS: 484352284Sobrien time1 = MAX_RECOG_OPERANDS * 4 + 5 + opnum; 484450397Sobrien break; 484550397Sobrien default: 484652284Sobrien time1 = MAX_RECOG_OPERANDS * 5 + 5; 484750397Sobrien } 484850397Sobrien 484950397Sobrien for (i = 0; i < n_reloads; i++) 485050397Sobrien { 485190075Sobrien rtx reg = rld[i].reg_rtx; 485250397Sobrien if (reg && GET_CODE (reg) == REG 485350397Sobrien && ((unsigned) regno - true_regnum (reg) 485490075Sobrien <= HARD_REGNO_NREGS (REGNO (reg), GET_MODE (reg)) - (unsigned) 1) 485550397Sobrien && i != reloadnum) 485650397Sobrien { 485790075Sobrien rtx other_input = rld[i].in; 485890075Sobrien 485990075Sobrien /* If the other reload loads the same input value, that 486090075Sobrien will not cause a conflict only if it's loading it into 486190075Sobrien the same register. */ 486290075Sobrien if (true_regnum (reg) != start_regno) 486390075Sobrien other_input = NULL_RTX; 486490075Sobrien if (! other_input || ! rtx_equal_p (other_input, value) 486590075Sobrien || rld[i].out || out) 486650397Sobrien { 486750397Sobrien int time2; 486890075Sobrien switch (rld[i].when_needed) 486950397Sobrien { 487050397Sobrien case RELOAD_FOR_OTHER_ADDRESS: 487150397Sobrien time2 = 0; 487250397Sobrien break; 487350397Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 487452284Sobrien /* find_reloads makes sure that a 487552284Sobrien RELOAD_FOR_{INP,OP,OUT}ADDR_ADDRESS reload is only used 487652284Sobrien by at most one - the first - 487752284Sobrien RELOAD_FOR_{INPUT,OPERAND,OUTPUT}_ADDRESS . If the 487852284Sobrien address reload is inherited, the address address reload 487952284Sobrien goes away, so we can ignore this conflict. */ 488052284Sobrien if (type == RELOAD_FOR_INPUT_ADDRESS && reloadnum == i + 1 488152284Sobrien && ignore_address_reloads 488252284Sobrien /* Unless the RELOAD_FOR_INPUT is an auto_inc expression. 488352284Sobrien Then the address address is still needed to store 488452284Sobrien back the new address. */ 488590075Sobrien && ! rld[reloadnum].out) 488652284Sobrien continue; 488752284Sobrien /* Likewise, if a RELOAD_FOR_INPUT can inherit a value, its 488852284Sobrien RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS 488952284Sobrien reloads go away. */ 489090075Sobrien if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum 489152284Sobrien && ignore_address_reloads 489252284Sobrien /* Unless we are reloading an auto_inc expression. */ 489390075Sobrien && ! rld[reloadnum].out) 489452284Sobrien continue; 489590075Sobrien time2 = rld[i].opnum * 4 + 2; 489650397Sobrien break; 489750397Sobrien case RELOAD_FOR_INPUT_ADDRESS: 489890075Sobrien if (type == RELOAD_FOR_INPUT && opnum == rld[i].opnum 489952284Sobrien && ignore_address_reloads 490090075Sobrien && ! rld[reloadnum].out) 490152284Sobrien continue; 490290075Sobrien time2 = rld[i].opnum * 4 + 3; 490350397Sobrien break; 490450397Sobrien case RELOAD_FOR_INPUT: 490590075Sobrien time2 = rld[i].opnum * 4 + 4; 490670635Sobrien check_earlyclobber = 1; 490750397Sobrien break; 490890075Sobrien /* rld[i].opnum * 4 + 4 <= (MAX_RECOG_OPERAND - 1) * 4 + 4 490990075Sobrien == MAX_RECOG_OPERAND * 4 */ 491052284Sobrien case RELOAD_FOR_OPADDR_ADDR: 491152284Sobrien if (type == RELOAD_FOR_OPERAND_ADDRESS && reloadnum == i + 1 491252284Sobrien && ignore_address_reloads 491390075Sobrien && ! rld[reloadnum].out) 491452284Sobrien continue; 491552284Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 1; 491652284Sobrien break; 491752284Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 491852284Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 2; 491970635Sobrien check_earlyclobber = 1; 492052284Sobrien break; 492152284Sobrien case RELOAD_FOR_INSN: 492252284Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 3; 492352284Sobrien break; 492450397Sobrien case RELOAD_FOR_OUTPUT: 492590075Sobrien /* All RELOAD_FOR_OUTPUT reloads become live just after the 492690075Sobrien instruction is executed. */ 492752284Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 4; 492850397Sobrien break; 492990075Sobrien /* The first RELOAD_FOR_OUTADDR_ADDRESS reload conflicts with 493090075Sobrien the RELOAD_FOR_OUTPUT reloads, so assign it the same time 493190075Sobrien value. */ 493252284Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 493352284Sobrien if (type == RELOAD_FOR_OUTPUT_ADDRESS && reloadnum == i + 1 493452284Sobrien && ignore_address_reloads 493590075Sobrien && ! rld[reloadnum].out) 493652284Sobrien continue; 493790075Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 4 + rld[i].opnum; 493852284Sobrien break; 493950397Sobrien case RELOAD_FOR_OUTPUT_ADDRESS: 494090075Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 5 + rld[i].opnum; 494150397Sobrien break; 494250397Sobrien case RELOAD_OTHER: 494352284Sobrien /* If there is no conflict in the input part, handle this 494452284Sobrien like an output reload. */ 494590075Sobrien if (! rld[i].in || rtx_equal_p (other_input, value)) 494650397Sobrien { 494752284Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 4; 494870635Sobrien /* Earlyclobbered outputs must conflict with inputs. */ 494990075Sobrien if (earlyclobber_operand_p (rld[i].out)) 495070635Sobrien time2 = MAX_RECOG_OPERANDS * 4 + 3; 495190075Sobrien 495250397Sobrien break; 495350397Sobrien } 495452284Sobrien time2 = 1; 495552284Sobrien /* RELOAD_OTHER might be live beyond instruction execution, 495652284Sobrien but this is not obvious when we set time2 = 1. So check 495752284Sobrien here if there might be a problem with the new reload 495852284Sobrien clobbering the register used by the RELOAD_OTHER. */ 495952284Sobrien if (out) 496052284Sobrien return 0; 496152284Sobrien break; 496250397Sobrien default: 496352284Sobrien return 0; 496450397Sobrien } 496552284Sobrien if ((time1 >= time2 496690075Sobrien && (! rld[i].in || rld[i].out 496790075Sobrien || ! rtx_equal_p (other_input, value))) 496890075Sobrien || (out && rld[reloadnum].out_reg 496952284Sobrien && time2 >= MAX_RECOG_OPERANDS * 4 + 3)) 497050397Sobrien return 0; 497150397Sobrien } 497250397Sobrien } 497350397Sobrien } 497470635Sobrien 497570635Sobrien /* Earlyclobbered outputs must conflict with inputs. */ 497670635Sobrien if (check_earlyclobber && out && earlyclobber_operand_p (out)) 497770635Sobrien return 0; 497870635Sobrien 497950397Sobrien return 1; 498050397Sobrien} 498150397Sobrien 498270635Sobrien/* Return 1 if the value in reload reg REGNO, as used by a reload 498370635Sobrien needed for the part of the insn specified by OPNUM and TYPE, 498470635Sobrien may be used to load VALUE into it. 498570635Sobrien 498670635Sobrien MODE is the mode in which the register is used, this is needed to 498770635Sobrien determine how many hard regs to test. 498870635Sobrien 498970635Sobrien Other read-only reloads with the same value do not conflict 499070635Sobrien unless OUT is non-zero and these other reloads have to live while 499170635Sobrien output reloads live. 499270635Sobrien If OUT is CONST0_RTX, this is a special case: it means that the 499370635Sobrien test should not be for using register REGNO as reload register, but 499470635Sobrien for copying from register REGNO into the reload register. 499570635Sobrien 499670635Sobrien RELOADNUM is the number of the reload we want to load this value for; 499770635Sobrien a reload does not conflict with itself. 499870635Sobrien 499970635Sobrien When IGNORE_ADDRESS_RELOADS is set, we can not have conflicts with 500070635Sobrien reloads that load an address for the very reload we are considering. 500170635Sobrien 500270635Sobrien The caller has to make sure that there is no conflict with the return 500370635Sobrien register. */ 500470635Sobrien 500570635Sobrienstatic int 500670635Sobrienfree_for_value_p (regno, mode, opnum, type, value, out, reloadnum, 500770635Sobrien ignore_address_reloads) 500870635Sobrien int regno; 500970635Sobrien enum machine_mode mode; 501070635Sobrien int opnum; 501170635Sobrien enum reload_type type; 501270635Sobrien rtx value, out; 501370635Sobrien int reloadnum; 501470635Sobrien int ignore_address_reloads; 501570635Sobrien{ 501670635Sobrien int nregs = HARD_REGNO_NREGS (regno, mode); 501770635Sobrien while (nregs-- > 0) 501890075Sobrien if (! reload_reg_free_for_value_p (regno, regno + nregs, opnum, type, 501990075Sobrien value, out, reloadnum, 502090075Sobrien ignore_address_reloads)) 502170635Sobrien return 0; 502270635Sobrien return 1; 502370635Sobrien} 502470635Sobrien 502570635Sobrien/* Determine whether the reload reg X overlaps any rtx'es used for 502670635Sobrien overriding inheritance. Return nonzero if so. */ 502770635Sobrien 502870635Sobrienstatic int 502970635Sobrienconflicts_with_override (x) 503070635Sobrien rtx x; 503170635Sobrien{ 503270635Sobrien int i; 503370635Sobrien for (i = 0; i < n_reloads; i++) 503470635Sobrien if (reload_override_in[i] 503570635Sobrien && reg_overlap_mentioned_p (x, reload_override_in[i])) 503670635Sobrien return 1; 503770635Sobrien return 0; 503870635Sobrien} 503990075Sobrien 504090075Sobrien/* Give an error message saying we failed to find a reload for INSN, 504190075Sobrien and clear out reload R. */ 504290075Sobrienstatic void 504390075Sobrienfailed_reload (insn, r) 504490075Sobrien rtx insn; 504590075Sobrien int r; 504690075Sobrien{ 504790075Sobrien if (asm_noperands (PATTERN (insn)) < 0) 504890075Sobrien /* It's the compiler's fault. */ 504990075Sobrien fatal_insn ("could not find a spill register", insn); 505070635Sobrien 505190075Sobrien /* It's the user's fault; the operand's mode and constraint 505290075Sobrien don't match. Disable this reload so we don't crash in final. */ 505390075Sobrien error_for_asm (insn, 505490075Sobrien "`asm' operand constraint incompatible with operand size"); 505590075Sobrien rld[r].in = 0; 505690075Sobrien rld[r].out = 0; 505790075Sobrien rld[r].reg_rtx = 0; 505890075Sobrien rld[r].optional = 1; 505990075Sobrien rld[r].secondary_p = 1; 506090075Sobrien} 506190075Sobrien 506290075Sobrien/* I is the index in SPILL_REG_RTX of the reload register we are to allocate 506390075Sobrien for reload R. If it's valid, get an rtx for it. Return nonzero if 506490075Sobrien successful. */ 506590075Sobrienstatic int 506690075Sobrienset_reload_reg (i, r) 506790075Sobrien int i, r; 506890075Sobrien{ 506990075Sobrien int regno; 507090075Sobrien rtx reg = spill_reg_rtx[i]; 507190075Sobrien 507290075Sobrien if (reg == 0 || GET_MODE (reg) != rld[r].mode) 507390075Sobrien spill_reg_rtx[i] = reg 507490075Sobrien = gen_rtx_REG (rld[r].mode, spill_regs[i]); 507590075Sobrien 507690075Sobrien regno = true_regnum (reg); 507790075Sobrien 507890075Sobrien /* Detect when the reload reg can't hold the reload mode. 507990075Sobrien This used to be one `if', but Sequent compiler can't handle that. */ 508090075Sobrien if (HARD_REGNO_MODE_OK (regno, rld[r].mode)) 508190075Sobrien { 508290075Sobrien enum machine_mode test_mode = VOIDmode; 508390075Sobrien if (rld[r].in) 508490075Sobrien test_mode = GET_MODE (rld[r].in); 508590075Sobrien /* If rld[r].in has VOIDmode, it means we will load it 508690075Sobrien in whatever mode the reload reg has: to wit, rld[r].mode. 508790075Sobrien We have already tested that for validity. */ 508890075Sobrien /* Aside from that, we need to test that the expressions 508990075Sobrien to reload from or into have modes which are valid for this 509090075Sobrien reload register. Otherwise the reload insns would be invalid. */ 509190075Sobrien if (! (rld[r].in != 0 && test_mode != VOIDmode 509290075Sobrien && ! HARD_REGNO_MODE_OK (regno, test_mode))) 509390075Sobrien if (! (rld[r].out != 0 509490075Sobrien && ! HARD_REGNO_MODE_OK (regno, GET_MODE (rld[r].out)))) 509590075Sobrien { 509690075Sobrien /* The reg is OK. */ 509790075Sobrien last_spill_reg = i; 509890075Sobrien 509990075Sobrien /* Mark as in use for this insn the reload regs we use 510090075Sobrien for this. */ 510190075Sobrien mark_reload_reg_in_use (spill_regs[i], rld[r].opnum, 510290075Sobrien rld[r].when_needed, rld[r].mode); 510390075Sobrien 510490075Sobrien rld[r].reg_rtx = reg; 510590075Sobrien reload_spill_index[r] = spill_regs[i]; 510690075Sobrien return 1; 510790075Sobrien } 510890075Sobrien } 510990075Sobrien return 0; 511090075Sobrien} 511190075Sobrien 511218334Speter/* Find a spill register to use as a reload register for reload R. 511318334Speter LAST_RELOAD is non-zero if this is the last reload for the insn being 511418334Speter processed. 511518334Speter 511690075Sobrien Set rld[R].reg_rtx to the register allocated. 511718334Speter 511890075Sobrien We return 1 if successful, or 0 if we couldn't find a spill reg and 511990075Sobrien we didn't change anything. */ 512018334Speter 512118334Speterstatic int 512290075Sobrienallocate_reload_reg (chain, r, last_reload) 512390075Sobrien struct insn_chain *chain ATTRIBUTE_UNUSED; 512418334Speter int r; 512518334Speter int last_reload; 512618334Speter{ 512790075Sobrien int i, pass, count; 512818334Speter 512918334Speter /* If we put this reload ahead, thinking it is a group, 513018334Speter then insist on finding a group. Otherwise we can grab a 513118334Speter reg that some other reload needs. 513218334Speter (That can happen when we have a 68000 DATA_OR_FP_REG 513318334Speter which is a group of data regs or one fp reg.) 513418334Speter We need not be so restrictive if there are no more reloads 513518334Speter for this insn. 513618334Speter 513718334Speter ??? Really it would be nicer to have smarter handling 513818334Speter for that kind of reg class, where a problem like this is normal. 513918334Speter Perhaps those classes should be avoided for reloading 514018334Speter by use of more alternatives. */ 514118334Speter 514290075Sobrien int force_group = rld[r].nregs > 1 && ! last_reload; 514318334Speter 514418334Speter /* If we want a single register and haven't yet found one, 514518334Speter take any reg in the right class and not in use. 514618334Speter If we want a consecutive group, here is where we look for it. 514718334Speter 514818334Speter We use two passes so we can first look for reload regs to 514918334Speter reuse, which are already in use for other reloads in this insn, 515018334Speter and only then use additional registers. 515118334Speter I think that maximizing reuse is needed to make sure we don't 515218334Speter run out of reload regs. Suppose we have three reloads, and 515318334Speter reloads A and B can share regs. These need two regs. 515418334Speter Suppose A and B are given different regs. 515518334Speter That leaves none for C. */ 515618334Speter for (pass = 0; pass < 2; pass++) 515718334Speter { 515818334Speter /* I is the index in spill_regs. 515918334Speter We advance it round-robin between insns to use all spill regs 516018334Speter equally, so that inherited reloads have a chance 516190075Sobrien of leapfrogging each other. */ 516218334Speter 516390075Sobrien i = last_spill_reg; 516490075Sobrien 516518334Speter for (count = 0; count < n_spills; count++) 516618334Speter { 516790075Sobrien int class = (int) rld[r].class; 516852284Sobrien int regnum; 516918334Speter 517052284Sobrien i++; 517152284Sobrien if (i >= n_spills) 517252284Sobrien i -= n_spills; 517352284Sobrien regnum = spill_regs[i]; 517418334Speter 517590075Sobrien if ((reload_reg_free_p (regnum, rld[r].opnum, 517690075Sobrien rld[r].when_needed) 517790075Sobrien || (rld[r].in 517890075Sobrien /* We check reload_reg_used to make sure we 517990075Sobrien don't clobber the return register. */ 518052284Sobrien && ! TEST_HARD_REG_BIT (reload_reg_used, regnum) 518190075Sobrien && free_for_value_p (regnum, rld[r].mode, rld[r].opnum, 518290075Sobrien rld[r].when_needed, rld[r].in, 518390075Sobrien rld[r].out, r, 1))) 518452284Sobrien && TEST_HARD_REG_BIT (reg_class_contents[class], regnum) 518590075Sobrien && HARD_REGNO_MODE_OK (regnum, rld[r].mode) 518618334Speter /* Look first for regs to share, then for unshared. But 518718334Speter don't share regs used for inherited reloads; they are 518818334Speter the ones we want to preserve. */ 518918334Speter && (pass 519018334Speter || (TEST_HARD_REG_BIT (reload_reg_used_at_all, 519152284Sobrien regnum) 519218334Speter && ! TEST_HARD_REG_BIT (reload_reg_used_for_inherit, 519352284Sobrien regnum)))) 519418334Speter { 519590075Sobrien int nr = HARD_REGNO_NREGS (regnum, rld[r].mode); 519618334Speter /* Avoid the problem where spilling a GENERAL_OR_FP_REG 519718334Speter (on 68000) got us two FP regs. If NR is 1, 519818334Speter we would reject both of them. */ 519918334Speter if (force_group) 520090075Sobrien nr = rld[r].nregs; 520118334Speter /* If we need only one reg, we have already won. */ 520218334Speter if (nr == 1) 520318334Speter { 520418334Speter /* But reject a single reg if we demand a group. */ 520518334Speter if (force_group) 520618334Speter continue; 520718334Speter break; 520818334Speter } 520918334Speter /* Otherwise check that as many consecutive regs as we need 521090075Sobrien are available here. */ 521190075Sobrien while (nr > 1) 521290075Sobrien { 521390075Sobrien int regno = regnum + nr - 1; 521490075Sobrien if (!(TEST_HARD_REG_BIT (reg_class_contents[class], regno) 521590075Sobrien && spill_reg_order[regno] >= 0 521690075Sobrien && reload_reg_free_p (regno, rld[r].opnum, 521790075Sobrien rld[r].when_needed))) 521890075Sobrien break; 521990075Sobrien nr--; 522090075Sobrien } 522118334Speter if (nr == 1) 522218334Speter break; 522318334Speter } 522418334Speter } 522518334Speter 522618334Speter /* If we found something on pass 1, omit pass 2. */ 522718334Speter if (count < n_spills) 522818334Speter break; 522918334Speter } 523018334Speter 523118334Speter /* We should have found a spill register by now. */ 523290075Sobrien if (count >= n_spills) 523390075Sobrien return 0; 523418334Speter 523518334Speter /* I is the index in SPILL_REG_RTX of the reload register we are to 523618334Speter allocate. Get an rtx for it and find its register number. */ 523718334Speter 523890075Sobrien return set_reload_reg (i, r); 523918334Speter} 524018334Speter 524190075Sobrien/* Initialize all the tables needed to allocate reload registers. 524290075Sobrien CHAIN is the insn currently being processed; SAVE_RELOAD_REG_RTX 524390075Sobrien is the array we use to restore the reg_rtx field for every reload. */ 524418334Speter 524518334Speterstatic void 524690075Sobrienchoose_reload_regs_init (chain, save_reload_reg_rtx) 524752284Sobrien struct insn_chain *chain; 524890075Sobrien rtx *save_reload_reg_rtx; 524918334Speter{ 525090075Sobrien int i; 525118334Speter 525290075Sobrien for (i = 0; i < n_reloads; i++) 525390075Sobrien rld[i].reg_rtx = save_reload_reg_rtx[i]; 525418334Speter 525590075Sobrien memset (reload_inherited, 0, MAX_RELOADS); 525690075Sobrien memset ((char *) reload_inheritance_insn, 0, MAX_RELOADS * sizeof (rtx)); 525790075Sobrien memset ((char *) reload_override_in, 0, MAX_RELOADS * sizeof (rtx)); 525818334Speter 525918334Speter CLEAR_HARD_REG_SET (reload_reg_used); 526018334Speter CLEAR_HARD_REG_SET (reload_reg_used_at_all); 526118334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr); 526218334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_op_addr_reload); 526318334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_insn); 526418334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_other_addr); 526518334Speter 526652284Sobrien CLEAR_HARD_REG_SET (reg_used_in_insn); 526752284Sobrien { 526852284Sobrien HARD_REG_SET tmp; 526990075Sobrien REG_SET_TO_HARD_REG_SET (tmp, &chain->live_throughout); 527052284Sobrien IOR_HARD_REG_SET (reg_used_in_insn, tmp); 527190075Sobrien REG_SET_TO_HARD_REG_SET (tmp, &chain->dead_or_set); 527252284Sobrien IOR_HARD_REG_SET (reg_used_in_insn, tmp); 527390075Sobrien compute_use_by_pseudos (®_used_in_insn, &chain->live_throughout); 527490075Sobrien compute_use_by_pseudos (®_used_in_insn, &chain->dead_or_set); 527552284Sobrien } 527690075Sobrien 527718334Speter for (i = 0; i < reload_n_operands; i++) 527818334Speter { 527918334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_output[i]); 528018334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_input[i]); 528118334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_input_addr[i]); 528250397Sobrien CLEAR_HARD_REG_SET (reload_reg_used_in_inpaddr_addr[i]); 528318334Speter CLEAR_HARD_REG_SET (reload_reg_used_in_output_addr[i]); 528450397Sobrien CLEAR_HARD_REG_SET (reload_reg_used_in_outaddr_addr[i]); 528518334Speter } 528618334Speter 528770635Sobrien COMPL_HARD_REG_SET (reload_reg_unavailable, chain->used_spill_regs); 528818334Speter 528990075Sobrien CLEAR_HARD_REG_SET (reload_reg_used_for_inherit); 529018334Speter 529190075Sobrien for (i = 0; i < n_reloads; i++) 529290075Sobrien /* If we have already decided to use a certain register, 529390075Sobrien don't use it in another way. */ 529490075Sobrien if (rld[i].reg_rtx) 529590075Sobrien mark_reload_reg_in_use (REGNO (rld[i].reg_rtx), rld[i].opnum, 529690075Sobrien rld[i].when_needed, rld[i].mode); 529790075Sobrien} 529818334Speter 529990075Sobrien/* Assign hard reg targets for the pseudo-registers we must reload 530090075Sobrien into hard regs for this insn. 530190075Sobrien Also output the instructions to copy them in and out of the hard regs. 530290075Sobrien 530390075Sobrien For machines with register classes, we are responsible for 530490075Sobrien finding a reload reg in the proper class. */ 530590075Sobrien 530690075Sobrienstatic void 530790075Sobrienchoose_reload_regs (chain) 530890075Sobrien struct insn_chain *chain; 530990075Sobrien{ 531090075Sobrien rtx insn = chain->insn; 531190075Sobrien int i, j; 531290075Sobrien unsigned int max_group_size = 1; 531390075Sobrien enum reg_class group_class = NO_REGS; 531490075Sobrien int pass, win, inheritance; 531590075Sobrien 531690075Sobrien rtx save_reload_reg_rtx[MAX_RELOADS]; 531790075Sobrien 531818334Speter /* In order to be certain of getting the registers we need, 531918334Speter we must sort the reloads into order of increasing register class. 532018334Speter Then our grabbing of reload registers will parallel the process 532118334Speter that provided the reload registers. 532218334Speter 532318334Speter Also note whether any of the reloads wants a consecutive group of regs. 532418334Speter If so, record the maximum size of the group desired and what 532518334Speter register class contains all the groups needed by this insn. */ 532618334Speter 532718334Speter for (j = 0; j < n_reloads; j++) 532818334Speter { 532918334Speter reload_order[j] = j; 533018334Speter reload_spill_index[j] = -1; 533118334Speter 533290075Sobrien if (rld[j].nregs > 1) 533318334Speter { 533490075Sobrien max_group_size = MAX (rld[j].nregs, max_group_size); 533590075Sobrien group_class 533690075Sobrien = reg_class_superunion[(int) rld[j].class][(int) group_class]; 533718334Speter } 533818334Speter 533990075Sobrien save_reload_reg_rtx[j] = rld[j].reg_rtx; 534018334Speter } 534118334Speter 534218334Speter if (n_reloads > 1) 534318334Speter qsort (reload_order, n_reloads, sizeof (short), reload_reg_class_lower); 534418334Speter 534518334Speter /* If -O, try first with inheritance, then turning it off. 534618334Speter If not -O, don't do inheritance. 534718334Speter Using inheritance when not optimizing leads to paradoxes 534818334Speter with fp on the 68k: fp numbers (not NaNs) fail to be equal to themselves 534918334Speter because one side of the comparison might be inherited. */ 535090075Sobrien win = 0; 535118334Speter for (inheritance = optimize > 0; inheritance >= 0; inheritance--) 535218334Speter { 535390075Sobrien choose_reload_regs_init (chain, save_reload_reg_rtx); 535490075Sobrien 535518334Speter /* Process the reloads in order of preference just found. 535618334Speter Beyond this point, subregs can be found in reload_reg_rtx. 535718334Speter 535890075Sobrien This used to look for an existing reloaded home for all of the 535990075Sobrien reloads, and only then perform any new reloads. But that could lose 536090075Sobrien if the reloads were done out of reg-class order because a later 536190075Sobrien reload with a looser constraint might have an old home in a register 536290075Sobrien needed by an earlier reload with a tighter constraint. 536318334Speter 536418334Speter To solve this, we make two passes over the reloads, in the order 536518334Speter described above. In the first pass we try to inherit a reload 536618334Speter from a previous insn. If there is a later reload that needs a 536718334Speter class that is a proper subset of the class being processed, we must 536818334Speter also allocate a spill register during the first pass. 536918334Speter 537018334Speter Then make a second pass over the reloads to allocate any reloads 537118334Speter that haven't been given registers yet. */ 537218334Speter 537318334Speter for (j = 0; j < n_reloads; j++) 537418334Speter { 537590075Sobrien int r = reload_order[j]; 537652284Sobrien rtx search_equiv = NULL_RTX; 537718334Speter 537818334Speter /* Ignore reloads that got marked inoperative. */ 537990075Sobrien if (rld[r].out == 0 && rld[r].in == 0 538090075Sobrien && ! rld[r].secondary_p) 538118334Speter continue; 538218334Speter 538352284Sobrien /* If find_reloads chose to use reload_in or reload_out as a reload 538450397Sobrien register, we don't need to chose one. Otherwise, try even if it 538550397Sobrien found one since we might save an insn if we find the value lying 538652284Sobrien around. 538752284Sobrien Try also when reload_in is a pseudo without a hard reg. */ 538890075Sobrien if (rld[r].in != 0 && rld[r].reg_rtx != 0 538990075Sobrien && (rtx_equal_p (rld[r].in, rld[r].reg_rtx) 539090075Sobrien || (rtx_equal_p (rld[r].out, rld[r].reg_rtx) 539190075Sobrien && GET_CODE (rld[r].in) != MEM 539290075Sobrien && true_regnum (rld[r].in) < FIRST_PSEUDO_REGISTER))) 539318334Speter continue; 539418334Speter 539518334Speter#if 0 /* No longer needed for correct operation. 539618334Speter It might give better code, or might not; worth an experiment? */ 539718334Speter /* If this is an optional reload, we can't inherit from earlier insns 539818334Speter until we are sure that any non-optional reloads have been allocated. 539918334Speter The following code takes advantage of the fact that optional reloads 540018334Speter are at the end of reload_order. */ 540190075Sobrien if (rld[r].optional != 0) 540218334Speter for (i = 0; i < j; i++) 540390075Sobrien if ((rld[reload_order[i]].out != 0 540490075Sobrien || rld[reload_order[i]].in != 0 540590075Sobrien || rld[reload_order[i]].secondary_p) 540690075Sobrien && ! rld[reload_order[i]].optional 540790075Sobrien && rld[reload_order[i]].reg_rtx == 0) 540890075Sobrien allocate_reload_reg (chain, reload_order[i], 0); 540918334Speter#endif 541018334Speter 541118334Speter /* First see if this pseudo is already available as reloaded 541218334Speter for a previous insn. We cannot try to inherit for reloads 541318334Speter that are smaller than the maximum number of registers needed 541418334Speter for groups unless the register we would allocate cannot be used 541518334Speter for the groups. 541618334Speter 541718334Speter We could check here to see if this is a secondary reload for 541818334Speter an object that is already in a register of the desired class. 541918334Speter This would avoid the need for the secondary reload register. 542018334Speter But this is complex because we can't easily determine what 542150397Sobrien objects might want to be loaded via this reload. So let a 542250397Sobrien register be allocated here. In `emit_reload_insns' we suppress 542350397Sobrien one of the loads in the case described above. */ 542418334Speter 542518334Speter if (inheritance) 542618334Speter { 542790075Sobrien int byte = 0; 542890075Sobrien int regno = -1; 542990075Sobrien enum machine_mode mode = VOIDmode; 543018334Speter 543190075Sobrien if (rld[r].in == 0) 543218334Speter ; 543390075Sobrien else if (GET_CODE (rld[r].in) == REG) 543418334Speter { 543590075Sobrien regno = REGNO (rld[r].in); 543690075Sobrien mode = GET_MODE (rld[r].in); 543718334Speter } 543890075Sobrien else if (GET_CODE (rld[r].in_reg) == REG) 543918334Speter { 544090075Sobrien regno = REGNO (rld[r].in_reg); 544190075Sobrien mode = GET_MODE (rld[r].in_reg); 544218334Speter } 544390075Sobrien else if (GET_CODE (rld[r].in_reg) == SUBREG 544490075Sobrien && GET_CODE (SUBREG_REG (rld[r].in_reg)) == REG) 544550397Sobrien { 544690075Sobrien byte = SUBREG_BYTE (rld[r].in_reg); 544790075Sobrien regno = REGNO (SUBREG_REG (rld[r].in_reg)); 544852284Sobrien if (regno < FIRST_PSEUDO_REGISTER) 544990075Sobrien regno = subreg_regno (rld[r].in_reg); 545090075Sobrien mode = GET_MODE (rld[r].in_reg); 545150397Sobrien } 545252284Sobrien#ifdef AUTO_INC_DEC 545390075Sobrien else if ((GET_CODE (rld[r].in_reg) == PRE_INC 545490075Sobrien || GET_CODE (rld[r].in_reg) == PRE_DEC 545590075Sobrien || GET_CODE (rld[r].in_reg) == POST_INC 545690075Sobrien || GET_CODE (rld[r].in_reg) == POST_DEC) 545790075Sobrien && GET_CODE (XEXP (rld[r].in_reg, 0)) == REG) 545852284Sobrien { 545990075Sobrien regno = REGNO (XEXP (rld[r].in_reg, 0)); 546090075Sobrien mode = GET_MODE (XEXP (rld[r].in_reg, 0)); 546190075Sobrien rld[r].out = rld[r].in; 546252284Sobrien } 546352284Sobrien#endif 546418334Speter#if 0 546518334Speter /* This won't work, since REGNO can be a pseudo reg number. 546618334Speter Also, it takes much more hair to keep track of all the things 546718334Speter that can invalidate an inherited reload of part of a pseudoreg. */ 546890075Sobrien else if (GET_CODE (rld[r].in) == SUBREG 546990075Sobrien && GET_CODE (SUBREG_REG (rld[r].in)) == REG) 547090075Sobrien regno = subreg_regno (rld[r].in); 547118334Speter#endif 547218334Speter 547318334Speter if (regno >= 0 && reg_last_reload_reg[regno] != 0) 547418334Speter { 547590075Sobrien enum reg_class class = rld[r].class, last_class; 547652284Sobrien rtx last_reg = reg_last_reload_reg[regno]; 547790075Sobrien enum machine_mode need_mode; 547890075Sobrien 547990075Sobrien i = REGNO (last_reg); 548090075Sobrien i += subreg_regno_offset (i, GET_MODE (last_reg), byte, mode); 548152284Sobrien last_class = REGNO_REG_CLASS (i); 548290075Sobrien 548390075Sobrien if (byte == 0) 548490075Sobrien need_mode = mode; 548590075Sobrien else 548690075Sobrien need_mode 548790075Sobrien = smallest_mode_for_size (GET_MODE_SIZE (mode) + byte, 548890075Sobrien GET_MODE_CLASS (mode)); 548990075Sobrien 549090075Sobrien if ( 549190075Sobrien#ifdef CLASS_CANNOT_CHANGE_MODE 549290075Sobrien (TEST_HARD_REG_BIT 549390075Sobrien (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE], i) 549490075Sobrien ? ! CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (last_reg), 549590075Sobrien need_mode) 549690075Sobrien : (GET_MODE_SIZE (GET_MODE (last_reg)) 549790075Sobrien >= GET_MODE_SIZE (need_mode))) 549890075Sobrien#else 549990075Sobrien (GET_MODE_SIZE (GET_MODE (last_reg)) 550090075Sobrien >= GET_MODE_SIZE (need_mode)) 550190075Sobrien#endif 550252284Sobrien && reg_reloaded_contents[i] == regno 550350397Sobrien && TEST_HARD_REG_BIT (reg_reloaded_valid, i) 550490075Sobrien && HARD_REGNO_MODE_OK (i, rld[r].mode) 550552284Sobrien && (TEST_HARD_REG_BIT (reg_class_contents[(int) class], i) 550652284Sobrien /* Even if we can't use this register as a reload 550752284Sobrien register, we might use it for reload_override_in, 550852284Sobrien if copying it to the desired class is cheap 550952284Sobrien enough. */ 551090075Sobrien || ((REGISTER_MOVE_COST (mode, last_class, class) 551152284Sobrien < MEMORY_MOVE_COST (mode, class, 1)) 551252284Sobrien#ifdef SECONDARY_INPUT_RELOAD_CLASS 551352284Sobrien && (SECONDARY_INPUT_RELOAD_CLASS (class, mode, 551452284Sobrien last_reg) 551552284Sobrien == NO_REGS) 551652284Sobrien#endif 551752284Sobrien#ifdef SECONDARY_MEMORY_NEEDED 551852284Sobrien && ! SECONDARY_MEMORY_NEEDED (last_class, class, 551952284Sobrien mode) 552052284Sobrien#endif 552152284Sobrien )) 552252284Sobrien 552390075Sobrien && (rld[r].nregs == max_group_size 552418334Speter || ! TEST_HARD_REG_BIT (reg_class_contents[(int) group_class], 552550397Sobrien i)) 552690075Sobrien && free_for_value_p (i, rld[r].mode, rld[r].opnum, 552790075Sobrien rld[r].when_needed, rld[r].in, 552870635Sobrien const0_rtx, r, 1)) 552918334Speter { 553018334Speter /* If a group is needed, verify that all the subsequent 553150397Sobrien registers still have their values intact. */ 553290075Sobrien int nr = HARD_REGNO_NREGS (i, rld[r].mode); 553318334Speter int k; 553418334Speter 553518334Speter for (k = 1; k < nr; k++) 553650397Sobrien if (reg_reloaded_contents[i + k] != regno 553750397Sobrien || ! TEST_HARD_REG_BIT (reg_reloaded_valid, i + k)) 553818334Speter break; 553918334Speter 554018334Speter if (k == nr) 554118334Speter { 554218334Speter int i1; 554390075Sobrien int bad_for_class; 554418334Speter 554552284Sobrien last_reg = (GET_MODE (last_reg) == mode 554652284Sobrien ? last_reg : gen_rtx_REG (mode, i)); 554752284Sobrien 554890075Sobrien bad_for_class = 0; 554990075Sobrien for (k = 0; k < nr; k++) 555090075Sobrien bad_for_class |= ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class], 555190075Sobrien i+k); 555290075Sobrien 555318334Speter /* We found a register that contains the 555418334Speter value we need. If this register is the 555518334Speter same as an `earlyclobber' operand of the 555618334Speter current insn, just mark it as a place to 555718334Speter reload from since we can't use it as the 555818334Speter reload register itself. */ 555918334Speter 556018334Speter for (i1 = 0; i1 < n_earlyclobbers; i1++) 556118334Speter if (reg_overlap_mentioned_for_reload_p 556218334Speter (reg_last_reload_reg[regno], 556318334Speter reload_earlyclobbers[i1])) 556418334Speter break; 556518334Speter 556618334Speter if (i1 != n_earlyclobbers 556790075Sobrien || ! (free_for_value_p (i, rld[r].mode, 556890075Sobrien rld[r].opnum, 556990075Sobrien rld[r].when_needed, rld[r].in, 557090075Sobrien rld[r].out, r, 1)) 557150397Sobrien /* Don't use it if we'd clobber a pseudo reg. */ 557252284Sobrien || (TEST_HARD_REG_BIT (reg_used_in_insn, i) 557390075Sobrien && rld[r].out 557450397Sobrien && ! TEST_HARD_REG_BIT (reg_reloaded_dead, i)) 557552284Sobrien /* Don't clobber the frame pointer. */ 557652284Sobrien || (i == HARD_FRAME_POINTER_REGNUM 557796263Sobrien && frame_pointer_needed 557890075Sobrien && rld[r].out) 557918334Speter /* Don't really use the inherited spill reg 558018334Speter if we need it wider than we've got it. */ 558190075Sobrien || (GET_MODE_SIZE (rld[r].mode) 558252284Sobrien > GET_MODE_SIZE (mode)) 558390075Sobrien || bad_for_class 558452284Sobrien 558552284Sobrien /* If find_reloads chose reload_out as reload 558652284Sobrien register, stay with it - that leaves the 558752284Sobrien inherited register for subsequent reloads. */ 558890075Sobrien || (rld[r].out && rld[r].reg_rtx 558990075Sobrien && rtx_equal_p (rld[r].out, rld[r].reg_rtx))) 559052284Sobrien { 559190075Sobrien if (! rld[r].optional) 559270635Sobrien { 559370635Sobrien reload_override_in[r] = last_reg; 559470635Sobrien reload_inheritance_insn[r] 559570635Sobrien = reg_reloaded_insn[i]; 559670635Sobrien } 559752284Sobrien } 559818334Speter else 559918334Speter { 560018334Speter int k; 560118334Speter /* We can use this as a reload reg. */ 560218334Speter /* Mark the register as in use for this part of 560318334Speter the insn. */ 560450397Sobrien mark_reload_reg_in_use (i, 560590075Sobrien rld[r].opnum, 560690075Sobrien rld[r].when_needed, 560790075Sobrien rld[r].mode); 560890075Sobrien rld[r].reg_rtx = last_reg; 560918334Speter reload_inherited[r] = 1; 561018334Speter reload_inheritance_insn[r] 561118334Speter = reg_reloaded_insn[i]; 561218334Speter reload_spill_index[r] = i; 561318334Speter for (k = 0; k < nr; k++) 561418334Speter SET_HARD_REG_BIT (reload_reg_used_for_inherit, 561550397Sobrien i + k); 561618334Speter } 561718334Speter } 561818334Speter } 561918334Speter } 562018334Speter } 562118334Speter 562218334Speter /* Here's another way to see if the value is already lying around. */ 562318334Speter if (inheritance 562490075Sobrien && rld[r].in != 0 562518334Speter && ! reload_inherited[r] 562690075Sobrien && rld[r].out == 0 562790075Sobrien && (CONSTANT_P (rld[r].in) 562890075Sobrien || GET_CODE (rld[r].in) == PLUS 562990075Sobrien || GET_CODE (rld[r].in) == REG 563090075Sobrien || GET_CODE (rld[r].in) == MEM) 563190075Sobrien && (rld[r].nregs == max_group_size 563290075Sobrien || ! reg_classes_intersect_p (rld[r].class, group_class))) 563390075Sobrien search_equiv = rld[r].in; 563452284Sobrien /* If this is an output reload from a simple move insn, look 563552284Sobrien if an equivalence for the input is available. */ 563690075Sobrien else if (inheritance && rld[r].in == 0 && rld[r].out != 0) 563718334Speter { 563852284Sobrien rtx set = single_set (insn); 563952284Sobrien 564052284Sobrien if (set 564190075Sobrien && rtx_equal_p (rld[r].out, SET_DEST (set)) 564252284Sobrien && CONSTANT_P (SET_SRC (set))) 564352284Sobrien search_equiv = SET_SRC (set); 564452284Sobrien } 564552284Sobrien 564652284Sobrien if (search_equiv) 564752284Sobrien { 564890075Sobrien rtx equiv 564990075Sobrien = find_equiv_reg (search_equiv, insn, rld[r].class, 565090075Sobrien -1, NULL, 0, rld[r].mode); 565190075Sobrien int regno = 0; 565218334Speter 565318334Speter if (equiv != 0) 565418334Speter { 565518334Speter if (GET_CODE (equiv) == REG) 565618334Speter regno = REGNO (equiv); 565718334Speter else if (GET_CODE (equiv) == SUBREG) 565818334Speter { 565918334Speter /* This must be a SUBREG of a hard register. 566018334Speter Make a new REG since this might be used in an 566118334Speter address and not all machines support SUBREGs 566218334Speter there. */ 566390075Sobrien regno = subreg_regno (equiv); 566490075Sobrien equiv = gen_rtx_REG (rld[r].mode, regno); 566518334Speter } 566618334Speter else 566718334Speter abort (); 566818334Speter } 566918334Speter 567018334Speter /* If we found a spill reg, reject it unless it is free 567118334Speter and of the desired class. */ 567218334Speter if (equiv != 0 567352284Sobrien && ((TEST_HARD_REG_BIT (reload_reg_used_at_all, regno) 567490075Sobrien && ! free_for_value_p (regno, rld[r].mode, 567590075Sobrien rld[r].opnum, rld[r].when_needed, 567690075Sobrien rld[r].in, rld[r].out, r, 1)) 567790075Sobrien || ! TEST_HARD_REG_BIT (reg_class_contents[(int) rld[r].class], 567818334Speter regno))) 567918334Speter equiv = 0; 568018334Speter 568190075Sobrien if (equiv != 0 && ! HARD_REGNO_MODE_OK (regno, rld[r].mode)) 568218334Speter equiv = 0; 568318334Speter 568418334Speter /* We found a register that contains the value we need. 568518334Speter If this register is the same as an `earlyclobber' operand 568618334Speter of the current insn, just mark it as a place to reload from 568718334Speter since we can't use it as the reload register itself. */ 568818334Speter 568918334Speter if (equiv != 0) 569018334Speter for (i = 0; i < n_earlyclobbers; i++) 569118334Speter if (reg_overlap_mentioned_for_reload_p (equiv, 569218334Speter reload_earlyclobbers[i])) 569318334Speter { 569490075Sobrien if (! rld[r].optional) 569570635Sobrien reload_override_in[r] = equiv; 569618334Speter equiv = 0; 569718334Speter break; 569818334Speter } 569918334Speter 570050397Sobrien /* If the equiv register we have found is explicitly clobbered 570150397Sobrien in the current insn, it depends on the reload type if we 570250397Sobrien can use it, use it for reload_override_in, or not at all. 570350397Sobrien In particular, we then can't use EQUIV for a 570450397Sobrien RELOAD_FOR_OUTPUT_ADDRESS reload. */ 570518334Speter 570690075Sobrien if (equiv != 0) 570718334Speter { 570890075Sobrien if (regno_clobbered_p (regno, insn, rld[r].mode, 0)) 570990075Sobrien switch (rld[r].when_needed) 571090075Sobrien { 571190075Sobrien case RELOAD_FOR_OTHER_ADDRESS: 571290075Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 571390075Sobrien case RELOAD_FOR_INPUT_ADDRESS: 571490075Sobrien case RELOAD_FOR_OPADDR_ADDR: 571590075Sobrien break; 571690075Sobrien case RELOAD_OTHER: 571790075Sobrien case RELOAD_FOR_INPUT: 571890075Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 571990075Sobrien if (! rld[r].optional) 572090075Sobrien reload_override_in[r] = equiv; 572190075Sobrien /* Fall through. */ 572290075Sobrien default: 572390075Sobrien equiv = 0; 572490075Sobrien break; 572590075Sobrien } 572690075Sobrien else if (regno_clobbered_p (regno, insn, rld[r].mode, 1)) 572790075Sobrien switch (rld[r].when_needed) 572890075Sobrien { 572990075Sobrien case RELOAD_FOR_OTHER_ADDRESS: 573090075Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 573190075Sobrien case RELOAD_FOR_INPUT_ADDRESS: 573290075Sobrien case RELOAD_FOR_OPADDR_ADDR: 573390075Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 573490075Sobrien case RELOAD_FOR_INPUT: 573590075Sobrien break; 573690075Sobrien case RELOAD_OTHER: 573790075Sobrien if (! rld[r].optional) 573890075Sobrien reload_override_in[r] = equiv; 573990075Sobrien /* Fall through. */ 574090075Sobrien default: 574190075Sobrien equiv = 0; 574290075Sobrien break; 574390075Sobrien } 574418334Speter } 574518334Speter 574618334Speter /* If we found an equivalent reg, say no code need be generated 574718334Speter to load it, and use it as our reload reg. */ 574896263Sobrien if (equiv != 0 574996263Sobrien && (regno != HARD_FRAME_POINTER_REGNUM 575096263Sobrien || !frame_pointer_needed)) 575118334Speter { 575290075Sobrien int nr = HARD_REGNO_NREGS (regno, rld[r].mode); 575350397Sobrien int k; 575490075Sobrien rld[r].reg_rtx = equiv; 575518334Speter reload_inherited[r] = 1; 575650397Sobrien 575750397Sobrien /* If reg_reloaded_valid is not set for this register, 575850397Sobrien there might be a stale spill_reg_store lying around. 575950397Sobrien We must clear it, since otherwise emit_reload_insns 576050397Sobrien might delete the store. */ 576150397Sobrien if (! TEST_HARD_REG_BIT (reg_reloaded_valid, regno)) 576250397Sobrien spill_reg_store[regno] = NULL_RTX; 576350397Sobrien /* If any of the hard registers in EQUIV are spill 576450397Sobrien registers, mark them as in use for this insn. */ 576550397Sobrien for (k = 0; k < nr; k++) 576618334Speter { 576750397Sobrien i = spill_reg_order[regno + k]; 576850397Sobrien if (i >= 0) 576950397Sobrien { 577090075Sobrien mark_reload_reg_in_use (regno, rld[r].opnum, 577190075Sobrien rld[r].when_needed, 577290075Sobrien rld[r].mode); 577350397Sobrien SET_HARD_REG_BIT (reload_reg_used_for_inherit, 577450397Sobrien regno + k); 577550397Sobrien } 577618334Speter } 577718334Speter } 577818334Speter } 577918334Speter 578018334Speter /* If we found a register to use already, or if this is an optional 578118334Speter reload, we are done. */ 578290075Sobrien if (rld[r].reg_rtx != 0 || rld[r].optional != 0) 578318334Speter continue; 578418334Speter 578590075Sobrien#if 0 578690075Sobrien /* No longer needed for correct operation. Might or might 578790075Sobrien not give better code on the average. Want to experiment? */ 578818334Speter 578918334Speter /* See if there is a later reload that has a class different from our 579018334Speter class that intersects our class or that requires less register 579118334Speter than our reload. If so, we must allocate a register to this 579218334Speter reload now, since that reload might inherit a previous reload 579318334Speter and take the only available register in our class. Don't do this 579418334Speter for optional reloads since they will force all previous reloads 579518334Speter to be allocated. Also don't do this for reloads that have been 579618334Speter turned off. */ 579718334Speter 579818334Speter for (i = j + 1; i < n_reloads; i++) 579918334Speter { 580018334Speter int s = reload_order[i]; 580118334Speter 580290075Sobrien if ((rld[s].in == 0 && rld[s].out == 0 580390075Sobrien && ! rld[s].secondary_p) 580490075Sobrien || rld[s].optional) 580518334Speter continue; 580618334Speter 580790075Sobrien if ((rld[s].class != rld[r].class 580890075Sobrien && reg_classes_intersect_p (rld[r].class, 580990075Sobrien rld[s].class)) 581090075Sobrien || rld[s].nregs < rld[r].nregs) 581190075Sobrien break; 581218334Speter } 581318334Speter 581418334Speter if (i == n_reloads) 581518334Speter continue; 581618334Speter 581790075Sobrien allocate_reload_reg (chain, r, j == n_reloads - 1); 581818334Speter#endif 581918334Speter } 582018334Speter 582118334Speter /* Now allocate reload registers for anything non-optional that 582218334Speter didn't get one yet. */ 582318334Speter for (j = 0; j < n_reloads; j++) 582418334Speter { 582590075Sobrien int r = reload_order[j]; 582618334Speter 582718334Speter /* Ignore reloads that got marked inoperative. */ 582890075Sobrien if (rld[r].out == 0 && rld[r].in == 0 && ! rld[r].secondary_p) 582918334Speter continue; 583018334Speter 583118334Speter /* Skip reloads that already have a register allocated or are 583250397Sobrien optional. */ 583390075Sobrien if (rld[r].reg_rtx != 0 || rld[r].optional) 583418334Speter continue; 583518334Speter 583690075Sobrien if (! allocate_reload_reg (chain, r, j == n_reloads - 1)) 583718334Speter break; 583818334Speter } 583918334Speter 584018334Speter /* If that loop got all the way, we have won. */ 584118334Speter if (j == n_reloads) 584290075Sobrien { 584390075Sobrien win = 1; 584490075Sobrien break; 584590075Sobrien } 584618334Speter 584718334Speter /* Loop around and try without any inheritance. */ 584890075Sobrien } 584990075Sobrien 585090075Sobrien if (! win) 585190075Sobrien { 585218334Speter /* First undo everything done by the failed attempt 585318334Speter to allocate with inheritance. */ 585490075Sobrien choose_reload_regs_init (chain, save_reload_reg_rtx); 585518334Speter 585690075Sobrien /* Some sanity tests to verify that the reloads found in the first 585790075Sobrien pass are identical to the ones we have now. */ 585890075Sobrien if (chain->n_reloads != n_reloads) 585990075Sobrien abort (); 586090075Sobrien 586190075Sobrien for (i = 0; i < n_reloads; i++) 586218334Speter { 586390075Sobrien if (chain->rld[i].regno < 0 || chain->rld[i].reg_rtx != 0) 586490075Sobrien continue; 586590075Sobrien if (chain->rld[i].when_needed != rld[i].when_needed) 586690075Sobrien abort (); 586790075Sobrien for (j = 0; j < n_spills; j++) 586890075Sobrien if (spill_regs[j] == chain->rld[i].regno) 586990075Sobrien if (! set_reload_reg (j, i)) 587090075Sobrien failed_reload (chain->insn, i); 587118334Speter } 587218334Speter } 587318334Speter 587418334Speter /* If we thought we could inherit a reload, because it seemed that 587518334Speter nothing else wanted the same reload register earlier in the insn, 587652284Sobrien verify that assumption, now that all reloads have been assigned. 587752284Sobrien Likewise for reloads where reload_override_in has been set. */ 587818334Speter 587952284Sobrien /* If doing expensive optimizations, do one preliminary pass that doesn't 588052284Sobrien cancel any inheritance, but removes reloads that have been needed only 588152284Sobrien for reloads that we know can be inherited. */ 588252284Sobrien for (pass = flag_expensive_optimizations; pass >= 0; pass--) 588318334Speter { 588452284Sobrien for (j = 0; j < n_reloads; j++) 588550397Sobrien { 588690075Sobrien int r = reload_order[j]; 588752284Sobrien rtx check_reg; 588890075Sobrien if (reload_inherited[r] && rld[r].reg_rtx) 588990075Sobrien check_reg = rld[r].reg_rtx; 589052284Sobrien else if (reload_override_in[r] 589152284Sobrien && (GET_CODE (reload_override_in[r]) == REG 589290075Sobrien || GET_CODE (reload_override_in[r]) == SUBREG)) 589352284Sobrien check_reg = reload_override_in[r]; 589452284Sobrien else 589552284Sobrien continue; 589690075Sobrien if (! free_for_value_p (true_regnum (check_reg), rld[r].mode, 589790075Sobrien rld[r].opnum, rld[r].when_needed, rld[r].in, 589870635Sobrien (reload_inherited[r] 589990075Sobrien ? rld[r].out : const0_rtx), 590070635Sobrien r, 1)) 590150397Sobrien { 590252284Sobrien if (pass) 590352284Sobrien continue; 590452284Sobrien reload_inherited[r] = 0; 590552284Sobrien reload_override_in[r] = 0; 590650397Sobrien } 590752284Sobrien /* If we can inherit a RELOAD_FOR_INPUT, or can use a 590852284Sobrien reload_override_in, then we do not need its related 590952284Sobrien RELOAD_FOR_INPUT_ADDRESS / RELOAD_FOR_INPADDR_ADDRESS reloads; 591052284Sobrien likewise for other reload types. 591152284Sobrien We handle this by removing a reload when its only replacement 591252284Sobrien is mentioned in reload_in of the reload we are going to inherit. 591352284Sobrien A special case are auto_inc expressions; even if the input is 591452284Sobrien inherited, we still need the address for the output. We can 591590075Sobrien recognize them because they have RELOAD_OUT set to RELOAD_IN. 591690075Sobrien If we succeeded removing some reload and we are doing a preliminary 591752284Sobrien pass just to remove such reloads, make another pass, since the 591852284Sobrien removal of one reload might allow us to inherit another one. */ 591990075Sobrien else if (rld[r].in 592090075Sobrien && rld[r].out != rld[r].in 592190075Sobrien && remove_address_replacements (rld[r].in) && pass) 592252284Sobrien pass = 2; 592350397Sobrien } 592418334Speter } 592518334Speter 592618334Speter /* Now that reload_override_in is known valid, 592718334Speter actually override reload_in. */ 592818334Speter for (j = 0; j < n_reloads; j++) 592918334Speter if (reload_override_in[j]) 593090075Sobrien rld[j].in = reload_override_in[j]; 593118334Speter 593218334Speter /* If this reload won't be done because it has been cancelled or is 593318334Speter optional and not inherited, clear reload_reg_rtx so other 593418334Speter routines (such as subst_reloads) don't get confused. */ 593518334Speter for (j = 0; j < n_reloads; j++) 593690075Sobrien if (rld[j].reg_rtx != 0 593790075Sobrien && ((rld[j].optional && ! reload_inherited[j]) 593890075Sobrien || (rld[j].in == 0 && rld[j].out == 0 593990075Sobrien && ! rld[j].secondary_p))) 594018334Speter { 594190075Sobrien int regno = true_regnum (rld[j].reg_rtx); 594218334Speter 594318334Speter if (spill_reg_order[regno] >= 0) 594490075Sobrien clear_reload_reg_in_use (regno, rld[j].opnum, 594590075Sobrien rld[j].when_needed, rld[j].mode); 594690075Sobrien rld[j].reg_rtx = 0; 594757844Sobrien reload_spill_index[j] = -1; 594818334Speter } 594918334Speter 595018334Speter /* Record which pseudos and which spill regs have output reloads. */ 595118334Speter for (j = 0; j < n_reloads; j++) 595218334Speter { 595390075Sobrien int r = reload_order[j]; 595418334Speter 595518334Speter i = reload_spill_index[r]; 595618334Speter 595750397Sobrien /* I is nonneg if this reload uses a register. 595890075Sobrien If rld[r].reg_rtx is 0, this is an optional reload 595918334Speter that we opted to ignore. */ 596090075Sobrien if (rld[r].out_reg != 0 && GET_CODE (rld[r].out_reg) == REG 596190075Sobrien && rld[r].reg_rtx != 0) 596218334Speter { 596390075Sobrien int nregno = REGNO (rld[r].out_reg); 596418334Speter int nr = 1; 596518334Speter 596618334Speter if (nregno < FIRST_PSEUDO_REGISTER) 596790075Sobrien nr = HARD_REGNO_NREGS (nregno, rld[r].mode); 596818334Speter 596918334Speter while (--nr >= 0) 597018334Speter reg_has_output_reload[nregno + nr] = 1; 597118334Speter 597218334Speter if (i >= 0) 597318334Speter { 597490075Sobrien nr = HARD_REGNO_NREGS (i, rld[r].mode); 597518334Speter while (--nr >= 0) 597650397Sobrien SET_HARD_REG_BIT (reg_is_output_reload, i + nr); 597718334Speter } 597818334Speter 597990075Sobrien if (rld[r].when_needed != RELOAD_OTHER 598090075Sobrien && rld[r].when_needed != RELOAD_FOR_OUTPUT 598190075Sobrien && rld[r].when_needed != RELOAD_FOR_INSN) 598218334Speter abort (); 598318334Speter } 598418334Speter } 598518334Speter} 598652284Sobrien 598752284Sobrien/* Deallocate the reload register for reload R. This is called from 598852284Sobrien remove_address_replacements. */ 598990075Sobrien 599052284Sobrienvoid 599152284Sobriendeallocate_reload_reg (r) 599252284Sobrien int r; 599352284Sobrien{ 599452284Sobrien int regno; 599552284Sobrien 599690075Sobrien if (! rld[r].reg_rtx) 599752284Sobrien return; 599890075Sobrien regno = true_regnum (rld[r].reg_rtx); 599990075Sobrien rld[r].reg_rtx = 0; 600052284Sobrien if (spill_reg_order[regno] >= 0) 600190075Sobrien clear_reload_reg_in_use (regno, rld[r].opnum, rld[r].when_needed, 600290075Sobrien rld[r].mode); 600352284Sobrien reload_spill_index[r] = -1; 600452284Sobrien} 600518334Speter 600650397Sobrien/* If SMALL_REGISTER_CLASSES is non-zero, we may not have merged two 600718334Speter reloads of the same item for fear that we might not have enough reload 600818334Speter registers. However, normally they will get the same reload register 600990075Sobrien and hence actually need not be loaded twice. 601018334Speter 601118334Speter Here we check for the most common case of this phenomenon: when we have 601218334Speter a number of reloads for the same object, each of which were allocated 601318334Speter the same reload_reg_rtx, that reload_reg_rtx is not used for any other 601418334Speter reload, and is not modified in the insn itself. If we find such, 601518334Speter merge all the reloads and set the resulting reload to RELOAD_OTHER. 601618334Speter This will not increase the number of spill registers needed and will 601718334Speter prevent redundant code. */ 601818334Speter 601918334Speterstatic void 602018334Spetermerge_assigned_reloads (insn) 602118334Speter rtx insn; 602218334Speter{ 602318334Speter int i, j; 602418334Speter 602518334Speter /* Scan all the reloads looking for ones that only load values and 602618334Speter are not already RELOAD_OTHER and ones whose reload_reg_rtx are 602718334Speter assigned and not modified by INSN. */ 602818334Speter 602918334Speter for (i = 0; i < n_reloads; i++) 603018334Speter { 603150397Sobrien int conflicting_input = 0; 603250397Sobrien int max_input_address_opnum = -1; 603350397Sobrien int min_conflicting_input_opnum = MAX_RECOG_OPERANDS; 603450397Sobrien 603590075Sobrien if (rld[i].in == 0 || rld[i].when_needed == RELOAD_OTHER 603690075Sobrien || rld[i].out != 0 || rld[i].reg_rtx == 0 603790075Sobrien || reg_set_p (rld[i].reg_rtx, insn)) 603818334Speter continue; 603918334Speter 604018334Speter /* Look at all other reloads. Ensure that the only use of this 604118334Speter reload_reg_rtx is in a reload that just loads the same value 604218334Speter as we do. Note that any secondary reloads must be of the identical 604318334Speter class since the values, modes, and result registers are the 604418334Speter same, so we need not do anything with any secondary reloads. */ 604518334Speter 604618334Speter for (j = 0; j < n_reloads; j++) 604718334Speter { 604890075Sobrien if (i == j || rld[j].reg_rtx == 0 604990075Sobrien || ! reg_overlap_mentioned_p (rld[j].reg_rtx, 605090075Sobrien rld[i].reg_rtx)) 605118334Speter continue; 605218334Speter 605390075Sobrien if (rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS 605490075Sobrien && rld[j].opnum > max_input_address_opnum) 605590075Sobrien max_input_address_opnum = rld[j].opnum; 605650397Sobrien 605718334Speter /* If the reload regs aren't exactly the same (e.g, different modes) 605850397Sobrien or if the values are different, we can't merge this reload. 605950397Sobrien But if it is an input reload, we might still merge 606050397Sobrien RELOAD_FOR_INPUT_ADDRESS and RELOAD_FOR_OTHER_ADDRESS reloads. */ 606118334Speter 606290075Sobrien if (! rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) 606390075Sobrien || rld[j].out != 0 || rld[j].in == 0 606490075Sobrien || ! rtx_equal_p (rld[i].in, rld[j].in)) 606550397Sobrien { 606690075Sobrien if (rld[j].when_needed != RELOAD_FOR_INPUT 606790075Sobrien || ((rld[i].when_needed != RELOAD_FOR_INPUT_ADDRESS 606890075Sobrien || rld[i].opnum > rld[j].opnum) 606990075Sobrien && rld[i].when_needed != RELOAD_FOR_OTHER_ADDRESS)) 607050397Sobrien break; 607150397Sobrien conflicting_input = 1; 607290075Sobrien if (min_conflicting_input_opnum > rld[j].opnum) 607390075Sobrien min_conflicting_input_opnum = rld[j].opnum; 607450397Sobrien } 607518334Speter } 607618334Speter 607718334Speter /* If all is OK, merge the reloads. Only set this to RELOAD_OTHER if 607818334Speter we, in fact, found any matching reloads. */ 607918334Speter 608050397Sobrien if (j == n_reloads 608150397Sobrien && max_input_address_opnum <= min_conflicting_input_opnum) 608218334Speter { 608318334Speter for (j = 0; j < n_reloads; j++) 608490075Sobrien if (i != j && rld[j].reg_rtx != 0 608590075Sobrien && rtx_equal_p (rld[i].reg_rtx, rld[j].reg_rtx) 608650397Sobrien && (! conflicting_input 608790075Sobrien || rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS 608890075Sobrien || rld[j].when_needed == RELOAD_FOR_OTHER_ADDRESS)) 608918334Speter { 609090075Sobrien rld[i].when_needed = RELOAD_OTHER; 609190075Sobrien rld[j].in = 0; 609250397Sobrien reload_spill_index[j] = -1; 609318334Speter transfer_replacements (i, j); 609418334Speter } 609518334Speter 609618334Speter /* If this is now RELOAD_OTHER, look for any reloads that load 609718334Speter parts of this operand and set them to RELOAD_FOR_OTHER_ADDRESS 609818334Speter if they were for inputs, RELOAD_OTHER for outputs. Note that 609918334Speter this test is equivalent to looking for reloads for this operand 610018334Speter number. */ 610118334Speter 610290075Sobrien if (rld[i].when_needed == RELOAD_OTHER) 610318334Speter for (j = 0; j < n_reloads; j++) 610490075Sobrien if (rld[j].in != 0 610590075Sobrien && rld[j].when_needed != RELOAD_OTHER 610690075Sobrien && reg_overlap_mentioned_for_reload_p (rld[j].in, 610790075Sobrien rld[i].in)) 610890075Sobrien rld[j].when_needed 610990075Sobrien = ((rld[j].when_needed == RELOAD_FOR_INPUT_ADDRESS 611090075Sobrien || rld[j].when_needed == RELOAD_FOR_INPADDR_ADDRESS) 611150397Sobrien ? RELOAD_FOR_OTHER_ADDRESS : RELOAD_OTHER); 611218334Speter } 611318334Speter } 611490075Sobrien} 611518334Speter 611690075Sobrien/* These arrays are filled by emit_reload_insns and its subroutines. */ 611790075Sobrienstatic rtx input_reload_insns[MAX_RECOG_OPERANDS]; 611890075Sobrienstatic rtx other_input_address_reload_insns = 0; 611990075Sobrienstatic rtx other_input_reload_insns = 0; 612090075Sobrienstatic rtx input_address_reload_insns[MAX_RECOG_OPERANDS]; 612190075Sobrienstatic rtx inpaddr_address_reload_insns[MAX_RECOG_OPERANDS]; 612290075Sobrienstatic rtx output_reload_insns[MAX_RECOG_OPERANDS]; 612390075Sobrienstatic rtx output_address_reload_insns[MAX_RECOG_OPERANDS]; 612490075Sobrienstatic rtx outaddr_address_reload_insns[MAX_RECOG_OPERANDS]; 612590075Sobrienstatic rtx operand_reload_insns = 0; 612690075Sobrienstatic rtx other_operand_reload_insns = 0; 612790075Sobrienstatic rtx other_output_reload_insns[MAX_RECOG_OPERANDS]; 612818334Speter 612990075Sobrien/* Values to be put in spill_reg_store are put here first. */ 613090075Sobrienstatic rtx new_spill_reg_store[FIRST_PSEUDO_REGISTER]; 613190075Sobrienstatic HARD_REG_SET reg_reloaded_died; 613290075Sobrien 613390075Sobrien/* Generate insns to perform reload RL, which is for the insn in CHAIN and 613490075Sobrien has the number J. OLD contains the value to be used as input. */ 613590075Sobrien 613618334Speterstatic void 613790075Sobrienemit_input_reload_insns (chain, rl, old, j) 613852284Sobrien struct insn_chain *chain; 613990075Sobrien struct reload *rl; 614090075Sobrien rtx old; 614190075Sobrien int j; 614218334Speter{ 614352284Sobrien rtx insn = chain->insn; 614490075Sobrien rtx reloadreg = rl->reg_rtx; 614590075Sobrien rtx oldequiv_reg = 0; 614690075Sobrien rtx oldequiv = 0; 614790075Sobrien int special = 0; 614890075Sobrien enum machine_mode mode; 614990075Sobrien rtx *where; 615052284Sobrien 615190075Sobrien /* Determine the mode to reload in. 615290075Sobrien This is very tricky because we have three to choose from. 615390075Sobrien There is the mode the insn operand wants (rl->inmode). 615490075Sobrien There is the mode of the reload register RELOADREG. 615590075Sobrien There is the intrinsic mode of the operand, which we could find 615690075Sobrien by stripping some SUBREGs. 615790075Sobrien It turns out that RELOADREG's mode is irrelevant: 615890075Sobrien we can change that arbitrarily. 615918334Speter 616090075Sobrien Consider (SUBREG:SI foo:QI) as an operand that must be SImode; 616190075Sobrien then the reload reg may not support QImode moves, so use SImode. 616290075Sobrien If foo is in memory due to spilling a pseudo reg, this is safe, 616390075Sobrien because the QImode value is in the least significant part of a 616490075Sobrien slot big enough for a SImode. If foo is some other sort of 616590075Sobrien memory reference, then it is impossible to reload this case, 616690075Sobrien so previous passes had better make sure this never happens. 616750397Sobrien 616890075Sobrien Then consider a one-word union which has SImode and one of its 616990075Sobrien members is a float, being fetched as (SUBREG:SF union:SI). 617090075Sobrien We must fetch that as SFmode because we could be loading into 617190075Sobrien a float-only register. In this case OLD's mode is correct. 617218334Speter 617390075Sobrien Consider an immediate integer: it has VOIDmode. Here we need 617490075Sobrien to get a mode from something else. 617518334Speter 617690075Sobrien In some cases, there is a fourth mode, the operand's 617790075Sobrien containing mode. If the insn specifies a containing mode for 617890075Sobrien this operand, it overrides all others. 617918334Speter 618090075Sobrien I am not sure whether the algorithm here is always right, 618190075Sobrien but it does the right things in those cases. */ 618218334Speter 618390075Sobrien mode = GET_MODE (old); 618490075Sobrien if (mode == VOIDmode) 618590075Sobrien mode = rl->inmode; 618652284Sobrien 618790075Sobrien#ifdef SECONDARY_INPUT_RELOAD_CLASS 618890075Sobrien /* If we need a secondary register for this operation, see if 618990075Sobrien the value is already in a register in that class. Don't 619090075Sobrien do this if the secondary register will be used as a scratch 619190075Sobrien register. */ 619218334Speter 619390075Sobrien if (rl->secondary_in_reload >= 0 619490075Sobrien && rl->secondary_in_icode == CODE_FOR_nothing 619590075Sobrien && optimize) 619690075Sobrien oldequiv 619790075Sobrien = find_equiv_reg (old, insn, 619890075Sobrien rld[rl->secondary_in_reload].class, 619990075Sobrien -1, NULL, 0, mode); 620090075Sobrien#endif 620118334Speter 620290075Sobrien /* If reloading from memory, see if there is a register 620390075Sobrien that already holds the same value. If so, reload from there. 620490075Sobrien We can pass 0 as the reload_reg_p argument because 620590075Sobrien any other reload has either already been emitted, 620690075Sobrien in which case find_equiv_reg will see the reload-insn, 620790075Sobrien or has yet to be emitted, in which case it doesn't matter 620890075Sobrien because we will use this equiv reg right away. */ 620918334Speter 621090075Sobrien if (oldequiv == 0 && optimize 621190075Sobrien && (GET_CODE (old) == MEM 621290075Sobrien || (GET_CODE (old) == REG 621390075Sobrien && REGNO (old) >= FIRST_PSEUDO_REGISTER 621490075Sobrien && reg_renumber[REGNO (old)] < 0))) 621590075Sobrien oldequiv = find_equiv_reg (old, insn, ALL_REGS, -1, NULL, 0, mode); 621618334Speter 621790075Sobrien if (oldequiv) 621890075Sobrien { 621990075Sobrien unsigned int regno = true_regnum (oldequiv); 622018334Speter 622190075Sobrien /* Don't use OLDEQUIV if any other reload changes it at an 622290075Sobrien earlier stage of this insn or at this stage. */ 622390075Sobrien if (! free_for_value_p (regno, rl->mode, rl->opnum, rl->when_needed, 622490075Sobrien rl->in, const0_rtx, j, 0)) 622590075Sobrien oldequiv = 0; 622618334Speter 622790075Sobrien /* If it is no cheaper to copy from OLDEQUIV into the 622890075Sobrien reload register than it would be to move from memory, 622990075Sobrien don't use it. Likewise, if we need a secondary register 623090075Sobrien or memory. */ 623118334Speter 623290075Sobrien if (oldequiv != 0 623390075Sobrien && ((REGNO_REG_CLASS (regno) != rl->class 623490075Sobrien && (REGISTER_MOVE_COST (mode, REGNO_REG_CLASS (regno), 623590075Sobrien rl->class) 623690075Sobrien >= MEMORY_MOVE_COST (mode, rl->class, 1))) 623718334Speter#ifdef SECONDARY_INPUT_RELOAD_CLASS 623890075Sobrien || (SECONDARY_INPUT_RELOAD_CLASS (rl->class, 623990075Sobrien mode, oldequiv) 624090075Sobrien != NO_REGS) 624118334Speter#endif 624290075Sobrien#ifdef SECONDARY_MEMORY_NEEDED 624390075Sobrien || SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (regno), 624490075Sobrien rl->class, 624590075Sobrien mode) 624690075Sobrien#endif 624790075Sobrien )) 624890075Sobrien oldequiv = 0; 624990075Sobrien } 625018334Speter 625190075Sobrien /* delete_output_reload is only invoked properly if old contains 625290075Sobrien the original pseudo register. Since this is replaced with a 625390075Sobrien hard reg when RELOAD_OVERRIDE_IN is set, see if we can 625490075Sobrien find the pseudo in RELOAD_IN_REG. */ 625590075Sobrien if (oldequiv == 0 625690075Sobrien && reload_override_in[j] 625790075Sobrien && GET_CODE (rl->in_reg) == REG) 625890075Sobrien { 625990075Sobrien oldequiv = old; 626090075Sobrien old = rl->in_reg; 626190075Sobrien } 626290075Sobrien if (oldequiv == 0) 626390075Sobrien oldequiv = old; 626490075Sobrien else if (GET_CODE (oldequiv) == REG) 626590075Sobrien oldequiv_reg = oldequiv; 626690075Sobrien else if (GET_CODE (oldequiv) == SUBREG) 626790075Sobrien oldequiv_reg = SUBREG_REG (oldequiv); 626818334Speter 626990075Sobrien /* If we are reloading from a register that was recently stored in 627090075Sobrien with an output-reload, see if we can prove there was 627190075Sobrien actually no need to store the old value in it. */ 627218334Speter 627390075Sobrien if (optimize && GET_CODE (oldequiv) == REG 627490075Sobrien && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER 627590075Sobrien && spill_reg_store[REGNO (oldequiv)] 627690075Sobrien && GET_CODE (old) == REG 627790075Sobrien && (dead_or_set_p (insn, spill_reg_stored_to[REGNO (oldequiv)]) 627890075Sobrien || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)], 627990075Sobrien rl->out_reg))) 628090075Sobrien delete_output_reload (insn, j, REGNO (oldequiv)); 628118334Speter 628290075Sobrien /* Encapsulate both RELOADREG and OLDEQUIV into that mode, 628390075Sobrien then load RELOADREG from OLDEQUIV. Note that we cannot use 628490075Sobrien gen_lowpart_common since it can do the wrong thing when 628590075Sobrien RELOADREG has a multi-word mode. Note that RELOADREG 628690075Sobrien must always be a REG here. */ 628718334Speter 628890075Sobrien if (GET_MODE (reloadreg) != mode) 628990075Sobrien reloadreg = gen_rtx_REG (mode, REGNO (reloadreg)); 629090075Sobrien while (GET_CODE (oldequiv) == SUBREG && GET_MODE (oldequiv) != mode) 629190075Sobrien oldequiv = SUBREG_REG (oldequiv); 629290075Sobrien if (GET_MODE (oldequiv) != VOIDmode 629390075Sobrien && mode != GET_MODE (oldequiv)) 629490075Sobrien oldequiv = gen_lowpart_SUBREG (mode, oldequiv); 629518334Speter 629690075Sobrien /* Switch to the right place to emit the reload insns. */ 629790075Sobrien switch (rl->when_needed) 629890075Sobrien { 629990075Sobrien case RELOAD_OTHER: 630090075Sobrien where = &other_input_reload_insns; 630190075Sobrien break; 630290075Sobrien case RELOAD_FOR_INPUT: 630390075Sobrien where = &input_reload_insns[rl->opnum]; 630490075Sobrien break; 630590075Sobrien case RELOAD_FOR_INPUT_ADDRESS: 630690075Sobrien where = &input_address_reload_insns[rl->opnum]; 630790075Sobrien break; 630890075Sobrien case RELOAD_FOR_INPADDR_ADDRESS: 630990075Sobrien where = &inpaddr_address_reload_insns[rl->opnum]; 631090075Sobrien break; 631190075Sobrien case RELOAD_FOR_OUTPUT_ADDRESS: 631290075Sobrien where = &output_address_reload_insns[rl->opnum]; 631390075Sobrien break; 631490075Sobrien case RELOAD_FOR_OUTADDR_ADDRESS: 631590075Sobrien where = &outaddr_address_reload_insns[rl->opnum]; 631690075Sobrien break; 631790075Sobrien case RELOAD_FOR_OPERAND_ADDRESS: 631890075Sobrien where = &operand_reload_insns; 631990075Sobrien break; 632090075Sobrien case RELOAD_FOR_OPADDR_ADDR: 632190075Sobrien where = &other_operand_reload_insns; 632290075Sobrien break; 632390075Sobrien case RELOAD_FOR_OTHER_ADDRESS: 632490075Sobrien where = &other_input_address_reload_insns; 632590075Sobrien break; 632690075Sobrien default: 632790075Sobrien abort (); 632890075Sobrien } 632918334Speter 633090075Sobrien push_to_sequence (*where); 633118334Speter 633290075Sobrien /* Auto-increment addresses must be reloaded in a special way. */ 633390075Sobrien if (rl->out && ! rl->out_reg) 633490075Sobrien { 633590075Sobrien /* We are not going to bother supporting the case where a 633690075Sobrien incremented register can't be copied directly from 633790075Sobrien OLDEQUIV since this seems highly unlikely. */ 633890075Sobrien if (rl->secondary_in_reload >= 0) 633990075Sobrien abort (); 634018334Speter 634190075Sobrien if (reload_inherited[j]) 634290075Sobrien oldequiv = reloadreg; 634318334Speter 634490075Sobrien old = XEXP (rl->in_reg, 0); 634518334Speter 634690075Sobrien if (optimize && GET_CODE (oldequiv) == REG 634790075Sobrien && REGNO (oldequiv) < FIRST_PSEUDO_REGISTER 634890075Sobrien && spill_reg_store[REGNO (oldequiv)] 634990075Sobrien && GET_CODE (old) == REG 635090075Sobrien && (dead_or_set_p (insn, 635190075Sobrien spill_reg_stored_to[REGNO (oldequiv)]) 635290075Sobrien || rtx_equal_p (spill_reg_stored_to[REGNO (oldequiv)], 635390075Sobrien old))) 635490075Sobrien delete_output_reload (insn, j, REGNO (oldequiv)); 635518334Speter 635690075Sobrien /* Prevent normal processing of this reload. */ 635790075Sobrien special = 1; 635890075Sobrien /* Output a special code sequence for this case. */ 635990075Sobrien new_spill_reg_store[REGNO (reloadreg)] 636090075Sobrien = inc_for_reload (reloadreg, oldequiv, rl->out, 636190075Sobrien rl->inc); 636290075Sobrien } 636390075Sobrien 636490075Sobrien /* If we are reloading a pseudo-register that was set by the previous 636590075Sobrien insn, see if we can get rid of that pseudo-register entirely 636690075Sobrien by redirecting the previous insn into our reload register. */ 636790075Sobrien 636890075Sobrien else if (optimize && GET_CODE (old) == REG 636990075Sobrien && REGNO (old) >= FIRST_PSEUDO_REGISTER 637090075Sobrien && dead_or_set_p (insn, old) 637190075Sobrien /* This is unsafe if some other reload 637290075Sobrien uses the same reg first. */ 637390075Sobrien && ! conflicts_with_override (reloadreg) 637490075Sobrien && free_for_value_p (REGNO (reloadreg), rl->mode, rl->opnum, 637590075Sobrien rl->when_needed, old, rl->out, j, 0)) 637690075Sobrien { 637790075Sobrien rtx temp = PREV_INSN (insn); 637890075Sobrien while (temp && GET_CODE (temp) == NOTE) 637990075Sobrien temp = PREV_INSN (temp); 638090075Sobrien if (temp 638190075Sobrien && GET_CODE (temp) == INSN 638290075Sobrien && GET_CODE (PATTERN (temp)) == SET 638390075Sobrien && SET_DEST (PATTERN (temp)) == old 638490075Sobrien /* Make sure we can access insn_operand_constraint. */ 638590075Sobrien && asm_noperands (PATTERN (temp)) < 0 638690075Sobrien /* This is unsafe if operand occurs more than once in current 638790075Sobrien insn. Perhaps some occurrences aren't reloaded. */ 6388107590Sobrien && count_occurrences (PATTERN (insn), old, 0) == 1) 638990075Sobrien { 6390107590Sobrien rtx old = SET_DEST (PATTERN (temp)); 639190075Sobrien /* Store into the reload register instead of the pseudo. */ 639290075Sobrien SET_DEST (PATTERN (temp)) = reloadreg; 639390075Sobrien 6394107590Sobrien /* Verify that resulting insn is valid. */ 6395107590Sobrien extract_insn (temp); 6396107590Sobrien if (constrain_operands (1)) 639718334Speter { 6398107590Sobrien /* If the previous insn is an output reload, the source is 6399107590Sobrien a reload register, and its spill_reg_store entry will 6400107590Sobrien contain the previous destination. This is now 6401107590Sobrien invalid. */ 6402107590Sobrien if (GET_CODE (SET_SRC (PATTERN (temp))) == REG 6403107590Sobrien && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER) 6404107590Sobrien { 6405107590Sobrien spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0; 6406107590Sobrien spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0; 6407107590Sobrien } 6408107590Sobrien 6409107590Sobrien /* If these are the only uses of the pseudo reg, 6410107590Sobrien pretend for GDB it lives in the reload reg we used. */ 6411107590Sobrien if (REG_N_DEATHS (REGNO (old)) == 1 6412107590Sobrien && REG_N_SETS (REGNO (old)) == 1) 6413107590Sobrien { 6414107590Sobrien reg_renumber[REGNO (old)] = REGNO (rl->reg_rtx); 6415107590Sobrien alter_reg (REGNO (old), -1); 6416107590Sobrien } 6417107590Sobrien special = 1; 641818334Speter } 6419107590Sobrien else 642018334Speter { 6421107590Sobrien SET_DEST (PATTERN (temp)) = old; 642290075Sobrien } 642390075Sobrien } 642490075Sobrien } 642552284Sobrien 642690075Sobrien /* We can't do that, so output an insn to load RELOADREG. */ 642752284Sobrien 642890075Sobrien#ifdef SECONDARY_INPUT_RELOAD_CLASS 642990075Sobrien /* If we have a secondary reload, pick up the secondary register 643090075Sobrien and icode, if any. If OLDEQUIV and OLD are different or 643190075Sobrien if this is an in-out reload, recompute whether or not we 643290075Sobrien still need a secondary register and what the icode should 643390075Sobrien be. If we still need a secondary register and the class or 643490075Sobrien icode is different, go back to reloading from OLD if using 643590075Sobrien OLDEQUIV means that we got the wrong type of register. We 643690075Sobrien cannot have different class or icode due to an in-out reload 643790075Sobrien because we don't make such reloads when both the input and 643890075Sobrien output need secondary reload registers. */ 643952284Sobrien 644090075Sobrien if (! special && rl->secondary_in_reload >= 0) 644190075Sobrien { 644290075Sobrien rtx second_reload_reg = 0; 644390075Sobrien int secondary_reload = rl->secondary_in_reload; 644490075Sobrien rtx real_oldequiv = oldequiv; 644590075Sobrien rtx real_old = old; 644690075Sobrien rtx tmp; 644790075Sobrien enum insn_code icode; 644852284Sobrien 644990075Sobrien /* If OLDEQUIV is a pseudo with a MEM, get the real MEM 645090075Sobrien and similarly for OLD. 645190075Sobrien See comments in get_secondary_reload in reload.c. */ 645290075Sobrien /* If it is a pseudo that cannot be replaced with its 645390075Sobrien equivalent MEM, we must fall back to reload_in, which 645490075Sobrien will have all the necessary substitutions registered. 645590075Sobrien Likewise for a pseudo that can't be replaced with its 645690075Sobrien equivalent constant. 645718334Speter 645890075Sobrien Take extra care for subregs of such pseudos. Note that 645990075Sobrien we cannot use reg_equiv_mem in this case because it is 646090075Sobrien not in the right mode. */ 646118334Speter 646290075Sobrien tmp = oldequiv; 646390075Sobrien if (GET_CODE (tmp) == SUBREG) 646490075Sobrien tmp = SUBREG_REG (tmp); 646590075Sobrien if (GET_CODE (tmp) == REG 646690075Sobrien && REGNO (tmp) >= FIRST_PSEUDO_REGISTER 646790075Sobrien && (reg_equiv_memory_loc[REGNO (tmp)] != 0 646890075Sobrien || reg_equiv_constant[REGNO (tmp)] != 0)) 646990075Sobrien { 647090075Sobrien if (! reg_equiv_mem[REGNO (tmp)] 647190075Sobrien || num_not_at_initial_offset 647290075Sobrien || GET_CODE (oldequiv) == SUBREG) 647390075Sobrien real_oldequiv = rl->in; 647490075Sobrien else 647590075Sobrien real_oldequiv = reg_equiv_mem[REGNO (tmp)]; 647690075Sobrien } 647790075Sobrien 647890075Sobrien tmp = old; 647990075Sobrien if (GET_CODE (tmp) == SUBREG) 648090075Sobrien tmp = SUBREG_REG (tmp); 648190075Sobrien if (GET_CODE (tmp) == REG 648290075Sobrien && REGNO (tmp) >= FIRST_PSEUDO_REGISTER 648390075Sobrien && (reg_equiv_memory_loc[REGNO (tmp)] != 0 648490075Sobrien || reg_equiv_constant[REGNO (tmp)] != 0)) 648590075Sobrien { 648690075Sobrien if (! reg_equiv_mem[REGNO (tmp)] 648790075Sobrien || num_not_at_initial_offset 648890075Sobrien || GET_CODE (old) == SUBREG) 648990075Sobrien real_old = rl->in; 649090075Sobrien else 649190075Sobrien real_old = reg_equiv_mem[REGNO (tmp)]; 649290075Sobrien } 649390075Sobrien 649490075Sobrien second_reload_reg = rld[secondary_reload].reg_rtx; 649590075Sobrien icode = rl->secondary_in_icode; 649690075Sobrien 649790075Sobrien if ((old != oldequiv && ! rtx_equal_p (old, oldequiv)) 649890075Sobrien || (rl->in != 0 && rl->out != 0)) 649990075Sobrien { 650090075Sobrien enum reg_class new_class 650190075Sobrien = SECONDARY_INPUT_RELOAD_CLASS (rl->class, 650290075Sobrien mode, real_oldequiv); 650390075Sobrien 650490075Sobrien if (new_class == NO_REGS) 650590075Sobrien second_reload_reg = 0; 650690075Sobrien else 650718334Speter { 650890075Sobrien enum insn_code new_icode; 650990075Sobrien enum machine_mode new_mode; 651090075Sobrien 651190075Sobrien if (! TEST_HARD_REG_BIT (reg_class_contents[(int) new_class], 651290075Sobrien REGNO (second_reload_reg))) 651390075Sobrien oldequiv = old, real_oldequiv = real_old; 651490075Sobrien else 651518334Speter { 651690075Sobrien new_icode = reload_in_optab[(int) mode]; 651790075Sobrien if (new_icode != CODE_FOR_nothing 651890075Sobrien && ((insn_data[(int) new_icode].operand[0].predicate 651990075Sobrien && ! ((*insn_data[(int) new_icode].operand[0].predicate) 652090075Sobrien (reloadreg, mode))) 652190075Sobrien || (insn_data[(int) new_icode].operand[1].predicate 652290075Sobrien && ! ((*insn_data[(int) new_icode].operand[1].predicate) 652390075Sobrien (real_oldequiv, mode))))) 652490075Sobrien new_icode = CODE_FOR_nothing; 652552284Sobrien 652690075Sobrien if (new_icode == CODE_FOR_nothing) 652790075Sobrien new_mode = mode; 652890075Sobrien else 652990075Sobrien new_mode = insn_data[(int) new_icode].operand[2].mode; 653052284Sobrien 653190075Sobrien if (GET_MODE (second_reload_reg) != new_mode) 653218334Speter { 653390075Sobrien if (!HARD_REGNO_MODE_OK (REGNO (second_reload_reg), 653490075Sobrien new_mode)) 653590075Sobrien oldequiv = old, real_oldequiv = real_old; 653690075Sobrien else 653790075Sobrien second_reload_reg 653890075Sobrien = gen_rtx_REG (new_mode, 653990075Sobrien REGNO (second_reload_reg)); 654018334Speter } 654118334Speter } 654218334Speter } 654390075Sobrien } 654418334Speter 654590075Sobrien /* If we still need a secondary reload register, check 654690075Sobrien to see if it is being used as a scratch or intermediate 654790075Sobrien register and generate code appropriately. If we need 654890075Sobrien a scratch register, use REAL_OLDEQUIV since the form of 654990075Sobrien the insn may depend on the actual address if it is 655090075Sobrien a MEM. */ 655118334Speter 655290075Sobrien if (second_reload_reg) 655390075Sobrien { 655490075Sobrien if (icode != CODE_FOR_nothing) 655518334Speter { 655690075Sobrien emit_insn (GEN_FCN (icode) (reloadreg, real_oldequiv, 655790075Sobrien second_reload_reg)); 655890075Sobrien special = 1; 655990075Sobrien } 656090075Sobrien else 656190075Sobrien { 656290075Sobrien /* See if we need a scratch register to load the 656390075Sobrien intermediate register (a tertiary reload). */ 656490075Sobrien enum insn_code tertiary_icode 656590075Sobrien = rld[secondary_reload].secondary_in_icode; 656618334Speter 656790075Sobrien if (tertiary_icode != CODE_FOR_nothing) 656818334Speter { 656990075Sobrien rtx third_reload_reg 657090075Sobrien = rld[rld[secondary_reload].secondary_in_reload].reg_rtx; 657118334Speter 657290075Sobrien emit_insn ((GEN_FCN (tertiary_icode) 657390075Sobrien (second_reload_reg, real_oldequiv, 657490075Sobrien third_reload_reg))); 657590075Sobrien } 657690075Sobrien else 657790075Sobrien gen_reload (second_reload_reg, real_oldequiv, 657890075Sobrien rl->opnum, 657990075Sobrien rl->when_needed); 658018334Speter 658190075Sobrien oldequiv = second_reload_reg; 658290075Sobrien } 658390075Sobrien } 658490075Sobrien } 658590075Sobrien#endif 658618334Speter 658790075Sobrien if (! special && ! rtx_equal_p (reloadreg, oldequiv)) 658890075Sobrien { 658990075Sobrien rtx real_oldequiv = oldequiv; 659052284Sobrien 659190075Sobrien if ((GET_CODE (oldequiv) == REG 659290075Sobrien && REGNO (oldequiv) >= FIRST_PSEUDO_REGISTER 659390075Sobrien && (reg_equiv_memory_loc[REGNO (oldequiv)] != 0 659490075Sobrien || reg_equiv_constant[REGNO (oldequiv)] != 0)) 659590075Sobrien || (GET_CODE (oldequiv) == SUBREG 659690075Sobrien && GET_CODE (SUBREG_REG (oldequiv)) == REG 659790075Sobrien && (REGNO (SUBREG_REG (oldequiv)) 659890075Sobrien >= FIRST_PSEUDO_REGISTER) 659990075Sobrien && ((reg_equiv_memory_loc 660090075Sobrien [REGNO (SUBREG_REG (oldequiv))] != 0) 660190075Sobrien || (reg_equiv_constant 660290075Sobrien [REGNO (SUBREG_REG (oldequiv))] != 0))) 660390075Sobrien || (CONSTANT_P (oldequiv) 660490075Sobrien && (PREFERRED_RELOAD_CLASS (oldequiv, 660590075Sobrien REGNO_REG_CLASS (REGNO (reloadreg))) 660690075Sobrien == NO_REGS))) 660790075Sobrien real_oldequiv = rl->in; 660890075Sobrien gen_reload (reloadreg, real_oldequiv, rl->opnum, 660990075Sobrien rl->when_needed); 661090075Sobrien } 661118334Speter 661290075Sobrien if (flag_non_call_exceptions) 661390075Sobrien copy_eh_notes (insn, get_insns ()); 661418334Speter 661590075Sobrien /* End this sequence. */ 661690075Sobrien *where = get_insns (); 661790075Sobrien end_sequence (); 661890075Sobrien 661990075Sobrien /* Update reload_override_in so that delete_address_reloads_1 662090075Sobrien can see the actual register usage. */ 662190075Sobrien if (oldequiv_reg) 662290075Sobrien reload_override_in[j] = oldequiv; 662390075Sobrien} 662418334Speter 662590075Sobrien/* Generate insns to for the output reload RL, which is for the insn described 662690075Sobrien by CHAIN and has the number J. */ 662790075Sobrienstatic void 662890075Sobrienemit_output_reload_insns (chain, rl, j) 662990075Sobrien struct insn_chain *chain; 663090075Sobrien struct reload *rl; 663190075Sobrien int j; 663290075Sobrien{ 663390075Sobrien rtx reloadreg = rl->reg_rtx; 663490075Sobrien rtx insn = chain->insn; 663590075Sobrien int special = 0; 663690075Sobrien rtx old = rl->out; 663790075Sobrien enum machine_mode mode = GET_MODE (old); 663890075Sobrien rtx p; 663918334Speter 664090075Sobrien if (rl->when_needed == RELOAD_OTHER) 664190075Sobrien start_sequence (); 664290075Sobrien else 664390075Sobrien push_to_sequence (output_reload_insns[rl->opnum]); 664418334Speter 664590075Sobrien /* Determine the mode to reload in. 664690075Sobrien See comments above (for input reloading). */ 664718334Speter 664890075Sobrien if (mode == VOIDmode) 664990075Sobrien { 665090075Sobrien /* VOIDmode should never happen for an output. */ 665190075Sobrien if (asm_noperands (PATTERN (insn)) < 0) 665290075Sobrien /* It's the compiler's fault. */ 665390075Sobrien fatal_insn ("VOIDmode on an output", insn); 665490075Sobrien error_for_asm (insn, "output operand is constant in `asm'"); 665590075Sobrien /* Prevent crash--use something we know is valid. */ 665690075Sobrien mode = word_mode; 665790075Sobrien old = gen_rtx_REG (mode, REGNO (reloadreg)); 665890075Sobrien } 665918334Speter 666090075Sobrien if (GET_MODE (reloadreg) != mode) 666190075Sobrien reloadreg = gen_rtx_REG (mode, REGNO (reloadreg)); 666218334Speter 666390075Sobrien#ifdef SECONDARY_OUTPUT_RELOAD_CLASS 666418334Speter 666590075Sobrien /* If we need two reload regs, set RELOADREG to the intermediate 666690075Sobrien one, since it will be stored into OLD. We might need a secondary 666790075Sobrien register only for an input reload, so check again here. */ 666818334Speter 666990075Sobrien if (rl->secondary_out_reload >= 0) 667090075Sobrien { 667190075Sobrien rtx real_old = old; 667218334Speter 667390075Sobrien if (GET_CODE (old) == REG && REGNO (old) >= FIRST_PSEUDO_REGISTER 667490075Sobrien && reg_equiv_mem[REGNO (old)] != 0) 667590075Sobrien real_old = reg_equiv_mem[REGNO (old)]; 667618334Speter 667790075Sobrien if ((SECONDARY_OUTPUT_RELOAD_CLASS (rl->class, 667890075Sobrien mode, real_old) 667990075Sobrien != NO_REGS)) 668090075Sobrien { 668190075Sobrien rtx second_reloadreg = reloadreg; 668290075Sobrien reloadreg = rld[rl->secondary_out_reload].reg_rtx; 668352284Sobrien 668490075Sobrien /* See if RELOADREG is to be used as a scratch register 668590075Sobrien or as an intermediate register. */ 668690075Sobrien if (rl->secondary_out_icode != CODE_FOR_nothing) 668790075Sobrien { 668890075Sobrien emit_insn ((GEN_FCN (rl->secondary_out_icode) 668990075Sobrien (real_old, second_reloadreg, reloadreg))); 669090075Sobrien special = 1; 669118334Speter } 669290075Sobrien else 669390075Sobrien { 669490075Sobrien /* See if we need both a scratch and intermediate reload 669590075Sobrien register. */ 669618334Speter 669790075Sobrien int secondary_reload = rl->secondary_out_reload; 669890075Sobrien enum insn_code tertiary_icode 669990075Sobrien = rld[secondary_reload].secondary_out_icode; 670052284Sobrien 670190075Sobrien if (GET_MODE (reloadreg) != mode) 670290075Sobrien reloadreg = gen_rtx_REG (mode, REGNO (reloadreg)); 670318334Speter 670490075Sobrien if (tertiary_icode != CODE_FOR_nothing) 670590075Sobrien { 670690075Sobrien rtx third_reloadreg 670790075Sobrien = rld[rld[secondary_reload].secondary_out_reload].reg_rtx; 670890075Sobrien rtx tem; 670918334Speter 671090075Sobrien /* Copy primary reload reg to secondary reload reg. 671190075Sobrien (Note that these have been swapped above, then 671290075Sobrien secondary reload reg to OLD using our insn.) */ 671318334Speter 671490075Sobrien /* If REAL_OLD is a paradoxical SUBREG, remove it 671590075Sobrien and try to put the opposite SUBREG on 671690075Sobrien RELOADREG. */ 671790075Sobrien if (GET_CODE (real_old) == SUBREG 671890075Sobrien && (GET_MODE_SIZE (GET_MODE (real_old)) 671990075Sobrien > GET_MODE_SIZE (GET_MODE (SUBREG_REG (real_old)))) 672090075Sobrien && 0 != (tem = gen_lowpart_common 672190075Sobrien (GET_MODE (SUBREG_REG (real_old)), 672290075Sobrien reloadreg))) 672390075Sobrien real_old = SUBREG_REG (real_old), reloadreg = tem; 672418334Speter 672590075Sobrien gen_reload (reloadreg, second_reloadreg, 672690075Sobrien rl->opnum, rl->when_needed); 672790075Sobrien emit_insn ((GEN_FCN (tertiary_icode) 672890075Sobrien (real_old, reloadreg, third_reloadreg))); 672990075Sobrien special = 1; 673090075Sobrien } 673118334Speter 673290075Sobrien else 673390075Sobrien /* Copy between the reload regs here and then to 673490075Sobrien OUT later. */ 673552284Sobrien 673690075Sobrien gen_reload (reloadreg, second_reloadreg, 673790075Sobrien rl->opnum, rl->when_needed); 673890075Sobrien } 673990075Sobrien } 674090075Sobrien } 674150397Sobrien#endif 674218334Speter 674390075Sobrien /* Output the last reload insn. */ 674490075Sobrien if (! special) 674590075Sobrien { 674690075Sobrien rtx set; 674718334Speter 674890075Sobrien /* Don't output the last reload if OLD is not the dest of 674990075Sobrien INSN and is in the src and is clobbered by INSN. */ 675090075Sobrien if (! flag_expensive_optimizations 675190075Sobrien || GET_CODE (old) != REG 675290075Sobrien || !(set = single_set (insn)) 675390075Sobrien || rtx_equal_p (old, SET_DEST (set)) 675490075Sobrien || !reg_mentioned_p (old, SET_SRC (set)) 675590075Sobrien || !regno_clobbered_p (REGNO (old), insn, rl->mode, 0)) 675690075Sobrien gen_reload (old, reloadreg, rl->opnum, 675790075Sobrien rl->when_needed); 675890075Sobrien } 675918334Speter 676090075Sobrien /* Look at all insns we emitted, just to be safe. */ 676190075Sobrien for (p = get_insns (); p; p = NEXT_INSN (p)) 676290075Sobrien if (INSN_P (p)) 676390075Sobrien { 676490075Sobrien rtx pat = PATTERN (p); 676518334Speter 676690075Sobrien /* If this output reload doesn't come from a spill reg, 676790075Sobrien clear any memory of reloaded copies of the pseudo reg. 676890075Sobrien If this output reload comes from a spill reg, 676990075Sobrien reg_has_output_reload will make this do nothing. */ 677090075Sobrien note_stores (pat, forget_old_reloads_1, NULL); 677118334Speter 677290075Sobrien if (reg_mentioned_p (rl->reg_rtx, pat)) 677390075Sobrien { 677490075Sobrien rtx set = single_set (insn); 677590075Sobrien if (reload_spill_index[j] < 0 677690075Sobrien && set 677790075Sobrien && SET_SRC (set) == rl->reg_rtx) 677890075Sobrien { 677990075Sobrien int src = REGNO (SET_SRC (set)); 678018334Speter 678190075Sobrien reload_spill_index[j] = src; 678290075Sobrien SET_HARD_REG_BIT (reg_is_output_reload, src); 678390075Sobrien if (find_regno_note (insn, REG_DEAD, src)) 678490075Sobrien SET_HARD_REG_BIT (reg_reloaded_died, src); 678590075Sobrien } 678690075Sobrien if (REGNO (rl->reg_rtx) < FIRST_PSEUDO_REGISTER) 678790075Sobrien { 678890075Sobrien int s = rl->secondary_out_reload; 678990075Sobrien set = single_set (p); 679090075Sobrien /* If this reload copies only to the secondary reload 679190075Sobrien register, the secondary reload does the actual 679290075Sobrien store. */ 679390075Sobrien if (s >= 0 && set == NULL_RTX) 679490075Sobrien /* We can't tell what function the secondary reload 679590075Sobrien has and where the actual store to the pseudo is 679690075Sobrien made; leave new_spill_reg_store alone. */ 679790075Sobrien ; 679890075Sobrien else if (s >= 0 679990075Sobrien && SET_SRC (set) == rl->reg_rtx 680090075Sobrien && SET_DEST (set) == rld[s].reg_rtx) 680190075Sobrien { 680290075Sobrien /* Usually the next instruction will be the 680390075Sobrien secondary reload insn; if we can confirm 680490075Sobrien that it is, setting new_spill_reg_store to 680590075Sobrien that insn will allow an extra optimization. */ 680690075Sobrien rtx s_reg = rld[s].reg_rtx; 680790075Sobrien rtx next = NEXT_INSN (p); 680890075Sobrien rld[s].out = rl->out; 680990075Sobrien rld[s].out_reg = rl->out_reg; 681090075Sobrien set = single_set (next); 681190075Sobrien if (set && SET_SRC (set) == s_reg 681290075Sobrien && ! new_spill_reg_store[REGNO (s_reg)]) 681390075Sobrien { 681490075Sobrien SET_HARD_REG_BIT (reg_is_output_reload, 681590075Sobrien REGNO (s_reg)); 681690075Sobrien new_spill_reg_store[REGNO (s_reg)] = next; 681790075Sobrien } 681890075Sobrien } 681990075Sobrien else 682090075Sobrien new_spill_reg_store[REGNO (rl->reg_rtx)] = p; 682190075Sobrien } 682290075Sobrien } 682390075Sobrien } 682452284Sobrien 682590075Sobrien if (rl->when_needed == RELOAD_OTHER) 682690075Sobrien { 682790075Sobrien emit_insns (other_output_reload_insns[rl->opnum]); 682890075Sobrien other_output_reload_insns[rl->opnum] = get_insns (); 682990075Sobrien } 683090075Sobrien else 683190075Sobrien output_reload_insns[rl->opnum] = get_insns (); 683218334Speter 683390075Sobrien if (flag_non_call_exceptions) 683490075Sobrien copy_eh_notes (insn, get_insns ()); 683518334Speter 683690075Sobrien end_sequence (); 683790075Sobrien} 683818334Speter 683990075Sobrien/* Do input reloading for reload RL, which is for the insn described by CHAIN 684090075Sobrien and has the number J. */ 684190075Sobrienstatic void 684290075Sobriendo_input_reload (chain, rl, j) 684390075Sobrien struct insn_chain *chain; 684490075Sobrien struct reload *rl; 684590075Sobrien int j; 684690075Sobrien{ 684790075Sobrien int expect_occurrences = 1; 684890075Sobrien rtx insn = chain->insn; 684990075Sobrien rtx old = (rl->in && GET_CODE (rl->in) == MEM 685090075Sobrien ? rl->in_reg : rl->in); 685118334Speter 685290075Sobrien if (old != 0 685390075Sobrien /* AUTO_INC reloads need to be handled even if inherited. We got an 685490075Sobrien AUTO_INC reload if reload_out is set but reload_out_reg isn't. */ 685590075Sobrien && (! reload_inherited[j] || (rl->out && ! rl->out_reg)) 685690075Sobrien && ! rtx_equal_p (rl->reg_rtx, old) 685790075Sobrien && rl->reg_rtx != 0) 685890075Sobrien emit_input_reload_insns (chain, rld + j, old, j); 685918334Speter 686090075Sobrien /* When inheriting a wider reload, we have a MEM in rl->in, 686190075Sobrien e.g. inheriting a SImode output reload for 686290075Sobrien (mem:HI (plus:SI (reg:SI 14 fp) (const_int 10))) */ 686390075Sobrien if (optimize && reload_inherited[j] && rl->in 686490075Sobrien && GET_CODE (rl->in) == MEM 686590075Sobrien && GET_CODE (rl->in_reg) == MEM 686690075Sobrien && reload_spill_index[j] >= 0 686790075Sobrien && TEST_HARD_REG_BIT (reg_reloaded_valid, reload_spill_index[j])) 686890075Sobrien { 686990075Sobrien expect_occurrences 687090075Sobrien = count_occurrences (PATTERN (insn), rl->in, 0) == 1 ? 0 : -1; 687190075Sobrien rl->in = regno_reg_rtx[reg_reloaded_contents[reload_spill_index[j]]]; 687290075Sobrien } 687318334Speter 687490075Sobrien /* If we are reloading a register that was recently stored in with an 687590075Sobrien output-reload, see if we can prove there was 687690075Sobrien actually no need to store the old value in it. */ 687718334Speter 687890075Sobrien if (optimize 687990075Sobrien && (reload_inherited[j] || reload_override_in[j]) 688090075Sobrien && rl->reg_rtx 688190075Sobrien && GET_CODE (rl->reg_rtx) == REG 688290075Sobrien && spill_reg_store[REGNO (rl->reg_rtx)] != 0 688390075Sobrien#if 0 688490075Sobrien /* There doesn't seem to be any reason to restrict this to pseudos 688590075Sobrien and doing so loses in the case where we are copying from a 688690075Sobrien register of the wrong class. */ 688790075Sobrien && (REGNO (spill_reg_stored_to[REGNO (rl->reg_rtx)]) 688890075Sobrien >= FIRST_PSEUDO_REGISTER) 688990075Sobrien#endif 689090075Sobrien /* The insn might have already some references to stackslots 689190075Sobrien replaced by MEMs, while reload_out_reg still names the 689290075Sobrien original pseudo. */ 689390075Sobrien && (dead_or_set_p (insn, 689490075Sobrien spill_reg_stored_to[REGNO (rl->reg_rtx)]) 689590075Sobrien || rtx_equal_p (spill_reg_stored_to[REGNO (rl->reg_rtx)], 689690075Sobrien rl->out_reg))) 689790075Sobrien delete_output_reload (insn, j, REGNO (rl->reg_rtx)); 689890075Sobrien} 689918334Speter 690090075Sobrien/* Do output reloading for reload RL, which is for the insn described by 690190075Sobrien CHAIN and has the number J. 690290075Sobrien ??? At some point we need to support handling output reloads of 690390075Sobrien JUMP_INSNs or insns that set cc0. */ 690490075Sobrienstatic void 690590075Sobriendo_output_reload (chain, rl, j) 690690075Sobrien struct insn_chain *chain; 690790075Sobrien struct reload *rl; 690890075Sobrien int j; 690990075Sobrien{ 691090075Sobrien rtx note, old; 691190075Sobrien rtx insn = chain->insn; 691290075Sobrien /* If this is an output reload that stores something that is 691390075Sobrien not loaded in this same reload, see if we can eliminate a previous 691490075Sobrien store. */ 691590075Sobrien rtx pseudo = rl->out_reg; 691618334Speter 691790075Sobrien if (pseudo 6918102780Skan && optimize 691990075Sobrien && GET_CODE (pseudo) == REG 692090075Sobrien && ! rtx_equal_p (rl->in_reg, pseudo) 692190075Sobrien && REGNO (pseudo) >= FIRST_PSEUDO_REGISTER 692290075Sobrien && reg_last_reload_reg[REGNO (pseudo)]) 692390075Sobrien { 692490075Sobrien int pseudo_no = REGNO (pseudo); 692590075Sobrien int last_regno = REGNO (reg_last_reload_reg[pseudo_no]); 692618334Speter 692790075Sobrien /* We don't need to test full validity of last_regno for 692890075Sobrien inherit here; we only want to know if the store actually 692990075Sobrien matches the pseudo. */ 693090075Sobrien if (TEST_HARD_REG_BIT (reg_reloaded_valid, last_regno) 693190075Sobrien && reg_reloaded_contents[last_regno] == pseudo_no 693290075Sobrien && spill_reg_store[last_regno] 693390075Sobrien && rtx_equal_p (pseudo, spill_reg_stored_to[last_regno])) 693490075Sobrien delete_output_reload (insn, j, last_regno); 693590075Sobrien } 693618334Speter 693790075Sobrien old = rl->out_reg; 693890075Sobrien if (old == 0 693990075Sobrien || rl->reg_rtx == old 694090075Sobrien || rl->reg_rtx == 0) 694190075Sobrien return; 694218334Speter 694390075Sobrien /* An output operand that dies right away does need a reload, 694490075Sobrien but need not be copied from it. Show the new location in the 694590075Sobrien REG_UNUSED note. */ 694690075Sobrien if ((GET_CODE (old) == REG || GET_CODE (old) == SCRATCH) 694790075Sobrien && (note = find_reg_note (insn, REG_UNUSED, old)) != 0) 694890075Sobrien { 694990075Sobrien XEXP (note, 0) = rl->reg_rtx; 695090075Sobrien return; 695190075Sobrien } 695290075Sobrien /* Likewise for a SUBREG of an operand that dies. */ 695390075Sobrien else if (GET_CODE (old) == SUBREG 695490075Sobrien && GET_CODE (SUBREG_REG (old)) == REG 695590075Sobrien && 0 != (note = find_reg_note (insn, REG_UNUSED, 695690075Sobrien SUBREG_REG (old)))) 695790075Sobrien { 695890075Sobrien XEXP (note, 0) = gen_lowpart_common (GET_MODE (old), 695990075Sobrien rl->reg_rtx); 696090075Sobrien return; 696190075Sobrien } 696290075Sobrien else if (GET_CODE (old) == SCRATCH) 696390075Sobrien /* If we aren't optimizing, there won't be a REG_UNUSED note, 696490075Sobrien but we don't want to make an output reload. */ 696590075Sobrien return; 696618334Speter 696790075Sobrien /* If is a JUMP_INSN, we can't support output reloads yet. */ 696890075Sobrien if (GET_CODE (insn) == JUMP_INSN) 696990075Sobrien abort (); 697018334Speter 697190075Sobrien emit_output_reload_insns (chain, rld + j, j); 697290075Sobrien} 697318334Speter 697490075Sobrien/* Output insns to reload values in and out of the chosen reload regs. */ 697518334Speter 697690075Sobrienstatic void 697790075Sobrienemit_reload_insns (chain) 697890075Sobrien struct insn_chain *chain; 697990075Sobrien{ 698090075Sobrien rtx insn = chain->insn; 698118334Speter 698290075Sobrien int j; 698318334Speter 698490075Sobrien CLEAR_HARD_REG_SET (reg_reloaded_died); 698550397Sobrien 698690075Sobrien for (j = 0; j < reload_n_operands; j++) 698790075Sobrien input_reload_insns[j] = input_address_reload_insns[j] 698890075Sobrien = inpaddr_address_reload_insns[j] 698990075Sobrien = output_reload_insns[j] = output_address_reload_insns[j] 699090075Sobrien = outaddr_address_reload_insns[j] 699190075Sobrien = other_output_reload_insns[j] = 0; 699290075Sobrien other_input_address_reload_insns = 0; 699390075Sobrien other_input_reload_insns = 0; 699490075Sobrien operand_reload_insns = 0; 699590075Sobrien other_operand_reload_insns = 0; 699650397Sobrien 699790075Sobrien /* Dump reloads into the dump file. */ 699890075Sobrien if (rtl_dump_file) 699990075Sobrien { 700090075Sobrien fprintf (rtl_dump_file, "\nReloads for insn # %d\n", INSN_UID (insn)); 700190075Sobrien debug_reload_to_stream (rtl_dump_file); 700290075Sobrien } 700318334Speter 700490075Sobrien /* Now output the instructions to copy the data into and out of the 700590075Sobrien reload registers. Do these in the order that the reloads were reported, 700690075Sobrien since reloads of base and index registers precede reloads of operands 700790075Sobrien and the operands may need the base and index registers reloaded. */ 700850397Sobrien 700990075Sobrien for (j = 0; j < n_reloads; j++) 701090075Sobrien { 701190075Sobrien if (rld[j].reg_rtx 701290075Sobrien && REGNO (rld[j].reg_rtx) < FIRST_PSEUDO_REGISTER) 701390075Sobrien new_spill_reg_store[REGNO (rld[j].reg_rtx)] = 0; 701418334Speter 701590075Sobrien do_input_reload (chain, rld + j, j); 701690075Sobrien do_output_reload (chain, rld + j, j); 701718334Speter } 701818334Speter 701918334Speter /* Now write all the insns we made for reloads in the order expected by 702018334Speter the allocation functions. Prior to the insn being reloaded, we write 702118334Speter the following reloads: 702218334Speter 702318334Speter RELOAD_FOR_OTHER_ADDRESS reloads for input addresses. 702418334Speter 702550397Sobrien RELOAD_OTHER reloads. 702618334Speter 702750397Sobrien For each operand, any RELOAD_FOR_INPADDR_ADDRESS reloads followed 702850397Sobrien by any RELOAD_FOR_INPUT_ADDRESS reloads followed by the 702950397Sobrien RELOAD_FOR_INPUT reload for the operand. 703018334Speter 703118334Speter RELOAD_FOR_OPADDR_ADDRS reloads. 703218334Speter 703318334Speter RELOAD_FOR_OPERAND_ADDRESS reloads. 703418334Speter 703518334Speter After the insn being reloaded, we write the following: 703618334Speter 703750397Sobrien For each operand, any RELOAD_FOR_OUTADDR_ADDRESS reloads followed 703850397Sobrien by any RELOAD_FOR_OUTPUT_ADDRESS reload followed by the 703950397Sobrien RELOAD_FOR_OUTPUT reload, followed by any RELOAD_OTHER output 704050397Sobrien reloads for the operand. The RELOAD_OTHER output reloads are 704150397Sobrien output in descending order by reload number. */ 704218334Speter 704352284Sobrien emit_insns_before (other_input_address_reload_insns, insn); 704452284Sobrien emit_insns_before (other_input_reload_insns, insn); 704518334Speter 704618334Speter for (j = 0; j < reload_n_operands; j++) 704718334Speter { 704852284Sobrien emit_insns_before (inpaddr_address_reload_insns[j], insn); 704952284Sobrien emit_insns_before (input_address_reload_insns[j], insn); 705052284Sobrien emit_insns_before (input_reload_insns[j], insn); 705118334Speter } 705218334Speter 705352284Sobrien emit_insns_before (other_operand_reload_insns, insn); 705452284Sobrien emit_insns_before (operand_reload_insns, insn); 705518334Speter 705618334Speter for (j = 0; j < reload_n_operands; j++) 705718334Speter { 705890075Sobrien rtx x = emit_insns_after (outaddr_address_reload_insns[j], insn); 705990075Sobrien x = emit_insns_after (output_address_reload_insns[j], x); 706090075Sobrien x = emit_insns_after (output_reload_insns[j], x); 706190075Sobrien emit_insns_after (other_output_reload_insns[j], x); 706218334Speter } 706318334Speter 706418334Speter /* For all the spill regs newly reloaded in this instruction, 706518334Speter record what they were reloaded from, so subsequent instructions 706618334Speter can inherit the reloads. 706718334Speter 706818334Speter Update spill_reg_store for the reloads of this insn. 706918334Speter Copy the elements that were updated in the loop above. */ 707018334Speter 707118334Speter for (j = 0; j < n_reloads; j++) 707218334Speter { 707390075Sobrien int r = reload_order[j]; 707490075Sobrien int i = reload_spill_index[r]; 707518334Speter 707652284Sobrien /* If this is a non-inherited input reload from a pseudo, we must 707790075Sobrien clear any memory of a previous store to the same pseudo. Only do 707890075Sobrien something if there will not be an output reload for the pseudo 707990075Sobrien being reloaded. */ 708090075Sobrien if (rld[r].in_reg != 0 708190075Sobrien && ! (reload_inherited[r] || reload_override_in[r])) 708290075Sobrien { 708390075Sobrien rtx reg = rld[r].in_reg; 708452284Sobrien 708590075Sobrien if (GET_CODE (reg) == SUBREG) 708652284Sobrien reg = SUBREG_REG (reg); 708790075Sobrien 708890075Sobrien if (GET_CODE (reg) == REG 708952284Sobrien && REGNO (reg) >= FIRST_PSEUDO_REGISTER 709052284Sobrien && ! reg_has_output_reload[REGNO (reg)]) 709152284Sobrien { 709252284Sobrien int nregno = REGNO (reg); 709352284Sobrien 709452284Sobrien if (reg_last_reload_reg[nregno]) 709590075Sobrien { 709690075Sobrien int last_regno = REGNO (reg_last_reload_reg[nregno]); 709752284Sobrien 709890075Sobrien if (reg_reloaded_contents[last_regno] == nregno) 709952284Sobrien spill_reg_store[last_regno] = 0; 710090075Sobrien } 710152284Sobrien } 710252284Sobrien } 710390075Sobrien 710450397Sobrien /* I is nonneg if this reload used a register. 710590075Sobrien If rld[r].reg_rtx is 0, this is an optional reload 710650397Sobrien that we opted to ignore. */ 710718334Speter 710890075Sobrien if (i >= 0 && rld[r].reg_rtx != 0) 710918334Speter { 711090075Sobrien int nr = HARD_REGNO_NREGS (i, GET_MODE (rld[r].reg_rtx)); 711118334Speter int k; 711250397Sobrien int part_reaches_end = 0; 711350397Sobrien int all_reaches_end = 1; 711418334Speter 711550397Sobrien /* For a multi register reload, we need to check if all or part 711650397Sobrien of the value lives to the end. */ 711718334Speter for (k = 0; k < nr; k++) 711818334Speter { 711990075Sobrien if (reload_reg_reaches_end_p (i + k, rld[r].opnum, 712090075Sobrien rld[r].when_needed)) 712150397Sobrien part_reaches_end = 1; 712250397Sobrien else 712350397Sobrien all_reaches_end = 0; 712418334Speter } 712518334Speter 712650397Sobrien /* Ignore reloads that don't reach the end of the insn in 712750397Sobrien entirety. */ 712850397Sobrien if (all_reaches_end) 712918334Speter { 713050397Sobrien /* First, clear out memory of what used to be in this spill reg. 713150397Sobrien If consecutive registers are used, clear them all. */ 713218334Speter 713350397Sobrien for (k = 0; k < nr; k++) 713450397Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k); 713518334Speter 713650397Sobrien /* Maybe the spill reg contains a copy of reload_out. */ 713790075Sobrien if (rld[r].out != 0 713890075Sobrien && (GET_CODE (rld[r].out) == REG 713952284Sobrien#ifdef AUTO_INC_DEC 714090075Sobrien || ! rld[r].out_reg 714152284Sobrien#endif 714290075Sobrien || GET_CODE (rld[r].out_reg) == REG)) 714350397Sobrien { 714490075Sobrien rtx out = (GET_CODE (rld[r].out) == REG 714590075Sobrien ? rld[r].out 714690075Sobrien : rld[r].out_reg 714790075Sobrien ? rld[r].out_reg 714890075Sobrien/* AUTO_INC */ : XEXP (rld[r].in_reg, 0)); 714990075Sobrien int nregno = REGNO (out); 715050397Sobrien int nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1 715150397Sobrien : HARD_REGNO_NREGS (nregno, 715290075Sobrien GET_MODE (rld[r].reg_rtx))); 715318334Speter 715450397Sobrien spill_reg_store[i] = new_spill_reg_store[i]; 715552284Sobrien spill_reg_stored_to[i] = out; 715690075Sobrien reg_last_reload_reg[nregno] = rld[r].reg_rtx; 715718334Speter 715850397Sobrien /* If NREGNO is a hard register, it may occupy more than 715990075Sobrien one register. If it does, say what is in the 716050397Sobrien rest of the registers assuming that both registers 716150397Sobrien agree on how many words the object takes. If not, 716250397Sobrien invalidate the subsequent registers. */ 716350397Sobrien 716450397Sobrien if (nregno < FIRST_PSEUDO_REGISTER) 716550397Sobrien for (k = 1; k < nnr; k++) 716650397Sobrien reg_last_reload_reg[nregno + k] 716750397Sobrien = (nr == nnr 716890075Sobrien ? gen_rtx_REG (reg_raw_mode[REGNO (rld[r].reg_rtx) + k], 716990075Sobrien REGNO (rld[r].reg_rtx) + k) 717050397Sobrien : 0); 717150397Sobrien 717250397Sobrien /* Now do the inverse operation. */ 717350397Sobrien for (k = 0; k < nr; k++) 717450397Sobrien { 717550397Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k); 717650397Sobrien reg_reloaded_contents[i + k] 717750397Sobrien = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr 717850397Sobrien ? nregno 717950397Sobrien : nregno + k); 718050397Sobrien reg_reloaded_insn[i + k] = insn; 718150397Sobrien SET_HARD_REG_BIT (reg_reloaded_valid, i + k); 718250397Sobrien } 718318334Speter } 718418334Speter 718550397Sobrien /* Maybe the spill reg contains a copy of reload_in. Only do 718650397Sobrien something if there will not be an output reload for 718750397Sobrien the register being reloaded. */ 718890075Sobrien else if (rld[r].out_reg == 0 718990075Sobrien && rld[r].in != 0 719090075Sobrien && ((GET_CODE (rld[r].in) == REG 719190075Sobrien && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER 719290075Sobrien && ! reg_has_output_reload[REGNO (rld[r].in)]) 719390075Sobrien || (GET_CODE (rld[r].in_reg) == REG 719490075Sobrien && ! reg_has_output_reload[REGNO (rld[r].in_reg)])) 719590075Sobrien && ! reg_set_p (rld[r].reg_rtx, PATTERN (insn))) 719650397Sobrien { 719790075Sobrien int nregno; 719850397Sobrien int nnr; 719918334Speter 720090075Sobrien if (GET_CODE (rld[r].in) == REG 720190075Sobrien && REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER) 720290075Sobrien nregno = REGNO (rld[r].in); 720390075Sobrien else if (GET_CODE (rld[r].in_reg) == REG) 720490075Sobrien nregno = REGNO (rld[r].in_reg); 720550397Sobrien else 720690075Sobrien nregno = REGNO (XEXP (rld[r].in_reg, 0)); 720718334Speter 720850397Sobrien nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1 720950397Sobrien : HARD_REGNO_NREGS (nregno, 721090075Sobrien GET_MODE (rld[r].reg_rtx))); 721118334Speter 721290075Sobrien reg_last_reload_reg[nregno] = rld[r].reg_rtx; 721390075Sobrien 721450397Sobrien if (nregno < FIRST_PSEUDO_REGISTER) 721550397Sobrien for (k = 1; k < nnr; k++) 721650397Sobrien reg_last_reload_reg[nregno + k] 721750397Sobrien = (nr == nnr 721890075Sobrien ? gen_rtx_REG (reg_raw_mode[REGNO (rld[r].reg_rtx) + k], 721990075Sobrien REGNO (rld[r].reg_rtx) + k) 722050397Sobrien : 0); 722118334Speter 722250397Sobrien /* Unless we inherited this reload, show we haven't 722352284Sobrien recently done a store. 722452284Sobrien Previous stores of inherited auto_inc expressions 722552284Sobrien also have to be discarded. */ 722652284Sobrien if (! reload_inherited[r] 722790075Sobrien || (rld[r].out && ! rld[r].out_reg)) 722850397Sobrien spill_reg_store[i] = 0; 722918334Speter 723050397Sobrien for (k = 0; k < nr; k++) 723150397Sobrien { 723250397Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_dead, i + k); 723350397Sobrien reg_reloaded_contents[i + k] 723450397Sobrien = (nregno >= FIRST_PSEUDO_REGISTER || nr != nnr 723550397Sobrien ? nregno 723650397Sobrien : nregno + k); 723750397Sobrien reg_reloaded_insn[i + k] = insn; 723850397Sobrien SET_HARD_REG_BIT (reg_reloaded_valid, i + k); 723950397Sobrien } 724050397Sobrien } 724150397Sobrien } 724218334Speter 724350397Sobrien /* However, if part of the reload reaches the end, then we must 724450397Sobrien invalidate the old info for the part that survives to the end. */ 724550397Sobrien else if (part_reaches_end) 724650397Sobrien { 724718334Speter for (k = 0; k < nr; k++) 724850397Sobrien if (reload_reg_reaches_end_p (i + k, 724990075Sobrien rld[r].opnum, 725090075Sobrien rld[r].when_needed)) 725150397Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k); 725218334Speter } 725318334Speter } 725418334Speter 725518334Speter /* The following if-statement was #if 0'd in 1.34 (or before...). 725618334Speter It's reenabled in 1.35 because supposedly nothing else 725718334Speter deals with this problem. */ 725818334Speter 725918334Speter /* If a register gets output-reloaded from a non-spill register, 726018334Speter that invalidates any previous reloaded copy of it. 726118334Speter But forget_old_reloads_1 won't get to see it, because 726218334Speter it thinks only about the original insn. So invalidate it here. */ 726390075Sobrien if (i < 0 && rld[r].out != 0 726490075Sobrien && (GET_CODE (rld[r].out) == REG 726590075Sobrien || (GET_CODE (rld[r].out) == MEM 726690075Sobrien && GET_CODE (rld[r].out_reg) == REG))) 726718334Speter { 726890075Sobrien rtx out = (GET_CODE (rld[r].out) == REG 726990075Sobrien ? rld[r].out : rld[r].out_reg); 727090075Sobrien int nregno = REGNO (out); 727118334Speter if (nregno >= FIRST_PSEUDO_REGISTER) 727252284Sobrien { 727390075Sobrien rtx src_reg, store_insn = NULL_RTX; 727452284Sobrien 727552284Sobrien reg_last_reload_reg[nregno] = 0; 727652284Sobrien 727752284Sobrien /* If we can find a hard register that is stored, record 727852284Sobrien the storing insn so that we may delete this insn with 727952284Sobrien delete_output_reload. */ 728090075Sobrien src_reg = rld[r].reg_rtx; 728152284Sobrien 728252284Sobrien /* If this is an optional reload, try to find the source reg 728352284Sobrien from an input reload. */ 728452284Sobrien if (! src_reg) 728552284Sobrien { 728652284Sobrien rtx set = single_set (insn); 728790075Sobrien if (set && SET_DEST (set) == rld[r].out) 728852284Sobrien { 728952284Sobrien int k; 729052284Sobrien 729152284Sobrien src_reg = SET_SRC (set); 729252284Sobrien store_insn = insn; 729352284Sobrien for (k = 0; k < n_reloads; k++) 729452284Sobrien { 729590075Sobrien if (rld[k].in == src_reg) 729652284Sobrien { 729790075Sobrien src_reg = rld[k].reg_rtx; 729852284Sobrien break; 729952284Sobrien } 730052284Sobrien } 730152284Sobrien } 730252284Sobrien } 730352284Sobrien else 730452284Sobrien store_insn = new_spill_reg_store[REGNO (src_reg)]; 730552284Sobrien if (src_reg && GET_CODE (src_reg) == REG 730652284Sobrien && REGNO (src_reg) < FIRST_PSEUDO_REGISTER) 730752284Sobrien { 730852284Sobrien int src_regno = REGNO (src_reg); 730990075Sobrien int nr = HARD_REGNO_NREGS (src_regno, rld[r].mode); 731052284Sobrien /* The place where to find a death note varies with 731152284Sobrien PRESERVE_DEATH_INFO_REGNO_P . The condition is not 731252284Sobrien necessarily checked exactly in the code that moves 731352284Sobrien notes, so just check both locations. */ 731452284Sobrien rtx note = find_regno_note (insn, REG_DEAD, src_regno); 731590075Sobrien if (! note && store_insn) 731652284Sobrien note = find_regno_note (store_insn, REG_DEAD, src_regno); 731752284Sobrien while (nr-- > 0) 731852284Sobrien { 731952284Sobrien spill_reg_store[src_regno + nr] = store_insn; 732052284Sobrien spill_reg_stored_to[src_regno + nr] = out; 732152284Sobrien reg_reloaded_contents[src_regno + nr] = nregno; 732252284Sobrien reg_reloaded_insn[src_regno + nr] = store_insn; 732352284Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr); 732452284Sobrien SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr); 732552284Sobrien SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr); 732652284Sobrien if (note) 732752284Sobrien SET_HARD_REG_BIT (reg_reloaded_died, src_regno); 732852284Sobrien else 732952284Sobrien CLEAR_HARD_REG_BIT (reg_reloaded_died, src_regno); 733052284Sobrien } 733152284Sobrien reg_last_reload_reg[nregno] = src_reg; 733252284Sobrien } 733352284Sobrien } 733418334Speter else 733518334Speter { 733690075Sobrien int num_regs = HARD_REGNO_NREGS (nregno, GET_MODE (rld[r].out)); 733718334Speter 733818334Speter while (num_regs-- > 0) 733918334Speter reg_last_reload_reg[nregno + num_regs] = 0; 734018334Speter } 734118334Speter } 734218334Speter } 734350397Sobrien IOR_HARD_REG_SET (reg_reloaded_dead, reg_reloaded_died); 734418334Speter} 734518334Speter 734618334Speter/* Emit code to perform a reload from IN (which may be a reload register) to 734718334Speter OUT (which may also be a reload register). IN or OUT is from operand 734890075Sobrien OPNUM with reload type TYPE. 734918334Speter 735018334Speter Returns first insn emitted. */ 735118334Speter 735218334Speterrtx 735318334Spetergen_reload (out, in, opnum, type) 735418334Speter rtx out; 735518334Speter rtx in; 735618334Speter int opnum; 735718334Speter enum reload_type type; 735818334Speter{ 735918334Speter rtx last = get_last_insn (); 736018334Speter rtx tem; 7361104752Skan#ifdef SECONDARY_MEMORY_NEEDED 7362104752Skan int in_regnum, out_regnum; 7363104752Skan#endif 736418334Speter 736518334Speter /* If IN is a paradoxical SUBREG, remove it and try to put the 736618334Speter opposite SUBREG on OUT. Likewise for a paradoxical SUBREG on OUT. */ 736718334Speter if (GET_CODE (in) == SUBREG 736818334Speter && (GET_MODE_SIZE (GET_MODE (in)) 736918334Speter > GET_MODE_SIZE (GET_MODE (SUBREG_REG (in)))) 737018334Speter && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (in)), out)) != 0) 737118334Speter in = SUBREG_REG (in), out = tem; 737218334Speter else if (GET_CODE (out) == SUBREG 737390075Sobrien && (GET_MODE_SIZE (GET_MODE (out)) 737490075Sobrien > GET_MODE_SIZE (GET_MODE (SUBREG_REG (out)))) 737590075Sobrien && (tem = gen_lowpart_common (GET_MODE (SUBREG_REG (out)), in)) != 0) 737618334Speter out = SUBREG_REG (out), in = tem; 737718334Speter 737818334Speter /* How to do this reload can get quite tricky. Normally, we are being 737918334Speter asked to reload a simple operand, such as a MEM, a constant, or a pseudo 738018334Speter register that didn't get a hard register. In that case we can just 738118334Speter call emit_move_insn. 738218334Speter 738318334Speter We can also be asked to reload a PLUS that adds a register or a MEM to 738418334Speter another register, constant or MEM. This can occur during frame pointer 738518334Speter elimination and while reloading addresses. This case is handled by 738618334Speter trying to emit a single insn to perform the add. If it is not valid, 738718334Speter we use a two insn sequence. 738818334Speter 738918334Speter Finally, we could be called to handle an 'o' constraint by putting 739018334Speter an address into a register. In that case, we first try to do this 739118334Speter with a named pattern of "reload_load_address". If no such pattern 739218334Speter exists, we just emit a SET insn and hope for the best (it will normally 739318334Speter be valid on machines that use 'o'). 739418334Speter 739518334Speter This entire process is made complex because reload will never 739618334Speter process the insns we generate here and so we must ensure that 739718334Speter they will fit their constraints and also by the fact that parts of 739818334Speter IN might be being reloaded separately and replaced with spill registers. 739918334Speter Because of this, we are, in some sense, just guessing the right approach 740018334Speter here. The one listed above seems to work. 740118334Speter 740218334Speter ??? At some point, this whole thing needs to be rethought. */ 740318334Speter 740418334Speter if (GET_CODE (in) == PLUS 740518334Speter && (GET_CODE (XEXP (in, 0)) == REG 740650397Sobrien || GET_CODE (XEXP (in, 0)) == SUBREG 740718334Speter || GET_CODE (XEXP (in, 0)) == MEM) 740818334Speter && (GET_CODE (XEXP (in, 1)) == REG 740950397Sobrien || GET_CODE (XEXP (in, 1)) == SUBREG 741018334Speter || CONSTANT_P (XEXP (in, 1)) 741118334Speter || GET_CODE (XEXP (in, 1)) == MEM)) 741218334Speter { 741318334Speter /* We need to compute the sum of a register or a MEM and another 741418334Speter register, constant, or MEM, and put it into the reload 741518334Speter register. The best possible way of doing this is if the machine 741618334Speter has a three-operand ADD insn that accepts the required operands. 741718334Speter 741818334Speter The simplest approach is to try to generate such an insn and see if it 741918334Speter is recognized and matches its constraints. If so, it can be used. 742018334Speter 742118334Speter It might be better not to actually emit the insn unless it is valid, 742218334Speter but we need to pass the insn as an operand to `recog' and 742352284Sobrien `extract_insn' and it is simpler to emit and then delete the insn if 742418334Speter not valid than to dummy things up. */ 742518334Speter 742618334Speter rtx op0, op1, tem, insn; 742718334Speter int code; 742818334Speter 742918334Speter op0 = find_replacement (&XEXP (in, 0)); 743018334Speter op1 = find_replacement (&XEXP (in, 1)); 743118334Speter 743218334Speter /* Since constraint checking is strict, commutativity won't be 743318334Speter checked, so we need to do that here to avoid spurious failure 743418334Speter if the add instruction is two-address and the second operand 743518334Speter of the add is the same as the reload reg, which is frequently 743618334Speter the case. If the insn would be A = B + A, rearrange it so 743750397Sobrien it will be A = A + B as constrain_operands expects. */ 743818334Speter 743918334Speter if (GET_CODE (XEXP (in, 1)) == REG 744018334Speter && REGNO (out) == REGNO (XEXP (in, 1))) 744118334Speter tem = op0, op0 = op1, op1 = tem; 744218334Speter 744318334Speter if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1)) 744450397Sobrien in = gen_rtx_PLUS (GET_MODE (in), op0, op1); 744518334Speter 744650397Sobrien insn = emit_insn (gen_rtx_SET (VOIDmode, out, in)); 744718334Speter code = recog_memoized (insn); 744818334Speter 744918334Speter if (code >= 0) 745018334Speter { 745152284Sobrien extract_insn (insn); 745218334Speter /* We want constrain operands to treat this insn strictly in 745318334Speter its validity determination, i.e., the way it would after reload 745418334Speter has completed. */ 745552284Sobrien if (constrain_operands (1)) 745618334Speter return insn; 745718334Speter } 745818334Speter 745918334Speter delete_insns_since (last); 746018334Speter 746118334Speter /* If that failed, we must use a conservative two-insn sequence. 746218334Speter 746390075Sobrien Use a move to copy one operand into the reload register. Prefer 746490075Sobrien to reload a constant, MEM or pseudo since the move patterns can 746590075Sobrien handle an arbitrary operand. If OP1 is not a constant, MEM or 746690075Sobrien pseudo and OP1 is not a valid operand for an add instruction, then 746790075Sobrien reload OP1. 746890075Sobrien 746990075Sobrien After reloading one of the operands into the reload register, add 747090075Sobrien the reload register to the output register. 747190075Sobrien 747218334Speter If there is another way to do this for a specific machine, a 747318334Speter DEFINE_PEEPHOLE should be specified that recognizes the sequence 747418334Speter we emit below. */ 747518334Speter 747652284Sobrien code = (int) add_optab->handlers[(int) GET_MODE (out)].insn_code; 747752284Sobrien 747850397Sobrien if (CONSTANT_P (op1) || GET_CODE (op1) == MEM || GET_CODE (op1) == SUBREG 747918334Speter || (GET_CODE (op1) == REG 748090075Sobrien && REGNO (op1) >= FIRST_PSEUDO_REGISTER) 748190075Sobrien || (code != CODE_FOR_nothing 748290075Sobrien && ! ((*insn_data[code].operand[2].predicate) 748390075Sobrien (op1, insn_data[code].operand[2].mode)))) 748418334Speter tem = op0, op0 = op1, op1 = tem; 748518334Speter 748650397Sobrien gen_reload (out, op0, opnum, type); 748718334Speter 748818334Speter /* If OP0 and OP1 are the same, we can use OUT for OP1. 748918334Speter This fixes a problem on the 32K where the stack pointer cannot 749018334Speter be used as an operand of an add insn. */ 749118334Speter 749218334Speter if (rtx_equal_p (op0, op1)) 749318334Speter op1 = out; 749418334Speter 749518334Speter insn = emit_insn (gen_add2_insn (out, op1)); 749618334Speter 749718334Speter /* If that failed, copy the address register to the reload register. 749850397Sobrien Then add the constant to the reload register. */ 749918334Speter 750018334Speter code = recog_memoized (insn); 750118334Speter 750218334Speter if (code >= 0) 750318334Speter { 750452284Sobrien extract_insn (insn); 750518334Speter /* We want constrain operands to treat this insn strictly in 750618334Speter its validity determination, i.e., the way it would after reload 750718334Speter has completed. */ 750852284Sobrien if (constrain_operands (1)) 750950397Sobrien { 751050397Sobrien /* Add a REG_EQUIV note so that find_equiv_reg can find it. */ 751150397Sobrien REG_NOTES (insn) 751250397Sobrien = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn)); 751350397Sobrien return insn; 751450397Sobrien } 751518334Speter } 751618334Speter 751718334Speter delete_insns_since (last); 751818334Speter 751950397Sobrien gen_reload (out, op1, opnum, type); 752050397Sobrien insn = emit_insn (gen_add2_insn (out, op0)); 752150397Sobrien REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUIV, in, REG_NOTES (insn)); 752218334Speter } 752318334Speter 752418334Speter#ifdef SECONDARY_MEMORY_NEEDED 752518334Speter /* If we need a memory location to do the move, do it that way. */ 7526104752Skan else if ((in_regnum = true_regnum (in)) >= 0 7527104752Skan && in_regnum < FIRST_PSEUDO_REGISTER 7528104752Skan && (out_regnum = true_regnum (out)) >= 0 7529104752Skan && out_regnum < FIRST_PSEUDO_REGISTER 7530104752Skan && SECONDARY_MEMORY_NEEDED (REGNO_REG_CLASS (in_regnum), 7531104752Skan REGNO_REG_CLASS (out_regnum), 753218334Speter GET_MODE (out))) 753318334Speter { 753418334Speter /* Get the memory to use and rewrite both registers to its mode. */ 753518334Speter rtx loc = get_secondary_mem (in, GET_MODE (out), opnum, type); 753618334Speter 753718334Speter if (GET_MODE (loc) != GET_MODE (out)) 7538104752Skan out = gen_rtx_REG (GET_MODE (loc), out_regnum); 753918334Speter 754018334Speter if (GET_MODE (loc) != GET_MODE (in)) 7541104752Skan in = gen_rtx_REG (GET_MODE (loc), in_regnum); 754218334Speter 754350397Sobrien gen_reload (loc, in, opnum, type); 754450397Sobrien gen_reload (out, loc, opnum, type); 754518334Speter } 754618334Speter#endif 754718334Speter 754818334Speter /* If IN is a simple operand, use gen_move_insn. */ 754918334Speter else if (GET_RTX_CLASS (GET_CODE (in)) == 'o' || GET_CODE (in) == SUBREG) 755018334Speter emit_insn (gen_move_insn (out, in)); 755118334Speter 755218334Speter#ifdef HAVE_reload_load_address 755318334Speter else if (HAVE_reload_load_address) 755418334Speter emit_insn (gen_reload_load_address (out, in)); 755518334Speter#endif 755618334Speter 755718334Speter /* Otherwise, just write (set OUT IN) and hope for the best. */ 755818334Speter else 755950397Sobrien emit_insn (gen_rtx_SET (VOIDmode, out, in)); 756018334Speter 756118334Speter /* Return the first insn emitted. 756218334Speter We can not just return get_last_insn, because there may have 756318334Speter been multiple instructions emitted. Also note that gen_move_insn may 756418334Speter emit more than one insn itself, so we can not assume that there is one 756518334Speter insn emitted per emit_insn_before call. */ 756618334Speter 756718334Speter return last ? NEXT_INSN (last) : get_insns (); 756818334Speter} 756918334Speter 757090075Sobrien/* Delete a previously made output-reload whose result we now believe 757190075Sobrien is not needed. First we double-check. 757218334Speter 757318334Speter INSN is the insn now being processed. 757452284Sobrien LAST_RELOAD_REG is the hard register number for which we want to delete 757552284Sobrien the last output reload. 757652284Sobrien J is the reload-number that originally used REG. The caller has made 757752284Sobrien certain that reload J doesn't use REG any longer for input. */ 757818334Speter 757918334Speterstatic void 758052284Sobriendelete_output_reload (insn, j, last_reload_reg) 758118334Speter rtx insn; 758218334Speter int j; 758352284Sobrien int last_reload_reg; 758418334Speter{ 758552284Sobrien rtx output_reload_insn = spill_reg_store[last_reload_reg]; 758652284Sobrien rtx reg = spill_reg_stored_to[last_reload_reg]; 758752284Sobrien int k; 758852284Sobrien int n_occurrences; 758952284Sobrien int n_inherited = 0; 759090075Sobrien rtx i1; 759152284Sobrien rtx substed; 759290075Sobrien 7593104752Skan /* It is possible that this reload has been only used to set another reload 7594104752Skan we eliminated earlier and thus deleted this instruction too. */ 7595104752Skan if (INSN_DELETED_P (output_reload_insn)) 7596104752Skan return; 7597104752Skan 759818334Speter /* Get the raw pseudo-register referred to. */ 759918334Speter 760018334Speter while (GET_CODE (reg) == SUBREG) 760118334Speter reg = SUBREG_REG (reg); 760252284Sobrien substed = reg_equiv_memory_loc[REGNO (reg)]; 760318334Speter 760452284Sobrien /* This is unsafe if the operand occurs more often in the current 760552284Sobrien insn than it is inherited. */ 760652284Sobrien for (k = n_reloads - 1; k >= 0; k--) 760752284Sobrien { 760890075Sobrien rtx reg2 = rld[k].in; 760952284Sobrien if (! reg2) 761052284Sobrien continue; 761152284Sobrien if (GET_CODE (reg2) == MEM || reload_override_in[k]) 761290075Sobrien reg2 = rld[k].in_reg; 761352284Sobrien#ifdef AUTO_INC_DEC 761490075Sobrien if (rld[k].out && ! rld[k].out_reg) 761590075Sobrien reg2 = XEXP (rld[k].in_reg, 0); 761652284Sobrien#endif 761752284Sobrien while (GET_CODE (reg2) == SUBREG) 761852284Sobrien reg2 = SUBREG_REG (reg2); 761952284Sobrien if (rtx_equal_p (reg2, reg)) 762052284Sobrien { 762152284Sobrien if (reload_inherited[k] || reload_override_in[k] || k == j) 762252284Sobrien { 762352284Sobrien n_inherited++; 762490075Sobrien reg2 = rld[k].out_reg; 762552284Sobrien if (! reg2) 762652284Sobrien continue; 762752284Sobrien while (GET_CODE (reg2) == SUBREG) 762852284Sobrien reg2 = XEXP (reg2, 0); 762952284Sobrien if (rtx_equal_p (reg2, reg)) 763052284Sobrien n_inherited++; 763152284Sobrien } 763252284Sobrien else 763352284Sobrien return; 763452284Sobrien } 763552284Sobrien } 763690075Sobrien n_occurrences = count_occurrences (PATTERN (insn), reg, 0); 763752284Sobrien if (substed) 763890075Sobrien n_occurrences += count_occurrences (PATTERN (insn), 763990075Sobrien eliminate_regs (substed, 0, 764090075Sobrien NULL_RTX), 0); 764152284Sobrien if (n_occurrences > n_inherited) 764252284Sobrien return; 764352284Sobrien 764418334Speter /* If the pseudo-reg we are reloading is no longer referenced 764518334Speter anywhere between the store into it and here, 764618334Speter and no jumps or labels intervene, then the value can get 764718334Speter here through the reload reg alone. 764818334Speter Otherwise, give up--return. */ 764918334Speter for (i1 = NEXT_INSN (output_reload_insn); 765018334Speter i1 != insn; i1 = NEXT_INSN (i1)) 765118334Speter { 765218334Speter if (GET_CODE (i1) == CODE_LABEL || GET_CODE (i1) == JUMP_INSN) 765318334Speter return; 765418334Speter if ((GET_CODE (i1) == INSN || GET_CODE (i1) == CALL_INSN) 765518334Speter && reg_mentioned_p (reg, PATTERN (i1))) 765650397Sobrien { 765752284Sobrien /* If this is USE in front of INSN, we only have to check that 765852284Sobrien there are no more references than accounted for by inheritance. */ 765952284Sobrien while (GET_CODE (i1) == INSN && GET_CODE (PATTERN (i1)) == USE) 766050397Sobrien { 766152284Sobrien n_occurrences += rtx_equal_p (reg, XEXP (PATTERN (i1), 0)) != 0; 766250397Sobrien i1 = NEXT_INSN (i1); 766350397Sobrien } 766452284Sobrien if (n_occurrences <= n_inherited && i1 == insn) 766550397Sobrien break; 766650397Sobrien return; 766750397Sobrien } 766818334Speter } 766918334Speter 767090075Sobrien /* We will be deleting the insn. Remove the spill reg information. */ 767190075Sobrien for (k = HARD_REGNO_NREGS (last_reload_reg, GET_MODE (reg)); k-- > 0; ) 767290075Sobrien { 767390075Sobrien spill_reg_store[last_reload_reg + k] = 0; 767490075Sobrien spill_reg_stored_to[last_reload_reg + k] = 0; 767590075Sobrien } 767690075Sobrien 767750397Sobrien /* The caller has already checked that REG dies or is set in INSN. 767890075Sobrien It has also checked that we are optimizing, and thus some 767990075Sobrien inaccurancies in the debugging information are acceptable. 768090075Sobrien So we could just delete output_reload_insn. But in some cases 768190075Sobrien we can improve the debugging information without sacrificing 768290075Sobrien optimization - maybe even improving the code: See if the pseudo 768390075Sobrien reg has been completely replaced with reload regs. If so, delete 768490075Sobrien the store insn and forget we had a stack slot for the pseudo. */ 768590075Sobrien if (rld[j].out != rld[j].in 768650397Sobrien && REG_N_DEATHS (REGNO (reg)) == 1 768752284Sobrien && REG_N_SETS (REGNO (reg)) == 1 768850397Sobrien && REG_BASIC_BLOCK (REGNO (reg)) >= 0 768950397Sobrien && find_regno_note (insn, REG_DEAD, REGNO (reg))) 769018334Speter { 769118334Speter rtx i2; 769218334Speter 769390075Sobrien /* We know that it was used only between here and the beginning of 769490075Sobrien the current basic block. (We also know that the last use before 769590075Sobrien INSN was the output reload we are thinking of deleting, but never 769690075Sobrien mind that.) Search that range; see if any ref remains. */ 769718334Speter for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2)) 769818334Speter { 769918334Speter rtx set = single_set (i2); 770018334Speter 770118334Speter /* Uses which just store in the pseudo don't count, 770218334Speter since if they are the only uses, they are dead. */ 770318334Speter if (set != 0 && SET_DEST (set) == reg) 770418334Speter continue; 770518334Speter if (GET_CODE (i2) == CODE_LABEL 770618334Speter || GET_CODE (i2) == JUMP_INSN) 770718334Speter break; 770818334Speter if ((GET_CODE (i2) == INSN || GET_CODE (i2) == CALL_INSN) 770918334Speter && reg_mentioned_p (reg, PATTERN (i2))) 771050397Sobrien { 771150397Sobrien /* Some other ref remains; just delete the output reload we 771250397Sobrien know to be dead. */ 771352284Sobrien delete_address_reloads (output_reload_insn, insn); 771490075Sobrien delete_insn (output_reload_insn); 771550397Sobrien return; 771650397Sobrien } 771718334Speter } 771818334Speter 771990075Sobrien /* Delete the now-dead stores into this pseudo. Note that this 772090075Sobrien loop also takes care of deleting output_reload_insn. */ 772118334Speter for (i2 = PREV_INSN (insn); i2; i2 = PREV_INSN (i2)) 772218334Speter { 772318334Speter rtx set = single_set (i2); 772418334Speter 772518334Speter if (set != 0 && SET_DEST (set) == reg) 772650397Sobrien { 772752284Sobrien delete_address_reloads (i2, insn); 772890075Sobrien delete_insn (i2); 772950397Sobrien } 773018334Speter if (GET_CODE (i2) == CODE_LABEL 773118334Speter || GET_CODE (i2) == JUMP_INSN) 773218334Speter break; 773318334Speter } 773418334Speter 773590075Sobrien /* For the debugging info, say the pseudo lives in this reload reg. */ 773690075Sobrien reg_renumber[REGNO (reg)] = REGNO (rld[j].reg_rtx); 773718334Speter alter_reg (REGNO (reg), -1); 773818334Speter } 773990075Sobrien else 774090075Sobrien { 774190075Sobrien delete_address_reloads (output_reload_insn, insn); 774290075Sobrien delete_insn (output_reload_insn); 774390075Sobrien } 774418334Speter} 774552284Sobrien 774652284Sobrien/* We are going to delete DEAD_INSN. Recursively delete loads of 774752284Sobrien reload registers used in DEAD_INSN that are not used till CURRENT_INSN. 774852284Sobrien CURRENT_INSN is being reloaded, so we have to check its reloads too. */ 774952284Sobrienstatic void 775052284Sobriendelete_address_reloads (dead_insn, current_insn) 775152284Sobrien rtx dead_insn, current_insn; 775252284Sobrien{ 775352284Sobrien rtx set = single_set (dead_insn); 775452284Sobrien rtx set2, dst, prev, next; 775552284Sobrien if (set) 775652284Sobrien { 775752284Sobrien rtx dst = SET_DEST (set); 775852284Sobrien if (GET_CODE (dst) == MEM) 775952284Sobrien delete_address_reloads_1 (dead_insn, XEXP (dst, 0), current_insn); 776052284Sobrien } 776152284Sobrien /* If we deleted the store from a reloaded post_{in,de}c expression, 776252284Sobrien we can delete the matching adds. */ 776352284Sobrien prev = PREV_INSN (dead_insn); 776452284Sobrien next = NEXT_INSN (dead_insn); 776552284Sobrien if (! prev || ! next) 776652284Sobrien return; 776752284Sobrien set = single_set (next); 776852284Sobrien set2 = single_set (prev); 776952284Sobrien if (! set || ! set2 777052284Sobrien || GET_CODE (SET_SRC (set)) != PLUS || GET_CODE (SET_SRC (set2)) != PLUS 777152284Sobrien || GET_CODE (XEXP (SET_SRC (set), 1)) != CONST_INT 777252284Sobrien || GET_CODE (XEXP (SET_SRC (set2), 1)) != CONST_INT) 777352284Sobrien return; 777452284Sobrien dst = SET_DEST (set); 777552284Sobrien if (! rtx_equal_p (dst, SET_DEST (set2)) 777652284Sobrien || ! rtx_equal_p (dst, XEXP (SET_SRC (set), 0)) 777752284Sobrien || ! rtx_equal_p (dst, XEXP (SET_SRC (set2), 0)) 777852284Sobrien || (INTVAL (XEXP (SET_SRC (set), 1)) 777990075Sobrien != -INTVAL (XEXP (SET_SRC (set2), 1)))) 778052284Sobrien return; 778190075Sobrien delete_related_insns (prev); 778290075Sobrien delete_related_insns (next); 778352284Sobrien} 778452284Sobrien 778552284Sobrien/* Subfunction of delete_address_reloads: process registers found in X. */ 778652284Sobrienstatic void 778752284Sobriendelete_address_reloads_1 (dead_insn, x, current_insn) 778852284Sobrien rtx dead_insn, x, current_insn; 778952284Sobrien{ 779052284Sobrien rtx prev, set, dst, i2; 779152284Sobrien int i, j; 779252284Sobrien enum rtx_code code = GET_CODE (x); 779352284Sobrien 779452284Sobrien if (code != REG) 779552284Sobrien { 779690075Sobrien const char *fmt = GET_RTX_FORMAT (code); 779752284Sobrien for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 779852284Sobrien { 779952284Sobrien if (fmt[i] == 'e') 780052284Sobrien delete_address_reloads_1 (dead_insn, XEXP (x, i), current_insn); 780152284Sobrien else if (fmt[i] == 'E') 780252284Sobrien { 780390075Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 780452284Sobrien delete_address_reloads_1 (dead_insn, XVECEXP (x, i, j), 780552284Sobrien current_insn); 780652284Sobrien } 780752284Sobrien } 780852284Sobrien return; 780952284Sobrien } 781052284Sobrien 781152284Sobrien if (spill_reg_order[REGNO (x)] < 0) 781252284Sobrien return; 781352284Sobrien 781452284Sobrien /* Scan backwards for the insn that sets x. This might be a way back due 781552284Sobrien to inheritance. */ 781652284Sobrien for (prev = PREV_INSN (dead_insn); prev; prev = PREV_INSN (prev)) 781752284Sobrien { 781852284Sobrien code = GET_CODE (prev); 781952284Sobrien if (code == CODE_LABEL || code == JUMP_INSN) 782052284Sobrien return; 782152284Sobrien if (GET_RTX_CLASS (code) != 'i') 782252284Sobrien continue; 782352284Sobrien if (reg_set_p (x, PATTERN (prev))) 782452284Sobrien break; 782552284Sobrien if (reg_referenced_p (x, PATTERN (prev))) 782652284Sobrien return; 782752284Sobrien } 782852284Sobrien if (! prev || INSN_UID (prev) < reload_first_uid) 782952284Sobrien return; 783052284Sobrien /* Check that PREV only sets the reload register. */ 783152284Sobrien set = single_set (prev); 783252284Sobrien if (! set) 783352284Sobrien return; 783452284Sobrien dst = SET_DEST (set); 783552284Sobrien if (GET_CODE (dst) != REG 783652284Sobrien || ! rtx_equal_p (dst, x)) 783752284Sobrien return; 783852284Sobrien if (! reg_set_p (dst, PATTERN (dead_insn))) 783952284Sobrien { 784052284Sobrien /* Check if DST was used in a later insn - 784152284Sobrien it might have been inherited. */ 784252284Sobrien for (i2 = NEXT_INSN (dead_insn); i2; i2 = NEXT_INSN (i2)) 784352284Sobrien { 784452284Sobrien if (GET_CODE (i2) == CODE_LABEL) 784552284Sobrien break; 784690075Sobrien if (! INSN_P (i2)) 784752284Sobrien continue; 784852284Sobrien if (reg_referenced_p (dst, PATTERN (i2))) 784952284Sobrien { 785052284Sobrien /* If there is a reference to the register in the current insn, 785152284Sobrien it might be loaded in a non-inherited reload. If no other 785252284Sobrien reload uses it, that means the register is set before 785352284Sobrien referenced. */ 785452284Sobrien if (i2 == current_insn) 785552284Sobrien { 785652284Sobrien for (j = n_reloads - 1; j >= 0; j--) 785790075Sobrien if ((rld[j].reg_rtx == dst && reload_inherited[j]) 785852284Sobrien || reload_override_in[j] == dst) 785952284Sobrien return; 786052284Sobrien for (j = n_reloads - 1; j >= 0; j--) 786190075Sobrien if (rld[j].in && rld[j].reg_rtx == dst) 786252284Sobrien break; 786352284Sobrien if (j >= 0) 786452284Sobrien break; 786552284Sobrien } 786652284Sobrien return; 786752284Sobrien } 786852284Sobrien if (GET_CODE (i2) == JUMP_INSN) 786952284Sobrien break; 787052284Sobrien /* If DST is still live at CURRENT_INSN, check if it is used for 787152284Sobrien any reload. Note that even if CURRENT_INSN sets DST, we still 787252284Sobrien have to check the reloads. */ 787352284Sobrien if (i2 == current_insn) 787452284Sobrien { 787552284Sobrien for (j = n_reloads - 1; j >= 0; j--) 787690075Sobrien if ((rld[j].reg_rtx == dst && reload_inherited[j]) 787752284Sobrien || reload_override_in[j] == dst) 787852284Sobrien return; 787952284Sobrien /* ??? We can't finish the loop here, because dst might be 788052284Sobrien allocated to a pseudo in this block if no reload in this 788152284Sobrien block needs any of the clsses containing DST - see 788252284Sobrien spill_hard_reg. There is no easy way to tell this, so we 788352284Sobrien have to scan till the end of the basic block. */ 788452284Sobrien } 788552284Sobrien if (reg_set_p (dst, PATTERN (i2))) 788652284Sobrien break; 788752284Sobrien } 788852284Sobrien } 788952284Sobrien delete_address_reloads_1 (prev, SET_SRC (set), current_insn); 789052284Sobrien reg_reloaded_contents[REGNO (dst)] = -1; 789190075Sobrien delete_insn (prev); 789252284Sobrien} 789318334Speter 789418334Speter/* Output reload-insns to reload VALUE into RELOADREG. 789518334Speter VALUE is an autoincrement or autodecrement RTX whose operand 789618334Speter is a register or memory location; 789718334Speter so reloading involves incrementing that location. 789852284Sobrien IN is either identical to VALUE, or some cheaper place to reload from. 789918334Speter 790018334Speter INC_AMOUNT is the number to increment or decrement by (always positive). 790152284Sobrien This cannot be deduced from VALUE. 790218334Speter 790352284Sobrien Return the instruction that stores into RELOADREG. */ 790452284Sobrien 790552284Sobrienstatic rtx 790652284Sobrieninc_for_reload (reloadreg, in, value, inc_amount) 790718334Speter rtx reloadreg; 790852284Sobrien rtx in, value; 790918334Speter int inc_amount; 791018334Speter{ 791118334Speter /* REG or MEM to be copied and incremented. */ 791218334Speter rtx incloc = XEXP (value, 0); 791318334Speter /* Nonzero if increment after copying. */ 791418334Speter int post = (GET_CODE (value) == POST_DEC || GET_CODE (value) == POST_INC); 791518334Speter rtx last; 791618334Speter rtx inc; 791718334Speter rtx add_insn; 791818334Speter int code; 791952284Sobrien rtx store; 792052284Sobrien rtx real_in = in == value ? XEXP (in, 0) : in; 792118334Speter 792218334Speter /* No hard register is equivalent to this register after 792318334Speter inc/dec operation. If REG_LAST_RELOAD_REG were non-zero, 792418334Speter we could inc/dec that register as well (maybe even using it for 792518334Speter the source), but I'm not sure it's worth worrying about. */ 792618334Speter if (GET_CODE (incloc) == REG) 792718334Speter reg_last_reload_reg[REGNO (incloc)] = 0; 792818334Speter 792918334Speter if (GET_CODE (value) == PRE_DEC || GET_CODE (value) == POST_DEC) 793090075Sobrien inc_amount = -inc_amount; 793118334Speter 793218334Speter inc = GEN_INT (inc_amount); 793318334Speter 793418334Speter /* If this is post-increment, first copy the location to the reload reg. */ 793552284Sobrien if (post && real_in != reloadreg) 793652284Sobrien emit_insn (gen_move_insn (reloadreg, real_in)); 793718334Speter 793852284Sobrien if (in == value) 793952284Sobrien { 794052284Sobrien /* See if we can directly increment INCLOC. Use a method similar to 794152284Sobrien that in gen_reload. */ 794218334Speter 794352284Sobrien last = get_last_insn (); 794452284Sobrien add_insn = emit_insn (gen_rtx_SET (VOIDmode, incloc, 794552284Sobrien gen_rtx_PLUS (GET_MODE (incloc), 794652284Sobrien incloc, inc))); 794790075Sobrien 794852284Sobrien code = recog_memoized (add_insn); 794952284Sobrien if (code >= 0) 795018334Speter { 795152284Sobrien extract_insn (add_insn); 795252284Sobrien if (constrain_operands (1)) 795352284Sobrien { 795452284Sobrien /* If this is a pre-increment and we have incremented the value 795552284Sobrien where it lives, copy the incremented value to RELOADREG to 795652284Sobrien be used as an address. */ 795718334Speter 795852284Sobrien if (! post) 795952284Sobrien emit_insn (gen_move_insn (reloadreg, incloc)); 796018334Speter 796152284Sobrien return add_insn; 796252284Sobrien } 796318334Speter } 796452284Sobrien delete_insns_since (last); 796518334Speter } 796618334Speter 796718334Speter /* If couldn't do the increment directly, must increment in RELOADREG. 796818334Speter The way we do this depends on whether this is pre- or post-increment. 796918334Speter For pre-increment, copy INCLOC to the reload register, increment it 797018334Speter there, then save back. */ 797118334Speter 797218334Speter if (! post) 797318334Speter { 797452284Sobrien if (in != reloadreg) 797552284Sobrien emit_insn (gen_move_insn (reloadreg, real_in)); 797618334Speter emit_insn (gen_add2_insn (reloadreg, inc)); 797752284Sobrien store = emit_insn (gen_move_insn (incloc, reloadreg)); 797818334Speter } 797918334Speter else 798018334Speter { 798118334Speter /* Postincrement. 798218334Speter Because this might be a jump insn or a compare, and because RELOADREG 798318334Speter may not be available after the insn in an input reload, we must do 798418334Speter the incrementation before the insn being reloaded for. 798518334Speter 798652284Sobrien We have already copied IN to RELOADREG. Increment the copy in 798718334Speter RELOADREG, save that back, then decrement RELOADREG so it has 798818334Speter the original value. */ 798918334Speter 799018334Speter emit_insn (gen_add2_insn (reloadreg, inc)); 799152284Sobrien store = emit_insn (gen_move_insn (incloc, reloadreg)); 799218334Speter emit_insn (gen_add2_insn (reloadreg, GEN_INT (-inc_amount))); 799318334Speter } 799418334Speter 799552284Sobrien return store; 799618334Speter} 799718334Speter 799890075Sobrien/* INSN is a no-op; delete it. 799990075Sobrien If this sets the return value of the function, we must keep a USE around, 800090075Sobrien in case this is in a different basic block than the final USE. Otherwise, 800190075Sobrien we could loose important register lifeness information on 800290075Sobrien SMALL_REGISTER_CLASSES machines, where return registers might be used as 800390075Sobrien spills: subsequent passes assume that spill registers are dead at the end 800490075Sobrien of a basic block. 800590075Sobrien VALUE must be the return value in such a case, NULL otherwise. */ 800690075Sobrienstatic void 800790075Sobrienreload_cse_delete_noop_set (insn, value) 800890075Sobrien rtx insn, value; 800918334Speter{ 801096263Sobrien bool purge = BLOCK_FOR_INSN (insn)->end == insn; 801190075Sobrien if (value) 801218334Speter { 801390075Sobrien PATTERN (insn) = gen_rtx_USE (VOIDmode, value); 801490075Sobrien INSN_CODE (insn) = -1; 801590075Sobrien REG_NOTES (insn) = NULL_RTX; 801618334Speter } 801790075Sobrien else 801890075Sobrien delete_insn (insn); 801996263Sobrien if (purge) 802096263Sobrien purge_dead_edges (BLOCK_FOR_INSN (insn)); 802190075Sobrien} 802218334Speter 802390075Sobrien/* See whether a single set SET is a noop. */ 802490075Sobrienstatic int 802590075Sobrienreload_cse_noop_set_p (set) 802690075Sobrien rtx set; 802790075Sobrien{ 802890075Sobrien return rtx_equal_for_cselib_p (SET_DEST (set), SET_SRC (set)); 802918334Speter} 803050397Sobrien 803190075Sobrien/* Try to simplify INSN. */ 803250397Sobrienstatic void 803390075Sobrienreload_cse_simplify (insn) 803490075Sobrien rtx insn; 803550397Sobrien{ 803690075Sobrien rtx body = PATTERN (insn); 803750397Sobrien 803890075Sobrien if (GET_CODE (body) == SET) 803990075Sobrien { 804090075Sobrien int count = 0; 804150397Sobrien 804290075Sobrien /* Simplify even if we may think it is a no-op. 804390075Sobrien We may think a memory load of a value smaller than WORD_SIZE 804490075Sobrien is redundant because we haven't taken into account possible 804590075Sobrien implicit extension. reload_cse_simplify_set() will bring 804690075Sobrien this out, so it's safer to simplify before we delete. */ 804790075Sobrien count += reload_cse_simplify_set (body, insn); 804850397Sobrien 804990075Sobrien if (!count && reload_cse_noop_set_p (body)) 805050397Sobrien { 805190075Sobrien rtx value = SET_DEST (body); 805290075Sobrien if (! REG_FUNCTION_VALUE_P (SET_DEST (body))) 805390075Sobrien value = 0; 805490075Sobrien reload_cse_delete_noop_set (insn, value); 805590075Sobrien return; 805650397Sobrien } 805790075Sobrien 805890075Sobrien if (count > 0) 805990075Sobrien apply_change_group (); 806090075Sobrien else 806190075Sobrien reload_cse_simplify_operands (insn); 806250397Sobrien } 806390075Sobrien else if (GET_CODE (body) == PARALLEL) 806450397Sobrien { 806590075Sobrien int i; 806690075Sobrien int count = 0; 806790075Sobrien rtx value = NULL_RTX; 806850397Sobrien 806990075Sobrien /* If every action in a PARALLEL is a noop, we can delete 807090075Sobrien the entire PARALLEL. */ 807190075Sobrien for (i = XVECLEN (body, 0) - 1; i >= 0; --i) 807250397Sobrien { 807390075Sobrien rtx part = XVECEXP (body, 0, i); 807490075Sobrien if (GET_CODE (part) == SET) 807550397Sobrien { 807690075Sobrien if (! reload_cse_noop_set_p (part)) 807790075Sobrien break; 807890075Sobrien if (REG_FUNCTION_VALUE_P (SET_DEST (part))) 807950397Sobrien { 808090075Sobrien if (value) 808190075Sobrien break; 808290075Sobrien value = SET_DEST (part); 808350397Sobrien } 808450397Sobrien } 808590075Sobrien else if (GET_CODE (part) != CLOBBER) 808690075Sobrien break; 808750397Sobrien } 808850397Sobrien 808990075Sobrien if (i < 0) 809050397Sobrien { 809190075Sobrien reload_cse_delete_noop_set (insn, value); 809290075Sobrien /* We're done with this insn. */ 809390075Sobrien return; 809450397Sobrien } 809550397Sobrien 809690075Sobrien /* It's not a no-op, but we can try to simplify it. */ 809790075Sobrien for (i = XVECLEN (body, 0) - 1; i >= 0; --i) 809890075Sobrien if (GET_CODE (XVECEXP (body, 0, i)) == SET) 809990075Sobrien count += reload_cse_simplify_set (XVECEXP (body, 0, i), insn); 810050397Sobrien 810190075Sobrien if (count > 0) 810290075Sobrien apply_change_group (); 810390075Sobrien else 810490075Sobrien reload_cse_simplify_operands (insn); 810550397Sobrien } 810650397Sobrien} 810750397Sobrien 810850397Sobrien/* Do a very simple CSE pass over the hard registers. 810950397Sobrien 811050397Sobrien This function detects no-op moves where we happened to assign two 811150397Sobrien different pseudo-registers to the same hard register, and then 811250397Sobrien copied one to the other. Reload will generate a useless 811350397Sobrien instruction copying a register to itself. 811450397Sobrien 811550397Sobrien This function also detects cases where we load a value from memory 811650397Sobrien into two different registers, and (if memory is more expensive than 811750397Sobrien registers) changes it to simply copy the first register into the 811890075Sobrien second register. 811950397Sobrien 812050397Sobrien Another optimization is performed that scans the operands of each 812150397Sobrien instruction to see whether the value is already available in a 812250397Sobrien hard register. It then replaces the operand with the hard register 812350397Sobrien if possible, much like an optional reload would. */ 812450397Sobrien 812552284Sobrienstatic void 812652284Sobrienreload_cse_regs_1 (first) 812750397Sobrien rtx first; 812850397Sobrien{ 812950397Sobrien rtx insn; 813050397Sobrien 813190075Sobrien cselib_init (); 813250397Sobrien init_alias_analysis (); 813350397Sobrien 813450397Sobrien for (insn = first; insn; insn = NEXT_INSN (insn)) 813550397Sobrien { 813690075Sobrien if (INSN_P (insn)) 813790075Sobrien reload_cse_simplify (insn); 813850397Sobrien 813990075Sobrien cselib_process_insn (insn); 814050397Sobrien } 814150397Sobrien 814290075Sobrien /* Clean up. */ 814390075Sobrien end_alias_analysis (); 814490075Sobrien cselib_finish (); 814550397Sobrien} 814650397Sobrien 814752284Sobrien/* Call cse / combine like post-reload optimization phases. 814852284Sobrien FIRST is the first instruction. */ 814952284Sobrienvoid 815052284Sobrienreload_cse_regs (first) 815152284Sobrien rtx first; 815252284Sobrien{ 815352284Sobrien reload_cse_regs_1 (first); 815452284Sobrien reload_combine (); 815552284Sobrien reload_cse_move2add (first); 815652284Sobrien if (flag_expensive_optimizations) 815752284Sobrien reload_cse_regs_1 (first); 815852284Sobrien} 815952284Sobrien 816050397Sobrien/* Try to simplify a single SET instruction. SET is the set pattern. 816150397Sobrien INSN is the instruction it came from. 816250397Sobrien This function only handles one case: if we set a register to a value 816350397Sobrien which is not a register, we try to find that value in some other register 816450397Sobrien and change the set into a register copy. */ 816550397Sobrien 816650397Sobrienstatic int 816750397Sobrienreload_cse_simplify_set (set, insn) 816850397Sobrien rtx set; 816950397Sobrien rtx insn; 817050397Sobrien{ 817190075Sobrien int did_change = 0; 817250397Sobrien int dreg; 817350397Sobrien rtx src; 817450397Sobrien enum reg_class dclass; 817590075Sobrien int old_cost; 817690075Sobrien cselib_val *val; 817790075Sobrien struct elt_loc_list *l; 817890075Sobrien#ifdef LOAD_EXTEND_OP 817990075Sobrien enum rtx_code extend_op = NIL; 818090075Sobrien#endif 818150397Sobrien 818250397Sobrien dreg = true_regnum (SET_DEST (set)); 818350397Sobrien if (dreg < 0) 818450397Sobrien return 0; 818550397Sobrien 818650397Sobrien src = SET_SRC (set); 818750397Sobrien if (side_effects_p (src) || true_regnum (src) >= 0) 818850397Sobrien return 0; 818950397Sobrien 819050397Sobrien dclass = REGNO_REG_CLASS (dreg); 819150397Sobrien 819290075Sobrien#ifdef LOAD_EXTEND_OP 819390075Sobrien /* When replacing a memory with a register, we need to honor assumptions 819490075Sobrien that combine made wrt the contents of sign bits. We'll do this by 819590075Sobrien generating an extend instruction instead of a reg->reg copy. Thus 819690075Sobrien the destination must be a register that we can widen. */ 819750397Sobrien if (GET_CODE (src) == MEM 819890075Sobrien && GET_MODE_BITSIZE (GET_MODE (src)) < BITS_PER_WORD 819990075Sobrien && (extend_op = LOAD_EXTEND_OP (GET_MODE (src))) != NIL 820090075Sobrien && GET_CODE (SET_DEST (set)) != REG) 820150397Sobrien return 0; 820290075Sobrien#endif 820350397Sobrien 820490075Sobrien /* If memory loads are cheaper than register copies, don't change them. */ 820590075Sobrien if (GET_CODE (src) == MEM) 820690075Sobrien old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1); 820790075Sobrien else if (CONSTANT_P (src)) 820890075Sobrien old_cost = rtx_cost (src, SET); 820990075Sobrien else if (GET_CODE (src) == REG) 821090075Sobrien old_cost = REGISTER_MOVE_COST (GET_MODE (src), 821190075Sobrien REGNO_REG_CLASS (REGNO (src)), dclass); 821290075Sobrien else 821390075Sobrien /* ??? */ 821490075Sobrien old_cost = rtx_cost (src, SET); 821590075Sobrien 821690075Sobrien val = cselib_lookup (src, GET_MODE (SET_DEST (set)), 0); 821790075Sobrien if (! val) 821850397Sobrien return 0; 821990075Sobrien for (l = val->locs; l; l = l->next) 822090075Sobrien { 822190075Sobrien rtx this_rtx = l->loc; 822290075Sobrien int this_cost; 822350397Sobrien 822490075Sobrien if (CONSTANT_P (this_rtx) && ! references_value_p (this_rtx, 0)) 822550397Sobrien { 822690075Sobrien#ifdef LOAD_EXTEND_OP 822790075Sobrien if (extend_op != NIL) 822890075Sobrien { 822990075Sobrien HOST_WIDE_INT this_val; 823050397Sobrien 823190075Sobrien /* ??? I'm lazy and don't wish to handle CONST_DOUBLE. Other 823290075Sobrien constants, such as SYMBOL_REF, cannot be extended. */ 823390075Sobrien if (GET_CODE (this_rtx) != CONST_INT) 823490075Sobrien continue; 823550397Sobrien 823690075Sobrien this_val = INTVAL (this_rtx); 823790075Sobrien switch (extend_op) 823890075Sobrien { 823990075Sobrien case ZERO_EXTEND: 824090075Sobrien this_val &= GET_MODE_MASK (GET_MODE (src)); 824190075Sobrien break; 824290075Sobrien case SIGN_EXTEND: 824390075Sobrien /* ??? In theory we're already extended. */ 824490075Sobrien if (this_val == trunc_int_for_mode (this_val, GET_MODE (src))) 824590075Sobrien break; 824690075Sobrien default: 824790075Sobrien abort (); 824890075Sobrien } 824990075Sobrien this_rtx = GEN_INT (this_val); 825090075Sobrien } 825190075Sobrien#endif 825290075Sobrien this_cost = rtx_cost (this_rtx, SET); 825390075Sobrien } 825490075Sobrien else if (GET_CODE (this_rtx) == REG) 825590075Sobrien { 825690075Sobrien#ifdef LOAD_EXTEND_OP 825790075Sobrien if (extend_op != NIL) 825890075Sobrien { 825990075Sobrien this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx); 826090075Sobrien this_cost = rtx_cost (this_rtx, SET); 826190075Sobrien } 826290075Sobrien else 826390075Sobrien#endif 826490075Sobrien this_cost = REGISTER_MOVE_COST (GET_MODE (this_rtx), 826590075Sobrien REGNO_REG_CLASS (REGNO (this_rtx)), 826690075Sobrien dclass); 826790075Sobrien } 826890075Sobrien else 826990075Sobrien continue; 827050397Sobrien 827190075Sobrien /* If equal costs, prefer registers over anything else. That 827290075Sobrien tends to lead to smaller instructions on some machines. */ 827390075Sobrien if (this_cost < old_cost 827490075Sobrien || (this_cost == old_cost 827590075Sobrien && GET_CODE (this_rtx) == REG 827690075Sobrien && GET_CODE (SET_SRC (set)) != REG)) 827790075Sobrien { 827890075Sobrien#ifdef LOAD_EXTEND_OP 827990075Sobrien if (GET_MODE_BITSIZE (GET_MODE (SET_DEST (set))) < BITS_PER_WORD 828090075Sobrien && extend_op != NIL) 828190075Sobrien { 828290075Sobrien rtx wide_dest = gen_rtx_REG (word_mode, REGNO (SET_DEST (set))); 828390075Sobrien ORIGINAL_REGNO (wide_dest) = ORIGINAL_REGNO (SET_DEST (set)); 828490075Sobrien validate_change (insn, &SET_DEST (set), wide_dest, 1); 828590075Sobrien } 828690075Sobrien#endif 828750397Sobrien 828890075Sobrien validate_change (insn, &SET_SRC (set), copy_rtx (this_rtx), 1); 828990075Sobrien old_cost = this_cost, did_change = 1; 829050397Sobrien } 829150397Sobrien } 829290075Sobrien 829390075Sobrien return did_change; 829450397Sobrien} 829550397Sobrien 829650397Sobrien/* Try to replace operands in INSN with equivalent values that are already 829790075Sobrien in registers. This can be viewed as optional reloading. 829890075Sobrien 829950397Sobrien For each non-register operand in the insn, see if any hard regs are 830050397Sobrien known to be equivalent to that operand. Record the alternatives which 830150397Sobrien can accept these hard registers. Among all alternatives, select the 830250397Sobrien ones which are better or equal to the one currently matching, where 830350397Sobrien "better" is in terms of '?' and '!' constraints. Among the remaining 830450397Sobrien alternatives, select the one which replaces most operands with 830550397Sobrien hard registers. */ 830650397Sobrien 830750397Sobrienstatic int 830850397Sobrienreload_cse_simplify_operands (insn) 830950397Sobrien rtx insn; 831050397Sobrien{ 831190075Sobrien int i, j; 831250397Sobrien 831390075Sobrien /* For each operand, all registers that are equivalent to it. */ 831490075Sobrien HARD_REG_SET equiv_regs[MAX_RECOG_OPERANDS]; 831590075Sobrien 831652284Sobrien const char *constraints[MAX_RECOG_OPERANDS]; 831790075Sobrien 831850397Sobrien /* Vector recording how bad an alternative is. */ 831950397Sobrien int *alternative_reject; 832050397Sobrien /* Vector recording how many registers can be introduced by choosing 832150397Sobrien this alternative. */ 832250397Sobrien int *alternative_nregs; 832350397Sobrien /* Array of vectors recording, for each operand and each alternative, 832450397Sobrien which hard register to substitute, or -1 if the operand should be 832550397Sobrien left as it is. */ 832650397Sobrien int *op_alt_regno[MAX_RECOG_OPERANDS]; 832750397Sobrien /* Array of alternatives, sorted in order of decreasing desirability. */ 832850397Sobrien int *alternative_order; 832950397Sobrien rtx reg = gen_rtx_REG (VOIDmode, -1); 833090075Sobrien 833152284Sobrien extract_insn (insn); 833250397Sobrien 833390075Sobrien if (recog_data.n_alternatives == 0 || recog_data.n_operands == 0) 833450397Sobrien return 0; 833550397Sobrien 833650397Sobrien /* Figure out which alternative currently matches. */ 833752284Sobrien if (! constrain_operands (1)) 833850397Sobrien fatal_insn_not_found (insn); 833950397Sobrien 834090075Sobrien alternative_reject = (int *) alloca (recog_data.n_alternatives * sizeof (int)); 834190075Sobrien alternative_nregs = (int *) alloca (recog_data.n_alternatives * sizeof (int)); 834290075Sobrien alternative_order = (int *) alloca (recog_data.n_alternatives * sizeof (int)); 834390075Sobrien memset ((char *) alternative_reject, 0, recog_data.n_alternatives * sizeof (int)); 834490075Sobrien memset ((char *) alternative_nregs, 0, recog_data.n_alternatives * sizeof (int)); 834550397Sobrien 834690075Sobrien /* For each operand, find out which regs are equivalent. */ 834790075Sobrien for (i = 0; i < recog_data.n_operands; i++) 834850397Sobrien { 834990075Sobrien cselib_val *v; 835090075Sobrien struct elt_loc_list *l; 835190075Sobrien 835290075Sobrien CLEAR_HARD_REG_SET (equiv_regs[i]); 835390075Sobrien 835490075Sobrien /* cselib blows up on CODE_LABELs. Trying to fix that doesn't seem 835590075Sobrien right, so avoid the problem here. Likewise if we have a constant 835690075Sobrien and the insn pattern doesn't tell us the mode we need. */ 835790075Sobrien if (GET_CODE (recog_data.operand[i]) == CODE_LABEL 835890075Sobrien || (CONSTANT_P (recog_data.operand[i]) 835990075Sobrien && recog_data.operand_mode[i] == VOIDmode)) 836090075Sobrien continue; 836190075Sobrien 836290075Sobrien v = cselib_lookup (recog_data.operand[i], recog_data.operand_mode[i], 0); 836390075Sobrien if (! v) 836490075Sobrien continue; 836590075Sobrien 836690075Sobrien for (l = v->locs; l; l = l->next) 836790075Sobrien if (GET_CODE (l->loc) == REG) 836890075Sobrien SET_HARD_REG_BIT (equiv_regs[i], REGNO (l->loc)); 836990075Sobrien } 837090075Sobrien 837190075Sobrien for (i = 0; i < recog_data.n_operands; i++) 837290075Sobrien { 837350397Sobrien enum machine_mode mode; 837450397Sobrien int regno; 837552284Sobrien const char *p; 837650397Sobrien 837790075Sobrien op_alt_regno[i] = (int *) alloca (recog_data.n_alternatives * sizeof (int)); 837890075Sobrien for (j = 0; j < recog_data.n_alternatives; j++) 837950397Sobrien op_alt_regno[i][j] = -1; 838050397Sobrien 838190075Sobrien p = constraints[i] = recog_data.constraints[i]; 838290075Sobrien mode = recog_data.operand_mode[i]; 838350397Sobrien 838450397Sobrien /* Add the reject values for each alternative given by the constraints 838550397Sobrien for this operand. */ 838650397Sobrien j = 0; 838750397Sobrien while (*p != '\0') 838850397Sobrien { 838950397Sobrien char c = *p++; 839050397Sobrien if (c == ',') 839150397Sobrien j++; 839250397Sobrien else if (c == '?') 839350397Sobrien alternative_reject[j] += 3; 839450397Sobrien else if (c == '!') 839550397Sobrien alternative_reject[j] += 300; 839650397Sobrien } 839750397Sobrien 839850397Sobrien /* We won't change operands which are already registers. We 839950397Sobrien also don't want to modify output operands. */ 840090075Sobrien regno = true_regnum (recog_data.operand[i]); 840150397Sobrien if (regno >= 0 840250397Sobrien || constraints[i][0] == '=' 840350397Sobrien || constraints[i][0] == '+') 840450397Sobrien continue; 840550397Sobrien 840650397Sobrien for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) 840750397Sobrien { 840850397Sobrien int class = (int) NO_REGS; 840950397Sobrien 841090075Sobrien if (! TEST_HARD_REG_BIT (equiv_regs[i], regno)) 841150397Sobrien continue; 841250397Sobrien 841350397Sobrien REGNO (reg) = regno; 841450397Sobrien PUT_MODE (reg, mode); 841550397Sobrien 841650397Sobrien /* We found a register equal to this operand. Now look for all 841750397Sobrien alternatives that can accept this register and have not been 841850397Sobrien assigned a register they can use yet. */ 841950397Sobrien j = 0; 842050397Sobrien p = constraints[i]; 842150397Sobrien for (;;) 842250397Sobrien { 842350397Sobrien char c = *p++; 842490075Sobrien 842550397Sobrien switch (c) 842650397Sobrien { 842750397Sobrien case '=': case '+': case '?': 842850397Sobrien case '#': case '&': case '!': 842990075Sobrien case '*': case '%': 843050397Sobrien case '0': case '1': case '2': case '3': case '4': 843190075Sobrien case '5': case '6': case '7': case '8': case '9': 843250397Sobrien case 'm': case '<': case '>': case 'V': case 'o': 843350397Sobrien case 'E': case 'F': case 'G': case 'H': 843450397Sobrien case 's': case 'i': case 'n': 843550397Sobrien case 'I': case 'J': case 'K': case 'L': 843650397Sobrien case 'M': case 'N': case 'O': case 'P': 843750397Sobrien case 'p': case 'X': 843850397Sobrien /* These don't say anything we care about. */ 843950397Sobrien break; 844050397Sobrien 844150397Sobrien case 'g': case 'r': 844250397Sobrien class = reg_class_subunion[(int) class][(int) GENERAL_REGS]; 844350397Sobrien break; 844450397Sobrien 844550397Sobrien default: 844650397Sobrien class 844790075Sobrien = reg_class_subunion[(int) class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)]; 844850397Sobrien break; 844950397Sobrien 845050397Sobrien case ',': case '\0': 845150397Sobrien /* See if REGNO fits this alternative, and set it up as the 845250397Sobrien replacement register if we don't have one for this 845350397Sobrien alternative yet and the operand being replaced is not 845490075Sobrien a cheap CONST_INT. */ 845550397Sobrien if (op_alt_regno[i][j] == -1 845650397Sobrien && reg_fits_class_p (reg, class, 0, mode) 845790075Sobrien && (GET_CODE (recog_data.operand[i]) != CONST_INT 845890075Sobrien || (rtx_cost (recog_data.operand[i], SET) 845990075Sobrien > rtx_cost (reg, SET)))) 846050397Sobrien { 846150397Sobrien alternative_nregs[j]++; 846250397Sobrien op_alt_regno[i][j] = regno; 846350397Sobrien } 846450397Sobrien j++; 846550397Sobrien break; 846650397Sobrien } 846750397Sobrien 846850397Sobrien if (c == '\0') 846950397Sobrien break; 847050397Sobrien } 847150397Sobrien } 847250397Sobrien } 847350397Sobrien 847450397Sobrien /* Record all alternatives which are better or equal to the currently 847550397Sobrien matching one in the alternative_order array. */ 847690075Sobrien for (i = j = 0; i < recog_data.n_alternatives; i++) 847750397Sobrien if (alternative_reject[i] <= alternative_reject[which_alternative]) 847850397Sobrien alternative_order[j++] = i; 847990075Sobrien recog_data.n_alternatives = j; 848050397Sobrien 848150397Sobrien /* Sort it. Given a small number of alternatives, a dumb algorithm 848250397Sobrien won't hurt too much. */ 848390075Sobrien for (i = 0; i < recog_data.n_alternatives - 1; i++) 848450397Sobrien { 848550397Sobrien int best = i; 848650397Sobrien int best_reject = alternative_reject[alternative_order[i]]; 848750397Sobrien int best_nregs = alternative_nregs[alternative_order[i]]; 848850397Sobrien int tmp; 848950397Sobrien 849090075Sobrien for (j = i + 1; j < recog_data.n_alternatives; j++) 849150397Sobrien { 849250397Sobrien int this_reject = alternative_reject[alternative_order[j]]; 849350397Sobrien int this_nregs = alternative_nregs[alternative_order[j]]; 849450397Sobrien 849550397Sobrien if (this_reject < best_reject 849650397Sobrien || (this_reject == best_reject && this_nregs < best_nregs)) 849750397Sobrien { 849850397Sobrien best = j; 849950397Sobrien best_reject = this_reject; 850050397Sobrien best_nregs = this_nregs; 850150397Sobrien } 850250397Sobrien } 850390075Sobrien 850450397Sobrien tmp = alternative_order[best]; 850550397Sobrien alternative_order[best] = alternative_order[i]; 850650397Sobrien alternative_order[i] = tmp; 850750397Sobrien } 850890075Sobrien 850950397Sobrien /* Substitute the operands as determined by op_alt_regno for the best 851050397Sobrien alternative. */ 851150397Sobrien j = alternative_order[0]; 851250397Sobrien 851390075Sobrien for (i = 0; i < recog_data.n_operands; i++) 851450397Sobrien { 851590075Sobrien enum machine_mode mode = recog_data.operand_mode[i]; 851650397Sobrien if (op_alt_regno[i][j] == -1) 851750397Sobrien continue; 851850397Sobrien 851990075Sobrien validate_change (insn, recog_data.operand_loc[i], 852050397Sobrien gen_rtx_REG (mode, op_alt_regno[i][j]), 1); 852150397Sobrien } 852250397Sobrien 852390075Sobrien for (i = recog_data.n_dups - 1; i >= 0; i--) 852450397Sobrien { 852590075Sobrien int op = recog_data.dup_num[i]; 852690075Sobrien enum machine_mode mode = recog_data.operand_mode[op]; 852750397Sobrien 852850397Sobrien if (op_alt_regno[op][j] == -1) 852950397Sobrien continue; 853050397Sobrien 853190075Sobrien validate_change (insn, recog_data.dup_loc[i], 853250397Sobrien gen_rtx_REG (mode, op_alt_regno[op][j]), 1); 853350397Sobrien } 853450397Sobrien 853550397Sobrien return apply_change_group (); 853650397Sobrien} 853752284Sobrien 853852284Sobrien/* If reload couldn't use reg+reg+offset addressing, try to use reg+reg 853952284Sobrien addressing now. 854052284Sobrien This code might also be useful when reload gave up on reg+reg addresssing 854152284Sobrien because of clashes between the return register and INDEX_REG_CLASS. */ 854252284Sobrien 854352284Sobrien/* The maximum number of uses of a register we can keep track of to 854452284Sobrien replace them with reg+reg addressing. */ 854552284Sobrien#define RELOAD_COMBINE_MAX_USES 6 854652284Sobrien 854752284Sobrien/* INSN is the insn where a register has ben used, and USEP points to the 854852284Sobrien location of the register within the rtl. */ 854952284Sobrienstruct reg_use { rtx insn, *usep; }; 855052284Sobrien 855152284Sobrien/* If the register is used in some unknown fashion, USE_INDEX is negative. 855252284Sobrien If it is dead, USE_INDEX is RELOAD_COMBINE_MAX_USES, and STORE_RUID 855352284Sobrien indicates where it becomes live again. 855452284Sobrien Otherwise, USE_INDEX is the index of the last encountered use of the 855552284Sobrien register (which is first among these we have seen since we scan backwards), 855652284Sobrien OFFSET contains the constant offset that is added to the register in 855752284Sobrien all encountered uses, and USE_RUID indicates the first encountered, i.e. 855852284Sobrien last, of these uses. 855952284Sobrien STORE_RUID is always meaningful if we only want to use a value in a 856052284Sobrien register in a different place: it denotes the next insn in the insn 856152284Sobrien stream (i.e. the last ecountered) that sets or clobbers the register. */ 856252284Sobrienstatic struct 856352284Sobrien { 856452284Sobrien struct reg_use reg_use[RELOAD_COMBINE_MAX_USES]; 856552284Sobrien int use_index; 856652284Sobrien rtx offset; 856752284Sobrien int store_ruid; 856852284Sobrien int use_ruid; 856952284Sobrien } reg_state[FIRST_PSEUDO_REGISTER]; 857052284Sobrien 857152284Sobrien/* Reverse linear uid. This is increased in reload_combine while scanning 857252284Sobrien the instructions from last to first. It is used to set last_label_ruid 857352284Sobrien and the store_ruid / use_ruid fields in reg_state. */ 857452284Sobrienstatic int reload_combine_ruid; 857552284Sobrien 857652284Sobrien#define LABEL_LIVE(LABEL) \ 857752284Sobrien (label_live[CODE_LABEL_NUMBER (LABEL) - min_labelno]) 857852284Sobrien 857952284Sobrienstatic void 858052284Sobrienreload_combine () 858152284Sobrien{ 858252284Sobrien rtx insn, set; 858390075Sobrien int first_index_reg = -1; 858490075Sobrien int last_index_reg = 0; 858552284Sobrien int i; 858690075Sobrien unsigned int r; 858752284Sobrien int last_label_ruid; 858852284Sobrien int min_labelno, n_labels; 858952284Sobrien HARD_REG_SET ever_live_at_start, *label_live; 859052284Sobrien 859190075Sobrien /* If reg+reg can be used in offsetable memory addresses, the main chunk of 859252284Sobrien reload has already used it where appropriate, so there is no use in 859352284Sobrien trying to generate it now. */ 859452284Sobrien if (double_reg_address_ok && INDEX_REG_CLASS != NO_REGS) 859552284Sobrien return; 859652284Sobrien 859752284Sobrien /* To avoid wasting too much time later searching for an index register, 859852284Sobrien determine the minimum and maximum index register numbers. */ 859990075Sobrien for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 860090075Sobrien if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], r)) 860190075Sobrien { 860290075Sobrien if (first_index_reg == -1) 860390075Sobrien first_index_reg = r; 860490075Sobrien 860590075Sobrien last_index_reg = r; 860690075Sobrien } 860790075Sobrien 860852284Sobrien /* If no index register is available, we can quit now. */ 860990075Sobrien if (first_index_reg == -1) 861052284Sobrien return; 861152284Sobrien 861252284Sobrien /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime 861352284Sobrien information is a bit fuzzy immediately after reload, but it's 861452284Sobrien still good enough to determine which registers are live at a jump 861552284Sobrien destination. */ 861652284Sobrien min_labelno = get_first_label_num (); 861752284Sobrien n_labels = max_label_num () - min_labelno; 861852284Sobrien label_live = (HARD_REG_SET *) xmalloc (n_labels * sizeof (HARD_REG_SET)); 861952284Sobrien CLEAR_HARD_REG_SET (ever_live_at_start); 862090075Sobrien 862152284Sobrien for (i = n_basic_blocks - 1; i >= 0; i--) 862252284Sobrien { 862352284Sobrien insn = BLOCK_HEAD (i); 862452284Sobrien if (GET_CODE (insn) == CODE_LABEL) 862552284Sobrien { 862652284Sobrien HARD_REG_SET live; 862752284Sobrien 862890075Sobrien REG_SET_TO_HARD_REG_SET (live, 862990075Sobrien BASIC_BLOCK (i)->global_live_at_start); 863090075Sobrien compute_use_by_pseudos (&live, 863190075Sobrien BASIC_BLOCK (i)->global_live_at_start); 863252284Sobrien COPY_HARD_REG_SET (LABEL_LIVE (insn), live); 863352284Sobrien IOR_HARD_REG_SET (ever_live_at_start, live); 863452284Sobrien } 863552284Sobrien } 863652284Sobrien 863752284Sobrien /* Initialize last_label_ruid, reload_combine_ruid and reg_state. */ 863852284Sobrien last_label_ruid = reload_combine_ruid = 0; 863990075Sobrien for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 864052284Sobrien { 864190075Sobrien reg_state[r].store_ruid = reload_combine_ruid; 864290075Sobrien if (fixed_regs[r]) 864390075Sobrien reg_state[r].use_index = -1; 864452284Sobrien else 864590075Sobrien reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; 864652284Sobrien } 864752284Sobrien 864852284Sobrien for (insn = get_last_insn (); insn; insn = PREV_INSN (insn)) 864952284Sobrien { 865052284Sobrien rtx note; 865152284Sobrien 865252284Sobrien /* We cannot do our optimization across labels. Invalidating all the use 865352284Sobrien information we have would be costly, so we just note where the label 865490075Sobrien is and then later disable any optimization that would cross it. */ 865552284Sobrien if (GET_CODE (insn) == CODE_LABEL) 865652284Sobrien last_label_ruid = reload_combine_ruid; 865790075Sobrien else if (GET_CODE (insn) == BARRIER) 865890075Sobrien for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 865990075Sobrien if (! fixed_regs[r]) 866090075Sobrien reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; 866190075Sobrien 866290075Sobrien if (! INSN_P (insn)) 866352284Sobrien continue; 866490075Sobrien 866552284Sobrien reload_combine_ruid++; 866652284Sobrien 866752284Sobrien /* Look for (set (REGX) (CONST_INT)) 866890075Sobrien (set (REGX) (PLUS (REGX) (REGY))) 866990075Sobrien ... 867090075Sobrien ... (MEM (REGX)) ... 867152284Sobrien and convert it to 867290075Sobrien (set (REGZ) (CONST_INT)) 867390075Sobrien ... 867490075Sobrien ... (MEM (PLUS (REGZ) (REGY)))... . 867552284Sobrien 867652284Sobrien First, check that we have (set (REGX) (PLUS (REGX) (REGY))) 867752284Sobrien and that we know all uses of REGX before it dies. */ 867852284Sobrien set = single_set (insn); 867952284Sobrien if (set != NULL_RTX 868052284Sobrien && GET_CODE (SET_DEST (set)) == REG 868152284Sobrien && (HARD_REGNO_NREGS (REGNO (SET_DEST (set)), 868252284Sobrien GET_MODE (SET_DEST (set))) 868352284Sobrien == 1) 868452284Sobrien && GET_CODE (SET_SRC (set)) == PLUS 868552284Sobrien && GET_CODE (XEXP (SET_SRC (set), 1)) == REG 868652284Sobrien && rtx_equal_p (XEXP (SET_SRC (set), 0), SET_DEST (set)) 868752284Sobrien && last_label_ruid < reg_state[REGNO (SET_DEST (set))].use_ruid) 868852284Sobrien { 868952284Sobrien rtx reg = SET_DEST (set); 869052284Sobrien rtx plus = SET_SRC (set); 869152284Sobrien rtx base = XEXP (plus, 1); 869252284Sobrien rtx prev = prev_nonnote_insn (insn); 869352284Sobrien rtx prev_set = prev ? single_set (prev) : NULL_RTX; 869490075Sobrien unsigned int regno = REGNO (reg); 869590075Sobrien rtx const_reg = NULL_RTX; 869652284Sobrien rtx reg_sum = NULL_RTX; 869752284Sobrien 869852284Sobrien /* Now, we need an index register. 869952284Sobrien We'll set index_reg to this index register, const_reg to the 870052284Sobrien register that is to be loaded with the constant 870152284Sobrien (denoted as REGZ in the substitution illustration above), 870252284Sobrien and reg_sum to the register-register that we want to use to 870352284Sobrien substitute uses of REG (typically in MEMs) with. 870452284Sobrien First check REG and BASE for being index registers; 870552284Sobrien we can use them even if they are not dead. */ 870652284Sobrien if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno) 870752284Sobrien || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], 870852284Sobrien REGNO (base))) 870952284Sobrien { 871052284Sobrien const_reg = reg; 871152284Sobrien reg_sum = plus; 871252284Sobrien } 871352284Sobrien else 871452284Sobrien { 871590075Sobrien /* Otherwise, look for a free index register. Since we have 871690075Sobrien checked above that neiter REG nor BASE are index registers, 871790075Sobrien if we find anything at all, it will be different from these 871890075Sobrien two registers. */ 871990075Sobrien for (i = first_index_reg; i <= last_index_reg; i++) 872052284Sobrien { 872190075Sobrien if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], 872290075Sobrien i) 872352284Sobrien && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES 872452284Sobrien && reg_state[i].store_ruid <= reg_state[regno].use_ruid 872552284Sobrien && HARD_REGNO_NREGS (i, GET_MODE (reg)) == 1) 872652284Sobrien { 872752284Sobrien rtx index_reg = gen_rtx_REG (GET_MODE (reg), i); 872890075Sobrien 872952284Sobrien const_reg = index_reg; 873052284Sobrien reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base); 873152284Sobrien break; 873252284Sobrien } 873352284Sobrien } 873452284Sobrien } 873590075Sobrien 873652284Sobrien /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that 873752284Sobrien (REGY), i.e. BASE, is not clobbered before the last use we'll 873852284Sobrien create. */ 873990075Sobrien if (prev_set != 0 874052284Sobrien && GET_CODE (SET_SRC (prev_set)) == CONST_INT 874152284Sobrien && rtx_equal_p (SET_DEST (prev_set), reg) 874252284Sobrien && reg_state[regno].use_index >= 0 874390075Sobrien && (reg_state[REGNO (base)].store_ruid 874490075Sobrien <= reg_state[regno].use_ruid) 874590075Sobrien && reg_sum != 0) 874652284Sobrien { 874752284Sobrien int i; 874852284Sobrien 874990075Sobrien /* Change destination register and, if necessary, the 875052284Sobrien constant value in PREV, the constant loading instruction. */ 875152284Sobrien validate_change (prev, &SET_DEST (prev_set), const_reg, 1); 875252284Sobrien if (reg_state[regno].offset != const0_rtx) 875352284Sobrien validate_change (prev, 875452284Sobrien &SET_SRC (prev_set), 875552284Sobrien GEN_INT (INTVAL (SET_SRC (prev_set)) 875652284Sobrien + INTVAL (reg_state[regno].offset)), 875752284Sobrien 1); 875890075Sobrien 875952284Sobrien /* Now for every use of REG that we have recorded, replace REG 876052284Sobrien with REG_SUM. */ 876152284Sobrien for (i = reg_state[regno].use_index; 876252284Sobrien i < RELOAD_COMBINE_MAX_USES; i++) 876352284Sobrien validate_change (reg_state[regno].reg_use[i].insn, 876452284Sobrien reg_state[regno].reg_use[i].usep, 876590075Sobrien /* Each change must have its own 876690075Sobrien replacement. */ 876790075Sobrien copy_rtx (reg_sum), 1); 876852284Sobrien 876952284Sobrien if (apply_change_group ()) 877052284Sobrien { 877152284Sobrien rtx *np; 877252284Sobrien 877352284Sobrien /* Delete the reg-reg addition. */ 877490075Sobrien delete_insn (insn); 877552284Sobrien 877652284Sobrien if (reg_state[regno].offset != const0_rtx) 877790075Sobrien /* Previous REG_EQUIV / REG_EQUAL notes for PREV 877890075Sobrien are now invalid. */ 877990075Sobrien for (np = ®_NOTES (prev); *np;) 878090075Sobrien { 878190075Sobrien if (REG_NOTE_KIND (*np) == REG_EQUAL 878290075Sobrien || REG_NOTE_KIND (*np) == REG_EQUIV) 878390075Sobrien *np = XEXP (*np, 1); 878490075Sobrien else 878590075Sobrien np = &XEXP (*np, 1); 878690075Sobrien } 878790075Sobrien 878852284Sobrien reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES; 878990075Sobrien reg_state[REGNO (const_reg)].store_ruid 879090075Sobrien = reload_combine_ruid; 879152284Sobrien continue; 879252284Sobrien } 879352284Sobrien } 879452284Sobrien } 879590075Sobrien 879690075Sobrien note_stores (PATTERN (insn), reload_combine_note_store, NULL); 879790075Sobrien 879852284Sobrien if (GET_CODE (insn) == CALL_INSN) 879952284Sobrien { 880052284Sobrien rtx link; 880152284Sobrien 880290075Sobrien for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) 880390075Sobrien if (call_used_regs[r]) 880490075Sobrien { 880590075Sobrien reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; 880690075Sobrien reg_state[r].store_ruid = reload_combine_ruid; 880790075Sobrien } 880890075Sobrien 880952284Sobrien for (link = CALL_INSN_FUNCTION_USAGE (insn); link; 881052284Sobrien link = XEXP (link, 1)) 881152284Sobrien { 881290075Sobrien rtx usage_rtx = XEXP (XEXP (link, 0), 0); 881390075Sobrien if (GET_CODE (usage_rtx) == REG) 881490075Sobrien { 881590075Sobrien unsigned int i; 881690075Sobrien unsigned int start_reg = REGNO (usage_rtx); 881790075Sobrien unsigned int num_regs = 881890075Sobrien HARD_REGNO_NREGS (start_reg, GET_MODE (usage_rtx)); 881990075Sobrien unsigned int end_reg = start_reg + num_regs - 1; 882090075Sobrien for (i = start_reg; i <= end_reg; i++) 882190075Sobrien if (GET_CODE (XEXP (link, 0)) == CLOBBER) 882290075Sobrien { 882390075Sobrien reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; 882490075Sobrien reg_state[i].store_ruid = reload_combine_ruid; 882590075Sobrien } 882690075Sobrien else 882790075Sobrien reg_state[i].use_index = -1; 882890075Sobrien } 882990075Sobrien } 883090075Sobrien 883152284Sobrien } 883290075Sobrien else if (GET_CODE (insn) == JUMP_INSN 883390075Sobrien && GET_CODE (PATTERN (insn)) != RETURN) 883452284Sobrien { 883552284Sobrien /* Non-spill registers might be used at the call destination in 883652284Sobrien some unknown fashion, so we have to mark the unknown use. */ 883752284Sobrien HARD_REG_SET *live; 883890075Sobrien 883952284Sobrien if ((condjump_p (insn) || condjump_in_parallel_p (insn)) 884052284Sobrien && JUMP_LABEL (insn)) 884152284Sobrien live = &LABEL_LIVE (JUMP_LABEL (insn)); 884252284Sobrien else 884352284Sobrien live = &ever_live_at_start; 884490075Sobrien 884552284Sobrien for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; --i) 884690075Sobrien if (TEST_HARD_REG_BIT (*live, i)) 884790075Sobrien reg_state[i].use_index = -1; 884852284Sobrien } 884990075Sobrien 885052284Sobrien reload_combine_note_use (&PATTERN (insn), insn); 885152284Sobrien for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) 885252284Sobrien { 885352284Sobrien if (REG_NOTE_KIND (note) == REG_INC 885452284Sobrien && GET_CODE (XEXP (note, 0)) == REG) 885552284Sobrien { 885652284Sobrien int regno = REGNO (XEXP (note, 0)); 885752284Sobrien 885852284Sobrien reg_state[regno].store_ruid = reload_combine_ruid; 885952284Sobrien reg_state[regno].use_index = -1; 886052284Sobrien } 886152284Sobrien } 886252284Sobrien } 886390075Sobrien 886452284Sobrien free (label_live); 886552284Sobrien} 886652284Sobrien 886752284Sobrien/* Check if DST is a register or a subreg of a register; if it is, 886852284Sobrien update reg_state[regno].store_ruid and reg_state[regno].use_index 886952284Sobrien accordingly. Called via note_stores from reload_combine. */ 887090075Sobrien 887152284Sobrienstatic void 887290075Sobrienreload_combine_note_store (dst, set, data) 887352284Sobrien rtx dst, set; 887490075Sobrien void *data ATTRIBUTE_UNUSED; 887552284Sobrien{ 887652284Sobrien int regno = 0; 887752284Sobrien int i; 887890075Sobrien enum machine_mode mode = GET_MODE (dst); 887952284Sobrien 888052284Sobrien if (GET_CODE (dst) == SUBREG) 888152284Sobrien { 888290075Sobrien regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)), 888390075Sobrien GET_MODE (SUBREG_REG (dst)), 888490075Sobrien SUBREG_BYTE (dst), 888590075Sobrien GET_MODE (dst)); 888652284Sobrien dst = SUBREG_REG (dst); 888752284Sobrien } 888852284Sobrien if (GET_CODE (dst) != REG) 888952284Sobrien return; 889052284Sobrien regno += REGNO (dst); 889152284Sobrien 889252284Sobrien /* note_stores might have stripped a STRICT_LOW_PART, so we have to be 889390075Sobrien careful with registers / register parts that are not full words. 889452284Sobrien 889552284Sobrien Similarly for ZERO_EXTRACT and SIGN_EXTRACT. */ 889652284Sobrien if (GET_CODE (set) != SET 889752284Sobrien || GET_CODE (SET_DEST (set)) == ZERO_EXTRACT 889852284Sobrien || GET_CODE (SET_DEST (set)) == SIGN_EXTRACT 889952284Sobrien || GET_CODE (SET_DEST (set)) == STRICT_LOW_PART) 890052284Sobrien { 890190075Sobrien for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--) 890252284Sobrien { 890352284Sobrien reg_state[i].use_index = -1; 890452284Sobrien reg_state[i].store_ruid = reload_combine_ruid; 890552284Sobrien } 890652284Sobrien } 890752284Sobrien else 890852284Sobrien { 890990075Sobrien for (i = HARD_REGNO_NREGS (regno, mode) - 1 + regno; i >= regno; i--) 891052284Sobrien { 891152284Sobrien reg_state[i].store_ruid = reload_combine_ruid; 891252284Sobrien reg_state[i].use_index = RELOAD_COMBINE_MAX_USES; 891352284Sobrien } 891452284Sobrien } 891552284Sobrien} 891652284Sobrien 891752284Sobrien/* XP points to a piece of rtl that has to be checked for any uses of 891852284Sobrien registers. 891952284Sobrien *XP is the pattern of INSN, or a part of it. 892052284Sobrien Called from reload_combine, and recursively by itself. */ 892152284Sobrienstatic void 892252284Sobrienreload_combine_note_use (xp, insn) 892352284Sobrien rtx *xp, insn; 892452284Sobrien{ 892552284Sobrien rtx x = *xp; 892652284Sobrien enum rtx_code code = x->code; 892790075Sobrien const char *fmt; 892852284Sobrien int i, j; 892952284Sobrien rtx offset = const0_rtx; /* For the REG case below. */ 893052284Sobrien 893152284Sobrien switch (code) 893252284Sobrien { 893352284Sobrien case SET: 893452284Sobrien if (GET_CODE (SET_DEST (x)) == REG) 893552284Sobrien { 893652284Sobrien reload_combine_note_use (&SET_SRC (x), insn); 893752284Sobrien return; 893852284Sobrien } 893952284Sobrien break; 894052284Sobrien 894190075Sobrien case USE: 894290075Sobrien /* If this is the USE of a return value, we can't change it. */ 894390075Sobrien if (GET_CODE (XEXP (x, 0)) == REG && REG_FUNCTION_VALUE_P (XEXP (x, 0))) 894490075Sobrien { 894590075Sobrien /* Mark the return register as used in an unknown fashion. */ 894690075Sobrien rtx reg = XEXP (x, 0); 894790075Sobrien int regno = REGNO (reg); 894890075Sobrien int nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)); 894990075Sobrien 895090075Sobrien while (--nregs >= 0) 895190075Sobrien reg_state[regno + nregs].use_index = -1; 895290075Sobrien return; 895390075Sobrien } 895490075Sobrien break; 895590075Sobrien 895652284Sobrien case CLOBBER: 895752284Sobrien if (GET_CODE (SET_DEST (x)) == REG) 895890075Sobrien { 895990075Sobrien /* No spurious CLOBBERs of pseudo registers may remain. */ 896090075Sobrien if (REGNO (SET_DEST (x)) >= FIRST_PSEUDO_REGISTER) 896190075Sobrien abort (); 896290075Sobrien return; 896390075Sobrien } 896452284Sobrien break; 896552284Sobrien 896652284Sobrien case PLUS: 896752284Sobrien /* We are interested in (plus (reg) (const_int)) . */ 896890075Sobrien if (GET_CODE (XEXP (x, 0)) != REG 896990075Sobrien || GET_CODE (XEXP (x, 1)) != CONST_INT) 897052284Sobrien break; 897152284Sobrien offset = XEXP (x, 1); 897252284Sobrien x = XEXP (x, 0); 897390075Sobrien /* Fall through. */ 897452284Sobrien case REG: 897552284Sobrien { 897652284Sobrien int regno = REGNO (x); 897752284Sobrien int use_index; 897890075Sobrien int nregs; 897952284Sobrien 898090075Sobrien /* No spurious USEs of pseudo registers may remain. */ 898152284Sobrien if (regno >= FIRST_PSEUDO_REGISTER) 898290075Sobrien abort (); 898352284Sobrien 898490075Sobrien nregs = HARD_REGNO_NREGS (regno, GET_MODE (x)); 898590075Sobrien 898690075Sobrien /* We can't substitute into multi-hard-reg uses. */ 898790075Sobrien if (nregs > 1) 898890075Sobrien { 898990075Sobrien while (--nregs >= 0) 899090075Sobrien reg_state[regno + nregs].use_index = -1; 899190075Sobrien return; 899290075Sobrien } 899390075Sobrien 899452284Sobrien /* If this register is already used in some unknown fashion, we 899552284Sobrien can't do anything. 899652284Sobrien If we decrement the index from zero to -1, we can't store more 899752284Sobrien uses, so this register becomes used in an unknown fashion. */ 899852284Sobrien use_index = --reg_state[regno].use_index; 899952284Sobrien if (use_index < 0) 900052284Sobrien return; 900152284Sobrien 900252284Sobrien if (use_index != RELOAD_COMBINE_MAX_USES - 1) 900352284Sobrien { 900452284Sobrien /* We have found another use for a register that is already 900552284Sobrien used later. Check if the offsets match; if not, mark the 900652284Sobrien register as used in an unknown fashion. */ 900752284Sobrien if (! rtx_equal_p (offset, reg_state[regno].offset)) 900852284Sobrien { 900952284Sobrien reg_state[regno].use_index = -1; 901052284Sobrien return; 901152284Sobrien } 901252284Sobrien } 901352284Sobrien else 901452284Sobrien { 901552284Sobrien /* This is the first use of this register we have seen since we 901652284Sobrien marked it as dead. */ 901752284Sobrien reg_state[regno].offset = offset; 901852284Sobrien reg_state[regno].use_ruid = reload_combine_ruid; 901952284Sobrien } 902052284Sobrien reg_state[regno].reg_use[use_index].insn = insn; 902152284Sobrien reg_state[regno].reg_use[use_index].usep = xp; 902252284Sobrien return; 902352284Sobrien } 902452284Sobrien 902552284Sobrien default: 902652284Sobrien break; 902752284Sobrien } 902852284Sobrien 902952284Sobrien /* Recursively process the components of X. */ 903052284Sobrien fmt = GET_RTX_FORMAT (code); 903152284Sobrien for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 903252284Sobrien { 903352284Sobrien if (fmt[i] == 'e') 903452284Sobrien reload_combine_note_use (&XEXP (x, i), insn); 903552284Sobrien else if (fmt[i] == 'E') 903652284Sobrien { 903752284Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 903852284Sobrien reload_combine_note_use (&XVECEXP (x, i, j), insn); 903952284Sobrien } 904052284Sobrien } 904152284Sobrien} 904252284Sobrien 904390075Sobrien/* See if we can reduce the cost of a constant by replacing a move 904490075Sobrien with an add. We track situations in which a register is set to a 904590075Sobrien constant or to a register plus a constant. */ 904652284Sobrien/* We cannot do our optimization across labels. Invalidating all the 904752284Sobrien information about register contents we have would be costly, so we 904890075Sobrien use move2add_last_label_luid to note where the label is and then 904990075Sobrien later disable any optimization that would cross it. 905052284Sobrien reg_offset[n] / reg_base_reg[n] / reg_mode[n] are only valid if 905190075Sobrien reg_set_luid[n] is greater than last_label_luid[n] . */ 905252284Sobrienstatic int reg_set_luid[FIRST_PSEUDO_REGISTER]; 905390075Sobrien 905490075Sobrien/* If reg_base_reg[n] is negative, register n has been set to 905590075Sobrien reg_offset[n] in mode reg_mode[n] . 905690075Sobrien If reg_base_reg[n] is non-negative, register n has been set to the 905790075Sobrien sum of reg_offset[n] and the value of register reg_base_reg[n] 905890075Sobrien before reg_set_luid[n], calculated in mode reg_mode[n] . */ 905990075Sobrienstatic HOST_WIDE_INT reg_offset[FIRST_PSEUDO_REGISTER]; 906052284Sobrienstatic int reg_base_reg[FIRST_PSEUDO_REGISTER]; 906152284Sobrienstatic enum machine_mode reg_mode[FIRST_PSEUDO_REGISTER]; 906290075Sobrien 906352284Sobrien/* move2add_luid is linearily increased while scanning the instructions 906452284Sobrien from first to last. It is used to set reg_set_luid in 906552284Sobrien reload_cse_move2add and move2add_note_store. */ 906652284Sobrienstatic int move2add_luid; 906752284Sobrien 906890075Sobrien/* move2add_last_label_luid is set whenever a label is found. Labels 906990075Sobrien invalidate all previously collected reg_offset data. */ 907090075Sobrienstatic int move2add_last_label_luid; 907190075Sobrien 907252284Sobrien/* Generate a CONST_INT and force it in the range of MODE. */ 907390075Sobrien 907490075Sobrienstatic HOST_WIDE_INT 907590075Sobriensext_for_mode (mode, value) 907652284Sobrien enum machine_mode mode; 907752284Sobrien HOST_WIDE_INT value; 907852284Sobrien{ 907952284Sobrien HOST_WIDE_INT cval = value & GET_MODE_MASK (mode); 908052284Sobrien int width = GET_MODE_BITSIZE (mode); 908152284Sobrien 908252284Sobrien /* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative number, 908352284Sobrien sign extend it. */ 908452284Sobrien if (width > 0 && width < HOST_BITS_PER_WIDE_INT 908552284Sobrien && (cval & ((HOST_WIDE_INT) 1 << (width - 1))) != 0) 908652284Sobrien cval |= (HOST_WIDE_INT) -1 << width; 908752284Sobrien 908890075Sobrien return cval; 908952284Sobrien} 909052284Sobrien 909190075Sobrien/* ??? We don't know how zero / sign extension is handled, hence we 909290075Sobrien can't go from a narrower to a wider mode. */ 909390075Sobrien#define MODES_OK_FOR_MOVE2ADD(OUTMODE, INMODE) \ 909490075Sobrien (GET_MODE_SIZE (OUTMODE) == GET_MODE_SIZE (INMODE) \ 909590075Sobrien || (GET_MODE_SIZE (OUTMODE) <= GET_MODE_SIZE (INMODE) \ 909690075Sobrien && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (OUTMODE), \ 909790075Sobrien GET_MODE_BITSIZE (INMODE)))) 909890075Sobrien 909952284Sobrienstatic void 910052284Sobrienreload_cse_move2add (first) 910152284Sobrien rtx first; 910252284Sobrien{ 910352284Sobrien int i; 910452284Sobrien rtx insn; 910552284Sobrien 910690075Sobrien for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) 910752284Sobrien reg_set_luid[i] = 0; 910852284Sobrien 910990075Sobrien move2add_last_label_luid = 0; 911090075Sobrien move2add_luid = 2; 911152284Sobrien for (insn = first; insn; insn = NEXT_INSN (insn), move2add_luid++) 911252284Sobrien { 911352284Sobrien rtx pat, note; 911452284Sobrien 911552284Sobrien if (GET_CODE (insn) == CODE_LABEL) 911690075Sobrien { 911790075Sobrien move2add_last_label_luid = move2add_luid; 911890075Sobrien /* We're going to increment move2add_luid twice after a 911990075Sobrien label, so that we can use move2add_last_label_luid + 1 as 912090075Sobrien the luid for constants. */ 912190075Sobrien move2add_luid++; 912290075Sobrien continue; 912390075Sobrien } 912490075Sobrien if (! INSN_P (insn)) 912552284Sobrien continue; 912652284Sobrien pat = PATTERN (insn); 912752284Sobrien /* For simplicity, we only perform this optimization on 912852284Sobrien straightforward SETs. */ 912952284Sobrien if (GET_CODE (pat) == SET 913052284Sobrien && GET_CODE (SET_DEST (pat)) == REG) 913152284Sobrien { 913252284Sobrien rtx reg = SET_DEST (pat); 913352284Sobrien int regno = REGNO (reg); 913452284Sobrien rtx src = SET_SRC (pat); 913552284Sobrien 913652284Sobrien /* Check if we have valid information on the contents of this 913752284Sobrien register in the mode of REG. */ 913890075Sobrien if (reg_set_luid[regno] > move2add_last_label_luid 913990075Sobrien && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), reg_mode[regno])) 914052284Sobrien { 914152284Sobrien /* Try to transform (set (REGX) (CONST_INT A)) 914252284Sobrien ... 914352284Sobrien (set (REGX) (CONST_INT B)) 914452284Sobrien to 914552284Sobrien (set (REGX) (CONST_INT A)) 914652284Sobrien ... 914752284Sobrien (set (REGX) (plus (REGX) (CONST_INT B-A))) */ 914852284Sobrien 914952284Sobrien if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0) 915052284Sobrien { 915152284Sobrien int success = 0; 915290075Sobrien rtx new_src = GEN_INT (sext_for_mode (GET_MODE (reg), 915390075Sobrien INTVAL (src) 915490075Sobrien - reg_offset[regno])); 915552284Sobrien /* (set (reg) (plus (reg) (const_int 0))) is not canonical; 915652284Sobrien use (set (reg) (reg)) instead. 915752284Sobrien We don't delete this insn, nor do we convert it into a 915852284Sobrien note, to avoid losing register notes or the return 915952284Sobrien value flag. jump2 already knowns how to get rid of 916052284Sobrien no-op moves. */ 916152284Sobrien if (new_src == const0_rtx) 916252284Sobrien success = validate_change (insn, &SET_SRC (pat), reg, 0); 916352284Sobrien else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET) 916490075Sobrien && have_add2_insn (reg, new_src)) 916552284Sobrien success = validate_change (insn, &PATTERN (insn), 916652284Sobrien gen_add2_insn (reg, new_src), 0); 916752284Sobrien reg_set_luid[regno] = move2add_luid; 916852284Sobrien reg_mode[regno] = GET_MODE (reg); 916990075Sobrien reg_offset[regno] = INTVAL (src); 917052284Sobrien continue; 917152284Sobrien } 917252284Sobrien 917352284Sobrien /* Try to transform (set (REGX) (REGY)) 917452284Sobrien (set (REGX) (PLUS (REGX) (CONST_INT A))) 917552284Sobrien ... 917652284Sobrien (set (REGX) (REGY)) 917752284Sobrien (set (REGX) (PLUS (REGX) (CONST_INT B))) 917852284Sobrien to 917952284Sobrien (REGX) (REGY)) 918052284Sobrien (set (REGX) (PLUS (REGX) (CONST_INT A))) 918152284Sobrien ... 918252284Sobrien (set (REGX) (plus (REGX) (CONST_INT B-A))) */ 918352284Sobrien else if (GET_CODE (src) == REG 918490075Sobrien && reg_set_luid[regno] == reg_set_luid[REGNO (src)] 918590075Sobrien && reg_base_reg[regno] == reg_base_reg[REGNO (src)] 918690075Sobrien && MODES_OK_FOR_MOVE2ADD (GET_MODE (reg), 918790075Sobrien reg_mode[REGNO (src)])) 918852284Sobrien { 918952284Sobrien rtx next = next_nonnote_insn (insn); 919090075Sobrien rtx set = NULL_RTX; 919152284Sobrien if (next) 919252284Sobrien set = single_set (next); 919390075Sobrien if (set 919452284Sobrien && SET_DEST (set) == reg 919552284Sobrien && GET_CODE (SET_SRC (set)) == PLUS 919652284Sobrien && XEXP (SET_SRC (set), 0) == reg 919752284Sobrien && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT) 919852284Sobrien { 919952284Sobrien rtx src3 = XEXP (SET_SRC (set), 1); 920090075Sobrien HOST_WIDE_INT added_offset = INTVAL (src3); 920190075Sobrien HOST_WIDE_INT base_offset = reg_offset[REGNO (src)]; 920290075Sobrien HOST_WIDE_INT regno_offset = reg_offset[regno]; 920390075Sobrien rtx new_src = GEN_INT (sext_for_mode (GET_MODE (reg), 920490075Sobrien added_offset 920590075Sobrien + base_offset 920690075Sobrien - regno_offset)); 920752284Sobrien int success = 0; 920852284Sobrien 920952284Sobrien if (new_src == const0_rtx) 921052284Sobrien /* See above why we create (set (reg) (reg)) here. */ 921152284Sobrien success 921252284Sobrien = validate_change (next, &SET_SRC (set), reg, 0); 921352284Sobrien else if ((rtx_cost (new_src, PLUS) 921490075Sobrien < COSTS_N_INSNS (1) + rtx_cost (src3, SET)) 921590075Sobrien && have_add2_insn (reg, new_src)) 921652284Sobrien success 921752284Sobrien = validate_change (next, &PATTERN (next), 921852284Sobrien gen_add2_insn (reg, new_src), 0); 921952284Sobrien if (success) 922090075Sobrien delete_insn (insn); 922152284Sobrien insn = next; 922252284Sobrien reg_mode[regno] = GET_MODE (reg); 922390075Sobrien reg_offset[regno] = sext_for_mode (GET_MODE (reg), 922490075Sobrien added_offset 922590075Sobrien + base_offset); 922652284Sobrien continue; 922752284Sobrien } 922852284Sobrien } 922952284Sobrien } 923052284Sobrien } 923152284Sobrien 923252284Sobrien for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) 923352284Sobrien { 923452284Sobrien if (REG_NOTE_KIND (note) == REG_INC 923552284Sobrien && GET_CODE (XEXP (note, 0)) == REG) 923652284Sobrien { 923790075Sobrien /* Reset the information about this register. */ 923852284Sobrien int regno = REGNO (XEXP (note, 0)); 923952284Sobrien if (regno < FIRST_PSEUDO_REGISTER) 924090075Sobrien reg_set_luid[regno] = 0; 924152284Sobrien } 924252284Sobrien } 924390075Sobrien note_stores (PATTERN (insn), move2add_note_store, NULL); 924452284Sobrien /* If this is a CALL_INSN, all call used registers are stored with 924552284Sobrien unknown values. */ 924652284Sobrien if (GET_CODE (insn) == CALL_INSN) 924752284Sobrien { 924890075Sobrien for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) 924952284Sobrien { 925052284Sobrien if (call_used_regs[i]) 925190075Sobrien /* Reset the information about this register. */ 925290075Sobrien reg_set_luid[i] = 0; 925352284Sobrien } 925452284Sobrien } 925552284Sobrien } 925652284Sobrien} 925752284Sobrien 925852284Sobrien/* SET is a SET or CLOBBER that sets DST. 925952284Sobrien Update reg_set_luid, reg_offset and reg_base_reg accordingly. 926052284Sobrien Called from reload_cse_move2add via note_stores. */ 926190075Sobrien 926252284Sobrienstatic void 926390075Sobrienmove2add_note_store (dst, set, data) 926452284Sobrien rtx dst, set; 926590075Sobrien void *data ATTRIBUTE_UNUSED; 926652284Sobrien{ 926790075Sobrien unsigned int regno = 0; 926890075Sobrien unsigned int i; 926990075Sobrien enum machine_mode mode = GET_MODE (dst); 927052284Sobrien 927152284Sobrien if (GET_CODE (dst) == SUBREG) 927252284Sobrien { 927390075Sobrien regno = subreg_regno_offset (REGNO (SUBREG_REG (dst)), 927490075Sobrien GET_MODE (SUBREG_REG (dst)), 927590075Sobrien SUBREG_BYTE (dst), 927690075Sobrien GET_MODE (dst)); 927752284Sobrien dst = SUBREG_REG (dst); 927852284Sobrien } 927990075Sobrien 928090075Sobrien /* Some targets do argument pushes without adding REG_INC notes. */ 928190075Sobrien 928290075Sobrien if (GET_CODE (dst) == MEM) 928390075Sobrien { 928490075Sobrien dst = XEXP (dst, 0); 928590075Sobrien if (GET_CODE (dst) == PRE_INC || GET_CODE (dst) == POST_INC 928690075Sobrien || GET_CODE (dst) == PRE_DEC || GET_CODE (dst) == POST_DEC) 928790075Sobrien reg_set_luid[REGNO (XEXP (dst, 0))] = 0; 928890075Sobrien return; 928990075Sobrien } 929052284Sobrien if (GET_CODE (dst) != REG) 929152284Sobrien return; 929252284Sobrien 929352284Sobrien regno += REGNO (dst); 929452284Sobrien 929552284Sobrien if (HARD_REGNO_NREGS (regno, mode) == 1 && GET_CODE (set) == SET 929652284Sobrien && GET_CODE (SET_DEST (set)) != ZERO_EXTRACT 929752284Sobrien && GET_CODE (SET_DEST (set)) != SIGN_EXTRACT 929852284Sobrien && GET_CODE (SET_DEST (set)) != STRICT_LOW_PART) 929952284Sobrien { 930052284Sobrien rtx src = SET_SRC (set); 930190075Sobrien rtx base_reg; 930290075Sobrien HOST_WIDE_INT offset; 930390075Sobrien int base_regno; 930490075Sobrien /* This may be different from mode, if SET_DEST (set) is a 930590075Sobrien SUBREG. */ 930690075Sobrien enum machine_mode dst_mode = GET_MODE (dst); 930752284Sobrien 930852284Sobrien switch (GET_CODE (src)) 930952284Sobrien { 931052284Sobrien case PLUS: 931190075Sobrien if (GET_CODE (XEXP (src, 0)) == REG) 931290075Sobrien { 931390075Sobrien base_reg = XEXP (src, 0); 931452284Sobrien 931590075Sobrien if (GET_CODE (XEXP (src, 1)) == CONST_INT) 931690075Sobrien offset = INTVAL (XEXP (src, 1)); 931790075Sobrien else if (GET_CODE (XEXP (src, 1)) == REG 931890075Sobrien && (reg_set_luid[REGNO (XEXP (src, 1))] 931990075Sobrien > move2add_last_label_luid) 932090075Sobrien && (MODES_OK_FOR_MOVE2ADD 932190075Sobrien (dst_mode, reg_mode[REGNO (XEXP (src, 1))]))) 932290075Sobrien { 932390075Sobrien if (reg_base_reg[REGNO (XEXP (src, 1))] < 0) 932490075Sobrien offset = reg_offset[REGNO (XEXP (src, 1))]; 932590075Sobrien /* Maybe the first register is known to be a 932690075Sobrien constant. */ 932790075Sobrien else if (reg_set_luid[REGNO (base_reg)] 932890075Sobrien > move2add_last_label_luid 932990075Sobrien && (MODES_OK_FOR_MOVE2ADD 933090075Sobrien (dst_mode, reg_mode[REGNO (XEXP (src, 1))])) 933190075Sobrien && reg_base_reg[REGNO (base_reg)] < 0) 933290075Sobrien { 933390075Sobrien offset = reg_offset[REGNO (base_reg)]; 933490075Sobrien base_reg = XEXP (src, 1); 933590075Sobrien } 933690075Sobrien else 933790075Sobrien goto invalidate; 933890075Sobrien } 933990075Sobrien else 934090075Sobrien goto invalidate; 934190075Sobrien 934290075Sobrien break; 934390075Sobrien } 934490075Sobrien 934590075Sobrien goto invalidate; 934690075Sobrien 934752284Sobrien case REG: 934890075Sobrien base_reg = src; 934990075Sobrien offset = 0; 935052284Sobrien break; 935152284Sobrien 935290075Sobrien case CONST_INT: 935390075Sobrien /* Start tracking the register as a constant. */ 935490075Sobrien reg_base_reg[regno] = -1; 935590075Sobrien reg_offset[regno] = INTVAL (SET_SRC (set)); 935690075Sobrien /* We assign the same luid to all registers set to constants. */ 935790075Sobrien reg_set_luid[regno] = move2add_last_label_luid + 1; 935890075Sobrien reg_mode[regno] = mode; 935990075Sobrien return; 936090075Sobrien 936152284Sobrien default: 936290075Sobrien invalidate: 936390075Sobrien /* Invalidate the contents of the register. */ 936490075Sobrien reg_set_luid[regno] = 0; 936590075Sobrien return; 936652284Sobrien } 936790075Sobrien 936890075Sobrien base_regno = REGNO (base_reg); 936990075Sobrien /* If information about the base register is not valid, set it 937090075Sobrien up as a new base register, pretending its value is known 937190075Sobrien starting from the current insn. */ 937290075Sobrien if (reg_set_luid[base_regno] <= move2add_last_label_luid) 937390075Sobrien { 937490075Sobrien reg_base_reg[base_regno] = base_regno; 937590075Sobrien reg_offset[base_regno] = 0; 937690075Sobrien reg_set_luid[base_regno] = move2add_luid; 937790075Sobrien reg_mode[base_regno] = mode; 937890075Sobrien } 937990075Sobrien else if (! MODES_OK_FOR_MOVE2ADD (dst_mode, 938090075Sobrien reg_mode[base_regno])) 938190075Sobrien goto invalidate; 938290075Sobrien 938390075Sobrien reg_mode[regno] = mode; 938490075Sobrien 938590075Sobrien /* Copy base information from our base register. */ 938690075Sobrien reg_set_luid[regno] = reg_set_luid[base_regno]; 938790075Sobrien reg_base_reg[regno] = reg_base_reg[base_regno]; 938890075Sobrien 938990075Sobrien /* Compute the sum of the offsets or constants. */ 939090075Sobrien reg_offset[regno] = sext_for_mode (dst_mode, 939190075Sobrien offset 939290075Sobrien + reg_offset[base_regno]); 939352284Sobrien } 939452284Sobrien else 939552284Sobrien { 939690075Sobrien unsigned int endregno = regno + HARD_REGNO_NREGS (regno, mode); 939790075Sobrien 939890075Sobrien for (i = regno; i < endregno; i++) 939990075Sobrien /* Reset the information about this register. */ 940090075Sobrien reg_set_luid[i] = 0; 940152284Sobrien } 940252284Sobrien} 940352284Sobrien 940452284Sobrien#ifdef AUTO_INC_DEC 940552284Sobrienstatic void 940652284Sobrienadd_auto_inc_notes (insn, x) 940752284Sobrien rtx insn; 940852284Sobrien rtx x; 940952284Sobrien{ 941052284Sobrien enum rtx_code code = GET_CODE (x); 941190075Sobrien const char *fmt; 941252284Sobrien int i, j; 941352284Sobrien 941452284Sobrien if (code == MEM && auto_inc_p (XEXP (x, 0))) 941552284Sobrien { 941652284Sobrien REG_NOTES (insn) 941752284Sobrien = gen_rtx_EXPR_LIST (REG_INC, XEXP (XEXP (x, 0), 0), REG_NOTES (insn)); 941852284Sobrien return; 941952284Sobrien } 942052284Sobrien 942152284Sobrien /* Scan all the operand sub-expressions. */ 942252284Sobrien fmt = GET_RTX_FORMAT (code); 942352284Sobrien for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 942452284Sobrien { 942552284Sobrien if (fmt[i] == 'e') 942652284Sobrien add_auto_inc_notes (insn, XEXP (x, i)); 942752284Sobrien else if (fmt[i] == 'E') 942852284Sobrien for (j = XVECLEN (x, i) - 1; j >= 0; j--) 942952284Sobrien add_auto_inc_notes (insn, XVECEXP (x, i, j)); 943052284Sobrien } 943152284Sobrien} 943252284Sobrien#endif 943390075Sobrien 943490075Sobrien/* Copy EH notes from an insn to its reloads. */ 943590075Sobrienstatic void 943690075Sobriencopy_eh_notes (insn, x) 943790075Sobrien rtx insn; 943890075Sobrien rtx x; 943990075Sobrien{ 944090075Sobrien rtx eh_note = find_reg_note (insn, REG_EH_REGION, NULL_RTX); 944190075Sobrien if (eh_note) 944290075Sobrien { 944390075Sobrien for (; x != 0; x = NEXT_INSN (x)) 944490075Sobrien { 944590075Sobrien if (may_trap_p (PATTERN (x))) 944690075Sobrien REG_NOTES (x) 944790075Sobrien = gen_rtx_EXPR_LIST (REG_EH_REGION, XEXP (eh_note, 0), 944890075Sobrien REG_NOTES (x)); 944990075Sobrien } 945090075Sobrien } 945190075Sobrien} 945290075Sobrien 945390075Sobrien/* This is used by reload pass, that does emit some instructions after 945490075Sobrien abnormal calls moving basic block end, but in fact it wants to emit 945590075Sobrien them on the edge. Looks for abnormal call edges, find backward the 945690075Sobrien proper call and fix the damage. 945790075Sobrien 945890075Sobrien Similar handle instructions throwing exceptions internally. */ 945996263Sobrienvoid 946090075Sobrienfixup_abnormal_edges () 946190075Sobrien{ 946290075Sobrien int i; 946390075Sobrien bool inserted = false; 946490075Sobrien 946590075Sobrien for (i = 0; i < n_basic_blocks; i++) 946690075Sobrien { 946790075Sobrien basic_block bb = BASIC_BLOCK (i); 946890075Sobrien edge e; 946990075Sobrien 947090075Sobrien /* Look for cases we are interested in - an calls or instructions causing 947190075Sobrien exceptions. */ 947290075Sobrien for (e = bb->succ; e; e = e->succ_next) 947390075Sobrien { 947490075Sobrien if (e->flags & EDGE_ABNORMAL_CALL) 947590075Sobrien break; 947690075Sobrien if ((e->flags & (EDGE_ABNORMAL | EDGE_EH)) 947790075Sobrien == (EDGE_ABNORMAL | EDGE_EH)) 947890075Sobrien break; 947990075Sobrien } 948090075Sobrien if (e && GET_CODE (bb->end) != CALL_INSN && !can_throw_internal (bb->end)) 948190075Sobrien { 948290075Sobrien rtx insn = bb->end, stop = NEXT_INSN (bb->end); 948390075Sobrien rtx next; 948490075Sobrien for (e = bb->succ; e; e = e->succ_next) 948590075Sobrien if (e->flags & EDGE_FALLTHRU) 948690075Sobrien break; 948790075Sobrien /* Get past the new insns generated. Allow notes, as the insns may 948890075Sobrien be already deleted. */ 948990075Sobrien while ((GET_CODE (insn) == INSN || GET_CODE (insn) == NOTE) 949090075Sobrien && !can_throw_internal (insn) 949190075Sobrien && insn != bb->head) 949290075Sobrien insn = PREV_INSN (insn); 949390075Sobrien if (GET_CODE (insn) != CALL_INSN && !can_throw_internal (insn)) 949490075Sobrien abort (); 949590075Sobrien bb->end = insn; 949690075Sobrien inserted = true; 949790075Sobrien insn = NEXT_INSN (insn); 949890075Sobrien while (insn && insn != stop) 949990075Sobrien { 950090075Sobrien next = NEXT_INSN (insn); 950190075Sobrien if (INSN_P (insn)) 950290075Sobrien { 950396263Sobrien rtx seq; 950496263Sobrien 950590075Sobrien delete_insn (insn); 950696263Sobrien 950796263Sobrien /* We're not deleting it, we're moving it. */ 950896263Sobrien INSN_DELETED_P (insn) = 0; 950996263Sobrien 951096263Sobrien /* Emit a sequence, rather than scarfing the pattern, so 951196263Sobrien that we don't lose REG_NOTES etc. */ 951296263Sobrien /* ??? Could copy the test from gen_sequence, but don't 951396263Sobrien think it's worth the bother. */ 951496263Sobrien seq = gen_rtx_SEQUENCE (VOIDmode, gen_rtvec (1, insn)); 951596263Sobrien insert_insn_on_edge (seq, e); 951690075Sobrien } 951790075Sobrien insn = next; 951890075Sobrien } 951990075Sobrien } 952090075Sobrien } 952190075Sobrien if (inserted) 952290075Sobrien commit_edge_insertions (); 952390075Sobrien} 9524