diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2011-05-23 17:57:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2011-05-23 17:57:35 +0000 |
commit | 65712d5cf1e778ae8518b2193e484c53ddf1eb53 (patch) | |
tree | cbcfd8af4785e068775d431b87251e68e62356bf /gcc | |
parent | 9025085e6aa1f39e8e20f2f33be85bb2f2f05753 (diff) | |
download | gcc-65712d5cf1e778ae8518b2193e484c53ddf1eb53.zip gcc-65712d5cf1e778ae8518b2193e484c53ddf1eb53.tar.gz gcc-65712d5cf1e778ae8518b2193e484c53ddf1eb53.tar.bz2 |
re PR rtl-optimization/48826 (ICE in dwarf2out_var_location, at dwarf2out.c:22013)
gcc/
PR rtl-optimization/48826
* emit-rtl.c (try_split): When splitting a call that is followed
by a NOTE_INSN_CALL_ARG_LOCATION, move the note after the new call.
From-SVN: r174080
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 27 |
2 files changed, 31 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eabc32f..9771921 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2011-05-23 Richard Sandiford <rdsandiford@googlemail.com> + + PR rtl-optimization/48826 + * emit-rtl.c (try_split): When splitting a call that is followed + by a NOTE_INSN_CALL_ARG_LOCATION, move the note after the new call. + 2011-05-23 Jakub Jelinek <jakub@redhat.com> * cfgexpand.c (expand_debug_expr): For unused non-addressable diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 2e073b5..988072b 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3470,17 +3470,40 @@ try_split (rtx pat, rtx trial, int last) } /* If we are splitting a CALL_INSN, look for the CALL_INSN - in SEQ and copy our CALL_INSN_FUNCTION_USAGE to it. */ + in SEQ and copy any additional information across. */ if (CALL_P (trial)) { for (insn = insn_last; insn ; insn = PREV_INSN (insn)) if (CALL_P (insn)) { - rtx *p = &CALL_INSN_FUNCTION_USAGE (insn); + rtx next, *p; + + /* Add the old CALL_INSN_FUNCTION_USAGE to whatever the + target may have explicitly specified. */ + p = &CALL_INSN_FUNCTION_USAGE (insn); while (*p) p = &XEXP (*p, 1); *p = CALL_INSN_FUNCTION_USAGE (trial); + + /* If the old call was a sibling call, the new one must + be too. */ SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial); + + /* If the new call is the last instruction in the sequence, + it will effectively replace the old call in-situ. Otherwise + we must move any following NOTE_INSN_CALL_ARG_LOCATION note + so that it comes immediately after the new call. */ + if (NEXT_INSN (insn)) + { + next = NEXT_INSN (trial); + if (next + && NOTE_P (next) + && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION) + { + remove_insn (next); + add_insn_after (next, insn, NULL); + } + } } } |