https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63679
--- Comment #17 from Tejas Belagod <belagod at gcc dot gnu.org> --- > - > /* Do a block move either if the size is so small as to make > each individual move a sub-unit move on average, or if it > - is so large as to make individual moves inefficient. */ > + is so large as to make individual moves inefficient. Reuse > + the same costs logic as we use in the SRA passes. */ > + unsigned max_scalarization_size > + = optimize_function_for_size_p (cfun) > + ? PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE) > + : PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED); > + > if (size > 0 > && num_nonzero_elements > 1 > && (size < num_nonzero_elements > - || !can_move_by_pieces (size, align))) > + || size > max_scalarization_size)) > { > if (notify_temp_creation) > return GS_ERROR; I think both move_by_pieces and SRA can co-exist here: diff --git a/gcc/gimplify.c b/gcc/gimplify.c index 8e3dd83..be51ce7 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -70,6 +70,7 @@ along with GCC; see the file COPYING3. If not see #include "omp-low.h" #include "gimple-low.h" #include "cilk.h" +#include "params.h" #include "langhooks-def.h" /* FIXME: for lhd_set_decl_assembler_name */ #include "tree-pass.h" /* FIXME: only for PROP_gimple_any */ @@ -3895,7 +3896,6 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, DECL_ATTRIBUTES (current_function_decl)))) { HOST_WIDE_INT size = int_size_in_bytes (type); unsigned int align; /* ??? We can still get unbounded array types, at least from the C++ front end. This seems wrong, but attempt @@ -3907,20 +3907,19 @@ gimplify_init_constructor (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, TREE_TYPE (ctor) = type = TREE_TYPE (object); } /* Find the maximum alignment we can assume for the object. */ /* ??? Make use of DECL_OFFSET_ALIGN. */ if (DECL_P (object)) align = DECL_ALIGN (object); else align = TYPE_ALIGN (type); /* Do a block move either if the size is so small as to make each individual move a sub-unit move on average, or if it - is so large as to make individual moves inefficient. */ + is so large as to make individual moves inefficient. Reuse + the same costs logic as we use in the SRA passes. */ + unsigned max_scalarization_size + = optimize_function_for_size_p (cfun) + ? PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE) + : PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED); + if (size > 0 && num_nonzero_elements > 1 && (size < num_nonzero_elements + || size > max_scalarization_size || !can_move_by_pieces (size, align)) { if (notify_temp_creation) return GS_ERROR; If it isn't profitable to do an SRA, we can fall-back to the backend hook to move it by pieces. This way, I think we'll have move opportunity for optimization.