From 7524f419ae7935594e7ec85daf7cdf736a835b04 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 30 Oct 2015 12:18:34 +0000 Subject: [PATCH] gimple-fold.c (fold_gimple_assign): Do not dispatch to fold () on single RHSs. 2015-10-30 Richard Biener * gimple-fold.c (fold_gimple_assign): Do not dispatch to fold () on single RHSs. Allow CONSTRUCTORS with trailing zeros to be folded to VECTOR_CSTs. * tree.c (build_vector_from_ctor): Handle VECTOR_CST elements. * fold-const.c (fold): Use build_vector_from_ctor. From-SVN: r229574 --- gcc/ChangeLog | 8 ++++++++ gcc/fold-const.c | 25 ++++++------------------- gcc/gimple-fold.c | 37 +++++++++++++++---------------------- gcc/tree.c | 12 +++++++++--- 4 files changed, 38 insertions(+), 44 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f1aea782221..4e0d45d9c97 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-10-30 Richard Biener + + * gimple-fold.c (fold_gimple_assign): Do not dispatch to + fold () on single RHSs. Allow CONSTRUCTORS with trailing + zeros to be folded to VECTOR_CSTs. + * tree.c (build_vector_from_ctor): Handle VECTOR_CST elements. + * fold-const.c (fold): Use build_vector_from_ctor. + 2015-10-30 Evandro Menezes * config/aarch64/aarch64.md (*movhf_aarch64): Change the type of diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 47ed60923f8..7c5b75a2684 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -11968,26 +11968,13 @@ fold (tree expr) if (TREE_CODE (type) != VECTOR_TYPE) return t; - tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); - unsigned HOST_WIDE_INT idx, pos = 0; - tree value; - - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), idx, value) - { - if (!CONSTANT_CLASS_P (value)) - return t; - if (TREE_CODE (value) == VECTOR_CST) - { - for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i) - vec[pos++] = VECTOR_CST_ELT (value, i); - } - else - vec[pos++] = value; - } - for (; pos < TYPE_VECTOR_SUBPARTS (type); ++pos) - vec[pos] = build_zero_cst (TREE_TYPE (type)); + unsigned i; + tree val; + FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val) + if (! CONSTANT_CLASS_P (val)) + return t; - return build_vector (type, vec); + return build_vector_from_ctor (type, CONSTRUCTOR_ELTS (t)); } case CONST_DECL: diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 9760b8a3ad2..13a6219bf9d 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -354,8 +354,8 @@ fold_gimple_assign (gimple_stmt_iterator *si) return val; } } - } + else if (TREE_CODE (rhs) == ADDR_EXPR) { tree ref = TREE_OPERAND (rhs, 0); @@ -370,21 +370,29 @@ fold_gimple_assign (gimple_stmt_iterator *si) else if (TREE_CODE (ref) == MEM_REF && integer_zerop (TREE_OPERAND (ref, 1))) result = fold_convert (TREE_TYPE (rhs), TREE_OPERAND (ref, 0)); + + if (result) + { + /* Strip away useless type conversions. Both the + NON_LVALUE_EXPR that may have been added by fold, and + "useless" type conversions that might now be apparent + due to propagation. */ + STRIP_USELESS_TYPE_CONVERSION (result); + + if (result != rhs && valid_gimple_rhs_p (result)) + return result; + } } else if (TREE_CODE (rhs) == CONSTRUCTOR - && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE - && (CONSTRUCTOR_NELTS (rhs) - == TYPE_VECTOR_SUBPARTS (TREE_TYPE (rhs)))) + && TREE_CODE (TREE_TYPE (rhs)) == VECTOR_TYPE) { /* Fold a constant vector CONSTRUCTOR to VECTOR_CST. */ unsigned i; tree val; FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (rhs), i, val) - if (TREE_CODE (val) != INTEGER_CST - && TREE_CODE (val) != REAL_CST - && TREE_CODE (val) != FIXED_CST) + if (! CONSTANT_CLASS_P (val)) return NULL_TREE; return build_vector_from_ctor (TREE_TYPE (rhs), @@ -393,21 +401,6 @@ fold_gimple_assign (gimple_stmt_iterator *si) else if (DECL_P (rhs)) return get_symbol_constant_value (rhs); - - /* If we couldn't fold the RHS, hand over to the generic - fold routines. */ - if (result == NULL_TREE) - result = fold (rhs); - - /* Strip away useless type conversions. Both the NON_LVALUE_EXPR - that may have been added by fold, and "useless" type - conversions that might now be apparent due to propagation. */ - STRIP_USELESS_TYPE_CONVERSION (result); - - if (result != rhs && valid_gimple_rhs_p (result)) - return result; - - return NULL_TREE; } break; diff --git a/gcc/tree.c b/gcc/tree.c index 3570902855d..9228a6abd54 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -1729,13 +1729,19 @@ tree build_vector_from_ctor (tree type, vec *v) { tree *vec = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type)); - unsigned HOST_WIDE_INT idx; + unsigned HOST_WIDE_INT idx, pos = 0; tree value; FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value) - vec[idx] = value; + { + if (TREE_CODE (value) == VECTOR_CST) + for (unsigned i = 0; i < VECTOR_CST_NELTS (value); ++i) + vec[pos++] = VECTOR_CST_ELT (value, i); + else + vec[pos++] = value; + } for (; idx < TYPE_VECTOR_SUBPARTS (type); ++idx) - vec[idx] = build_zero_cst (TREE_TYPE (type)); + vec[pos++] = build_zero_cst (TREE_TYPE (type)); return build_vector (type, vec); } -- 2.30.2