aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2014-07-25 07:44:57 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2014-07-25 07:44:57 +0000
commitb2505143369334866ed98d69f08033068b24de34 (patch)
treec7fe34fd006f2ff66fbe4a743da4b4b825b9c156 /gcc/gimple-fold.c
parent1ed85d52ef443e528bfccc64d81a7b263e9defa3 (diff)
downloadgcc-b2505143369334866ed98d69f08033068b24de34.zip
gcc-b2505143369334866ed98d69f08033068b24de34.tar.gz
gcc-b2505143369334866ed98d69f08033068b24de34.tar.bz2
re PR middle-end/61762 (failure to optimize memcpy from constant string)
2014-07-25 Richard Biener <rguenther@suse.de> PR middle-end/61762 PR middle-end/61894 * fold-const.c (native_encode_int): Add and handle offset parameter to do partial encodings of expr. (native_encode_fixed): Likewise. (native_encode_real): Likewise. (native_encode_complex): Likewise. (native_encode_vector): Likewise. (native_encode_string): Likewise. (native_encode_expr): Likewise. * fold-const.c (native_encode_expr): Add offset parameter defaulting to -1. * gimple-fold.c (fold_string_cst_ctor_reference): Remove. (fold_ctor_reference): Handle all reads from tcc_constant ctors. * gcc.dg/pr61762.c: New testcase. * gcc.dg/fold-cstring.c: Likewise. * gcc.dg/fold-cvect.c: Likewise. From-SVN: r213045
Diffstat (limited to 'gcc/gimple-fold.c')
-rw-r--r--gcc/gimple-fold.c50
1 files changed, 13 insertions, 37 deletions
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 4e8de82..747c0aa 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -2881,41 +2881,6 @@ get_base_constructor (tree base, HOST_WIDE_INT *bit_offset,
}
}
-/* CTOR is STRING_CST. Fold reference of type TYPE and size SIZE
- to the memory at bit OFFSET.
-
- We do only simple job of folding byte accesses. */
-
-static tree
-fold_string_cst_ctor_reference (tree type, tree ctor,
- unsigned HOST_WIDE_INT offset,
- unsigned HOST_WIDE_INT size)
-{
- if (INTEGRAL_TYPE_P (type)
- && (TYPE_MODE (type)
- == TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
- && (GET_MODE_CLASS (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor))))
- == MODE_INT)
- && GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (TREE_TYPE (ctor)))) == 1
- && size == BITS_PER_UNIT
- && !(offset % BITS_PER_UNIT))
- {
- offset /= BITS_PER_UNIT;
- if (offset < (unsigned HOST_WIDE_INT) TREE_STRING_LENGTH (ctor))
- return build_int_cst_type (type, (TREE_STRING_POINTER (ctor)
- [offset]));
- /* Folding
- const char a[20]="hello";
- return a[10];
-
- might lead to offset greater than string length. In this case we
- know value is either initialized to 0 or out of bounds. Return 0
- in both cases. */
- return build_zero_cst (type);
- }
- return NULL_TREE;
-}
-
/* CTOR is CONSTRUCTOR of an array type. Fold reference of type TYPE and size
SIZE to the memory at bit OFFSET. */
@@ -3107,8 +3072,19 @@ fold_ctor_reference (tree type, tree ctor, unsigned HOST_WIDE_INT offset,
STRIP_NOPS (ret);
return ret;
}
- if (TREE_CODE (ctor) == STRING_CST)
- return fold_string_cst_ctor_reference (type, ctor, offset, size);
+ /* For constants and byte-aligned/sized reads try to go through
+ native_encode/interpret. */
+ if (CONSTANT_CLASS_P (ctor)
+ && BITS_PER_UNIT == 8
+ && offset % BITS_PER_UNIT == 0
+ && size % BITS_PER_UNIT == 0
+ && size <= MAX_BITSIZE_MODE_ANY_MODE)
+ {
+ unsigned char buf[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
+ if (native_encode_expr (ctor, buf, size / BITS_PER_UNIT,
+ offset / BITS_PER_UNIT) > 0)
+ return native_interpret_expr (type, buf, size / BITS_PER_UNIT);
+ }
if (TREE_CODE (ctor) == CONSTRUCTOR)
{