Allow constant global VAR_DECLs in constant jump functions
authorMartin Jambor <mjambor@suse.cz>
Wed, 18 May 2016 16:44:08 +0000 (18:44 +0200)
committerMartin Jambor <jamborm@gcc.gnu.org>
Wed, 18 May 2016 16:44:08 +0000 (18:44 +0200)
2016-05-18  Martin Jambor  <mjambor@suse.cz>

PR ipa/69708
* ipa-cp.c (ipa_get_jf_pass_through_result): Allow non-ip constant
input for NOP_EXPR pass-through functions.
* ipa-prop.c (ipa_compute_jump_functions_for_edge): Allow
aggregate global constant VAR_DECLs in constant jump functions.

testsuite/
* gcc.dg/ipa/iinline-cstagg-2.c: New test.
* gcc.dg/ipa/ipcp-cstagg-5.c: Likewise.
* gcc.dg/ipa/ipcp-cstagg-6.c: Likewise.
* gcc.dg/ipa/ipcp-cstagg-7.c: Likewise.

From-SVN: r236418

gcc/ChangeLog
gcc/ipa-cp.c
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c [new file with mode: 0644]

index 7924d1f98c93ee5d6b1aa930dc19130096fe050f..bb7855e8d06f2936d8ebd814a2621f390a2c3ac4 100644 (file)
@@ -1,3 +1,11 @@
+2016-05-18  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/69708
+       * ipa-cp.c (ipa_get_jf_pass_through_result): Allow non-ip constant
+       input for NOP_EXPR pass-through functions.
+       * ipa-prop.c (ipa_compute_jump_functions_for_edge): Allow
+       aggregate global constant VAR_DECLs in constant jump functions.
+
 2016-05-18  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/69708
index 2183da07b68b1ad340397f4fb42a8b1469f614d8..8caa973e46c7fe44a2e99c5d1b9bf618e81a986c 100644 (file)
@@ -1026,9 +1026,10 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
 {
   tree restype, res;
 
-  gcc_checking_assert (is_gimple_ip_invariant (input));
   if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
     return input;
+  if (!is_gimple_ip_invariant (input))
+    return NULL_TREE;
 
   if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
       == tcc_comparison)
index 117a0255b1b9f09ab8adb6152cd9cdd1bcd34e42..132b622639c0fa01d649ebce76f715167d9309c9 100644 (file)
@@ -1674,7 +1674,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
       else
        gcc_assert (!jfunc->alignment.known);
 
-      if (is_gimple_ip_invariant (arg))
+      if (is_gimple_ip_invariant (arg)
+         || (TREE_CODE (arg) == VAR_DECL
+             && is_global_var (arg)
+             && TREE_READONLY (arg)))
        ipa_set_jf_constant (jfunc, arg, cs);
       else if (!is_gimple_reg_type (TREE_TYPE (arg))
               && TREE_CODE (arg) == PARM_DECL)
index d7dc01607da1a754fbfd25399a13a39153945147..66f5cba3c8e80c16abfb87ca9eff1901fb7dd198 100644 (file)
@@ -1,3 +1,11 @@
+2016-05-18  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/69708
+       * gcc.dg/ipa/iinline-cstagg-2.c: New test.
+       * gcc.dg/ipa/ipcp-cstagg-5.c: Likewise.
+       * gcc.dg/ipa/ipcp-cstagg-6.c: Likewise.
+       * gcc.dg/ipa/ipcp-cstagg-7.c: Likewise.
+
 2016-05-18  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/69708
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c
new file mode 100644 (file)
index 0000000..546db87
--- /dev/null
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-inline-details -fno-early-inlining -fno-ipa-sra -fno-ipa-cp" } */
+
+typedef struct S
+{
+  int add_offset;
+  int (*call)(int);
+} S;
+
+static int
+bar (const S f, int x)
+{
+  x = f.call (x);
+  return x;
+}
+
+static int
+thisisthetarget (int x)
+{
+  return x * x;
+}
+
+int
+outerfunction (int x)
+{
+  return bar ((S){16, thisisthetarget}, x);
+}
+
+
+/* { dg-final { scan-ipa-dump "thisisthetarget\[^\\n\]*inline copy in outerfunction"  "inline"  } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c
new file mode 100644 (file)
index 0000000..56d544e
--- /dev/null
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+  int add_offset;
+  int (*call)(int);
+} S;
+
+extern const S *es;
+
+static int  __attribute__((noinline))
+foo (const S f, int x)
+{
+  es = &f;                     /* This disables IPA-SRA */
+  x = f.call(x+f.add_offset);
+  x = f.call(x);
+  x = f.call(x);
+  return x;
+}
+
+static int
+sq (int x)
+{
+  return x * x;
+}
+
+static const S s = {16, sq};
+
+int
+h (int x)
+{
+  return foo (s, x);
+}
+
+/* { dg-final { scan-ipa-dump "Discovered an indirect call to a known target" "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c
new file mode 100644 (file)
index 0000000..7891082
--- /dev/null
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+  int add_offset;
+  int (*call)(int);
+} S;
+
+extern const S *es, *fs;
+
+static int  __attribute__((noinline))
+foo (const S f, int x)
+{
+  es = &f;                     /* This disables IPA-SRA */
+  x = f.call(x+f.add_offset);
+  x = f.call(x);
+  x = f.call(x);
+  return x;
+}
+
+static int  __attribute__((noinline))
+bar (const S f, int x)
+{
+  fs = &f;                     /* This disables IPA-SRA */
+  return foo (f, x);
+}
+
+static int
+sq (int x)
+{
+  return x * x;
+}
+
+static const S s = {16, sq};
+
+int
+h (int x)
+{
+  return bar (s, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c
new file mode 100644 (file)
index 0000000..6af8bda
--- /dev/null
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+#define N 4
+
+typedef int (* const A[N])(int);
+
+typedef struct S
+{
+  int add_offset;
+  A a;
+} S;
+
+extern const S *gs, *hs;
+
+static int  __attribute__((noinline))
+foo (const S f, int x)
+{
+  gs = &f;
+  x = f.a[2](x);
+  x = f.a[2](x);
+  x = f.a[2](x);
+  return x;
+}
+
+static int  __attribute__((noinline))
+bar (const S f, int x)
+{
+  hs = &f;
+  return foo (f, x);
+}
+
+static int
+zero (int x)
+{
+  return 0;
+}
+
+static int
+addone (int x)
+{
+  return x + 1;
+}
+
+static int
+sq (int x)
+{
+  return x * x;
+}
+
+static int
+cube (int x)
+{
+  return x * x * x;
+}
+
+static const S s = {64, {zero, addone, sq, cube}};
+
+int
+h (int x)
+{
+  return bar (s, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */