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.ang...@bell.net


2014-12-16  John David Anglin  <dang...@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.

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;
+}

Reply via email to