mirror of git://gcc.gnu.org/git/gcc.git
re PR tree-optimization/88775 (Optimize std::string assignment)
PR tree-optimization/88775 * match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)): Optimize equal == 0 equality pointer comparisons some more if compared in integral types and either one points to an automatic var and the other to a global, or we can prove at least one points to the middle or both point to start or both point to end. * gcc.dg/tree-ssa/pr88775-1.c: New test. * gcc.dg/tree-ssa/pr88775-2.c: New test. From-SVN: r267931
This commit is contained in:
parent
6facd01f98
commit
93aa3c4aca
|
|
@ -1,3 +1,12 @@
|
||||||
|
2019-01-15 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR tree-optimization/88775
|
||||||
|
* match.pd (cmp (convert1?@2 addr@0) (convert2? addr@1)): Optimize
|
||||||
|
equal == 0 equality pointer comparisons some more if compared in
|
||||||
|
integral types and either one points to an automatic var and the
|
||||||
|
other to a global, or we can prove at least one points to the middle
|
||||||
|
or both point to start or both point to end.
|
||||||
|
|
||||||
2019-01-14 Andi Kleen <ak@linux.intel.com>
|
2019-01-14 Andi Kleen <ak@linux.intel.com>
|
||||||
|
|
||||||
* Makefile.in: Lower autofdo sampling rate by 10x.
|
* Makefile.in: Lower autofdo sampling rate by 10x.
|
||||||
|
|
|
||||||
62
gcc/match.pd
62
gcc/match.pd
|
|
@ -3896,6 +3896,52 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||||
|| TREE_CODE (base1) == SSA_NAME
|
|| TREE_CODE (base1) == SSA_NAME
|
||||||
|| TREE_CODE (base1) == STRING_CST))
|
|| TREE_CODE (base1) == STRING_CST))
|
||||||
equal = (base0 == base1);
|
equal = (base0 == base1);
|
||||||
|
if (equal == 0)
|
||||||
|
{
|
||||||
|
if (!DECL_P (base0) || !DECL_P (base1))
|
||||||
|
equal = 2;
|
||||||
|
else if (cmp != EQ_EXPR && cmp != NE_EXPR)
|
||||||
|
equal = 2;
|
||||||
|
/* If this is a pointer comparison, ignore for now even
|
||||||
|
valid equalities where one pointer is the offset zero
|
||||||
|
of one object and the other to one past end of another one. */
|
||||||
|
else if (!INTEGRAL_TYPE_P (TREE_TYPE (@2)))
|
||||||
|
;
|
||||||
|
/* Assume that automatic variables can't be adjacent to global
|
||||||
|
variables. */
|
||||||
|
else if (is_global_var (base0) != is_global_var (base1))
|
||||||
|
;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tree sz0 = DECL_SIZE_UNIT (base0);
|
||||||
|
tree sz1 = DECL_SIZE_UNIT (base1);
|
||||||
|
/* If sizes are unknown, e.g. VLA or not representable,
|
||||||
|
punt. */
|
||||||
|
if (!tree_fits_poly_int64_p (sz0)
|
||||||
|
|| !tree_fits_poly_int64_p (sz1))
|
||||||
|
equal = 2;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
poly_int64 size0 = tree_to_poly_int64 (sz0);
|
||||||
|
poly_int64 size1 = tree_to_poly_int64 (sz1);
|
||||||
|
/* If one offset is pointing (or could be) to the beginning
|
||||||
|
of one object and the other is pointing to one past the
|
||||||
|
last byte of the other object, punt. */
|
||||||
|
if (maybe_eq (off0, 0) && maybe_eq (off1, size1))
|
||||||
|
equal = 2;
|
||||||
|
else if (maybe_eq (off1, 0) && maybe_eq (off0, size0))
|
||||||
|
equal = 2;
|
||||||
|
/* If both offsets are the same, there are some cases
|
||||||
|
we know that are ok. Either if we know they aren't
|
||||||
|
zero, or if we know both sizes are no zero. */
|
||||||
|
if (equal == 2
|
||||||
|
&& known_eq (off0, off1)
|
||||||
|
&& (known_ne (off0, 0)
|
||||||
|
|| (known_ne (size0, 0) && known_ne (size1, 0))))
|
||||||
|
equal = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(if (equal == 1
|
(if (equal == 1
|
||||||
&& (cmp == EQ_EXPR || cmp == NE_EXPR
|
&& (cmp == EQ_EXPR || cmp == NE_EXPR
|
||||||
|
|
@ -3918,16 +3964,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|
||||||
{ constant_boolean_node (known_ge (off0, off1), type); })
|
{ constant_boolean_node (known_ge (off0, off1), type); })
|
||||||
(if (cmp == GT_EXPR && (known_gt (off0, off1) || known_le (off0, off1)))
|
(if (cmp == GT_EXPR && (known_gt (off0, off1) || known_le (off0, off1)))
|
||||||
{ constant_boolean_node (known_gt (off0, off1), type); }))
|
{ constant_boolean_node (known_gt (off0, off1), type); }))
|
||||||
(if (equal == 0
|
(if (equal == 0)
|
||||||
&& DECL_P (base0) && DECL_P (base1)
|
(switch
|
||||||
/* If we compare this as integers require equal offset. */
|
(if (cmp == EQ_EXPR)
|
||||||
&& (!INTEGRAL_TYPE_P (TREE_TYPE (@2))
|
{ constant_boolean_node (false, type); })
|
||||||
|| known_eq (off0, off1)))
|
(if (cmp == NE_EXPR)
|
||||||
(switch
|
{ constant_boolean_node (true, type); })))))))))
|
||||||
(if (cmp == EQ_EXPR)
|
|
||||||
{ constant_boolean_node (false, type); })
|
|
||||||
(if (cmp == NE_EXPR)
|
|
||||||
{ constant_boolean_node (true, type); })))))))))
|
|
||||||
|
|
||||||
/* Simplify pointer equality compares using PTA. */
|
/* Simplify pointer equality compares using PTA. */
|
||||||
(for neeq (ne eq)
|
(for neeq (ne eq)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2019-01-15 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
PR tree-optimization/88775
|
||||||
|
* gcc.dg/tree-ssa/pr88775-1.c: New test.
|
||||||
|
* gcc.dg/tree-ssa/pr88775-2.c: New test.
|
||||||
|
|
||||||
2019-01-14 Marek Polacek <polacek@redhat.com>
|
2019-01-14 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
PR c++/88825 - ICE with bogus function return type deduction.
|
PR c++/88825 - ICE with bogus function return type deduction.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/* PR tree-optimization/88775 */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||||
|
/* { dg-final { scan-tree-dump-times "return 1;" 10 "optimized" } } */
|
||||||
|
|
||||||
|
int a[64] = {};
|
||||||
|
int b[64] = {};
|
||||||
|
|
||||||
|
int
|
||||||
|
f1 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[2] != (__UINTPTR_TYPE__) &b[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f2 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[2] != (__UINTPTR_TYPE__) &b[10];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f3 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &b[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[64] != (__UINTPTR_TYPE__) &b[64];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f5 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &c[64];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f6 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &b[64] != (__UINTPTR_TYPE__) &c[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f7 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[2] != (__UINTPTR_TYPE__) &d[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f8 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[2] != (__UINTPTR_TYPE__) &d[10];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f9 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[0] != (__UINTPTR_TYPE__) &d[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f10 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[64] != (__UINTPTR_TYPE__) &d[64];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* PR tree-optimization/88775 */
|
||||||
|
/* { dg-do compile } */
|
||||||
|
/* { dg-options "-O2 -fdump-tree-optimized" } */
|
||||||
|
/* These can't be decided until we know how the variables will
|
||||||
|
be laid out in memory. */
|
||||||
|
/* { dg-final { scan-tree-dump-not "return 1;" "optimized" } } */
|
||||||
|
|
||||||
|
int a[64] = {};
|
||||||
|
int b[64] = {};
|
||||||
|
int e[0] = {};
|
||||||
|
int f[0] = {};
|
||||||
|
|
||||||
|
int
|
||||||
|
f1 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[0] != (__UINTPTR_TYPE__) &b[64];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f2 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &a[64] != (__UINTPTR_TYPE__) &b[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f3 (void)
|
||||||
|
{
|
||||||
|
return (__UINTPTR_TYPE__) &e[0] != (__UINTPTR_TYPE__) &f[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f4 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[0] != (__UINTPTR_TYPE__) &d[64];
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
f5 (void)
|
||||||
|
{
|
||||||
|
int c[64] = {}, d[64] = {};
|
||||||
|
return (__UINTPTR_TYPE__) &c[64] != (__UINTPTR_TYPE__) &d[0];
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue