On Wed, 7 Oct 2015, Jan Hubicka wrote:

> > > 
> > > The patch works for me but I'm not sure about the store_expr_with_bounds
> > > change.  Where does the actual copying take place?  adjust_address_nv
> > > just adjusts the mode ...
> > 
> > Yep, the mode was supposed to happen in the later path where we emit block 
> > moves,
> > but i missed an else there.  I will update the patch.  Thanks for catching 
> > this.
> 
> Hi,
> here is updated patch with temp not being ignored - it will fall into the 
> emit_block_move as expected. I tested the pach on x86_64-linux, ppc64-linux
> testing in progress, OK?
> 
> Honza
> 
>       * expr.c (store_expr_with_bounds): Handle aggregate moves from
>       BLKmode.
>       * gimple-expr.c (useless_type_conversion_p): Do not use TYPE_CANONICAL
>       to define gimple type system; compare aggregates only by size.
> 
> Index: ../gcc/expr.c
> ===================================================================
> --- ../gcc/expr.c     (revision 228267)
> +++ ../gcc/expr.c     (working copy)
> @@ -5425,6 +5425,15 @@ store_expr_with_bounds (tree exp, rtx ta
>      temp = convert_modes (GET_MODE (target), TYPE_MODE (TREE_TYPE (exp)),
>                         temp, TYPE_UNSIGNED (TREE_TYPE (exp)));
>  
> +  /* We allow move between structures of same size but different mode.
> +     If source is in memory and the mode differs, simply change the memory.  
> */
> +  if (GET_MODE (temp) == BLKmode && GET_MODE (target) != BLKmode)
> +    {
> +      gcc_assert (AGGREGATE_TYPE_P (TREE_TYPE (exp)));

I'd remove this assert as we can have, for example, BLKmode vector types.

> +      gcc_assert (MEM_P (temp));
> +      temp = adjust_address_nv (temp, GET_MODE (target), 0);
> +    }
> +
>    /* If value was not generated in the target, store it there.
>       Convert the value to TARGET's type first if necessary and emit the
>       pending incrementations that have been queued when expanding EXP.
> Index: ../gcc/gimple-expr.c
> ===================================================================
> --- ../gcc/gimple-expr.c      (revision 228267)
> +++ ../gcc/gimple-expr.c      (working copy)
> @@ -87,11 +87,6 @@ useless_type_conversion_p (tree outer_ty
>    if (inner_type == outer_type)
>      return true;
>  
> -  /* If we know the canonical types, compare them.  */
> -  if (TYPE_CANONICAL (inner_type)
> -      && TYPE_CANONICAL (inner_type) == TYPE_CANONICAL (outer_type))
> -    return true;
> -
>    /* Changes in machine mode are never useless conversions unless we
>       deal with aggregate types in which case we defer to later checks.  */
>    if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type)
> @@ -270,12 +265,23 @@ useless_type_conversion_p (tree outer_ty
>        return true;
>      }
>  
> -  /* For aggregates we rely on TYPE_CANONICAL exclusively and require
> -     explicit conversions for types involving to be structurally
> -     compared types.  */
> +  /* For aggregates compare only the size.  Accesses to fields do have
> +     a type information by themselves and thus we only care if we can i.e.
> +     use the types in move operations.  */
>    else if (AGGREGATE_TYPE_P (inner_type)
>          && TREE_CODE (inner_type) == TREE_CODE (outer_type))
> -    return false;
> +    return (!TYPE_SIZE (outer_type)
> +         || (TYPE_SIZE (inner_type)
> +             && operand_equal_p (TYPE_SIZE (inner_type),
> +                                 TYPE_SIZE (outer_type), 0)));
> +
> +  else if (TREE_CODE (inner_type) == OFFSET_TYPE
> +        && TREE_CODE (inner_type) == TREE_CODE (outer_type))

&& TREE_CODE (outer_type) == OFFSET_TYPE

Ok with those changes.

Thanks,
Richard.

> +    return useless_type_conversion_p (TREE_TYPE (outer_type),
> +                                   TREE_TYPE (inner_type))
> +        && useless_type_conversion_p
> +             (TYPE_OFFSET_BASETYPE (outer_type),
> +              TYPE_OFFSET_BASETYPE (inner_type));
>  
>    return false;
>  }

Reply via email to