Commit b496651b by Martin Jambor Committed by Martin Jambor

Make SRA less strict with memcpy performing MEM_REFs

2019-03-10  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/85762
	PR tree-optimization/87008
	PR tree-optimization/85459
	* tree-sra.c (contains_vce_or_bfcref_p): New parameter, set the bool
	it points to if there is a type changing MEM_REF.  Adjust all callers.
	(build_accesses_from_assign): Disable total scalarization if
	contains_vce_or_bfcref_p returns true through the new parameter, for
	both rhs and lhs.

	testsuite/
	* g++.dg/tree-ssa/pr87008.C: New test.
	* gcc.dg/guality/pr54970.c: Xfail tests querying a[0] everywhere.

From-SVN: r269556
parent 7f862706
2019-03-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/85762
PR tree-optimization/87008
PR tree-optimization/85459
* tree-sra.c (contains_vce_or_bfcref_p): New parameter, set the bool
it points to if there is a type changing MEM_REF. Adjust all callers.
(build_accesses_from_assign): Disable total scalarization if
contains_vce_or_bfcref_p returns true through the new parameter, for
both rhs and lhs.
2019-03-09 Jakub Jelinek <jakub@redhat.com> 2019-03-09 Jakub Jelinek <jakub@redhat.com>
PR c/88568 PR c/88568
......
2019-03-10 Martin Jambor <mjambor@suse.cz>
PR tree-optimization/85762
PR tree-optimization/87008
PR tree-optimization/85459
* g++.dg/tree-ssa/pr87008.C: New test.
* gcc.dg/guality/pr54970.c: Xfail tests querying a[0] everywhere.
2019-03-10 Thomas Koenig <tkoenig@gcc.gnu.org> 2019-03-10 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/66089 PR fortran/66089
......
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-optimized" } */
extern void dontcallthis();
struct A { long a, b; };
struct B : A {};
template<class T>void cp(T&a,T const&b){a=b;}
long f(B x){
B y; cp<A>(y,x);
B z; cp<A>(z,x);
if (y.a - z.a)
dontcallthis ();
return 0;
}
/* { dg-final { scan-tree-dump-not "dontcallthis" "optimized" } } */
...@@ -8,17 +8,17 @@ ...@@ -8,17 +8,17 @@
int int
main () main ()
{ {
int a[] = { 1, 2, 3 }; /* { dg-final { gdb-test .+4 "a\[0\]" "1" } } */ int a[] = { 1, 2, 3 }; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */
int *p = a + 2; /* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */ int *p = a + 2; /* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */
int *q = a + 1; /* { dg-final { gdb-test .+2 "a\[2\]" "3" } } */ int *q = a + 1; /* { dg-final { gdb-test .+2 "a\[2\]" "3" } } */
/* { dg-final { gdb-test .+1 "*p" "3" } } */ /* { dg-final { gdb-test .+1 "*p" "3" } } */
asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */
*p += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" } } */ *p += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "2" } } */
/* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */
/* { dg-final { gdb-test .+1 "*p" "13" } } */ /* { dg-final { gdb-test .+1 "*p" "13" } } */
asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */ asm volatile (NOP); /* { dg-final { gdb-test . "*q" "2" } } */
*q += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" } } */ *q += 10; /* { dg-final { gdb-test .+4 "a\[0\]" "1" { xfail { *-*-* } } } } */
/* { dg-final { gdb-test .+3 "a\[1\]" "12" } } */ /* { dg-final { gdb-test .+3 "a\[1\]" "12" } } */
/* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */ /* { dg-final { gdb-test .+2 "a\[2\]" "13" } } */
/* { dg-final { gdb-test .+1 "*p" "13" } } */ /* { dg-final { gdb-test .+1 "*p" "13" } } */
......
...@@ -1150,29 +1150,36 @@ contains_view_convert_expr_p (const_tree ref) ...@@ -1150,29 +1150,36 @@ contains_view_convert_expr_p (const_tree ref)
return false; return false;
} }
/* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs /* Return true if REF contains a VIEW_CONVERT_EXPR or a COMPONENT_REF with a
type conversion or a COMPONENT_REF with a bit-field field declaration. */ bit-field field declaration. If TYPE_CHANGING_P is non-NULL, set the bool
it points to will be set if REF contains any of the above or a MEM_REF
expression that effectively performs type conversion. */
static bool static bool
contains_vce_or_bfcref_p (const_tree ref) contains_vce_or_bfcref_p (const_tree ref, bool *type_changing_p = NULL)
{ {
while (handled_component_p (ref)) while (handled_component_p (ref))
{ {
if (TREE_CODE (ref) == VIEW_CONVERT_EXPR if (TREE_CODE (ref) == VIEW_CONVERT_EXPR
|| (TREE_CODE (ref) == COMPONENT_REF || (TREE_CODE (ref) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))) && DECL_BIT_FIELD (TREE_OPERAND (ref, 1))))
return true; {
if (type_changing_p)
*type_changing_p = true;
return true;
}
ref = TREE_OPERAND (ref, 0); ref = TREE_OPERAND (ref, 0);
} }
if (TREE_CODE (ref) != MEM_REF if (!type_changing_p
|| TREE_CODE (ref) != MEM_REF
|| TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR) || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR)
return false; return false;
tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
if (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) if (TYPE_MAIN_VARIANT (TREE_TYPE (ref))
!= TYPE_MAIN_VARIANT (TREE_TYPE (mem))) != TYPE_MAIN_VARIANT (TREE_TYPE (mem)))
return true; *type_changing_p = true;
return false; return false;
} }
...@@ -1368,15 +1375,26 @@ build_accesses_from_assign (gimple *stmt) ...@@ -1368,15 +1375,26 @@ build_accesses_from_assign (gimple *stmt)
lacc->grp_assignment_write = 1; lacc->grp_assignment_write = 1;
if (storage_order_barrier_p (rhs)) if (storage_order_barrier_p (rhs))
lacc->grp_unscalarizable_region = 1; lacc->grp_unscalarizable_region = 1;
if (should_scalarize_away_bitmap && !is_gimple_reg_type (lacc->type))
{
bool type_changing_p = false;
contains_vce_or_bfcref_p (lhs, &type_changing_p);
if (type_changing_p)
bitmap_set_bit (cannot_scalarize_away_bitmap,
DECL_UID (lacc->base));
}
} }
if (racc) if (racc)
{ {
racc->grp_assignment_read = 1; racc->grp_assignment_read = 1;
if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt) if (should_scalarize_away_bitmap && !is_gimple_reg_type (racc->type))
&& !is_gimple_reg_type (racc->type))
{ {
if (contains_vce_or_bfcref_p (rhs)) bool type_changing_p = false;
contains_vce_or_bfcref_p (rhs, &type_changing_p);
if (type_changing_p || gimple_has_volatile_ops (stmt))
bitmap_set_bit (cannot_scalarize_away_bitmap, bitmap_set_bit (cannot_scalarize_away_bitmap,
DECL_UID (racc->base)); DECL_UID (racc->base));
else else
......
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