This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[vta, vta4.4] Fix handling of dw_val_class_long_long
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Richard Henderson <rth at redhat dot com>, Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 30 Jul 2009 22:32:54 +0200
- Subject: [vta, vta4.4] Fix handling of dw_val_class_long_long
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
libgfortran build on powerpc64-linux --with-cpu=default32 ICEs when seeing
a TImode constant (CONST_DOUBLE). In this case HOST_BITS_PER_LONG is 32
(the compiler is 32-bit), but HOST_BITS_PER_WIDE_INT is 64 (as it supports
also -m64) and thus whenever seeing a CONST_DOUBLE in dwarf2out.c it ICEs
on gcc_assert (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT).
The patch below changes val_long_long to be really a pair of hwis rather
than pair of longs. Instead of making the structure longer, it just
sticks a pointer to a CONST_DOUBLE, as it is initialized from these always
anyways.
Bootstrapped/regtested on x86_64-linux, i686-linux and on powerpc64-linux
--with-cpu=default32 it extended the bootstrap further from libgfortran ICE
to an unrelated libjava ICE.
Ok for vta/vta4.4?
2009-07-30 Jakub Jelinek <jakub@redhat.com>
* dwarf2out.c (dw_long_long_const): Remove.
(struct dw_val_struct): Change val_long_long type to rtx.
(print_die, attr_checksum, same_dw_val_p, loc_descriptor): Adjust for
val_long_long change to CONST_DOUBLE rtx from a long hi/lo pair.
(output_die): Likewise. Use HOST_BITS_PER_WIDE_INT size of each
component instead of HOST_BITS_PER_LONG.
(output_loc_operands): Likewise. For const8* assert
HOST_BITS_PER_WIDE_INT rather than HOST_BITS_PER_LONG is >= 64.
(output_loc_operands_raw): For const8* assert HOST_BITS_PER_WIDE_INT
rather than HOST_BITS_PER_LONG is >= 64.
(add_AT_long_long): Remove val_hi and val_lo arguments, add
val_const_double.
(size_of_die): Use HOST_BITS_PER_WIDE_INT size multiplier instead of
HOST_BITS_PER_LONG for dw_val_class_long_long.
(add_const_value_attribute): Adjust add_AT_long_long caller.
--- gcc/dwarf2out.c.jj 2009-07-30 17:18:53.000000000 +0200
+++ gcc/dwarf2out.c 2009-07-30 19:32:27.000000000 +0200
@@ -4111,15 +4111,6 @@ enum dw_val_class
dw_val_class_file
};
-/* Describe a double word constant value. */
-/* ??? Every instance of long_long in the code really means CONST_DOUBLE. */
-
-typedef struct GTY(()) dw_long_long_struct {
- unsigned long hi;
- unsigned long low;
-}
-dw_long_long_const;
-
/* Describe a floating point constant value, or a vector constant value. */
typedef struct GTY(()) dw_vec_struct {
@@ -4142,7 +4133,7 @@ typedef struct GTY(()) dw_val_struct {
dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc;
HOST_WIDE_INT GTY ((default)) val_int;
unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_unsigned_const"))) val_unsigned;
- dw_long_long_const GTY ((tag ("dw_val_class_long_long"))) val_long_long;
+ rtx GTY ((tag ("dw_val_class_long_long"))) val_long_long;
dw_vec_const GTY ((tag ("dw_val_class_vec"))) val_vec;
struct dw_val_die_union
{
@@ -4775,7 +4766,7 @@ output_loc_operands (dw_loc_descr_ref lo
break;
case DW_OP_const8u:
case DW_OP_const8s:
- gcc_assert (HOST_BITS_PER_LONG >= 64);
+ gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
dw2_asm_output_data (8, val1->v.val_int, NULL);
break;
case DW_OP_skip:
@@ -4821,17 +4812,17 @@ output_loc_operands (dw_loc_descr_ref lo
if (WORDS_BIG_ENDIAN)
{
- first = val2->v.val_long_long.hi;
- second = val2->v.val_long_long.low;
+ first = CONST_DOUBLE_HIGH (val2->v.val_long_long);
+ second = CONST_DOUBLE_LOW (val2->v.val_long_long);
}
else
{
- first = val2->v.val_long_long.low;
- second = val2->v.val_long_long.hi;
+ first = CONST_DOUBLE_LOW (val2->v.val_long_long);
+ second = CONST_DOUBLE_HIGH (val2->v.val_long_long);
}
- dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR,
+ dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
first, "long long constant");
- dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR,
+ dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
second, NULL);
}
break;
@@ -5011,7 +5002,7 @@ output_loc_operands_raw (dw_loc_descr_re
case DW_OP_const8u:
case DW_OP_const8s:
- gcc_assert (HOST_BITS_PER_LONG >= 64);
+ gcc_assert (HOST_BITS_PER_WIDE_INT >= 64);
fputc (',', asm_out_file);
dw2_asm_output_data_raw (8, val1->v.val_int);
break;
@@ -5746,8 +5737,7 @@ static void add_AT_int (dw_die_ref, enum
static inline HOST_WIDE_INT AT_int (dw_attr_ref);
static void add_AT_unsigned (dw_die_ref, enum dwarf_attribute, unsigned HOST_WIDE_INT);
static inline unsigned HOST_WIDE_INT AT_unsigned (dw_attr_ref);
-static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, unsigned long,
- unsigned long);
+static void add_AT_long_long (dw_die_ref, enum dwarf_attribute, rtx);
static inline void add_AT_vec (dw_die_ref, enum dwarf_attribute, unsigned int,
unsigned int, unsigned char *);
static hashval_t debug_str_do_hash (const void *);
@@ -6668,14 +6658,13 @@ AT_unsigned (dw_attr_ref a)
static inline void
add_AT_long_long (dw_die_ref die, enum dwarf_attribute attr_kind,
- long unsigned int val_hi, long unsigned int val_low)
+ rtx val_const_double)
{
dw_attr_node attr;
attr.dw_attr = attr_kind;
attr.dw_attr_val.val_class = dw_val_class_long_long;
- attr.dw_attr_val.v.val_long_long.hi = val_hi;
- attr.dw_attr_val.v.val_long_long.low = val_low;
+ attr.dw_attr_val.v.val_long_long = val_const_double;
add_dwarf_attr (die, &attr);
}
@@ -7535,9 +7524,10 @@ print_die (dw_die_ref die, FILE *outfile
fprintf (outfile, HOST_WIDE_INT_PRINT_UNSIGNED, AT_unsigned (a));
break;
case dw_val_class_long_long:
- fprintf (outfile, "constant (%lu,%lu)",
- a->dw_attr_val.v.val_long_long.hi,
- a->dw_attr_val.v.val_long_long.low);
+ fprintf (outfile, "constant (" HOST_WIDE_INT_PRINT_UNSIGNED
+ "," HOST_WIDE_INT_PRINT_UNSIGNED ")",
+ CONST_DOUBLE_HIGH (a->dw_attr_val.v.val_long_long),
+ CONST_DOUBLE_LOW (a->dw_attr_val.v.val_long_long));
break;
case dw_val_class_vec:
fprintf (outfile, "floating-point or vector constant");
@@ -7694,7 +7684,8 @@ attr_checksum (dw_attr_ref at, struct md
CHECKSUM (at->dw_attr_val.v.val_unsigned);
break;
case dw_val_class_long_long:
- CHECKSUM (at->dw_attr_val.v.val_long_long);
+ CHECKSUM (CONST_DOUBLE_HIGH (at->dw_attr_val.v.val_long_long));
+ CHECKSUM (CONST_DOUBLE_LOW (at->dw_attr_val.v.val_long_long));
break;
case dw_val_class_vec:
CHECKSUM (at->dw_attr_val.v.val_vec);
@@ -7794,8 +7785,10 @@ same_dw_val_p (const dw_val_node *v1, co
case dw_val_class_unsigned_const:
return v1->v.val_unsigned == v2->v.val_unsigned;
case dw_val_class_long_long:
- return v1->v.val_long_long.hi == v2->v.val_long_long.hi
- && v1->v.val_long_long.low == v2->v.val_long_long.low;
+ return CONST_DOUBLE_HIGH (v1->v.val_long_long)
+ == CONST_DOUBLE_HIGH (v2->v.val_long_long)
+ && CONST_DOUBLE_LOW (v1->v.val_long_long)
+ == CONST_DOUBLE_LOW (v2->v.val_long_long);
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)
@@ -8404,7 +8397,7 @@ size_of_die (dw_die_ref die)
size += constant_size (AT_unsigned (a));
break;
case dw_val_class_long_long:
- size += 1 + 2*HOST_BITS_PER_LONG/HOST_BITS_PER_CHAR; /* block */
+ size += 1 + 2*HOST_BITS_PER_WIDE_INT/HOST_BITS_PER_CHAR; /* block */
break;
case dw_val_class_vec:
size += constant_size (a->dw_attr_val.v.val_vec.length
@@ -8886,23 +8879,24 @@ output_die (dw_die_ref die)
unsigned HOST_WIDE_INT first, second;
dw2_asm_output_data (1,
- 2 * HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR,
+ 2 * HOST_BITS_PER_WIDE_INT
+ / HOST_BITS_PER_CHAR,
"%s", name);
if (WORDS_BIG_ENDIAN)
{
- first = a->dw_attr_val.v.val_long_long.hi;
- second = a->dw_attr_val.v.val_long_long.low;
+ first = CONST_DOUBLE_HIGH (a->dw_attr_val.v.val_long_long);
+ second = CONST_DOUBLE_LOW (a->dw_attr_val.v.val_long_long);
}
else
{
- first = a->dw_attr_val.v.val_long_long.low;
- second = a->dw_attr_val.v.val_long_long.hi;
+ first = CONST_DOUBLE_LOW (a->dw_attr_val.v.val_long_long);
+ second = CONST_DOUBLE_HIGH (a->dw_attr_val.v.val_long_long);
}
- dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR,
+ dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
first, "long long constant");
- dw2_asm_output_data (HOST_BITS_PER_LONG / HOST_BITS_PER_CHAR,
+ dw2_asm_output_data (HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR,
second, NULL);
}
break;
@@ -11571,7 +11565,8 @@ loc_descriptor (rtx rtl, enum machine_mo
or a floating-point constant. A CONST_DOUBLE is used whenever
the constant requires more than one word in order to be
adequately represented. We output CONST_DOUBLEs as blocks. */
- mode = GET_MODE (rtl);
+ if (GET_MODE (rtl) != VOIDmode)
+ mode = GET_MODE (rtl);
loc_result = new_loc_descr (DW_OP_implicit_value,
GET_MODE_SIZE (mode), 0);
@@ -11588,14 +11583,8 @@ loc_descriptor (rtx rtl, enum machine_mo
}
else
{
- /* ??? We really should be using HOST_WIDE_INT throughout. */
- gcc_assert (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT);
-
loc_result->dw_loc_oprnd2.val_class = dw_val_class_long_long;
- loc_result->dw_loc_oprnd2.v.val_long_long.hi
- = CONST_DOUBLE_HIGH (rtl);
- loc_result->dw_loc_oprnd2.v.val_long_long.low
- = CONST_DOUBLE_LOW (rtl);
+ loc_result->dw_loc_oprnd2.v.val_long_long = rtl;
}
}
break;
@@ -12568,13 +12557,7 @@ add_const_value_attribute (dw_die_ref di
add_AT_vec (die, DW_AT_const_value, length / 4, 4, array);
}
else
- {
- /* ??? We really should be using HOST_WIDE_INT throughout. */
- gcc_assert (HOST_BITS_PER_LONG == HOST_BITS_PER_WIDE_INT);
-
- add_AT_long_long (die, DW_AT_const_value,
- CONST_DOUBLE_HIGH (rtl), CONST_DOUBLE_LOW (rtl));
- }
+ add_AT_long_long (die, DW_AT_const_value, rtl);
}
break;
Jakub