On Tue, 6 Oct 2015, Jan Hubicka wrote:

> Hi,
> While looking for uses of useless_type_conversion on non-gimple register types
> I run across few that seem to be completely unnecesary and I would like to get
> rid of them in hope to get rid of code comparing functions/method type and
> possibly more. 
> 
> usless_type_conversion is about operations on the types in gimple expressions,
> not about memory accesses nor about function calls.
> 
> First on is in fold-const.c that may be used on MEM_REF of aggregate type.
> As discussed earlier, the type compare is unnecesary when we only care about
> address that seems to be the most comon case we get into this path.
> 
> I also disabled type matching done by operand_equal_p and cleaned up the
> conditional of MEM_REF into multiple ones - for example it was passing
> OEP_ADDRESS_OF when comparing TYPE_SIZE which is quite a nonsense.
> 
> I wonder what to do about OPE_CONSTANT_ADDRESS_OF.  This flag does not seem
> to be used at all in current tree nor documented somehow.

Eric added that.  It's set when seeing ADDR_EXPRs and has an extra
special handling when TREE_SIDE_EFFECTS are tested.  It matters for
Ada I guess.

> I also made operand_equal_p to skip AA compare when -fno-strict-aliasing
> is used.
>
> Bootstrapped/regtested x86_64-linux, OK?

See comments below - otherwise it looks good.

Richard.

> Honza
> 
>       * fold-const.c (operand_equal_p): When in OEP_ADDRESS_OF
>       do not require types to match; also relax checking of MEM_REF.
> Index: fold-const.c
> ===================================================================
> --- fold-const.c      (revision 228131)
> +++ fold-const.c      (working copy)
> @@ -2712,26 +2712,31 @@ operand_equal_p (const_tree arg0, const_
>    if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
>      return tree_int_cst_equal (arg0, arg1);
>  
> -  /* If both types don't have the same signedness, then we can't consider
> -     them equal.  We must check this before the STRIP_NOPS calls
> -     because they may change the signedness of the arguments.  As pointers
> -     strictly don't have a signedness, require either two pointers or
> -     two non-pointers as well.  */
> -  if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE (arg1))
> -      || POINTER_TYPE_P (TREE_TYPE (arg0)) != POINTER_TYPE_P (TREE_TYPE 
> (arg1)))
> -    return 0;
> +  if (!(flags & OEP_ADDRESS_OF))
> +    {
> +      /* If both types don't have the same signedness, then we can't consider
> +      them equal.  We must check this before the STRIP_NOPS calls
> +      because they may change the signedness of the arguments.  As pointers
> +      strictly don't have a signedness, require either two pointers or
> +      two non-pointers as well.  */
> +      if (TYPE_UNSIGNED (TREE_TYPE (arg0)) != TYPE_UNSIGNED (TREE_TYPE 
> (arg1))
> +       || POINTER_TYPE_P (TREE_TYPE (arg0))
> +                          != POINTER_TYPE_P (TREE_TYPE (arg1)))
> +     return 0;
>  
> -  /* We cannot consider pointers to different address space equal.  */
> -  if (POINTER_TYPE_P (TREE_TYPE (arg0)) && POINTER_TYPE_P (TREE_TYPE (arg1))
> -      && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
> -       != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
> -    return 0;
> +      /* We cannot consider pointers to different address space equal.  */
> +      if (POINTER_TYPE_P (TREE_TYPE (arg0))
> +                       && POINTER_TYPE_P (TREE_TYPE (arg1))
> +       && (TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg0)))
> +           != TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (arg1)))))
> +     return 0;
>  
> -  /* If both types don't have the same precision, then it is not safe
> -     to strip NOPs.  */
> -  if (element_precision (TREE_TYPE (arg0))
> -      != element_precision (TREE_TYPE (arg1)))
> -    return 0;
> +      /* If both types don't have the same precision, then it is not safe
> +      to strip NOPs.  */
> +      if (element_precision (TREE_TYPE (arg0))
> +       != element_precision (TREE_TYPE (arg1)))
> +     return 0;

