re PR middle-end/52890 (Revision 185336 causes 10% degradation on cpu2000 benchmark 252.eon)
2012-11-30 Martin Jambor <mjambor@suse.cz> PR middle-end/52890 PR tree-optimization/55415 PR tree-optimization/54386 PR target/55448 * ipa-prop.c (ipa_modify_call_arguments): Be optimistic when get_pointer_alignment_1 returns false and the base was not a dereference. * tree-sra.c (access_precludes_ipa_sra_p): New parameter req_align, added check for required alignment. Update the user. * testsuite/gcc.dg/ipa/ipa-sra-7.c: New test. * testsuite/gcc.dg/ipa/ipa-sra-8.c: Likewise. * testsuite/gcc.dg/ipa/ipa-sra-9.c: Likewise. * testsuite/gcc.target/i386/pr55448.c: Likewise. From-SVN: r193998
This commit is contained in:
parent
d7b30db8d8
commit
c1ed6a0172
|
@ -1,3 +1,15 @@
|
||||||
|
2012-11-30 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR middle-end/52890
|
||||||
|
PR tree-optimization/55415
|
||||||
|
PR tree-optimization/54386
|
||||||
|
PR target/55448
|
||||||
|
* ipa-prop.c (ipa_modify_call_arguments): Be optimistic when
|
||||||
|
get_pointer_alignment_1 returns false and the base was not a
|
||||||
|
dereference.
|
||||||
|
* tree-sra.c (access_precludes_ipa_sra_p): New parameter req_align,
|
||||||
|
added check for required alignment. Update the user.
|
||||||
|
|
||||||
2012-11-30 Ramana Radhakrishnan <Ramana.Radhakrishnan@arm.com>
|
2012-11-30 Ramana Radhakrishnan <Ramana.Radhakrishnan@arm.com>
|
||||||
Greta Yorsh <Greta.Yorsh@arm.com>
|
Greta Yorsh <Greta.Yorsh@arm.com>
|
||||||
|
|
||||||
|
|
|
@ -2888,6 +2888,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||||
{
|
{
|
||||||
tree expr, base, off;
|
tree expr, base, off;
|
||||||
location_t loc;
|
location_t loc;
|
||||||
|
unsigned int deref_align;
|
||||||
|
bool deref_base = false;
|
||||||
|
|
||||||
/* We create a new parameter out of the value of the old one, we can
|
/* We create a new parameter out of the value of the old one, we can
|
||||||
do the following kind of transformations:
|
do the following kind of transformations:
|
||||||
|
@ -2921,9 +2923,15 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||||
{
|
{
|
||||||
HOST_WIDE_INT base_offset;
|
HOST_WIDE_INT base_offset;
|
||||||
tree prev_base;
|
tree prev_base;
|
||||||
|
bool addrof;
|
||||||
|
|
||||||
if (TREE_CODE (base) == ADDR_EXPR)
|
if (TREE_CODE (base) == ADDR_EXPR)
|
||||||
base = TREE_OPERAND (base, 0);
|
{
|
||||||
|
base = TREE_OPERAND (base, 0);
|
||||||
|
addrof = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addrof = false;
|
||||||
prev_base = base;
|
prev_base = base;
|
||||||
base = get_addr_base_and_unit_offset (base, &base_offset);
|
base = get_addr_base_and_unit_offset (base, &base_offset);
|
||||||
/* Aggregate arguments can have non-invariant addresses. */
|
/* Aggregate arguments can have non-invariant addresses. */
|
||||||
|
@ -2935,6 +2943,11 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (base) == MEM_REF)
|
else if (TREE_CODE (base) == MEM_REF)
|
||||||
{
|
{
|
||||||
|
if (!addrof)
|
||||||
|
{
|
||||||
|
deref_base = true;
|
||||||
|
deref_align = TYPE_ALIGN (TREE_TYPE (base));
|
||||||
|
}
|
||||||
off = build_int_cst (adj->alias_ptr_type,
|
off = build_int_cst (adj->alias_ptr_type,
|
||||||
base_offset
|
base_offset
|
||||||
+ adj->offset / BITS_PER_UNIT);
|
+ adj->offset / BITS_PER_UNIT);
|
||||||
|
@ -2957,7 +2970,17 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt,
|
||||||
unsigned int align;
|
unsigned int align;
|
||||||
unsigned HOST_WIDE_INT misalign;
|
unsigned HOST_WIDE_INT misalign;
|
||||||
|
|
||||||
get_pointer_alignment_1 (base, &align, &misalign);
|
if (deref_base)
|
||||||
|
{
|
||||||
|
align = deref_align;
|
||||||
|
misalign = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
get_pointer_alignment_1 (base, &align, &misalign);
|
||||||
|
if (TYPE_ALIGN (type) > align)
|
||||||
|
align = TYPE_ALIGN (type);
|
||||||
|
}
|
||||||
misalign += (tree_to_double_int (off)
|
misalign += (tree_to_double_int (off)
|
||||||
.sext (TYPE_PRECISION (TREE_TYPE (off))).low
|
.sext (TYPE_PRECISION (TREE_TYPE (off))).low
|
||||||
* BITS_PER_UNIT);
|
* BITS_PER_UNIT);
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
2012-11-30 Martin Jambor <mjambor@suse.cz>
|
||||||
|
|
||||||
|
PR middle-end/52890
|
||||||
|
PR tree-optimization/55415
|
||||||
|
PR tree-optimization/54386
|
||||||
|
PR target/55448
|
||||||
|
* gcc.dg/ipa/ipa-sra-7.c: New test.
|
||||||
|
* gcc.dg/ipa/ipa-sra-8.c: Likewise.
|
||||||
|
* gcc.dg/ipa/ipa-sra-9.c: Likewise.
|
||||||
|
* gcc.target/i386/pr55448.c: Likewise.
|
||||||
|
|
||||||
2012-11-29 Eric Botcazou <ebotcazou@adacore.com>
|
2012-11-29 Eric Botcazou <ebotcazou@adacore.com>
|
||||||
|
|
||||||
* loop_optimization14.ad[sb]: New test.
|
* loop_optimization14.ad[sb]: New test.
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-O3" } */
|
||||||
|
|
||||||
|
typedef unsigned int myint __attribute__((aligned(1)));
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed)) S {
|
||||||
|
unsigned a, b, c;
|
||||||
|
} SS;
|
||||||
|
|
||||||
|
typedef SS __attribute__((aligned(1))) SSS;
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int __attribute__ ((noinline))
|
||||||
|
get_a (SSS *p)
|
||||||
|
{
|
||||||
|
return p->a;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __attribute__ ((noinline, noclone))
|
||||||
|
foo (SS *p)
|
||||||
|
{
|
||||||
|
int r = (int) get_a(p) + 2;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
static SSS * __attribute__ ((noinline, noclone))
|
||||||
|
get_sss (void)
|
||||||
|
{
|
||||||
|
return (SSS *)(buf + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SSS *p = get_sss();
|
||||||
|
if (foo(p) != 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-O3" } */
|
||||||
|
|
||||||
|
typedef unsigned int myint __attribute__((aligned(1)));
|
||||||
|
|
||||||
|
typedef struct S {
|
||||||
|
unsigned a, b, c;
|
||||||
|
} SS;
|
||||||
|
|
||||||
|
typedef SS __attribute__((aligned(1))) SSS;
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int __attribute__ ((noinline))
|
||||||
|
get_a (SS s)
|
||||||
|
{
|
||||||
|
return s.a;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __attribute__ ((noinline, noclone))
|
||||||
|
foo (SSS *p)
|
||||||
|
{
|
||||||
|
int r = (int) get_a(*p) + 2;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
static SSS * __attribute__ ((noinline, noclone))
|
||||||
|
get_sss (void)
|
||||||
|
{
|
||||||
|
return (SSS *)(buf + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
SSS *p = get_sss();
|
||||||
|
if (foo(p) != 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
/* { dg-options "-O3" } */
|
||||||
|
|
||||||
|
typedef unsigned int myint __attribute__((aligned(1)));
|
||||||
|
|
||||||
|
typedef struct S {
|
||||||
|
unsigned a, b, c;
|
||||||
|
} SS;
|
||||||
|
|
||||||
|
typedef struct U {
|
||||||
|
SS s[2];
|
||||||
|
} UU;
|
||||||
|
|
||||||
|
typedef UU __attribute__((aligned(1))) UUU;
|
||||||
|
|
||||||
|
static unsigned int __attribute__ ((noinline))
|
||||||
|
get_a (SS s)
|
||||||
|
{
|
||||||
|
return s.a;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __attribute__ ((noinline, noclone))
|
||||||
|
foo (UUU *p)
|
||||||
|
{
|
||||||
|
int r = (int) get_a(p->s[0]) + 2;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buf[512];
|
||||||
|
|
||||||
|
static UUU * __attribute__ ((noinline, noclone))
|
||||||
|
get_uuu (void)
|
||||||
|
{
|
||||||
|
return (UUU *)(buf + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
UUU *p = get_uuu();
|
||||||
|
if (foo(p) != 2)
|
||||||
|
__builtin_abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -mavx" } */
|
||||||
|
|
||||||
|
#include <immintrin.h>
|
||||||
|
|
||||||
|
static inline __m256 add1(const __m256 *a, const __m256 *b)
|
||||||
|
{
|
||||||
|
return _mm256_add_ps(*a, *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo1(__m256 *a, const __m256 b)
|
||||||
|
{
|
||||||
|
*a = add1(a, &b);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline __m128 add2(const __m128 *a, const __m128 *b)
|
||||||
|
{
|
||||||
|
return _mm_add_ps(*a, *b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo2(__m128 *a, const __m128 b)
|
||||||
|
{
|
||||||
|
*a = add2(a, &b);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* { dg-final { scan-assembler-not "vmovups" } } */
|
|
@ -3891,12 +3891,13 @@ unmodified_by_ref_scalar_representative (tree parm)
|
||||||
return repr;
|
return repr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return true iff this access precludes IPA-SRA of the parameter it is
|
/* Return true iff this ACCESS precludes IPA-SRA of the parameter it is
|
||||||
associated with. */
|
associated with. REQ_ALIGN is the minimum required alignment. */
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
access_precludes_ipa_sra_p (struct access *access)
|
access_precludes_ipa_sra_p (struct access *access, unsigned int req_align)
|
||||||
{
|
{
|
||||||
|
unsigned int exp_align;
|
||||||
/* Avoid issues such as the second simple testcase in PR 42025. The problem
|
/* Avoid issues such as the second simple testcase in PR 42025. The problem
|
||||||
is incompatible assign in a call statement (and possibly even in asm
|
is incompatible assign in a call statement (and possibly even in asm
|
||||||
statements). This can be relaxed by using a new temporary but only for
|
statements). This can be relaxed by using a new temporary but only for
|
||||||
|
@ -3908,6 +3909,10 @@ access_precludes_ipa_sra_p (struct access *access)
|
||||||
|| gimple_code (access->stmt) == GIMPLE_ASM))
|
|| gimple_code (access->stmt) == GIMPLE_ASM))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
exp_align = get_object_alignment (access->expr);
|
||||||
|
if (exp_align < req_align)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3943,7 +3948,7 @@ splice_param_accesses (tree parm, bool *ro_grp)
|
||||||
tree a1_alias_type;
|
tree a1_alias_type;
|
||||||
access = (*access_vec)[i];
|
access = (*access_vec)[i];
|
||||||
modification = access->write;
|
modification = access->write;
|
||||||
if (access_precludes_ipa_sra_p (access))
|
if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type)))
|
||||||
return NULL;
|
return NULL;
|
||||||
a1_alias_type = reference_alias_ptr_type (access->expr);
|
a1_alias_type = reference_alias_ptr_type (access->expr);
|
||||||
|
|
||||||
|
@ -3966,7 +3971,7 @@ splice_param_accesses (tree parm, bool *ro_grp)
|
||||||
else if (ac2->size != access->size)
|
else if (ac2->size != access->size)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (access_precludes_ipa_sra_p (ac2)
|
if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type))
|
||||||
|| (ac2->type != access->type
|
|| (ac2->type != access->type
|
||||||
&& (TREE_ADDRESSABLE (ac2->type)
|
&& (TREE_ADDRESSABLE (ac2->type)
|
||||||
|| TREE_ADDRESSABLE (access->type)))
|
|| TREE_ADDRESSABLE (access->type)))
|
||||||
|
|
Loading…
Reference in New Issue