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 <[email protected]>
>
> 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 <[email protected]>
SUSE Software Solutions Germany GmbH,
Frankenstrasse 146, 90461 Nuernberg, Germany;
GF: Ivo Totev, Andrew McDonald, Werner Knoblich; (HRB 36809, AG Nuernberg)