Re: RFA: Clean up ADDRESS handling in alias.c

2012-04-17 Thread Richard Guenther
On Sun, Apr 15, 2012 at 5:11 PM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 The comment in alias.c says:

   The contents of an ADDRESS is not normally used, the mode of the
   ADDRESS determines whether the ADDRESS is a function argument or some
   other special value.  Pointer equality, not rtx_equal_p, determines whether
   two ADDRESS expressions refer to the same base address.

   The only use of the contents of an ADDRESS is for determining if the
   current function performs nonlocal memory memory references for the
   purposes of marking the function as a constant function.  */

 The first paragraph is a bit misleading IMO.  AFAICT, rtx_equal_p has
 always given ADDRESS the full recursive treatment, rather than saying
 that pointer equality determines ADDRESS equality.  (This is in contrast
 to something like VALUE, where pointer equality is used.)  And AFAICT
 we've always had:

 static int
 base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
                  enum machine_mode y_mode)
 {
  ...
  /* If the base addresses are equal nothing is known about aliasing.  */
  if (rtx_equal_p (x_base, y_base))
    return 1;
  ...
 }

 So I think the contents of an ADDRESS _are_ used to distinguish
 between different bases.

 The second paragraph ceased to be true in 2005 when the pure/const
 analysis moved to its own IPA pass.  Nothing now looks at the contents
 beyond rtx_equal_p.

 Also, base_alias_check effectively treats all arguments as a single base.
 That makes conceptual sense, because this analysis isn't strong enough
 to determine whether arguments are base values at all, never mind whether
 accesses based on different arguments conflict.  But the fact that we have
 a single base isn't obvious from the way the code is written, because we
 create several separate, non-rtx_equal_p, ADDRESSes to represent arguments.
 See:

  for (i = 0; i  FIRST_PSEUDO_REGISTER; i++)
    /* Check whether this register can hold an incoming pointer
       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
       numbers, so translate if necessary due to register windows.  */
    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
         HARD_REGNO_MODE_OK (i, Pmode))
      static_reg_base_value[i]
        = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));

 and:

      /* Check for an argument passed in memory.  Only record in the
         copying-arguments block; it is too hard to track changes
         otherwise.  */
      if (copying_arguments
           (XEXP (src, 0) == arg_pointer_rtx
              || (GET_CODE (XEXP (src, 0)) == PLUS
                   XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
        return gen_rtx_ADDRESS (VOIDmode, src);

 I think it would be cleaner and less wasteful to use a single rtx for
 the single base (really potential base).

 So if we wanted to, we could now remove the operand from ADDRESS and
 simply rely on pointer equality.  I'm a bit reluctant to do that though.
 It would make debugging harder, and it would mean either adding knowledge
 of this alias-specific code to other files (specifically rtl.c:rtx_equal_p),
 or adding special ADDRESS shortcuts to alias.c.  But I think the code
 would be more obvious if we replaced the rtx operand with a unique id,
 which is what we already use for the REG_NOALIAS case:

      new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
                                                   GEN_INT (unique_id++));

 And if we do that, we can make the id a direct operand of the ADDRESS,
 rather than a CONST_INT subrtx[*].  That should make rtx_equal_p cheaper too.

  [*] I'm trying to get rid of CONST_INTs like these that have
      no obvious mode.

 All of which led to the patch below.  I checked that it didn't change
 the code generated at -O2 for a recent set of cc1 .ii files.  Also
 bootstrapped  regression-tested on x86_64-linux-gnu.  OK to install?

 To cover my back: I'm just trying to rewrite the current code according
 to its current assumptions.  Whether those assumptions are correct or not
 is always open to debate...

This all looks reasonable and matches what I discovered by reverse
engineering the last time I ran into ADDRESSes ...

So, ok, given that nobody else has commented yet.

Thanks,
Richard.

 Richard


 gcc/
        * rtl.def (ADDRESS): Turn operand into a HOST_WIDE_INT.
        * alias.c (reg_base_value): Expand and update comment.
        (arg_base_value): New variable.
        (unique_id): Move up file.
        (unique_base_value, unique_base_value_p, known_base_value_p): New.
        (find_base_value): Use arg_base_value and known_base_value_p.
        (record_set): Document REG_NOALIAS handling.  Use unique_base_value.
        (find_base_term): Use known_base_value_p.
        (base_alias_check): Use unique_base_value_p.
        (init_alias_target): Initialize arg_base_value.  Use unique_base_value.
        (init_alias_analysis): Use 1 as the first id for REG_NOALIAS bases.

 Index: gcc/rtl.def
 

Re: RFA: Clean up ADDRESS handling in alias.c

2012-04-17 Thread H.J. Lu
On Sun, Apr 15, 2012 at 8:11 AM, Richard Sandiford
rdsandif...@googlemail.com wrote:
 The comment in alias.c says:

   The contents of an ADDRESS is not normally used, the mode of the
   ADDRESS determines whether the ADDRESS is a function argument or some
   other special value.  Pointer equality, not rtx_equal_p, determines whether
   two ADDRESS expressions refer to the same base address.

   The only use of the contents of an ADDRESS is for determining if the
   current function performs nonlocal memory memory references for the
   purposes of marking the function as a constant function.  */

 The first paragraph is a bit misleading IMO.  AFAICT, rtx_equal_p has
 always given ADDRESS the full recursive treatment, rather than saying
 that pointer equality determines ADDRESS equality.  (This is in contrast
 to something like VALUE, where pointer equality is used.)  And AFAICT
 we've always had:

 static int
 base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
                  enum machine_mode y_mode)
 {
  ...
  /* If the base addresses are equal nothing is known about aliasing.  */
  if (rtx_equal_p (x_base, y_base))
    return 1;
  ...
 }

 So I think the contents of an ADDRESS _are_ used to distinguish
 between different bases.

 The second paragraph ceased to be true in 2005 when the pure/const
 analysis moved to its own IPA pass.  Nothing now looks at the contents
 beyond rtx_equal_p.

 Also, base_alias_check effectively treats all arguments as a single base.
 That makes conceptual sense, because this analysis isn't strong enough
 to determine whether arguments are base values at all, never mind whether
 accesses based on different arguments conflict.  But the fact that we have
 a single base isn't obvious from the way the code is written, because we
 create several separate, non-rtx_equal_p, ADDRESSes to represent arguments.
 See:

  for (i = 0; i  FIRST_PSEUDO_REGISTER; i++)
    /* Check whether this register can hold an incoming pointer
       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
       numbers, so translate if necessary due to register windows.  */
    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
         HARD_REGNO_MODE_OK (i, Pmode))
      static_reg_base_value[i]
        = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));

 and:

      /* Check for an argument passed in memory.  Only record in the
         copying-arguments block; it is too hard to track changes
         otherwise.  */
      if (copying_arguments
           (XEXP (src, 0) == arg_pointer_rtx
              || (GET_CODE (XEXP (src, 0)) == PLUS
                   XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
        return gen_rtx_ADDRESS (VOIDmode, src);

 I think it would be cleaner and less wasteful to use a single rtx for
 the single base (really potential base).

 So if we wanted to, we could now remove the operand from ADDRESS and
 simply rely on pointer equality.  I'm a bit reluctant to do that though.
 It would make debugging harder, and it would mean either adding knowledge
 of this alias-specific code to other files (specifically rtl.c:rtx_equal_p),
 or adding special ADDRESS shortcuts to alias.c.  But I think the code
 would be more obvious if we replaced the rtx operand with a unique id,
 which is what we already use for the REG_NOALIAS case:

      new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
                                                   GEN_INT (unique_id++));

 And if we do that, we can make the id a direct operand of the ADDRESS,
 rather than a CONST_INT subrtx[*].  That should make rtx_equal_p cheaper too.

  [*] I'm trying to get rid of CONST_INTs like these that have
      no obvious mode.

 All of which led to the patch below.  I checked that it didn't change
 the code generated at -O2 for a recent set of cc1 .ii files.  Also
 bootstrapped  regression-tested on x86_64-linux-gnu.  OK to install?

 To cover my back: I'm just trying to rewrite the current code according
 to its current assumptions.  Whether those assumptions are correct or not
 is always open to debate...

 Richard


 gcc/
        * rtl.def (ADDRESS): Turn operand into a HOST_WIDE_INT.
        * alias.c (reg_base_value): Expand and update comment.
        (arg_base_value): New variable.
        (unique_id): Move up file.
        (unique_base_value, unique_base_value_p, known_base_value_p): New.
        (find_base_value): Use arg_base_value and known_base_value_p.
        (record_set): Document REG_NOALIAS handling.  Use unique_base_value.
        (find_base_term): Use known_base_value_p.
        (base_alias_check): Use unique_base_value_p.
        (init_alias_target): Initialize arg_base_value.  Use unique_base_value.
        (init_alias_analysis): Use 1 as the first id for REG_NOALIAS bases.


This breaks bootstrap on Linux/x86:


home/regress/tbox/native/build/./gcc/xgcc
-B/home/regress/tbox/native/build/./gcc/
-B/home/regress/tbox/objs/i686-pc-linux-gnu/bin/

Re: RFA: Clean up ADDRESS handling in alias.c

2012-04-17 Thread Richard Sandiford
H.J. Lu hjl.to...@gmail.com writes:
 On Sun, Apr 15, 2012 at 8:11 AM, Richard Sandiford
 rdsandif...@googlemail.com wrote:
 The comment in alias.c says:

   The contents of an ADDRESS is not normally used, the mode of the
   ADDRESS determines whether the ADDRESS is a function argument or some
   other special value.  Pointer equality, not rtx_equal_p, determines whether
   two ADDRESS expressions refer to the same base address.

   The only use of the contents of an ADDRESS is for determining if the
   current function performs nonlocal memory memory references for the
   purposes of marking the function as a constant function.  */

 The first paragraph is a bit misleading IMO.  AFAICT, rtx_equal_p has
 always given ADDRESS the full recursive treatment, rather than saying
 that pointer equality determines ADDRESS equality.  (This is in contrast
 to something like VALUE, where pointer equality is used.)  And AFAICT
 we've always had:

 static int
 base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
                  enum machine_mode y_mode)
 {
  ...
  /* If the base addresses are equal nothing is known about aliasing.  */
  if (rtx_equal_p (x_base, y_base))
    return 1;
  ...
 }

 So I think the contents of an ADDRESS _are_ used to distinguish
 between different bases.

 The second paragraph ceased to be true in 2005 when the pure/const
 analysis moved to its own IPA pass.  Nothing now looks at the contents
 beyond rtx_equal_p.

 Also, base_alias_check effectively treats all arguments as a single base.
 That makes conceptual sense, because this analysis isn't strong enough
 to determine whether arguments are base values at all, never mind whether
 accesses based on different arguments conflict.  But the fact that we have
 a single base isn't obvious from the way the code is written, because we
 create several separate, non-rtx_equal_p, ADDRESSes to represent arguments.
 See:

  for (i = 0; i  FIRST_PSEUDO_REGISTER; i++)
    /* Check whether this register can hold an incoming pointer
       argument.  FUNCTION_ARG_REGNO_P tests outgoing register
       numbers, so translate if necessary due to register windows.  */
    if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
         HARD_REGNO_MODE_OK (i, Pmode))
      static_reg_base_value[i]
        = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));

 and:

      /* Check for an argument passed in memory.  Only record in the
         copying-arguments block; it is too hard to track changes
         otherwise.  */
      if (copying_arguments
           (XEXP (src, 0) == arg_pointer_rtx
              || (GET_CODE (XEXP (src, 0)) == PLUS
                   XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
        return gen_rtx_ADDRESS (VOIDmode, src);

 I think it would be cleaner and less wasteful to use a single rtx for
 the single base (really potential base).

 So if we wanted to, we could now remove the operand from ADDRESS and
 simply rely on pointer equality.  I'm a bit reluctant to do that though.
 It would make debugging harder, and it would mean either adding knowledge
 of this alias-specific code to other files (specifically rtl.c:rtx_equal_p),
 or adding special ADDRESS shortcuts to alias.c.  But I think the code
 would be more obvious if we replaced the rtx operand with a unique id,
 which is what we already use for the REG_NOALIAS case:

      new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
                                                   GEN_INT (unique_id++));

 And if we do that, we can make the id a direct operand of the ADDRESS,
 rather than a CONST_INT subrtx[*].  That should make rtx_equal_p cheaper too.

  [*] I'm trying to get rid of CONST_INTs like these that have
      no obvious mode.

 All of which led to the patch below.  I checked that it didn't change
 the code generated at -O2 for a recent set of cc1 .ii files.  Also
 bootstrapped  regression-tested on x86_64-linux-gnu.  OK to install?

 To cover my back: I'm just trying to rewrite the current code according
 to its current assumptions.  Whether those assumptions are correct or not
 is always open to debate...

 Richard


 gcc/
        * rtl.def (ADDRESS): Turn operand into a HOST_WIDE_INT.
        * alias.c (reg_base_value): Expand and update comment.
        (arg_base_value): New variable.
        (unique_id): Move up file.
        (unique_base_value, unique_base_value_p, known_base_value_p): New.
        (find_base_value): Use arg_base_value and known_base_value_p.
        (record_set): Document REG_NOALIAS handling.  Use unique_base_value.
        (find_base_term): Use known_base_value_p.
        (base_alias_check): Use unique_base_value_p.
        (init_alias_target): Initialize arg_base_value.  Use 
 unique_base_value.
        (init_alias_analysis): Use 1 as the first id for REG_NOALIAS bases.


 This breaks bootstrap on Linux/x86:


 home/regress/tbox/native/build/./gcc/xgcc
 -B/home/regress/tbox/native/build/./gcc/
 -B/home/regress/tbox/objs/i686-pc-linux-gnu/bin/
 

RFA: Clean up ADDRESS handling in alias.c

2012-04-15 Thread Richard Sandiford
The comment in alias.c says:

   The contents of an ADDRESS is not normally used, the mode of the
   ADDRESS determines whether the ADDRESS is a function argument or some
   other special value.  Pointer equality, not rtx_equal_p, determines whether
   two ADDRESS expressions refer to the same base address.

   The only use of the contents of an ADDRESS is for determining if the
   current function performs nonlocal memory memory references for the
   purposes of marking the function as a constant function.  */

The first paragraph is a bit misleading IMO.  AFAICT, rtx_equal_p has
always given ADDRESS the full recursive treatment, rather than saying
that pointer equality determines ADDRESS equality.  (This is in contrast
to something like VALUE, where pointer equality is used.)  And AFAICT
we've always had:

static int
base_alias_check (rtx x, rtx y, enum machine_mode x_mode,
  enum machine_mode y_mode)
{
  ...
  /* If the base addresses are equal nothing is known about aliasing.  */
  if (rtx_equal_p (x_base, y_base))
return 1;
  ...
}

So I think the contents of an ADDRESS _are_ used to distinguish
between different bases.

The second paragraph ceased to be true in 2005 when the pure/const
analysis moved to its own IPA pass.  Nothing now looks at the contents
beyond rtx_equal_p.

Also, base_alias_check effectively treats all arguments as a single base.
That makes conceptual sense, because this analysis isn't strong enough
to determine whether arguments are base values at all, never mind whether
accesses based on different arguments conflict.  But the fact that we have
a single base isn't obvious from the way the code is written, because we
create several separate, non-rtx_equal_p, ADDRESSes to represent arguments.
See:

  for (i = 0; i  FIRST_PSEUDO_REGISTER; i++)
/* Check whether this register can hold an incoming pointer
   argument.  FUNCTION_ARG_REGNO_P tests outgoing register
   numbers, so translate if necessary due to register windows.  */
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
 HARD_REGNO_MODE_OK (i, Pmode))
  static_reg_base_value[i]
= gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));

