Hi Xiong Hu,

On Tue, Jun 02, 2020 at 04:41:50AM -0500, Xionghu Luo wrote:
> Double array in structure as function arguments or return value is accessed
> by BLKmode, they are stored to stack and load from stack with redundant
> conversion from DF->DI->DF.  This patch checks the homogeneous type and
> use the actual element type to do block move to by pass the conversions.

> @@ -2733,6 +2734,7 @@ expand_block_move (rtx operands[], bool might_overlap)
>    rtx loads[MAX_MOVE_REG];
>    rtx stores[MAX_MOVE_REG];
>    int num_reg = 0;
> +  machine_mode elt_mode = DImode;
>  
>    /* If this is not a fixed size move, just call memcpy */
>    if (! constp)
> @@ -2750,6 +2752,17 @@ expand_block_move (rtx operands[], bool might_overlap)
>    if (bytes > rs6000_block_move_inline_limit)
>      return 0;
>  
> +  tree type = TREE_TYPE (MEM_EXPR (orig_dest));

Declare elt_mode here as well?

> +  if (TREE_CODE (type) == RECORD_TYPE
> +      && rs6000_discover_homogeneous_aggregate (TYPE_MODE (type), type, NULL,
> +                                             NULL))
> +    {
> +      tree field_type = TREE_TYPE (first_field (type));
> +      if (field_type && TREE_CODE (field_type) == ARRAY_TYPE
> +       && TREE_CODE (TREE_TYPE (field_type)) == REAL_TYPE)
> +     elt_mode = TYPE_MODE (TREE_TYPE (field_type));
> +    }

Homogeneous aggregates only exist in the ELFv2 ABI, while the problem
here is the SP float things.  You also noticed (elsewhere) that if the
struct contains (say) SI, SF, SI, SF, then this does not help.

Is there some better condition this could use, and maybe an expansion
that works in more cases as well?

And, it would be lovely if generic code could expand to something better
already (not expand to a block move at all, certainly not for something
as tiny as this).


Segher

Reply via email to