summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-18 16:44:08 +0000
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-18 16:44:08 +0000
commitbe951c5998ecb9dec5574fdf3998912ff3e972b6 (patch)
tree1276e4f905c6f856a6887cb3e4bc04c542e58392 /gcc
parentab4891c2b5851a2921e10eadfa7c47da432e6757 (diff)
downloadgcc-be951c5998ecb9dec5574fdf3998912ff3e972b6.tar.gz
Allow constant global VAR_DECLs in constant jump functions
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@236418 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/ipa-cp.c3
-rw-r--r--gcc/ipa-prop.c5
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c37
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c43
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c65
8 files changed, 197 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7924d1f98c9..bb7855e8d06 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,6 +1,14 @@
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
* ipa-prop.c (parm_preserved_before_stmt_p): Return true for loads
from TREE_READONLY parameters.
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 2183da07b68..8caa973e46c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -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)
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 117a0255b1b..132b622639c 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -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)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d7dc01607da..66f5cba3c8e 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,6 +1,14 @@
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
* gcc.dg/ipa/iinline-cstagg-1.c: New test.
* gcc.dg/ipa/ipcp-cstagg-1.c: Likewise.
* gcc.dg/ipa/ipcp-cstagg-2.c: Likewise.
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
index 00000000000..546db87ea5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c
@@ -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
index 00000000000..56d544e5a64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c
@@ -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
index 00000000000..7891082f785
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c
@@ -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
index 00000000000..6af8bda6d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c
@@ -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" } } */