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.

Reply via email to