diff options
author | Richard Biener <rguenther@suse.de> | 2014-07-25 07:44:57 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2014-07-25 07:44:57 +0000 |
commit | b2505143369334866ed98d69f08033068b24de34 (patch) | |
tree | c7fe34fd006f2ff66fbe4a743da4b4b825b9c156 /gcc/gimple-fold.c | |
parent | 1ed85d52ef443e528bfccc64d81a7b263e9defa3 (diff) | |
download | gcc-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.c | 50 |
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) { |