and:

  /* Check for an argument passed in memory.  Only record in the
 copying-arguments block; it is too hard to track changes
 otherwise.  */
  if (copying_arguments
   (XEXP (src, 0) == arg_pointer_rtx
  || (GET_CODE (XEXP (src, 0)) == PLUS
   XEXP (XEXP (src, 0), 0) == arg_pointer_rtx)))
return gen_rtx_ADDRESS (VOIDmode, src);

I think it would be cleaner and less wasteful to use a single rtx for
the single base (really potential base).

So if we wanted to, we could now remove the operand from ADDRESS and
simply rely on pointer equality.  I'm a bit reluctant to do that though.
It would make debugging harder, and it would mean either adding knowledge
of this alias-specific code to other files (specifically rtl.c:rtx_equal_p),
or adding special ADDRESS shortcuts to alias.c.  But I think the code
would be more obvious if we replaced the rtx operand with a unique id,
which is what we already use for the REG_NOALIAS case:

  new_reg_base_value[regno] = gen_rtx_ADDRESS (Pmode,
   GEN_INT (unique_id++));

And if we do that, we can make the id a direct operand of the ADDRESS,
rather than a CONST_INT subrtx[*].  That should make rtx_equal_p cheaper too.

  [*] I'm trying to get rid of CONST_INTs like these that have
  no obvious mode.

