From: Martin Jambor Date: Wed, 18 May 2016 16:44:08 +0000 (+0200) Subject: Allow constant global VAR_DECLs in constant jump functions X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=04643334f9769263db3a2f71956876886ef6cdd5;p=gcc.git Allow constant global VAR_DECLs in constant jump functions 2016-05-18 Martin Jambor 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7924d1f98c9..bb7855e8d06 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-05-18 Martin Jambor + + 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 PR ipa/69708 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,3 +1,11 @@ +2016-05-18 Martin Jambor + + 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 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 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" } } */