Ping?

> > -----Original Message-----
> > From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
> > ow...@gcc.gnu.org] On Behalf Of Thomas Preud'homme
> > Sent: Thursday, August 07, 2014 1:57 PM
> > To: gcc-patches@gcc.gnu.org
> > Subject: RE: [PATCH] Fix confusion between target, host and symbolic
> > number byte sizes
> >
> > I suppose people were busy when I posted this patch and it got forgotten
> > since so here is a little ping.
> >
> > Best regards,
> >
> > Thomas
> >
> > > -----Original Message-----
> > > From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
> > > ow...@gcc.gnu.org] On Behalf Of Thomas Preud'homme
> > > Sent: Friday, July 04, 2014 12:53 PM
> > > To: gcc-patches@gcc.gnu.org
> > > Subject: [PATCH] Fix confusion between target, host and symbolic
> number
> > > byte sizes
> > >
> > > The bswap pass deals with 3 possibly different byte size: host, target and
> > the
> > > size a byte marker occupied in the symbolic_number structure [1].
> > However,
> > > as of now the code mixes the three size. This works in practice as the 
> > > pass
> > is
> > > only enabled for target with BITS_PER_UNIT == 8 and nobody runs GCC
> on
> > a
> > > host with CHAR_BIT != 8. As prompted by Jakub Jelinek, this patch fixes
> this
> > > mess. Byte marker are 8-bit quantities (they could be made 4-bit
> quantities
> > > but I prefered to keep the code working the same as before) for which a
> > > new macro is introduced (BITS_PER_MARKERS), anything related to
> storing
> > > the value or a byte marker in a variable should check for the host byte
> size
> > or
> > > wide integer size and anything aimed at manipulating the target value
> > should
> > > check for BITS_PER_UNIT.
> > >
> > >
> > > [1] Although the comment for this structure implies that a byte marker as
> > the
> > > same size as the host byte, the way it is used in the code (even before
> any
> > of
> > > my patch) shows that it uses a fixed size of 8 [2].
> > > [2] Note that since the pass is only active for targets with BITS_PER_UNIT
> > ==
> > > 8, it might be using the target byte size.
> > >
> > > gcc/ChangeLog:
> > >
> > > 2014-07-04  Thomas Preud'homme  <thomas.preudho...@arm.com>
> > >
> > >   * tree-ssa-math-opts.c (struct symbolic_number): Clarify comment
> > > about
> > >   the size of byte markers.
> > >   (do_shift_rotate): Fix confusion between host, target and marker
> > > byte
> > >   size.
> > >   (verify_symbolic_number_p): Likewise.
> > >   (find_bswap_or_nop_1): Likewise.
> > >   (find_bswap_or_nop): Likewise.
> > >
> > >
> > > diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
> > > index ca2b30d..55c5df7 100644
> > > --- a/gcc/tree-ssa-math-opts.c
> > > +++ b/gcc/tree-ssa-math-opts.c
> > > @@ -1602,11 +1602,10 @@ make_pass_cse_sincos (gcc::context *ctxt)
> > >
> > >  /* A symbolic number is used to detect byte permutation and selection
> > >     patterns.  Therefore the field N contains an artificial number
> > > -   consisting of byte size markers:
> > > +   consisting of octet sized markers:
> > >
> > > -   0    - byte has the value 0
> > > -   1..size - byte contains the content of the byte
> > > -   number indexed with that value minus one.
> > > +   0    - target byte has the value 0
> > > +   1..size - marker value is the target byte index minus one.
> > >
> > >     To detect permutations on memory sources (arrays and structures), a
> > > symbolic
> > >     number is also associated a base address (the array or structure the
> load
> > is
> > > @@ -1631,6 +1630,8 @@ struct symbolic_number {
> > >    unsigned HOST_WIDE_INT range;
> > >  };
> > >
> > > +#define BITS_PER_MARKER 8
> > > +
> > >  /* The number which the find_bswap_or_nop_1 result should match in
> > >     order to have a nop.  The number is masked according to the size of
> > >     the symbolic number before using it.  */
> > > @@ -1652,15 +1653,16 @@ do_shift_rotate (enum tree_code code,
> > >            struct symbolic_number *n,
> > >            int count)
> > >  {
> > > -  int bitsize = TYPE_PRECISION (n->type);
> > > +  int size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
> > >
> > > -  if (count % 8 != 0)
> > > +  if (count % BITS_PER_UNIT != 0)
> > >      return false;
> > > +  count = (count / BITS_PER_UNIT) * BITS_PER_MARKER;
> > >
> > >    /* Zero out the extra bits of N in order to avoid them being shifted
> > >       into the significant bits.  */
> > > -  if (bitsize < 8 * (int)sizeof (int64_t))
> > > -    n->n &= ((uint64_t)1 << bitsize) - 1;
> > > +  if (size < 64 / BITS_PER_MARKER)
> > > +    n->n &= ((uint64_t) 1 << (size * BITS_PER_MARKER)) - 1;
> > >
> > >    switch (code)
> > >      {
> > > @@ -1670,22 +1672,22 @@ do_shift_rotate (enum tree_code code,
> > >      case RSHIFT_EXPR:
> > >        /* Arithmetic shift of signed type: result is dependent on the 
> > > value.
> */
> > >        if (!TYPE_UNSIGNED (n->type)
> > > -   && (n->n & ((uint64_t) 0xff << (bitsize - 8))))
> > > +   && (n->n & ((uint64_t) 0xff << ((size - 1) * BITS_PER_MARKER))))
> > >   return false;
> > >        n->n >>= count;
> > >        break;
> > >      case LROTATE_EXPR:
> > > -      n->n = (n->n << count) | (n->n >> (bitsize - count));
> > > +      n->n = (n->n << count) | (n->n >> ((size * BITS_PER_MARKER) -
> > count));
> > >        break;
> > >      case RROTATE_EXPR:
> > > -      n->n = (n->n >> count) | (n->n << (bitsize - count));
> > > +      n->n = (n->n >> count) | (n->n << ((size * BITS_PER_MARKER) -
> > count));
> > >        break;
> > >      default:
> > >        return false;
> > >      }
> > >    /* Zero unused bits for size.  */
> > > -  if (bitsize < 8 * (int)sizeof (int64_t))
> > > -    n->n &= ((uint64_t)1 << bitsize) - 1;
> > > +  if (size < 64 / BITS_PER_MARKER)
> > > +    n->n &= ((uint64_t) 1 << (size * BITS_PER_MARKER)) - 1;
> > >    return true;
> > >  }
> > >
> > > @@ -1726,13 +1728,13 @@ init_symbolic_number (struct
> > symbolic_number
> > > *n, tree src)
> > >    if (size % BITS_PER_UNIT != 0)
> > >      return false;
> > >    size /= BITS_PER_UNIT;
> > > -  if (size > (int)sizeof (uint64_t))
> > > +  if (size > 64 / BITS_PER_MARKER)
> > >      return false;
> > >    n->range = size;
> > >    n->n = CMPNOP;
> > >
> > > -  if (size < (int)sizeof (int64_t))
> > > -    n->n &= ((uint64_t)1 << (size * BITS_PER_UNIT)) - 1;
> > > +  if (size < 64 / BITS_PER_MARKER)
> > > +    n->n &= ((uint64_t) 1 << (size * BITS_PER_MARKER)) - 1;
> > >
> > >    return true;
> > >  }
> > > @@ -1870,15 +1872,17 @@ find_bswap_or_nop_1 (gimple stmt, struct
> > > symbolic_number *n, int limit)
> > >   case BIT_AND_EXPR:
> > >     {
> > >       int i, size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
> > > -     uint64_t val = int_cst_value (rhs2);
> > > -     uint64_t tmp = val;
> > > +     uint64_t val = int_cst_value (rhs2), mask = 0;
> > > +     uint64_t tmp = (1 << BITS_PER_UNIT) - 1;
> > >
> > >       /* Only constants masking full bytes are allowed.  */
> > > -     for (i = 0; i < size; i++, tmp >>= BITS_PER_UNIT)
> > > -       if ((tmp & 0xff) != 0 && (tmp & 0xff) != 0xff)
> > > +     for (i = 0; i < size; i++, tmp <<= BITS_PER_UNIT)
> > > +       if ((val & tmp) != 0 && (val & tmp) != tmp)
> > >           return NULL;
> > > +       else if (val & tmp)
> > > +         mask |= (uint64_t) 0xff << (i * BITS_PER_MARKER);
> > >
> > > -     n->n &= val;
> > > +     n->n &= mask;
> > >     }
> > >     break;
> > >   case LSHIFT_EXPR:
> > > @@ -1897,25 +1901,27 @@ find_bswap_or_nop_1 (gimple stmt, struct
> > > symbolic_number *n, int limit)
> > >       type_size = TYPE_PRECISION (type);
> > >       if (type_size % BITS_PER_UNIT != 0)
> > >         return NULL;
> > > -     if (type_size > (int)sizeof (uint64_t) * 8)
> > > +     type_size /= BITS_PER_UNIT;
> > > +     if (type_size > 64 / BITS_PER_MARKER)
> > >         return NULL;
> > >
> > >       /* Sign extension: result is dependent on the value.  */
> > > -     old_type_size = TYPE_PRECISION (n->type);
> > > +     old_type_size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
> > >       if (!TYPE_UNSIGNED (n->type)
> > >           && type_size > old_type_size
> > > -         && n->n & ((uint64_t) 0xff << (old_type_size - 8)))
> > > +         && n->n & ((uint64_t) 0xff << ((old_type_size - 1)
> > > +                                        * BITS_PER_MARKER)))
> > >         return NULL;
> > >
> > > -     if (type_size / BITS_PER_UNIT < (int)(sizeof (int64_t)))
> > > +     if (type_size < 64 / BITS_PER_MARKER)
> > >         {
> > >           /* If STMT casts to a smaller type mask out the bits not
> > >              belonging to the target type.  */
> > > -         n->n &= ((uint64_t)1 << type_size) - 1;
> > > +         n->n &= ((uint64_t) 1 << (type_size * BITS_PER_MARKER)) -
> > > 1;
> > >         }
> > >       n->type = type;
> > >       if (!n->base_addr)
> > > -       n->range = type_size / BITS_PER_UNIT;
> > > +       n->range = type_size;
> > >     }
> > >     break;
> > >   default:
> > > @@ -1965,7 +1971,6 @@ find_bswap_or_nop_1 (gimple stmt, struct
> > > symbolic_number *n, int limit)
> > >         != gimple_assign_rhs1 (source_stmt2))
> > >       {
> > >         int64_t inc, mask;
> > > -       unsigned i;
> > >         HOST_WIDE_INT off_sub;
> > >         struct symbolic_number *n_ptr;
> > >
> > > @@ -1989,21 +1994,23 @@ find_bswap_or_nop_1 (gimple stmt, struct
> > > symbolic_number *n, int limit)
> > >
> > >         off_sub = n2.bytepos - n1.bytepos;
> > >
> > > -       /* Check that the range of memory covered < biggest int size.  */
> > > -       if (off_sub + n2.range > (int) sizeof (int64_t))
> > > +       /* Check that the range of memory covered can be represented
> > > by
> > > +          a symbolic number.  */
> > > +       if (off_sub + n2.range > 64 / BITS_PER_MARKER)
> > >           return NULL;
> > >         n->range = n2.range + off_sub;
> > >
> > >         /* Reinterpret byte marks in symbolic number holding the value
> > > of
> > >            bigger weight according to target endianness.  */
> > >         inc = BYTES_BIG_ENDIAN ? off_sub + n2.range - n1.range :
> > > off_sub;
> > > -       mask = 0xFF;
> > > +       size = TYPE_PRECISION (n1.type) / BITS_PER_UNIT;
> > > +       mask = 0xff;
> > >         if (BYTES_BIG_ENDIAN)
> > >           n_ptr = &n1;
> > >         else
> > >           n_ptr = &n2;
> > > -       for (i = 0; i < sizeof (int64_t); i++, inc <<= 8,
> > > -            mask <<= 8)
> > > +       for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER,
> > > +                                  mask <<= BITS_PER_MARKER)
> > >           {
> > >             if (n_ptr->n & mask)
> > >               n_ptr->n += inc;
> > > @@ -2023,7 +2030,7 @@ find_bswap_or_nop_1 (gimple stmt, struct
> > > symbolic_number *n, int limit)
> > >     n->bytepos = n1.bytepos;
> > >     n->type = n1.type;
> > >     size = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
> > > -   for (i = 0, mask = 0xff; i < size; i++, mask <<= BITS_PER_UNIT)
> > > +   for (i = 0, mask = 0xff; i < size; i++, mask <<= BITS_PER_MARKER)
> > >       {
> > >         uint64_t masked1, masked2;
> > >
> > > @@ -2084,17 +2091,17 @@ find_bswap_or_nop (gimple stmt, struct
> > > symbolic_number *n, bool *bswap)
> > >        int rsize;
> > >        uint64_t tmpn;
> > >
> > > -      for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_UNIT, 
> > > rsize++);
> > > +      for (tmpn = n->n, rsize = 0; tmpn; tmpn >>= BITS_PER_MARKER,
> > rsize++);
> > >        n->range = rsize;
> > >      }
> > >
> > >    /* Zero out the extra bits of N and CMP*.  */
> > > -  if (n->range < (int)sizeof (int64_t))
> > > +  if (n->range < (int) sizeof (int64_t))
> > >      {
> > >        uint64_t mask;
> > >
> > > -      mask = ((uint64_t)1 << (n->range * BITS_PER_UNIT)) - 1;
> > > -      cmpxchg >>= (sizeof (int64_t) - n->range) * BITS_PER_UNIT;
> > > +      mask = ((uint64_t) 1 << (n->range * BITS_PER_MARKER)) - 1;
> > > +      cmpxchg >>= (64 / BITS_PER_MARKER - n->range) *
> > BITS_PER_MARKER;
> > >        cmpnop &= mask;
> > >      }
> > >
> > > Ok for trunk?
> > >
> > > Best regards,
> > >
> > > Thomas
> > >
> > >
> >
> >
> >
> 
> 
> 



Reply via email to