diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-08-22 18:58:50 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-08-22 18:58:50 +0200 |
commit | 27004606de459d624247190ca0f752a9a9a7b76f (patch) | |
tree | a84c1cb04ef05b13f2b4cd991e221d8edbf8e2ec /gcc/flow.c | |
parent | ad685e8112bbaf64ff9ee993cb189feaa869e741 (diff) | |
download | gcc-27004606de459d624247190ca0f752a9a9a7b76f.zip gcc-27004606de459d624247190ca0f752a9a9a7b76f.tar.gz gcc-27004606de459d624247190ca0f752a9a9a7b76f.tar.bz2 |
re PR rtl-optimization/23478 (Miscompilation due to reloading of a var that is also used in EH pad)
PR rtl-optimization/23478
* regs.h (reg_info): Add throw_calls_crossed.
(REG_N_THROWING_CALLS_CROSSED): Define.
* flow.c (allocate_reg_life_data): Initialize
REG_N_THROWING_CALLS_CROSSED.
(propagate_one_insn, attempt_auto_inc): Update
REG_N_THROWING_CALLS_CROSSED.
* global.c (global_alloc): Don't allocate pseudos across
calls that may throw.
* g++.dg/opt/pr23478.C: New test.
From-SVN: r103348
Diffstat (limited to 'gcc/flow.c')
-rw-r--r-- | gcc/flow.c | 12 |
1 files changed, 10 insertions, 2 deletions
@@ -104,7 +104,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA life_analysis fills in certain vectors containing information about register usage: REG_N_REFS, REG_N_DEATHS, REG_N_SETS, REG_LIVE_LENGTH, - REG_N_CALLS_CROSSED and REG_BASIC_BLOCK. + REG_N_CALLS_CROSSED, REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK. life_analysis sets current_function_sp_is_unchanging if the function doesn't modify the stack pointer. */ @@ -1589,6 +1589,7 @@ allocate_reg_life_data (void) REG_N_REFS (i) = 0; REG_N_DEATHS (i) = 0; REG_N_CALLS_CROSSED (i) = 0; + REG_N_THROWING_CALLS_CROSSED (i) = 0; REG_LIVE_LENGTH (i) = 0; REG_FREQ (i) = 0; REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN; @@ -1820,6 +1821,9 @@ propagate_one_insn (struct propagate_block_info *pbi, rtx insn) reg_set_iterator rsi; EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi) REG_N_CALLS_CROSSED (i)++; + if (can_throw_internal (insn)) + EXECUTE_IF_SET_IN_REG_SET (pbi->reg_live, 0, i, rsi) + REG_N_THROWING_CALLS_CROSSED (i)++; } /* Record sets. Do this even for dead instructions, since they @@ -3512,7 +3516,11 @@ attempt_auto_inc (struct propagate_block_info *pbi, rtx inc, rtx insn, that REGNO now crosses them. */ for (temp = insn; temp != incr; temp = NEXT_INSN (temp)) if (CALL_P (temp)) - REG_N_CALLS_CROSSED (regno)++; + { + REG_N_CALLS_CROSSED (regno)++; + if (can_throw_internal (temp)) + REG_N_THROWING_CALLS_CROSSED (regno)++; + } /* Invalidate alias info for Q since we just changed its value. */ clear_reg_alias_info (q); |