re PR rtl-optimization/48826 (ICE in dwarf2out_var_location, at dwarf2out.c:22013)
authorRichard Sandiford <rdsandiford@googlemail.com>
Mon, 23 May 2011 17:57:35 +0000 (17:57 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Mon, 23 May 2011 17:57:35 +0000 (17:57 +0000)
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

gcc/ChangeLog
gcc/emit-rtl.c

index eabc32f6cd72e7fd523facefc1d6365053dc4022..97719219e4f23d9e512cce3fd767a401a465e6ab 100644 (file)
@@ -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
index 2e073b5da1f84661983d3e7e068d968ef7e2195d..988072b2cbfaf1898b13f6774aa3d0a4731a7868 100644 (file)
@@ -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);
+                 }
+             }
          }
     }