On Wed, 2 Apr 2025, Jakub Jelinek wrote:

> On Wed, Apr 02, 2025 at 09:22:54PM +0100, Richard Sandiford wrote:
> > I'm not sure the _1 template is worth it.  wi::to_widest ->
> > const wide_int_ref & should be very cheap (it doesn't for example
> > construct a widest_int), so I think native_encode_int could call
> > native_encode_wide_int.
> 
> You're right, I was afraid it would construct something expensive.
> Looking at --enable-checking=release build, I see native_encode_int
> is inlined into native_encode_expr and does
>   MEM[(struct wide_int_ref_storage *)&D.261480] ={v} {CLOBBER};
>   _30 = *expr_10.base.u.int_length.extended;
>   _31 = (unsigned int) _30;
>   _32 = &expr_10->int_cst.val[0];
>   MEM <const long int *> [(struct wide_int_ref_storage *)&D.261480] = _32;
>   MEM <unsigned int> [(struct wide_int_ref_storage *)&D.261480 + 8B] = _31;
>   MEM <unsigned int> [(struct wide_int_ref_storage *)&D.261480 + 12B] = 
> 131072;
>   _33 = expr_10->typed.type;
>   _34 = native_encode_wide_int (_33, &D.261480, ptr_11, len_12, off_8);
> there in optimized dump, which is
>   temp.val = &TREE_INT_CST_ELT (expr, 0);
>   temp.len = TREE_INT_CST_EXT_NUNITS (expr);
>   temp.precision = WIDEST_INT_MAX_PRECISION;
> so that seems fairly cheap.
> 
> So I'll retest:

OK if it worked out.

Richard.

> 2025-04-02  Jakub Jelinek  <ja...@redhat.com>
> 
>       PR cobol/119242
> gcc/
>       * fold-const.h (native_encode_wide_int): Declare.
>       * fold-const.cc (native_encode_wide_int): New function.
>       (native_encode_int): Use it.
> gcc/cobol/
>       * genapi.cc (binary_initial_from_float128): Use
>       native_encode_wide_int.
> 
> --- gcc/fold-const.h.jj       2025-04-02 19:26:55.300272195 +0200
> +++ gcc/fold-const.h  2025-04-02 22:36:19.066641205 +0200
> @@ -35,6 +35,8 @@ extern bool folding_cxx_constexpr;
>  extern int native_encode_expr (const_tree, unsigned char *, int, int off = 
> -1);
>  extern int native_encode_initializer (tree, unsigned char *, int,
>                                     int off = -1, unsigned char * = nullptr);
> +extern int native_encode_wide_int (tree, const wide_int_ref &,
> +                                unsigned char *, int, int off = -1);
>  extern int native_encode_real (scalar_float_mode, const REAL_VALUE_TYPE *,
>                              unsigned char *, int, int off = -1);
>  extern tree native_interpret_expr (tree, const unsigned char *, int);
> --- gcc/fold-const.cc.jj      2025-04-02 19:26:55.300272195 +0200
> +++ gcc/fold-const.cc 2025-04-02 22:39:04.932113465 +0200
> @@ -7465,15 +7465,16 @@ fold_plusminus_mult_expr (location_t loc
>    return NULL_TREE;
>  }
>  
> -/* Subroutine of native_encode_expr.  Encode the INTEGER_CST
> -   specified by EXPR into the buffer PTR of length LEN bytes.
> +
> +/* Subroutine of native_encode_int.  Encode the integer VAL with type TYPE
> +   into the buffer PTR of length LEN bytes.
>     Return the number of bytes placed in the buffer, or zero
>     upon failure.  */
>  
> -static int
> -native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
> +int
> +native_encode_wide_int (tree type, const wide_int_ref &val,
> +                     unsigned char *ptr, int len, int off)
>  {
> -  tree type = TREE_TYPE (expr);
>    int total_bytes;
>    if (TREE_CODE (type) == BITINT_TYPE)
>      {
> @@ -7516,7 +7517,7 @@ native_encode_int (const_tree expr, unsi
>        int bitpos = byte * BITS_PER_UNIT;
>        /* Extend EXPR according to TYPE_SIGN if the precision isn't a whole
>        number of bytes.  */
> -      value = wi::extract_uhwi (wi::to_widest (expr), bitpos, BITS_PER_UNIT);
> +      value = wi::extract_uhwi (val, bitpos, BITS_PER_UNIT);
>  
>        if (total_bytes > UNITS_PER_WORD)
>       {
> @@ -7537,6 +7538,18 @@ native_encode_int (const_tree expr, unsi
>    return MIN (len, total_bytes - off);
>  }
>  
> +/* Subroutine of native_encode_expr.  Encode the INTEGER_CST
> +   specified by EXPR into the buffer PTR of length LEN bytes.
> +   Return the number of bytes placed in the buffer, or zero
> +   upon failure.  */
> +
> +static int
> +native_encode_int (const_tree expr, unsigned char *ptr, int len, int off)
> +{
> +  return native_encode_wide_int (TREE_TYPE (expr), wi::to_widest (expr),
> +                              ptr, len, off);
> +}
> +
>  
>  /* Subroutine of native_encode_expr.  Encode the FIXED_CST
>     specified by EXPR into the buffer PTR of length LEN bytes.
> --- gcc/cobol/genapi.cc.jj    2025-04-02 19:26:55.265272660 +0200
> +++ gcc/cobol/genapi.cc       2025-04-02 22:36:19.071641137 +0200
> @@ -15216,25 +15216,19 @@ binary_initial_from_float128(cbl_field_t
>    FIXED_WIDE_INT(128) i
>      = FIXED_WIDE_INT(128)::from (real_to_integer (&value, &fail, 128), 
> SIGNED);
>  
> -  /* ???  Use native_encode_* below.  */
>    retval = (char *)xmalloc(field->data.capacity);
>    switch(field->data.capacity)
>      {
> +      tree type;
>      case 1:
> -      *(signed char *)retval = (signed char)i.slow ();
> -      break;
>      case 2:
> -      *(signed short *)retval = (signed short)i.slow ();
> -      break;
>      case 4:
> -      *(signed int *)retval = (signed int)i.slow ();
> -      break;
>      case 8:
> -      *(signed long *)retval = (signed long)i.slow ();
> -      break;
>      case 16:
> -      *(unsigned long *)retval = (unsigned long)i.ulow ();
> -      *((signed long *)retval + 1) = (signed long)i.shigh ();
> +      type = build_nonstandard_integer_type (field->data.capacity
> +                                          * BITS_PER_UNIT, 0);
> +      native_encode_wide_int (type, i, (unsigned char *)retval,
> +                           field->data.capacity);
>        break;
>      default:
>        fprintf(stderr,
> 
> 
>       Jakub
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)

Reply via email to