diff mbox

PR 48826: NOTE_INSN_CALL_ARG_LOCATION vs. define_split

Message ID 87aaeds3jh.fsf@firetop.home
State New
Headers show

Commit Message

Richard Sandiford May 23, 2011, 5:57 p.m. UTC
Eric Botcazou <ebotcazou@adacore.com> writes:
>> 	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.
>
> OK if you move up the comment and merge it in the comment of the
> block.  And it would be nice to add the missing blurb about the
> SIBLING_CALL_P flag.  TIA.

Doh, good catch.

In the end, it felt a bit awkward stringing together three essentially
separate bits of info into one comment, so I instead generalised the
block comment and added specific comments above each section.

It sounded like you were more concerned with having the comments staying
in sync than the actual specifics, so I went ahead and installed the
patch below.  Please let me know if you'd prefer something different
though.

Thanks,
Richard


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.

Comments

Eric Botcazou May 23, 2011, 8:04 p.m. UTC | #1
> It sounded like you were more concerned with having the comments staying
> in sync than the actual specifics, so I went ahead and installed the
> patch below.

That's fine, thanks.
diff mbox

Patch

Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c	2011-05-22 22:19:08.000000000 +0100
+++ gcc/emit-rtl.c	2011-05-23 18:48:23.000000000 +0100
@@ -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);
+		  }
+	      }
 	  }
     }