aboutsummaryrefslogtreecommitdiff
path: root/gcc/postreload.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/postreload.c')
-rw-r--r--gcc/postreload.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/gcc/postreload.c b/gcc/postreload.c
index 8849679..c9e6375 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -97,6 +97,16 @@ reload_cse_simplify (rtx_insn *insn, rtx testreg)
if (NO_FUNCTION_CSE && CALL_P (insn))
return false;
+ /* Remember if this insn has been sp += const_int. */
+ rtx sp_set = set_for_reg_notes (insn);
+ rtx sp_addend = NULL_RTX;
+ if (sp_set
+ && SET_DEST (sp_set) == stack_pointer_rtx
+ && GET_CODE (SET_SRC (sp_set)) == PLUS
+ && XEXP (SET_SRC (sp_set), 0) == stack_pointer_rtx
+ && CONST_INT_P (XEXP (SET_SRC (sp_set), 1)))
+ sp_addend = XEXP (SET_SRC (sp_set), 1);
+
if (GET_CODE (body) == SET)
{
int count = 0;
@@ -180,6 +190,15 @@ reload_cse_simplify (rtx_insn *insn, rtx testreg)
reload_cse_simplify_operands (insn, testreg);
}
+ /* If sp += const_int insn is changed into sp = reg;, add REG_EQUAL
+ note so that the stack_adjustments pass can undo it if beneficial. */
+ if (sp_addend
+ && SET_DEST (sp_set) == stack_pointer_rtx
+ && REG_P (SET_SRC (sp_set)))
+ set_dst_reg_note (insn, REG_EQUAL,
+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
+ sp_addend), stack_pointer_rtx);
+
done:
return (EDGE_COUNT (insn_bb->succs) != insn_bb_succs);
}
@@ -573,6 +592,13 @@ reload_cse_simplify_operands (rtx_insn *insn, rtx testreg)
}
}
+ /* The loop below sets alternative_order[0] but -Wmaybe-uninitialized
+ can't know that. Clear it here to avoid the warning. */
+ alternative_order[0] = 0;
+ gcc_assert (!recog_data.n_alternatives
+ || (which_alternative >= 0
+ && which_alternative < recog_data.n_alternatives));
+
/* Record all alternatives which are better or equal to the currently
matching one in the alternative_order array. */
for (i = j = 0; i < recog_data.n_alternatives; i++)
@@ -1204,11 +1230,10 @@ reload_combine_recognize_pattern (rtx_insn *insn)
/* Delete the reg-reg addition. */
delete_insn (insn);
- if (reg_state[regno].offset != const0_rtx
- /* Previous REG_EQUIV / REG_EQUAL notes for PREV
- are now invalid. */
- && remove_reg_equal_equiv_notes (prev))
- df_notes_rescan (prev);
+ if (reg_state[regno].offset != const0_rtx)
+ /* Previous REG_EQUIV / REG_EQUAL notes for PREV
+ are now invalid. */
+ remove_reg_equal_equiv_notes (prev);
reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
return true;