diff mbox

Treat a sibling call as though it does a wild read

Message ID BLU436-SMTP5376D37683465B0EBD24B0976B0@phx.gbl
State New
Headers show

Commit Message

John David Anglin Dec. 19, 2014, 11:45 p.m. UTC
On 16-Dec-14, at 8:17 PM, John David Anglin wrote:

> On 8-Dec-14, at 5:36 PM, Jeff Law wrote:
>
>> On 12/08/14 15:15, John David Anglin wrote:
>>> On 12/8/2014 3:01 PM, Jeff Law wrote:
>>>>> The above is wrong for sibcalls.  Sibcall arguments are relative
>>>>> to the incoming argument pointer.  Is this always the frame
>>>>> pointer?
>>>> I don't think it's always the frame pointer.  Don't we use an
>>>> argument pointer for the PA64 runtime?  If I recall, it was the
>>>> only port that had a non-eliminable argument pointer at the time.
>>> I don't think PA64 is an argument against this as sibcalls don't  
>>> work
>>> in the PA64 runtime (they are disabled in pa.c) because the argument
>>> pointer isn't a fixed register.  I guess in theory it could be fixed
>>> if it was saved and restored across calls.
>> But there's nothing that says another port in the future won't have  
>> similar characteristics as the PA, so while the PA isn't  
>> particularly important, it shows there's cases where arguments  
>> won't be accessed by the FP.
>>
>>
>>>
>>> DSE as it stands doesn't look at argument pointer based stores and I
>>> suspect they would be deleted with current code.
>> Agreed.
>
>
> I believe that this version addresses the above issues.  While there  
> may be some opportunity to
> optimize the handling of sibling call arguments, I think it is more  
> important to get the overall logic
> correct.  Also, it's obviously a rare situation for the arguments to  
> be pushed to the stack.
>
> Tested on hppa-unknown-linux-gnu and hppa64-hp-hpux11.11.
>
> Okay?


Sorry, forgot to append testcase and ChangeLog entry for it.

Dave
--
John David Anglin	dave.anglin@bell.net
2014-12-16  John David Anglin  <danglin@gcc.gnu.org>

	PR target/55023
	* dse.c (scan_insn): Treat sibling call as though it does a wild read.

	* gcc.dg/pr55023.c: New file.

Comments

Jeff Law Dec. 22, 2014, 4:59 p.m. UTC | #1
On 12/19/14 16:45, John David Anglin wrote:
>> I believe that this version addresses the above issues.  While there
>> may be some opportunity to
>> optimize the handling of sibling call arguments, I think it is more
>> important to get the overall logic
>> correct.  Also, it's obviously a rare situation for the arguments to
>> be pushed to the stack.
>>
>> Tested on hppa-unknown-linux-gnu and hppa64-hp-hpux11.11.
>>
>> Okay?
>
>
> Sorry, forgot to append testcase and ChangeLog entry for it.
No worries, I was sick last week and didn't do any patch review as a 
result.


>
> Dave
> --
> John David Anglin dave.anglin@bell.net
>
>
>
> dse.c.d.4.txt
>
>
> 2014-12-16  John David Anglin<danglin@gcc.gnu.org>
>
> 	PR target/55023
> 	* dse.c (scan_insn): Treat sibling call as though it does a wild read.
>
> 	* gcc.dg/pr55023.c: New file.
OK.

jeff
diff mbox

Patch

Index: dse.c
===================================================================
--- dse.c	(revision 218616)
+++ dse.c	(working copy)
@@ -2483,6 +2483,17 @@ 
 
       insn_info->cannot_delete = true;
 
+      /* Arguments for a sibling call that are pushed to memory are passed
+	 using the incoming argument pointer of the current function.  These
+	 may or may not be frame related depending on the target.  Since
+	 argument pointer related stores are not currently tracked, we treat
+	 a sibling call as though it does a wild read.  */
+      if (SIBLING_CALL_P (insn))
+	{
+	  add_wild_read (bb_info);
+	  return;
+	}
+
       /* Const functions cannot do anything bad i.e. read memory,
 	 however, they can read their parameters which may have
 	 been pushed onto the stack.
--- /dev/null	2014-11-28 19:44:51.440000000 -0500
+++ gcc/testsuite/gcc.dg/pr55023.c	2014-12-04 19:49:45.887701600 -0500
@@ -0,0 +1,33 @@ 
+/* PR rtl-optimization/55023 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-inline" } */
+
+extern void abort (void);
+typedef long long int64_t;
+
+struct foo {
+    int x;
+    int y;
+};
+
+int64_t foo(int64_t a, int64_t b, int64_t c)
+{
+    return a + b + c;
+}
+
+int64_t bar(int64_t a, struct foo bq, struct foo cq)
+{
+    int64_t b = bq.x + bq.y;
+    int64_t c = cq.x + cq.y;
+    return foo(a, b, c);
+}
+
+int main(void)
+{
+  int64_t a = 1;
+  struct foo b = { 2, 3 };
+  struct foo c = { 4, 5 };
+  if (bar (a, b, c) != 15)
+    abort ();
+  return 0;
+}