diff options
author | Martin Jambor <mjambor@suse.cz> | 2017-08-14 14:33:54 +0000 |
---|---|---|
committer | Martin Jambor <mjambor@suse.cz> | 2017-08-14 14:33:54 +0000 |
commit | ae281588ac673801c2890f4679a211d24e4f8e01 (patch) | |
tree | ffda4ecce65bb72e54a07d8ed2c09288fa207b43 /gcc/expr.c | |
parent | 7e05bab54f745defb749670b8c84eaf513c0b214 (diff) |
Merged trunk revision 251080 into the hsa branchhsa
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/hsa@251093 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 69 |
1 files changed, 38 insertions, 31 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 0e8216ba7d0..b194866313d 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -6589,6 +6589,7 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, rtvec vector = NULL; unsigned n_elts; alias_set_type alias; + bool vec_vec_init_p = false; gcc_assert (eltmode != BLKmode); @@ -6596,27 +6597,30 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, if (REG_P (target) && VECTOR_MODE_P (GET_MODE (target))) { machine_mode mode = GET_MODE (target); + machine_mode emode = eltmode; - icode = (int) optab_handler (vec_init_optab, mode); - /* Don't use vec_init<mode> if some elements have VECTOR_TYPE. */ - if (icode != CODE_FOR_nothing) + if (CONSTRUCTOR_NELTS (exp) + && (TREE_CODE (TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value)) + == VECTOR_TYPE)) { - tree value; - - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) - if (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE) - { - icode = CODE_FOR_nothing; - break; - } + tree etype = TREE_TYPE (CONSTRUCTOR_ELT (exp, 0)->value); + gcc_assert (CONSTRUCTOR_NELTS (exp) * TYPE_VECTOR_SUBPARTS (etype) + == n_elts); + emode = TYPE_MODE (etype); } + icode = (int) convert_optab_handler (vec_init_optab, mode, emode); if (icode != CODE_FOR_nothing) { - unsigned int i; + unsigned int i, n = n_elts; - vector = rtvec_alloc (n_elts); - for (i = 0; i < n_elts; i++) - RTVEC_ELT (vector, i) = CONST0_RTX (GET_MODE_INNER (mode)); + if (emode != eltmode) + { + n = CONSTRUCTOR_NELTS (exp); + vec_vec_init_p = true; + } + vector = rtvec_alloc (n); + for (i = 0; i < n; i++) + RTVEC_ELT (vector, i) = CONST0_RTX (emode); } } @@ -6634,10 +6638,10 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (exp), idx, value) { - int n_elts_here = tree_to_uhwi - (int_const_binop (TRUNC_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (value)), - TYPE_SIZE (elttype))); + tree sz = TYPE_SIZE (TREE_TYPE (value)); + int n_elts_here + = tree_to_uhwi (int_const_binop (TRUNC_DIV_EXPR, sz, + TYPE_SIZE (elttype))); count += n_elts_here; if (mostly_zeros_p (value)) @@ -6687,18 +6691,21 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, if (vector) { - /* vec_init<mode> should not be used if there are VECTOR_TYPE - elements. */ - gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE); - RTVEC_ELT (vector, eltpos) - = expand_normal (value); + if (vec_vec_init_p) + { + gcc_assert (ce->index == NULL_TREE); + gcc_assert (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE); + eltpos = idx; + } + else + gcc_assert (TREE_CODE (TREE_TYPE (value)) != VECTOR_TYPE); + RTVEC_ELT (vector, eltpos) = expand_normal (value); } else { - machine_mode value_mode = - TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE - ? TYPE_MODE (TREE_TYPE (value)) - : eltmode; + machine_mode value_mode + = (TREE_CODE (TREE_TYPE (value)) == VECTOR_TYPE + ? TYPE_MODE (TREE_TYPE (value)) : eltmode); bitpos = eltpos * elt_size; store_constructor_field (target, bitsize, bitpos, 0, bitregion_end, value_mode, @@ -6707,9 +6714,9 @@ store_constructor (tree exp, rtx target, int cleared, HOST_WIDE_INT size, } if (vector) - emit_insn (GEN_FCN (icode) - (target, - gen_rtx_PARALLEL (GET_MODE (target), vector))); + emit_insn (GEN_FCN (icode) (target, + gen_rtx_PARALLEL (GET_MODE (target), + vector))); break; } |