mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-21 14:50:57 +08:00
re PR tree-optimization/69047 (memcpy is not as optimized as union is)
2016-08-26 Richard Biener <rguenther@suse.de> PR tree-optimization/69047 * tree-ssa.c (maybe_rewrite_mem_ref_base): Handle general bitfield extracts similar to what FRE does. (non_rewritable_mem_ref_base): Likewise. * gcc.dg/pr69047.c: New testcase. From-SVN: r239778
This commit is contained in:
parent
52066eae5d
commit
ebfa15ab65
@ -1,3 +1,10 @@
|
||||
2016-08-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/69047
|
||||
* tree-ssa.c (maybe_rewrite_mem_ref_base): Handle general bitfield
|
||||
extracts similar to what FRE does.
|
||||
(non_rewritable_mem_ref_base): Likewise.
|
||||
|
||||
2016-08-26 Joseph Myers <joseph@codesourcery.com>
|
||||
|
||||
* config/i386/i386.c (ix86_libgcc_floating_mode_supported_p)
|
||||
|
@ -1,3 +1,8 @@
|
||||
2016-08-26 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/69047
|
||||
* gcc.dg/pr69047.c: New testcase.
|
||||
|
||||
2016-08-26 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
|
||||
Martin Jambhor <mjambor@suse.cz>
|
||||
|
||||
|
18
gcc/testsuite/gcc.dg/pr69047.c
Normal file
18
gcc/testsuite/gcc.dg/pr69047.c
Normal file
@ -0,0 +1,18 @@
|
||||
/* { dg-do compile } */
|
||||
/* { dg-options "-O -fdump-tree-cddce1" } */
|
||||
|
||||
__UINT8_TYPE__
|
||||
f(__UINT16_TYPE__ b)
|
||||
{
|
||||
__UINT8_TYPE__ a;
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
__builtin_memcpy(&a, &b, sizeof a);
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
__builtin_memcpy(&a, (char *)&b + sizeof a, sizeof a);
|
||||
#else
|
||||
a = b;
|
||||
#endif
|
||||
return a;
|
||||
}
|
||||
|
||||
/* { dg-final { scan-tree-dump "_\[0-9\]+ = \\(\[^)\]+\\) b" "cddce1" } } */
|
@ -1292,7 +1292,9 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
|
||||
&& (sym = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0))
|
||||
&& DECL_P (sym)
|
||||
&& !TREE_ADDRESSABLE (sym)
|
||||
&& bitmap_bit_p (suitable_for_renaming, DECL_UID (sym)))
|
||||
&& bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
|
||||
&& is_gimple_reg_type (TREE_TYPE (*tp))
|
||||
&& ! VOID_TYPE_P (TREE_TYPE (*tp)))
|
||||
{
|
||||
if (TREE_CODE (TREE_TYPE (sym)) == VECTOR_TYPE
|
||||
&& useless_type_conversion_p (TREE_TYPE (*tp),
|
||||
@ -1314,7 +1316,8 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
|
||||
? REALPART_EXPR : IMAGPART_EXPR,
|
||||
TREE_TYPE (*tp), sym);
|
||||
}
|
||||
else if (integer_zerop (TREE_OPERAND (*tp, 1)))
|
||||
else if (integer_zerop (TREE_OPERAND (*tp, 1))
|
||||
&& DECL_SIZE (sym) == TYPE_SIZE (TREE_TYPE (*tp)))
|
||||
{
|
||||
if (!useless_type_conversion_p (TREE_TYPE (*tp),
|
||||
TREE_TYPE (sym)))
|
||||
@ -1323,6 +1326,24 @@ maybe_rewrite_mem_ref_base (tree *tp, bitmap suitable_for_renaming)
|
||||
else
|
||||
*tp = sym;
|
||||
}
|
||||
else if (DECL_SIZE (sym)
|
||||
&& TREE_CODE (DECL_SIZE (sym)) == INTEGER_CST
|
||||
&& mem_ref_offset (*tp) >= 0
|
||||
&& wi::leu_p (mem_ref_offset (*tp)
|
||||
+ wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (*tp))),
|
||||
wi::to_offset (DECL_SIZE_UNIT (sym)))
|
||||
&& (! INTEGRAL_TYPE_P (TREE_TYPE (*tp))
|
||||
|| (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp)))
|
||||
== TYPE_PRECISION (TREE_TYPE (*tp))))
|
||||
&& wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (*tp))),
|
||||
BITS_PER_UNIT) == 0)
|
||||
{
|
||||
*tp = build3 (BIT_FIELD_REF, TREE_TYPE (*tp), sym,
|
||||
TYPE_SIZE (TREE_TYPE (*tp)),
|
||||
wide_int_to_tree (bitsizetype,
|
||||
mem_ref_offset (*tp)
|
||||
<< LOG2_BITS_PER_UNIT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1352,6 +1373,11 @@ non_rewritable_mem_ref_base (tree ref)
|
||||
&& TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
|
||||
{
|
||||
tree decl = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
|
||||
if (! DECL_P (decl))
|
||||
return NULL_TREE;
|
||||
if (! is_gimple_reg_type (TREE_TYPE (base))
|
||||
|| VOID_TYPE_P (TREE_TYPE (base)))
|
||||
return decl;
|
||||
if ((TREE_CODE (TREE_TYPE (decl)) == VECTOR_TYPE
|
||||
|| TREE_CODE (TREE_TYPE (decl)) == COMPLEX_TYPE)
|
||||
&& useless_type_conversion_p (TREE_TYPE (base),
|
||||
@ -1362,12 +1388,28 @@ non_rewritable_mem_ref_base (tree ref)
|
||||
&& multiple_of_p (sizetype, TREE_OPERAND (base, 1),
|
||||
TYPE_SIZE_UNIT (TREE_TYPE (base))))
|
||||
return NULL_TREE;
|
||||
if (DECL_P (decl)
|
||||
&& (!integer_zerop (TREE_OPERAND (base, 1))
|
||||
|| (DECL_SIZE (decl)
|
||||
!= TYPE_SIZE (TREE_TYPE (base)))
|
||||
|| TREE_THIS_VOLATILE (decl) != TREE_THIS_VOLATILE (base)))
|
||||
return decl;
|
||||
/* For same sizes and zero offset we can use a VIEW_CONVERT_EXPR. */
|
||||
if (integer_zerop (TREE_OPERAND (base, 1))
|
||||
&& DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (base)))
|
||||
return NULL_TREE;
|
||||
/* For integral typed extracts we can use a BIT_FIELD_REF. */
|
||||
if (DECL_SIZE (decl)
|
||||
&& TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST
|
||||
&& mem_ref_offset (base) >= 0
|
||||
&& wi::leu_p (mem_ref_offset (base)
|
||||
+ wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (base))),
|
||||
wi::to_offset (DECL_SIZE_UNIT (decl)))
|
||||
/* ??? We can't handle bitfield precision extracts without
|
||||
either using an alternate type for the BIT_FIELD_REF and
|
||||
then doing a conversion or possibly adjusting the offset
|
||||
according to endianess. */
|
||||
&& (! INTEGRAL_TYPE_P (TREE_TYPE (base))
|
||||
|| (wi::to_offset (TYPE_SIZE (TREE_TYPE (base)))
|
||||
== TYPE_PRECISION (TREE_TYPE (base))))
|
||||
&& wi::umod_trunc (wi::to_offset (TYPE_SIZE (TREE_TYPE (base))),
|
||||
BITS_PER_UNIT) == 0)
|
||||
return NULL_TREE;
|
||||
return decl;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
|
Loading…
x
Reference in New Issue
Block a user