Hi,

the patch below enables IRA live-range splitting that later
facilitates shrink-wrapping also work on ppc64.  The difference is
that while on x86_64 it was enough to look for single sets from a hard
register to a pseudo in the first BB, on ppc the instructions are more
complicated and can look like this (example from pr10474.c testcase):

(insn 6 3 7 2 (parallel [
            (set (reg:CC 124)
                (compare:CC (reg:DI 3 3 [ i ])
                    (const_int 0 [0])))
            (set (reg/v/f:DI 123 [ i ])
                (reg:DI 3 3 [ i ]))
        ]) pr10474.c:6 428 {*movdi_internal2}
     (expr_list:REG_DEAD (reg:DI 3 3 [ i ])
        (nil)))

So I changed the code that determines whether an instruction is
interesting or not to also go through a parallel instructions and be
happy with them if there is exactly one interesting SET part.

Unfortunately, I also had to change two testcases that check this to
use long instead of int, otherwise I get SUBREG uses that make
split_live_ranges_for_shrink_wrap give up.  I will try to get rid of
that limitation (and have other ideas for improvement as well) but
that is something for 4.10.  It works for pointers (e.g. in pr10474.c)
and that is probably most important.

Bootstrapped and tested on ppc64-linux ("all" languages), x86_64-linux
("all" languages + Ada and ObjC++) and on ia64-linux (C, C++ and
Fortran).  OK for trunk?

Thanks,

Martin


2013-11-20  Martin Jambor  <mjam...@suse.cz>

        PR rtl-optimization/10474
        * ira.c (interesting_dest_for_shprep_1): New function.
        (interesting_dest_for_shprep): Use interesting_dest_for_shprep_1,
        also check parallels.

testsuite/
        * gcc.dg/pr10474.c: Also test ppc64.
        * gcc.dg/ira-shrinkwrap-prep-1.c: Also tes ppc64, changed all ints
        to longs.
        * gcc.dg/ira-shrinkwrap-prep-2.c: Likewise.

diff --git a/gcc/ira.c b/gcc/ira.c
index f4fdb11..34d9649 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -4847,17 +4847,13 @@ find_moveable_pseudos (void)
   free_dominance_info (CDI_DOMINATORS);
 }
 
-
-/* If insn is interesting for parameter range-splitting shring-wrapping
-   preparation, i.e. it is a single set from a hard register to a pseudo, which
-   is live at CALL_DOM, return the destination.  Otherwise return NULL.  */
+/* If SET pattern SET is an assignment from a hard register to a pseudo which
+   is live at CALL_DOM (if non-NULL, otherwise this check is omitted), return
+   the destination.  Otherwise return NULL.  */
 
 static rtx
-interesting_dest_for_shprep (rtx insn, basic_block call_dom)
+interesting_dest_for_shprep_1 (rtx set, basic_block call_dom)
 {
-  rtx set = single_set (insn);
-  if (!set)
-    return NULL;
   rtx src = SET_SRC (set);
   rtx dest = SET_DEST (set);
   if (!REG_P (src) || !HARD_REGISTER_P (src)
@@ -4867,6 +4863,41 @@ interesting_dest_for_shprep (rtx insn, basic_block 
call_dom)
   return dest;
 }
 
+/* If insn is interesting for parameter range-splitting shring-wrapping
+   preparation, i.e. it is a single set from a hard register to a pseudo, which
+   is live at CALL_DOM (if non-NULL, otherwise this check is omitted), or a
+   parallel statement with only one such statement, return the destination.
+   Otherwise return NULL.  */
+
+static rtx
+interesting_dest_for_shprep (rtx insn, basic_block call_dom)
+{
+  if (!INSN_P (insn))
+    return NULL;
+  rtx pat = PATTERN (insn);
+  if (GET_CODE (pat) == SET)
+    return interesting_dest_for_shprep_1 (pat, call_dom);
+
+  if (GET_CODE (pat) != PARALLEL)
+    return NULL;
+  rtx ret = NULL;
+  for (int i = 0; i < XVECLEN (pat, 0); i++)
+    {
+      rtx sub = XVECEXP (pat, 0, i);
+      if (GET_CODE (sub) == USE || GET_CODE (sub) == CLOBBER)
+       continue;
+      if (GET_CODE (sub) != SET
+         || side_effects_p (sub))
+       return NULL;
+      rtx dest = interesting_dest_for_shprep_1 (sub, call_dom);
+      if (dest && ret)
+       return NULL;
+      if (dest)
+       ret = dest;
+    }
+  return ret;
+}
+
 /* Split live ranges of pseudos that are loaded from hard registers in the
    first BB in a BB that dominates all non-sibling call if such a BB can be
    found and is not in a loop.  Return true if the function has made any
diff --git a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c 
b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c
index 4fc00b2..54d3e76 100644
--- a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c
+++ b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-1.c
@@ -1,18 +1,18 @@
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 
} } } } */
 /* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue"  } */
 
-int __attribute__((noinline, noclone))
-foo (int a)
+long __attribute__((noinline, noclone))
+foo (long a)
 {
   return a + 5;
 }
 
-static int g;
+static long g;
 
-int __attribute__((noinline, noclone))
-bar (int a)
+long __attribute__((noinline, noclone))
+bar (long a)
 {
-  int r;
+  long r;
 
   if (a)
     {
diff --git a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c 
b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c
index bb725e1..ed08494 100644
--- a/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c
+++ b/gcc/testsuite/gcc.dg/ira-shrinkwrap-prep-2.c
@@ -1,18 +1,18 @@
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 
} } } } */
 /* { dg-options "-O3 -fdump-rtl-ira -fdump-rtl-pro_and_epilogue"  } */
 
-int __attribute__((noinline, noclone))
-foo (int a)
+long __attribute__((noinline, noclone))
+foo (long a)
 {
   return a + 5;
 }
 
-static int g;
+static long g;
 
-int __attribute__((noinline, noclone))
-bar (int a)
+long __attribute__((noinline, noclone))
+bar (long a)
 {
-  int r;
+  long r;
 
   if (a)
     {
diff --git a/gcc/testsuite/gcc.dg/pr10474.c b/gcc/testsuite/gcc.dg/pr10474.c
index 08324d8..77ccc46 100644
--- a/gcc/testsuite/gcc.dg/pr10474.c
+++ b/gcc/testsuite/gcc.dg/pr10474.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { x86_64-*-* && lp64 } } } */
+/* { dg-do compile { target { { x86_64-*-* && lp64 } || { powerpc*-*-* && lp64 
} } } } */
 /* { dg-options "-O3 -fdump-rtl-pro_and_epilogue"  } */
 
 void f(int *i)

Reply via email to