+2011-10-06 Richard Henderson <rth@redhat.com>
+
+ * combine-stack-adjust.c (maybe_move_args_size_note): Add after
+ parameter; use it to decide whether to merge two notes.
+ (combine_stack_adjustments_for_block): Use maybe_move_args_size_note
+ for the deallocation case as well.
+
2011-10-06 Anatoly Sokolov <aesok@post.ru>
* system.h (OUTPUT_ADDR_CONST_EXTRA): Poison.
return 0;
}
-/* If INSN has a REG_ARGS_SIZE note, move it to LAST. */
+/* If INSN has a REG_ARGS_SIZE note, move it to LAST.
+ AFTER is true iff LAST follows INSN in the instruction stream. */
static void
-maybe_move_args_size_note (rtx last, rtx insn)
+maybe_move_args_size_note (rtx last, rtx insn, bool after)
{
rtx note, last_note;
last_note = find_reg_note (last, REG_ARGS_SIZE, NULL_RTX);
if (last_note)
- XEXP (last_note, 0) = XEXP (note, 0);
+ {
+ /* The ARGS_SIZE notes are *not* cumulative. They represent an
+ absolute value, and the "most recent" note wins. */
+ if (!after)
+ XEXP (last_note, 0) = XEXP (note, 0);
+ }
else
add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0));
}
last_sp_adjust + this_adjust,
this_adjust))
{
- maybe_move_args_size_note (last_sp_set, insn);
+ maybe_move_args_size_note (last_sp_set, insn, false);
/* It worked! */
delete_insn (insn);
last_sp_adjust + this_adjust,
-last_sp_adjust))
{
+ maybe_move_args_size_note (insn, last_sp_set, true);
+
/* It worked! */
delete_insn (last_sp_set);
last_sp_set = insn;