It's odd that you move this under the !OEP_ADDRESS_OF case but
not the STRIP_NOPS itself.

> +    }
>  
>    STRIP_NOPS (arg0);
>    STRIP_NOPS (arg1);
> @@ -2935,27 +2940,34 @@ operand_equal_p (const_tree arg0, const_
>  
>       case TARGET_MEM_REF:
>       case MEM_REF:
> -       /* Require equal access sizes, and similar pointer types.
> -          We can have incomplete types for array references of
> -          variable-sized arrays from the Fortran frontend
> -          though.  Also verify the types are compatible.  */
> -       if (!((TYPE_SIZE (TREE_TYPE (arg0)) == TYPE_SIZE (TREE_TYPE (arg1))
> -                || (TYPE_SIZE (TREE_TYPE (arg0))
> -                    && TYPE_SIZE (TREE_TYPE (arg1))
> -                    && operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
> -                                        TYPE_SIZE (TREE_TYPE (arg1)), 
> flags)))
> -               && types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1))
> -               && ((flags & OEP_ADDRESS_OF)
> -                   || (alias_ptr_types_compatible_p
> -                         (TREE_TYPE (TREE_OPERAND (arg0, 1)),
> -                          TREE_TYPE (TREE_OPERAND (arg1, 1)))
> -                       && (MR_DEPENDENCE_CLIQUE (arg0)
> -                           == MR_DEPENDENCE_CLIQUE (arg1))
> -                       && (MR_DEPENDENCE_BASE (arg0)
> -                           == MR_DEPENDENCE_BASE (arg1))
> -                       && (TYPE_ALIGN (TREE_TYPE (arg0))
> -                         == TYPE_ALIGN (TREE_TYPE (arg1)))))))
> -         return 0;
> +       if (!(flags & OEP_ADDRESS_OF))
> +         {
> +           /* Require equal access sizes */
> +           if (TYPE_SIZE (TREE_TYPE (arg0)) != TYPE_SIZE (TREE_TYPE (arg1))
> +               && (!TYPE_SIZE (TREE_TYPE (arg0))
> +                   || !TYPE_SIZE (TREE_TYPE (arg1))
> +                   || !operand_equal_p (TYPE_SIZE (TREE_TYPE (arg0)),
> +                                        TYPE_SIZE (TREE_TYPE (arg1)),
> +                                        flags & ~OEP_CONSTANT_ADDRESS_OF)))

so you still pass OEP_ADDRESS_OF ...

> +             return 0;
> +           /* Verify that access happens in similar types.  */
> +           if (!types_compatible_p (TREE_TYPE (arg0), TREE_TYPE (arg1)))
> +             return 0;
> +           /* Verify that accesses are TBAA compatible.  */
> +           if ((flag_strict_aliasing
> +                && !alias_ptr_types_compatible_p
> +                     (TREE_TYPE (TREE_OPERAND (arg0, 1)),
> +                      TREE_TYPE (TREE_OPERAND (arg1, 1))))
> +               || MR_DEPENDENCE_CLIQUE (arg0)
> +                  != MR_DEPENDENCE_CLIQUE (arg1)
> +               || MR_DEPENDENCE_BASE (arg0)
> +                  != MR_DEPENDENCE_BASE (arg1))
> +             return 0;
> +         }
> +        /* Verify that alignment is compatible.  */
> +        if (TYPE_ALIGN (TREE_TYPE (arg0))
> +            != TYPE_ALIGN (TREE_TYPE (arg1)))
> +           return 0;

why's compatible alignment required for OEP_ADDRESS_OF?  We only
look at type alignment on memory references (see get_pointer_alignment
vs. get_object_alignment).

>         flags &= ~(OEP_CONSTANT_ADDRESS_OF|OEP_ADDRESS_OF);
>         return (OP_SAME (0) && OP_SAME (1)
>                 /* TARGET_MEM_REF require equal extra operands.  */
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to