diff options
author | Martin Jambor <mjambor@suse.cz> | 2012-11-30 17:11:33 +0100 |
---|---|---|
committer | Martin Jambor <jamborm@gcc.gnu.org> | 2012-11-30 17:11:33 +0100 |
commit | c1ed6a0172fa629c31f23f99d76b3fa0109bb66b (patch) | |
tree | 84ce44d7b1f68a3a6a1630d3502026119cf95162 /gcc | |
parent | d7b30db8d85f828c2a2c146142c6b07e7b69ba18 (diff) | |
download | gcc-c1ed6a0172fa629c31f23f99d76b3fa0109bb66b.zip gcc-c1ed6a0172fa629c31f23f99d76b3fa0109bb66b.tar.gz gcc-c1ed6a0172fa629c31f23f99d76b3fa0109bb66b.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 12 | ||||
-rw-r--r-- | gcc/ipa-prop.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c | 42 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c | 44 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/pr55448.c | 26 | ||||
-rw-r--r-- | gcc/tree-sra.c | 15 |
8 files changed, 211 insertions, 7 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ceba51d..013ccf5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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> Greta Yorsh <Greta.Yorsh@arm.com> diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c index 6016257..01d142b 100644 --- a/gcc/ipa-prop.c +++ b/gcc/ipa-prop.c @@ -2888,6 +2888,8 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, { tree expr, base, off; 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 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; tree prev_base; + bool addrof; if (TREE_CODE (base) == ADDR_EXPR) - base = TREE_OPERAND (base, 0); + { + base = TREE_OPERAND (base, 0); + addrof = true; + } + else + addrof = false; prev_base = base; base = get_addr_base_and_unit_offset (base, &base_offset); /* 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) { + if (!addrof) + { + deref_base = true; + deref_align = TYPE_ALIGN (TREE_TYPE (base)); + } off = build_int_cst (adj->alias_ptr_type, base_offset + adj->offset / BITS_PER_UNIT); @@ -2957,7 +2970,17 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gimple stmt, unsigned int align; 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) .sext (TYPE_PRECISION (TREE_TYPE (off))).low * BITS_PER_UNIT); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 54692e1..6bfa093 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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> * loop_optimization14.ad[sb]: New test. diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c new file mode 100644 index 0000000..921334a --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-7.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c new file mode 100644 index 0000000..9e6e40a --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-8.c @@ -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; +} diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c new file mode 100644 index 0000000..c5468cf --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-9.c @@ -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; +} diff --git a/gcc/testsuite/gcc.target/i386/pr55448.c b/gcc/testsuite/gcc.target/i386/pr55448.c new file mode 100644 index 0000000..874a507 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr55448.c @@ -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" } } */ diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index b560648..4580ad2 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3891,12 +3891,13 @@ unmodified_by_ref_scalar_representative (tree parm) return repr; } -/* Return true iff this access precludes IPA-SRA of the parameter it is - associated with. */ +/* Return true iff this ACCESS precludes IPA-SRA of the parameter it is + associated with. REQ_ALIGN is the minimum required alignment. */ 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 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 @@ -3908,6 +3909,10 @@ access_precludes_ipa_sra_p (struct access *access) || gimple_code (access->stmt) == GIMPLE_ASM)) return true; + exp_align = get_object_alignment (access->expr); + if (exp_align < req_align) + return true; + return false; } @@ -3943,7 +3948,7 @@ splice_param_accesses (tree parm, bool *ro_grp) tree a1_alias_type; access = (*access_vec)[i]; modification = access->write; - if (access_precludes_ipa_sra_p (access)) + if (access_precludes_ipa_sra_p (access, TYPE_ALIGN (access->type))) return NULL; 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) return NULL; - if (access_precludes_ipa_sra_p (ac2) + if (access_precludes_ipa_sra_p (ac2, TYPE_ALIGN (access->type)) || (ac2->type != access->type && (TREE_ADDRESSABLE (ac2->type) || TREE_ADDRESSABLE (access->type))) |