PR bootstrap/44970 PR middle-end/45009 * postreload.c: Include "target.h". (reload_combine_closest_single_use): Don't take DEBUG_INSNs into account. (fixup_debug_insns): Don't copy the rtx. (reload_combine_recognize_const_pattern): DEBUG_INSNs can't have uses. Don't copy when replacing. Call fixup_debug_insns in the case where we merged one add with another. (reload_combine_recognize_pattern): Fail if there aren't any uses. Try harder to determine whether we're picking a valid index register. Don't set store_ruid for an insn we're going to scan in the next iteration. (reload_combine): Remove unused code. (reload_combine_note_use): When updating use information for an old insn, ignore a use that occurs after store_ruid. * Makefile.in (postreload.o): Update dependencies. Index: gcc/postreload.c =================================================================== --- gcc/postreload.c (revision 162372) +++ gcc/postreload.c (working copy) @@ -44,6 +44,7 @@ along with GCC; see the file COPYING3. #include "toplev.h" #include "except.h" #include "tree.h" +#include "target.h" #include "timevar.h" #include "tree-pass.h" #include "df.h" @@ -816,8 +817,7 @@ reload_combine_purge_reg_uses_after_ruid /* Find the use of REGNO with the ruid that is highest among those lower than RUID_LIMIT, and return it if it is the only use of this - reg in the insn (or if the insn is a debug insn). Return NULL - otherwise. */ + reg in the insn. Return NULL otherwise. */ static struct reg_use * reload_combine_closest_single_use (unsigned regno, int ruid_limit) @@ -838,9 +838,9 @@ reload_combine_closest_single_use (unsig if (this_ruid > best_ruid) { best_ruid = this_ruid; - retval = reg_state[regno].reg_use + i; + retval = use; } - else if (this_ruid == best_ruid && !DEBUG_INSN_P (use->insn)) + else if (this_ruid == best_ruid) retval = NULL; } if (last_label_ruid >= best_ruid) @@ -866,7 +866,7 @@ fixup_debug_insns (rtx reg, rtx replacem continue; t = INSN_VAR_LOCATION_LOC (insn); - t = simplify_replace_rtx (t, reg, copy_rtx (replacement)); + t = simplify_replace_rtx (t, reg, replacement); validate_change (insn, &INSN_VAR_LOCATION_LOC (insn), t, 0); } } @@ -938,10 +938,6 @@ reload_combine_recognize_const_pattern ( /* Start the search for the next use from here. */ from_ruid = use->ruid; - /* We'll fix up DEBUG_INSNs after we're done. */ - if (use && DEBUG_INSN_P (use->insn)) - continue; - if (use && GET_MODE (*use->usep) == Pmode) { rtx use_insn = use->insn; @@ -972,7 +968,7 @@ reload_combine_recognize_const_pattern ( int old_cost = address_cost (oldaddr, GET_MODE (mem), as, speed); int new_cost; - newaddr = simplify_replace_rtx (oldaddr, reg, copy_rtx (src)); + newaddr = simplify_replace_rtx (oldaddr, reg, src); if (memory_address_addr_space_p (GET_MODE (mem), newaddr, as)) { XEXP (mem, 0) = newaddr; @@ -1008,8 +1004,7 @@ reload_combine_recognize_const_pattern ( int old_cost = rtx_cost (SET_SRC (new_set), SET, speed); gcc_assert (rtx_equal_p (XEXP (SET_SRC (new_set), 0), reg)); - new_src = simplify_replace_rtx (SET_SRC (new_set), reg, - copy_rtx (src)); + new_src = simplify_replace_rtx (SET_SRC (new_set), reg, src); if (rtx_cost (new_src, SET, speed) <= old_cost && validate_change (use_insn, &SET_SRC (new_set), @@ -1024,6 +1019,7 @@ reload_combine_recognize_const_pattern ( /* See if that took care of the add insn. */ if (rtx_equal_p (SET_DEST (new_set), reg)) { + fixup_debug_insns (reg, src, insn, use_insn); delete_insn (insn); return true; } @@ -1102,6 +1098,8 @@ reload_combine_recognize_pattern (rtx in && REG_P (XEXP (src, 1)) && rtx_equal_p (XEXP (src, 0), reg) && !rtx_equal_p (XEXP (src, 1), reg) + && reg_state[regno].use_index >= 0 + && reg_state[regno].use_index < RELOAD_COMBINE_MAX_USES && last_label_ruid < reg_state[regno].use_ruid) { rtx base = XEXP (src, 1); @@ -1134,7 +1132,11 @@ reload_combine_recognize_pattern (rtx in if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], i) && reg_state[i].use_index == RELOAD_COMBINE_MAX_USES && reg_state[i].store_ruid <= reg_state[regno].use_ruid - && hard_regno_nregs[i][GET_MODE (reg)] == 1) + && (call_used_regs[i] || df_regs_ever_live_p (i)) + && (!frame_pointer_needed || i != HARD_FRAME_POINTER_REGNUM) + && !fixed_regs[i] && !global_regs[i] + && hard_regno_nregs[i][GET_MODE (reg)] == 1 + && targetm.hard_regno_scratch_ok (regno)) { index_reg = gen_rtx_REG (GET_MODE (reg), i); reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base); @@ -1150,7 +1152,6 @@ reload_combine_recognize_pattern (rtx in && prev_set && CONST_INT_P (SET_SRC (prev_set)) && rtx_equal_p (SET_DEST (prev_set), reg) - && reg_state[regno].use_index >= 0 && (reg_state[REGNO (base)].store_ruid <= reg_state[regno].use_ruid)) { @@ -1201,8 +1202,6 @@ reload_combine_recognize_pattern (rtx in remove_reg_equal_equiv_notes (prev); reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES; - reg_state[REGNO (index_reg)].store_ruid - = reload_combine_ruid; return true; } } @@ -1244,14 +1243,6 @@ reload_combine (void) } } -#if 0 - /* If reg+reg can be used in offsetable memory addresses, the main chunk of - reload has already used it where appropriate, so there is no use in - trying to generate it now. */ - if (double_reg_address_ok || last_index_reg == -1) - return; -#endif - /* Set up LABEL_LIVE and EVER_LIVE_AT_START. The register lifetime information is a bit fuzzy immediately after reload, but it's still good enough to determine which registers are live at a jump @@ -1511,6 +1502,11 @@ reload_combine_note_use (rtx *xp, rtx in return; } + /* We may be called to update uses in previously seen insns. + Don't add uses beyond the last store we saw. */ + if (ruid < reg_state[regno].store_ruid) + return; + /* If this register is already used in some unknown fashion, we can't do anything. If we decrement the index from zero to -1, we can't store more Index: Makefile.in =================================================================== --- Makefile.in (revision 162372) +++ Makefile.in (working copy) @@ -3288,7 +3288,7 @@ postreload.o : postreload.c $(CONFIG_H) $(RTL_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) \ hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) output.h \ $(FUNCTION_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) cselib.h $(TM_P_H) $(EXCEPT_H) $(TREE_H) $(MACHMODE_H) \ - $(OBSTACK_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) + $(OBSTACK_H) $(TARGET_H) $(TIMEVAR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) $(FUNCTION_H) output.h $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) \