re PR debug/35896 (gfortran TLS symbols broken with debug info)

PR debug/35896
	* dwarf2out.c (dw_expand_expr, common_check): Removed.
	(fortran_common): New function.
	(gen_variable_die): Call fortran_common instead of common_check,
	adjust for it returning tree instead of rtx.    Formatting.

From-SVN: r135060
This commit is contained in:
Jakub Jelinek 2008-05-08 01:15:50 +02:00 committed by Jakub Jelinek
parent 4218dc2db0
commit 1f16b47cd0
2 changed files with 49 additions and 136 deletions

View File

@ -3,6 +3,12 @@
* tree-parloops.c (create_parallel_loop): Set OMP_RETURN_NOWAIT * tree-parloops.c (create_parallel_loop): Set OMP_RETURN_NOWAIT
on OMP_RETURN for OMP_FOR. on OMP_RETURN for OMP_FOR.
PR debug/35896
* dwarf2out.c (dw_expand_expr, common_check): Removed.
(fortran_common): New function.
(gen_variable_die): Call fortran_common instead of common_check,
adjust for it returning tree instead of rtx. Formatting.
2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com> 2008-05-07 Kenneth Zadeck <zadeck@naturalbridge.com>
PATCH rtl/7335 PATCH rtl/7335

View File

