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)