All of which led to the patch below.  I checked that it didn't change
the code generated at -O2 for a recent set of cc1 .ii files.  Also
bootstrapped  regression-tested on x86_64-linux-gnu.  OK to install?

To cover my back: I'm just trying to rewrite the current code according
to its current assumptions.  Whether those assumptions are correct or not
is always open to debate...

Richard


gcc/
* rtl.def (ADDRESS): Turn operand into a HOST_WIDE_INT.
* alias.c (reg_base_value): Expand and update comment.
(arg_base_value): New variable.
(unique_id): Move up file.
(unique_base_value, unique_base_value_p, known_base_value_p): New.
(find_base_value): Use arg_base_value and known_base_value_p.
(record_set): Document REG_NOALIAS handling.  Use unique_base_value.
(find_base_term): Use known_base_value_p.
(base_alias_check): Use unique_base_value_p.
(init_alias_target): Initialize arg_base_value.  Use unique_base_value.
(init_alias_analysis): Use 1 as the first id for REG_NOALIAS bases.

Index: gcc/rtl.def
===
--- gcc/rtl.def 2012-04-15 15:23:52.747632394 +0100
+++ gcc/rtl.def 2012-04-15 15:58:48.234515667 +0100
@@ -109,8 +109,8 @@ DEF_RTL_EXPR(INSN_LIST, insn_list, ue
`emit_insn' takes the SEQUENCE apart and makes separate insns.  */