Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch. This patch covers the dwarf code.
Ok?
* dwarf2out.c (get_full_len): New. (dw_val_equal_p): Add case dw_val_class_wide_int. (size_of_loc_descr): Likewise. (output_loc_operands): Likewise. (insert_double): Remove. (insert_wide_int): New. (add_AT_wide): New. (print_die): Add case dw_val_class_wide_int. (attr_checksum): Likewise. (attr_checksum_ordered): Likewise. (same_dw_val_p): Likewise. (size_of_die): Likewise. (value_format): Likewise. (output_die): Likewise. (double_int_type_size_in_bits): Rename to offset_int_type_size_in_bits. Use wide-int. (clz_loc_descriptor): Use wide-int interfaces. (mem_loc_descriptor): Likewise. Handle CONST_WIDE_INT. (loc_descriptor): Use wide-int interfaces. Handle CONST_WIDE_INT. (round_up_to_align): Use wide-int interfaces. (field_byte_offset): Likewise. (insert_double): Rename to insert_wide_int. Use wide-int interfaces. (add_const_value_attribute): Handle CONST_WIDE_INT. Update CONST_DOUBLE handling. Use wide-int interfaces. (add_bound_info): Use tree_fits_uhwi_p. Use wide-int interfaces. (gen_enumeration_type_die): Use add_AT_wide. (hash_loc_operands): Add case dw_val_class_wide_int. (compare_loc_operands): Likewise. * dwarf2out.h: Include wide-int.h. (wide_int_ptr): New. (enum dw_val_class): Add dw_val_class_wide_int. (struct dw_val_struct): Add val_wide. diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index bd372b7..04d4988 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -353,6 +353,16 @@ dump_struct_debug (tree type, enum debug_info_usage usage, #endif +/* Get the number of HOST_WIDE_INTs needed to represent the precision + of the number. */ + +static unsigned int +get_full_len (const wide_int &op) +{ + return ((op.get_precision () + HOST_BITS_PER_WIDE_INT - 1) + / HOST_BITS_PER_WIDE_INT); +} + static bool should_emit_struct_debug (tree type, enum debug_info_usage usage) { @@ -1388,6 +1398,9 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b) return (a->v.val_double.high == b->v.val_double.high && a->v.val_double.low == b->v.val_double.low); + case dw_val_class_wide_int: + return *a->v.val_wide == *b->v.val_wide; + case dw_val_class_vec: { size_t a_len = a->v.val_vec.elt_size * a->v.val_vec.length; @@ -1644,6 +1657,10 @@ size_of_loc_descr (dw_loc_descr_ref loc) case dw_val_class_const_double: size += HOST_BITS_PER_DOUBLE_INT / BITS_PER_UNIT; break; + case dw_val_class_wide_int: + size += (get_full_len (*loc->dw_loc_oprnd2.v.val_wide) + * HOST_BITS_PER_WIDE_INT / BITS_PER_UNIT); + break; default: gcc_unreachable (); } @@ -1821,6 +1838,20 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip) second, NULL); } break; + case dw_val_class_wide_int: + { + int i; + int len = get_full_len (*val2->v.val_wide); + if (WORDS_BIG_ENDIAN) + for (i = len; i >= 0; --i) + dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR, + val2->v.val_wide->elt (i), NULL); + else + for (i = 0; i < len; ++i) + dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR, + val2->v.val_wide->elt (i), NULL); + } + break; case dw_val_class_addr: gcc_assert (val1->v.val_unsigned == DWARF2_ADDR_SIZE); dw2_asm_output_addr_rtx (DWARF2_ADDR_SIZE, val2->v.val_addr, NULL); @@ -2030,6 +2061,21 @@ output_loc_operands (dw_loc_descr_ref loc, int for_eh_or_skip) dw2_asm_output_data (l, second, NULL); } break; + case dw_val_class_wide_int: + { + int i; + int len = get_full_len (*val2->v.val_wide); + l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; + + dw2_asm_output_data (1, len * l, NULL); + if (WORDS_BIG_ENDIAN) + for (i = len; i >= 0; --i) + dw2_asm_output_data (l, val2->v.val_wide->elt (i), NULL); + else + for (i = 0; i < len; ++i) + dw2_asm_output_data (l, val2->v.val_wide->elt (i), NULL); + } + break; default: gcc_unreachable (); } @@ -3122,7 +3168,7 @@ static void add_AT_location_description (dw_die_ref, enum dwarf_attribute, static void add_data_member_location_attribute (dw_die_ref, tree); static bool add_const_value_attribute (dw_die_ref, rtx); static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *); -static void insert_double (double_int, unsigned char *); +static void insert_wide_int (const wide_int &, unsigned char *, int); static void insert_float (const_rtx, unsigned char *); static rtx rtl_for_decl_location (tree); static bool add_location_or_const_value_attribute (dw_die_ref, tree, bool, @@ -3753,6 +3799,21 @@ AT_unsigned (dw_attr_ref a) return a->dw_attr_val.v.val_unsigned; } +/* Add an unsigned wide integer attribute value to a DIE. */ + +static inline void +add_AT_wide (dw_die_ref die, enum dwarf_attribute attr_kind, + const wide_int& w) +{ + dw_attr_node attr; + + attr.dw_attr = attr_kind; + attr.dw_attr_val.val_class = dw_val_class_wide_int; + attr.dw_attr_val.v.val_wide = ggc_alloc_cleared_wide_int (); + *attr.dw_attr_val.v.val_wide = w; + add_dwarf_attr (die, &attr); +} + /* Add an unsigned double integer attribute value to a DIE. */ static inline void @@ -5327,6 +5388,21 @@ print_die (dw_die_ref die, FILE *outfile) a->dw_attr_val.v.val_double.high, a->dw_attr_val.v.val_double.low); break; + case dw_val_class_wide_int: + { + int i = a->dw_attr_val.v.val_wide->get_len (); + fprintf (outfile, "constant ("); + gcc_assert (i > 0); + if (a->dw_attr_val.v.val_wide->elt (i) == 0) + fprintf (outfile, "0x"); + fprintf (outfile, HOST_WIDE_INT_PRINT_HEX, + a->dw_attr_val.v.val_wide->elt (--i)); + while (-- i >= 0) + fprintf (outfile, HOST_WIDE_INT_PRINT_PADDED_HEX, + a->dw_attr_val.v.val_wide->elt (i)); + fprintf (outfile, ")"); + break; + } case dw_val_class_vec: fprintf (outfile, "floating-point or vector constant"); break; @@ -5500,6 +5576,9 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark) case dw_val_class_const_double: CHECKSUM (at->dw_attr_val.v.val_double); break; + case dw_val_class_wide_int: + CHECKSUM (*at->dw_attr_val.v.val_wide); + break; case dw_val_class_vec: CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array, (at->dw_attr_val.v.val_vec.length @@ -5777,6 +5856,12 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at, CHECKSUM (at->dw_attr_val.v.val_double); break; + case dw_val_class_wide_int: + CHECKSUM_ULEB128 (DW_FORM_block); + CHECKSUM_ULEB128 (sizeof (*at->dw_attr_val.v.val_wide)); + CHECKSUM (*at->dw_attr_val.v.val_wide); + break; + case dw_val_class_vec: CHECKSUM_ULEB128 (DW_FORM_block); CHECKSUM_ULEB128 (at->dw_attr_val.v.val_vec.length @@ -6259,6 +6344,8 @@ same_dw_val_p (const dw_val_node *v1, const dw_val_node *v2, int *mark) case dw_val_class_const_double: return v1->v.val_double.high == v2->v.val_double.high && v1->v.val_double.low == v2->v.val_double.low; + case dw_val_class_wide_int: + return *v1->v.val_wide == *v2->v.val_wide; case dw_val_class_vec: if (v1->v.val_vec.length != v2->v.val_vec.length || v1->v.val_vec.elt_size != v2->v.val_vec.elt_size) @@ -7792,6 +7879,13 @@ size_of_die (dw_die_ref die) if (HOST_BITS_PER_WIDE_INT >= 64) size++; /* block */ break; + case dw_val_class_wide_int: + size += (get_full_len (*a->dw_attr_val.v.val_wide) + * HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR); + if (get_full_len (*a->dw_attr_val.v.val_wide) * HOST_BITS_PER_WIDE_INT + > 64) + size++; /* block */ + break; case dw_val_class_vec: size += constant_size (a->dw_attr_val.v.val_vec.length * a->dw_attr_val.v.val_vec.elt_size) @@ -8161,6 +8255,20 @@ value_format (dw_attr_ref a) default: return DW_FORM_block1; } + case dw_val_class_wide_int: + switch (get_full_len (*a->dw_attr_val.v.val_wide) * HOST_BITS_PER_WIDE_INT) + { + case 8: + return DW_FORM_data1; + case 16: + return DW_FORM_data2; + case 32: + return DW_FORM_data4; + case 64: + return DW_FORM_data8; + default: + return DW_FORM_block1; + } case dw_val_class_vec: switch (constant_size (a->dw_attr_val.v.val_vec.length * a->dw_attr_val.v.val_vec.elt_size)) @@ -8600,6 +8708,32 @@ output_die (dw_die_ref die) } break; + case dw_val_class_wide_int: + { + int i; + int len = get_full_len (*a->dw_attr_val.v.val_wide); + int l = HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; + if (len * HOST_BITS_PER_WIDE_INT > 64) + dw2_asm_output_data (1, get_full_len (*a->dw_attr_val.v.val_wide) * l, + NULL); + + if (WORDS_BIG_ENDIAN) + for (i = len; i >= 0; --i) + { + dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i), + name); + name = NULL; + } + else + for (i = 0; i < len; ++i) + { + dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i), + name); + name = NULL; + } + } + break; + case dw_val_class_vec: { unsigned int elt_size = a->dw_attr_val.v.val_vec.elt_size; @@ -10275,19 +10409,19 @@ simple_type_size_in_bits (const_tree type) return TYPE_ALIGN (type); } -/* Similarly, but return a double_int instead of UHWI. */ +/* Similarly, but return an offset_int instead of UHWI. */ -static inline double_int -double_int_type_size_in_bits (const_tree type) +static inline offset_int +offset_int_type_size_in_bits (const_tree type) { if (TREE_CODE (type) == ERROR_MARK) - return double_int::from_uhwi (BITS_PER_WORD); + return BITS_PER_WORD; else if (TYPE_SIZE (type) == NULL_TREE) - return double_int_zero; + return 0; else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) - return tree_to_double_int (TYPE_SIZE (type)); + return wi::to_offset (TYPE_SIZE (type)); else - return double_int::from_uhwi (TYPE_ALIGN (type)); + return TYPE_ALIGN (type); } /* Given a pointer to a tree node for a subrange type, return a pointer @@ -11774,9 +11908,7 @@ clz_loc_descriptor (rtx rtl, enum machine_mode mode, rtx msb; if (GET_MODE_CLASS (mode) != MODE_INT - || GET_MODE (XEXP (rtl, 0)) != mode - || (GET_CODE (rtl) == CLZ - && GET_MODE_BITSIZE (mode) > HOST_BITS_PER_DOUBLE_INT)) + || GET_MODE (XEXP (rtl, 0)) != mode) return NULL; op0 = mem_loc_descriptor (XEXP (rtl, 0), mode, mem_mode, @@ -11820,9 +11952,9 @@ clz_loc_descriptor (rtx rtl, enum machine_mode mode, msb = GEN_INT ((unsigned HOST_WIDE_INT) 1 << (GET_MODE_BITSIZE (mode) - 1)); else - msb = immed_double_const (0, (unsigned HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (mode) - - HOST_BITS_PER_WIDE_INT - 1), mode); + msb = immed_wide_int_const + (wi::set_bit_in_zero (GET_MODE_PRECISION (mode) - 1, + GET_MODE_PRECISION (mode)), mode); if (GET_CODE (msb) == CONST_INT && INTVAL (msb) < 0) tmp = new_loc_descr (HOST_BITS_PER_WIDE_INT == 32 ? DW_OP_const4u : HOST_BITS_PER_WIDE_INT == 64 @@ -12764,7 +12896,16 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref; mem_loc_result->dw_loc_oprnd1.v.val_die_ref.die = type_die; mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0; - if (SCALAR_FLOAT_MODE_P (mode)) +#if TARGET_SUPPORTS_WIDE_INT == 0 + if (!SCALAR_FLOAT_MODE_P (mode)) + { + mem_loc_result->dw_loc_oprnd2.val_class + = dw_val_class_const_double; + mem_loc_result->dw_loc_oprnd2.v.val_double + = rtx_to_double_int (rtl); + } + else +#endif { unsigned int length = GET_MODE_SIZE (mode); unsigned char *array @@ -12776,13 +12917,26 @@ mem_loc_descriptor (rtx rtl, enum machine_mode mode, mem_loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4; mem_loc_result->dw_loc_oprnd2.v.val_vec.array = array; } - else - { - mem_loc_result->dw_loc_oprnd2.val_class - = dw_val_class_const_double; - mem_loc_result->dw_loc_oprnd2.v.val_double - = rtx_to_double_int (rtl); - } + } + break; + + case CONST_WIDE_INT: + if (!dwarf_strict) + { + dw_die_ref type_die; + + type_die = base_type_for_mode (mode, + GET_MODE_CLASS (mode) == MODE_INT); + if (type_die == NULL) + return NULL; + mem_loc_result = new_loc_descr (DW_OP_GNU_const_type, 0, 0); + mem_loc_result->dw_loc_oprnd1.val_class = dw_val_class_die_ref; + mem_loc_result->dw_loc_oprnd1.v.val_die_ref.die = type_die; + mem_loc_result->dw_loc_oprnd1.v.val_die_ref.external = 0; + mem_loc_result->dw_loc_oprnd2.val_class + = dw_val_class_wide_int; + mem_loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc_cleared_wide_int (); + *mem_loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode); } break; @@ -13253,7 +13407,15 @@ loc_descriptor (rtx rtl, enum machine_mode mode, adequately represented. We output CONST_DOUBLEs as blocks. */ loc_result = new_loc_descr (DW_OP_implicit_value, GET_MODE_SIZE (mode), 0); - if (SCALAR_FLOAT_MODE_P (mode)) +#if TARGET_SUPPORTS_WIDE_INT == 0 + if (!SCALAR_FLOAT_MODE_P (mode)) + { + loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double; + loc_result->dw_loc_oprnd2.v.val_double + = rtx_to_double_int (rtl); + } + else +#endif { unsigned int length = GET_MODE_SIZE (mode); unsigned char *array @@ -13265,12 +13427,20 @@ loc_descriptor (rtx rtl, enum machine_mode mode, loc_result->dw_loc_oprnd2.v.val_vec.elt_size = 4; loc_result->dw_loc_oprnd2.v.val_vec.array = array; } - else - { - loc_result->dw_loc_oprnd2.val_class = dw_val_class_const_double; - loc_result->dw_loc_oprnd2.v.val_double - = rtx_to_double_int (rtl); - } + } + break; + + case CONST_WIDE_INT: + if (mode == VOIDmode) + mode = GET_MODE (rtl); + + if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict)) + { + loc_result = new_loc_descr (DW_OP_implicit_value, + GET_MODE_SIZE (mode), 0); + loc_result->dw_loc_oprnd2.val_class = dw_val_class_wide_int; + loc_result->dw_loc_oprnd2.v.val_wide = ggc_alloc_cleared_wide_int (); + *loc_result->dw_loc_oprnd2.v.val_wide = std::make_pair (rtl, mode); } break; @@ -13286,6 +13456,7 @@ loc_descriptor (rtx rtl, enum machine_mode mode, ggc_alloc_atomic (length * elt_size); unsigned int i; unsigned char *p; + enum machine_mode imode = GET_MODE_INNER (mode); gcc_assert (mode == GET_MODE (rtl) || VOIDmode == GET_MODE (rtl)); switch (GET_MODE_CLASS (mode)) @@ -13294,15 +13465,7 @@ loc_descriptor (rtx rtl, enum machine_mode mode, for (i = 0, p = array; i < length; i++, p += elt_size) { rtx elt = CONST_VECTOR_ELT (rtl, i); - double_int val = rtx_to_double_int (elt); - - if (elt_size <= sizeof (HOST_WIDE_INT)) - insert_int (val.to_shwi (), elt_size, p); - else - { - gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT)); - insert_double (val, p); - } + insert_wide_int (std::make_pair (elt, imode), p, elt_size); } break; @@ -14624,14 +14787,12 @@ simple_decl_align_in_bits (const_tree decl) /* Return the result of rounding T up to ALIGN. */ -static inline double_int -round_up_to_align (double_int t, unsigned int align) +static inline offset_int +round_up_to_align (offset_int t, unsigned int align) { - double_int alignd = double_int::from_uhwi (align); - t += alignd; - t += double_int_minus_one; - t = t.div (alignd, true, TRUNC_DIV_EXPR); - t *= alignd; + t += align - 1; + t = wi::udiv_trunc (t, align); + t *= align; return t; } @@ -14645,9 +14806,9 @@ round_up_to_align (double_int t, unsigned int align) static HOST_WIDE_INT field_byte_offset (const_tree decl) { - double_int object_offset_in_bits; - double_int object_offset_in_bytes; - double_int bitpos_int; + offset_int object_offset_in_bits; + offset_int object_offset_in_bytes; + offset_int bitpos_int; if (TREE_CODE (decl) == ERROR_MARK) return 0; @@ -14660,21 +14821,21 @@ field_byte_offset (const_tree decl) if (TREE_CODE (bit_position (decl)) != INTEGER_CST) return 0; - bitpos_int = tree_to_double_int (bit_position (decl)); + bitpos_int = wi::to_offset (bit_position (decl)); #ifdef PCC_BITFIELD_TYPE_MATTERS if (PCC_BITFIELD_TYPE_MATTERS) { tree type; tree field_size_tree; - double_int deepest_bitpos; - double_int field_size_in_bits; + offset_int deepest_bitpos; + offset_int field_size_in_bits; unsigned int type_align_in_bits; unsigned int decl_align_in_bits; - double_int type_size_in_bits; + offset_int type_size_in_bits; type = field_type (decl); - type_size_in_bits = double_int_type_size_in_bits (type); + type_size_in_bits = offset_int_type_size_in_bits (type); type_align_in_bits = simple_type_align_in_bits (type); field_size_tree = DECL_SIZE (decl); @@ -14686,7 +14847,7 @@ field_byte_offset (const_tree decl) /* If the size of the field is not constant, use the type size. */ if (TREE_CODE (field_size_tree) == INTEGER_CST) - field_size_in_bits = tree_to_double_int (field_size_tree); + field_size_in_bits = wi::to_offset (field_size_tree); else field_size_in_bits = type_size_in_bits; @@ -14750,7 +14911,7 @@ field_byte_offset (const_tree decl) object_offset_in_bits = round_up_to_align (object_offset_in_bits, type_align_in_bits); - if (object_offset_in_bits.ugt (bitpos_int)) + if (wi::gtu_p (object_offset_in_bits, bitpos_int)) { object_offset_in_bits = deepest_bitpos - type_size_in_bits; @@ -14764,8 +14925,7 @@ field_byte_offset (const_tree decl) object_offset_in_bits = bitpos_int; object_offset_in_bytes - = object_offset_in_bits.div (double_int::from_uhwi (BITS_PER_UNIT), - true, TRUNC_DIV_EXPR); + = wi::udiv_trunc (object_offset_in_bits, BITS_PER_UNIT); return object_offset_in_bytes.to_shwi (); } @@ -14941,22 +15101,36 @@ extract_int (const unsigned char *src, unsigned int size) return val; } -/* Writes double_int values to dw_vec_const array. */ +/* Writes wide_int values to dw_vec_const array. */ static void -insert_double (double_int val, unsigned char *dest) +insert_wide_int (const wide_int &val, unsigned char *dest, int elt_size) { - unsigned char *p0 = dest; - unsigned char *p1 = dest + sizeof (HOST_WIDE_INT); + int i; - if (WORDS_BIG_ENDIAN) + if (elt_size <= HOST_BITS_PER_WIDE_INT/BITS_PER_UNIT) { - p0 = p1; - p1 = dest; + insert_int ((HOST_WIDE_INT) val.elt (0), elt_size, dest); + return; } - insert_int ((HOST_WIDE_INT) val.low, sizeof (HOST_WIDE_INT), p0); - insert_int ((HOST_WIDE_INT) val.high, sizeof (HOST_WIDE_INT), p1); + /* We'd have to extend this code to support odd sizes. */ + gcc_assert (elt_size % (HOST_BITS_PER_WIDE_INT/BITS_PER_UNIT) == 0); + + int n = elt_size / (HOST_BITS_PER_WIDE_INT/BITS_PER_UNIT); + + if (WORDS_BIG_ENDIAN) + for (i = n - 1; i >= 0; i--) + { + insert_int ((HOST_WIDE_INT) val.elt (i), sizeof (HOST_WIDE_INT), dest); + dest += sizeof (HOST_WIDE_INT); + } + else + for (i = 0; i < n; i++) + { + insert_int ((HOST_WIDE_INT) val.elt (i), sizeof (HOST_WIDE_INT), dest); + dest += sizeof (HOST_WIDE_INT); + } } /* Writes floating point values to dw_vec_const array. */ @@ -15001,6 +15175,11 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) } return true; + case CONST_WIDE_INT: + add_AT_wide (die, DW_AT_const_value, + std::make_pair (rtl, GET_MODE (rtl))); + return true; + case CONST_DOUBLE: /* Note that a CONST_DOUBLE rtx could represent either an integer or a floating-point constant. A CONST_DOUBLE is used whenever the @@ -15009,7 +15188,10 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) { enum machine_mode mode = GET_MODE (rtl); - if (SCALAR_FLOAT_MODE_P (mode)) + if (TARGET_SUPPORTS_WIDE_INT == 0 && !SCALAR_FLOAT_MODE_P (mode)) + add_AT_double (die, DW_AT_const_value, + CONST_DOUBLE_HIGH (rtl), CONST_DOUBLE_LOW (rtl)); + else { unsigned int length = GET_MODE_SIZE (mode); unsigned char *array = (unsigned char *) ggc_alloc_atomic (length); @@ -15017,9 +15199,6 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) insert_float (rtl, array); add_AT_vec (die, DW_AT_const_value, length / 4, 4, array); } - else - add_AT_double (die, DW_AT_const_value, - CONST_DOUBLE_HIGH (rtl), CONST_DOUBLE_LOW (rtl)); } return true; @@ -15032,6 +15211,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) (length * elt_size); unsigned int i; unsigned char *p; + enum machine_mode imode = GET_MODE_INNER (mode); switch (GET_MODE_CLASS (mode)) { @@ -15039,15 +15219,7 @@ add_const_value_attribute (dw_die_ref die, rtx rtl) for (i = 0, p = array; i < length; i++, p += elt_size) { rtx elt = CONST_VECTOR_ELT (rtl, i); - double_int val = rtx_to_double_int (elt); - - if (elt_size <= sizeof (HOST_WIDE_INT)) - insert_int (val.to_shwi (), elt_size, p); - else - { - gcc_assert (elt_size == 2 * sizeof (HOST_WIDE_INT)); - insert_double (val, p); - } + insert_wide_int (std::make_pair (elt, imode), p, elt_size); } break; @@ -16183,13 +16355,11 @@ add_bound_info (dw_die_ref subrange_die, enum dwarf_attribute bound_attr, tree b add_AT_unsigned (subrange_die, bound_attr, TREE_INT_CST_LOW (bound) & mask); } - else if (prec == HOST_BITS_PER_WIDE_INT - || TREE_INT_CST_HIGH (bound) == 0) + else if (prec == HOST_BITS_PER_WIDE_INT || tree_fits_uhwi_p (bound)) add_AT_unsigned (subrange_die, bound_attr, TREE_INT_CST_LOW (bound)); else - add_AT_double (subrange_die, bound_attr, TREE_INT_CST_HIGH (bound), - TREE_INT_CST_LOW (bound)); + add_AT_wide (subrange_die, bound_attr, bound); } break; @@ -17347,8 +17517,7 @@ gen_enumeration_type_die (tree type, dw_die_ref context_die) else /* Enumeration constants may be wider than HOST_WIDE_INT. Handle that here. */ - add_AT_double (enum_die, DW_AT_const_value, - TREE_INT_CST_HIGH (value), TREE_INT_CST_LOW (value)); + add_AT_wide (enum_die, DW_AT_const_value, value); } add_gnat_descriptive_type_attribute (type_die, type, context_die); @@ -23416,6 +23585,9 @@ hash_loc_operands (dw_loc_descr_ref loc, hashval_t hash) hash = iterative_hash_object (val2->v.val_double.low, hash); hash = iterative_hash_object (val2->v.val_double.high, hash); break; + case dw_val_class_wide_int: + hash = iterative_hash_object (*val2->v.val_wide, hash); + break; case dw_val_class_addr: hash = iterative_hash_rtx (val2->v.val_addr, hash); break; @@ -23505,6 +23677,9 @@ hash_loc_operands (dw_loc_descr_ref loc, hashval_t hash) hash = iterative_hash_object (val2->v.val_double.low, hash); hash = iterative_hash_object (val2->v.val_double.high, hash); break; + case dw_val_class_wide_int: + hash = iterative_hash_object (*val2->v.val_wide, hash); + break; default: gcc_unreachable (); } @@ -23653,6 +23828,8 @@ compare_loc_operands (dw_loc_descr_ref x, dw_loc_descr_ref y) case dw_val_class_const_double: return valx2->v.val_double.low == valy2->v.val_double.low && valx2->v.val_double.high == valy2->v.val_double.high; + case dw_val_class_wide_int: + return *valx2->v.val_wide == *valy2->v.val_wide; case dw_val_class_addr: return rtx_equal_p (valx2->v.val_addr, valy2->v.val_addr); default: @@ -23696,6 +23873,8 @@ compare_loc_operands (dw_loc_descr_ref x, dw_loc_descr_ref y) case dw_val_class_const_double: return valx2->v.val_double.low == valy2->v.val_double.low && valx2->v.val_double.high == valy2->v.val_double.high; + case dw_val_class_wide_int: + return *valx2->v.val_wide == *valy2->v.val_wide; default: gcc_unreachable (); } diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index ad03a34..78d8cc0 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see #define GCC_DWARF2OUT_H 1 #include "dwarf2.h" /* ??? Remove this once only used by dwarf2foo.c. */ +#include "wide-int.h" typedef struct die_struct *dw_die_ref; typedef const struct die_struct *const_dw_die_ref; @@ -29,6 +30,7 @@ typedef struct dw_val_struct *dw_val_ref; typedef struct dw_cfi_struct *dw_cfi_ref; typedef struct dw_loc_descr_struct *dw_loc_descr_ref; typedef struct dw_loc_list_struct *dw_loc_list_ref; +typedef wide_int *wide_int_ptr; /* Call frames are described using a sequence of Call Frame @@ -139,6 +141,7 @@ enum dw_val_class dw_val_class_const, dw_val_class_unsigned_const, dw_val_class_const_double, + dw_val_class_wide_int, dw_val_class_vec, dw_val_class_flag, dw_val_class_die_ref, @@ -180,6 +183,7 @@ typedef struct GTY(()) dw_val_struct { HOST_WIDE_INT GTY ((default)) val_int; unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned; double_int GTY ((tag ("dw_val_class_const_double"))) val_double; + wide_int_ptr GTY ((tag ("dw_val_class_wide_int"))) val_wide; dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec; struct dw_val_die_union {