Commit 04643334 by Martin Jambor Committed by Martin Jambor

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.

From-SVN: r236418
parent 776e4fe2
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.
......
......@@ -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)
......
......@@ -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)
......
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.
......
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
/* { 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" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment