aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rdsandiford@googlemail.com>2011-05-23 17:57:35 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2011-05-23 17:57:35 +0000
commit65712d5cf1e778ae8518b2193e484c53ddf1eb53 (patch)
treecbcfd8af4785e068775d431b87251e68e62356bf /gcc
parent9025085e6aa1f39e8e20f2f33be85bb2f2f05753 (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/emit-rtl.c27
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);
+ }
+ }
}
}