diff options
author | Jakub Jelinek <jakub@redhat.com> | 2011-01-19 16:13:01 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2011-01-19 16:13:01 +0100 |
commit | 2e0642cde2ace61ba98145609d5f62796666cbfa (patch) | |
tree | 5646308e390bbb76c0d494c9bae522ddbfc05847 /gcc/dce.c | |
parent | 46e7483cbaff644bc21d2a69469921709e1a849c (diff) | |
download | gcc-2e0642cde2ace61ba98145609d5f62796666cbfa.tar.gz |
re PR rtl-optimization/47337 (Wrong RTL dce of calls)
PR rtl-optimization/47337
* dce.c (check_argument_store): New function.
(find_call_stack_args): Ignore debug insns. Use check_argument_store.
* gcc.c-torture/execute/pr47337.c: New test.
From-SVN: r168997
Diffstat (limited to 'gcc/dce.c')
-rw-r--r-- | gcc/dce.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/gcc/dce.c b/gcc/dce.c index e6e98365005..f63d09e4164 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -1,5 +1,5 @@ /* RTL dead code elimination. - Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 + Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. This file is part of GCC. @@ -220,6 +220,26 @@ mark_nonreg_stores (rtx body, rtx insn, bool fast) } +/* Return true if store to MEM, starting OFF bytes from stack pointer, + is a call argument store, and clear corresponding bits from SP_BYTES + bitmap if it is. */ + +static bool +check_argument_store (rtx mem, HOST_WIDE_INT off, HOST_WIDE_INT min_sp_off, + HOST_WIDE_INT max_sp_off, bitmap sp_bytes) +{ + HOST_WIDE_INT byte; + for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++) + { + if (byte < min_sp_off + || byte >= max_sp_off + || !bitmap_clear_bit (sp_bytes, byte - min_sp_off)) + return false; + } + return true; +} + + /* Try to find all stack stores of CALL_INSN arguments if ACCUMULATE_OUTGOING_ARGS. If all stack stores have been found and it is therefore safe to eliminate the call, return true, @@ -364,7 +384,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, for (insn = PREV_INSN (call_insn); insn; insn = prev_insn) { rtx set, mem, addr; - HOST_WIDE_INT off, byte; + HOST_WIDE_INT off; if (insn == BB_HEAD (BLOCK_FOR_INSN (call_insn))) prev_insn = NULL_RTX; @@ -374,7 +394,7 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, if (CALL_P (insn)) break; - if (!INSN_P (insn)) + if (!NONDEBUG_INSN_P (insn)) continue; set = single_set (insn); @@ -433,17 +453,11 @@ find_call_stack_args (rtx call_insn, bool do_mark, bool fast, break; } - if (GET_MODE_SIZE (GET_MODE (mem)) == 0) + if (GET_MODE_SIZE (GET_MODE (mem)) == 0 + || !check_argument_store (mem, off, min_sp_off, + max_sp_off, sp_bytes)) break; - for (byte = off; byte < off + GET_MODE_SIZE (GET_MODE (mem)); byte++) - { - if (byte < min_sp_off - || byte >= max_sp_off - || !bitmap_clear_bit (sp_bytes, byte - min_sp_off)) - break; - } - if (!deletable_insn_p (insn, fast, NULL)) break; |