@ -10527,63 +10527,6 @@ rtl_for_decl_init (tree init, tree type)
return rtl; return rtl;
} }
/* This is a specialized subset of expand_expr to evaluate a DECL_VALUE_EXPR.
We stop if we find decls that haven't been expanded, or if the expression is
getting so complex we won't be able to represent it anyway. Returns NULL on
failure. */
static rtx
dw_expand_expr (tree expr)
{
switch (TREE_CODE (expr))
{
case VAR_DECL:
case PARM_DECL:
if (DECL_HAS_VALUE_EXPR_P (expr))
return dw_expand_expr (DECL_VALUE_EXPR (expr));
/* FALLTHRU */
case CONST_DECL:
case RESULT_DECL:
return DECL_RTL_IF_SET (expr);
case INTEGER_CST:
return expand_expr (expr, NULL_RTX, VOIDmode, EXPAND_INITIALIZER);
case COMPONENT_REF:
case ARRAY_REF:
case ARRAY_RANGE_REF:
case BIT_FIELD_REF:
{
enum machine_mode mode;
HOST_WIDE_INT bitsize, bitpos;
tree offset, tem;
int volatilep = 0, unsignedp = 0;
rtx x;
tem = get_inner_reference (expr, &bitsize, &bitpos, &offset,
&mode, &unsignedp, &volatilep, true);
x = dw_expand_expr (tem);
if (x == NULL || !MEM_P (x))
return NULL;
if (offset != NULL)
{
if (!host_integerp (offset, 0))
return NULL;
x = adjust_address_nv (x, mode, tree_low_cst (offset, 0));
}
if (bitpos != 0)
x = adjust_address_nv (x, mode, bitpos / BITS_PER_UNIT);
return x;
}
default:
return NULL;
}
}
/* Generate RTL for the variable DECL to represent its location. */ /* Generate RTL for the variable DECL to represent its location. */
static rtx static rtx
@ -10820,86 +10763,50 @@ secname_for_decl (const_tree decl)
If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the If so, the rtx for the SYMBOL_REF for the COMMON block is returned, and the
value is the offset into the common block for the symbol. */ value is the offset into the common block for the symbol. */
static rtx static tree
common_check (tree decl, HOST_WIDE_INT *value) fortran_common (tree decl, HOST_WIDE_INT *value)
{ {
rtx home; tree val_expr, cvar;
rtx sym_addr; enum machine_mode mode;
rtx res = NULL_RTX; HOST_WIDE_INT bitsize, bitpos;
tree offset;
int volatilep = 0, unsignedp = 0;
/* If the decl isn't a VAR_DECL, or if it isn't public or static, or if /* If the decl isn't a VAR_DECL, or if it isn't public or static, or if
it does not have a value (the offset into the common area), or if it it does not have a value (the offset into the common area), or if it
is thread local (as opposed to global) then it isn't common, and shouldn't is thread local (as opposed to global) then it isn't common, and shouldn't
be handled as such. */ be handled as such. */
if (TREE_CODE (decl) != VAR_DECL if (TREE_CODE (decl) != VAR_DECL
|| !TREE_PUBLIC(decl) || !TREE_PUBLIC (decl)
|| !TREE_STATIC(decl) || !TREE_STATIC (decl)
|| !DECL_HAS_VALUE_EXPR_P(decl) || !DECL_HAS_VALUE_EXPR_P (decl)
|| DECL_THREAD_LOCAL_P (decl) || !is_fortran ())
|| !is_fortran()) return NULL_TREE;
return NULL;
home = DECL_RTL (decl); val_expr = DECL_VALUE_EXPR (decl);
if (home == NULL_RTX || GET_CODE (home) != MEM) if (TREE_CODE (val_expr) != COMPONENT_REF)
return NULL; return NULL_TREE;
sym_addr = dw_expand_expr (DECL_VALUE_EXPR (decl)); cvar = get_inner_reference (val_expr, &bitsize, &bitpos, &offset,
if (sym_addr == NULL_RTX || GET_CODE (sym_addr) != MEM) &mode, &unsignedp, &volatilep, true);
return NULL;
sym_addr = XEXP (sym_addr, 0); if (cvar == NULL_TREE
if (GET_CODE (sym_addr) == CONST) || TREE_CODE (cvar) != VAR_DECL
sym_addr = XEXP (sym_addr, 0); || DECL_ARTIFICIAL (cvar)
if ((GET_CODE (sym_addr) == SYMBOL_REF || GET_CODE (sym_addr) == PLUS) || !TREE_PUBLIC (cvar))
&& DECL_INITIAL (decl) == 0) return NULL_TREE;
*value = 0;
if (offset != NULL)
{ {
if (!host_integerp (offset, 0))
/* We have a sym that will go into a common area, meaning that it return NULL_TREE;
will get storage reserved with a .comm/.lcomm assembler pseudo-op. *value = tree_low_cst (offset, 0);
Determine name of common area this symbol will be an offset into,
and offset into that area. Also retrieve the decl for the area
that the symbol is offset into. */
tree cdecl = NULL;
switch (GET_CODE (sym_addr))
{
case PLUS:
if (GET_CODE (XEXP (sym_addr, 0)) == CONST_INT)
{
res = XEXP (sym_addr, 1);
*value = INTVAL (XEXP (sym_addr, 0));
cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 1));
}
else
{
res = XEXP (sym_addr, 0);
*value = INTVAL (XEXP (sym_addr, 1));
cdecl = SYMBOL_REF_DECL (XEXP (sym_addr, 0));
}
break;
case SYMBOL_REF:
res = sym_addr;
*value = 0;
cdecl = SYMBOL_REF_DECL (sym_addr);
break;
default:
error ("common symbol debug info is not structured as "
"symbol+offset");
}
/* Check area common symbol is offset into. If this is not public, then
it is not a symbol in a common block. It must be a .lcomm symbol, not
a .comm symbol. */
if (cdecl == NULL || !TREE_PUBLIC(cdecl))
res = NULL_RTX;
} }
else if (bitpos != 0)
res = NULL_RTX; *value += bitpos / BITS_PER_UNIT;
return res; return cvar;
} }
@ -12800,7 +12707,7 @@ static void
gen_variable_die (tree decl, dw_die_ref context_die) gen_variable_die (tree decl, dw_die_ref context_die)
{ {
HOST_WIDE_INT off; HOST_WIDE_INT off;
rtx csym; tree com_decl;
dw_die_ref var_die; dw_die_ref var_die;
tree origin = decl_ultimate_origin (decl); tree origin = decl_ultimate_origin (decl);
dw_die_ref old_die = lookup_decl_die (decl); dw_die_ref old_die = lookup_decl_die (decl);
@ -12826,31 +12733,31 @@ gen_variable_die (tree decl, dw_die_ref context_die)
&& DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl)) && DECL_COMDAT (decl) && !TREE_ASM_WRITTEN (decl))
|| class_or_namespace_scope_p (context_die)); || class_or_namespace_scope_p (context_die));
csym = common_check (decl, &off); com_decl = fortran_common (decl, &off);
/* Symbol in common gets emitted as a child of the common block, in the form /* Symbol in common gets emitted as a child of the common block, in the form
of a data member. of a data member.
??? This creates a new common block die for every common block symbol. ??? This creates a new common block die for every common block symbol.
Better to share same common block die for all symbols in that block. */ Better to share same common block die for all symbols in that block. */
if (csym) if (com_decl)
{ {
tree blok; tree field;
dw_die_ref com_die; dw_die_ref com_die;
const char *cnam = targetm.strip_name_encoding(XSTR (csym, 0)); const char *cnam = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (com_decl));
dw_loc_descr_ref loc = mem_loc_descriptor (csym, dw_val_class_addr, dw_loc_descr_ref loc = loc_descriptor_from_tree (com_decl);
VAR_INIT_STATUS_INITIALIZED);
blok = (tree) TREE_OPERAND (DECL_VALUE_EXPR (decl), 0); field = TREE_OPERAND (DECL_VALUE_EXPR (decl), 0);
var_die = new_die (DW_TAG_common_block, context_die, decl); var_die = new_die (DW_TAG_common_block, context_die, decl);
add_name_and_src_coords_attributes (var_die, blok); add_name_and_src_coords_attributes (var_die, field);
add_AT_flag (var_die, DW_AT_external, 1); add_AT_flag (var_die, DW_AT_external, 1);
add_AT_loc (var_die, DW_AT_location, loc); add_AT_loc (var_die, DW_AT_location, loc);
com_die = new_die (DW_TAG_member, var_die, decl); com_die = new_die (DW_TAG_member, var_die, decl);
add_name_and_src_coords_attributes (com_die, decl); add_name_and_src_coords_attributes (com_die, decl);
add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl), add_type_attribute (com_die, TREE_TYPE (decl), TREE_READONLY (decl),
TREE_THIS_VOLATILE (decl), context_die); TREE_THIS_VOLATILE (decl), context_die);
add_AT_loc (com_die, DW_AT_data_member_location, int_loc_descriptor(off)); add_AT_loc (com_die, DW_AT_data_member_location,
int_loc_descriptor (off));
add_pubname_string (cnam, var_die); /* ??? needed? */ add_pubname_string (cnam, var_die); /* ??? needed? */
return; return;
} }