This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[lto] fix TYPE_DECL reading/writing


The patch below tweaks the recently-added support for reading/writing
TYPE_DECLs to work as advertised.

The base problem--why this support was added in the first place--is that
TYPE_DECLs find themselves chained into the local variables for a
function (e.g. in gcc.c:used_arg, the declaration for 'struct
mswitchstr' appears in the chain of local variables) and we need to
reconstitute that from LTO objects.  The difficulty with this is that
the dwarf writer is very choosy about what sort of TYPE_DECLs it deigns
to emit to the debug info.  The example given above is an instance where
the dwarf writer decided that a DIE for that declaration wasn't needed.
In fact, most instances of local TYPE_DECLs (exhaustively examined by
running gcc/*.c through 'gcc -flto') have this quality of being ignored
by the dwarf writer.  This is suboptimal for our purposes and also
causes asserts in the pseudo-code sequence:

  if (die_exists_for (typedecl))
    return it
  else
    generate_die_for (typedecl)		/* try really hard */
    gcc_assert (die_exists_for (typedecl)
    return it

which reflects roughly what the dwarf writer does.

The initial impulse is to "fix" the dwarf writer by making it pay
attention to such TYPE_DECLs.  DannyB assured me that this was the wrong
solution, as the output generated in this process would make gcc eat my
hard drive.

The chosen fix is to notice that all these TYPE_DECLs we want to dump
seem to have a NULL DECL_NAME, so all we really care about
reconstituting is the TREE_TYPE.  lto_typedecl_ref (writing side) and
lto_resolve_typedecl_ref (reading side) were therefore changed to dump
only the TREE_TYPE and reconstitute the TYPE_DECL, respectively.  It's
possible that some TYPE_DECL that we wish to dump in this fashion will
have a non-NULL DECL_NAME, but that is a task for later.

Along the way, we also realized that all the support for TYPE_DECLs had
not yet been fleshed out--lto_{flags,types}_needed_for had not be
updated--and the code to read in the TYPE_DECLs was not computing the
proper offset for where the TYPE_DECLs began in the section.

The patch also includes a small fix: we were inhibiting the generation
of dwarf frame information while we were emitting early debug
information for a function.  This is the right idea, but the scope of
the inhibition needs to be widened slightly or we get segfaults in
unusual places that also force output of dwarf.

This still doesn't fix everything where TYPE_DECLs are concerned; we now
get weird GC lossage when reading in such files, but this is at least
forward progress.

Committed to the LTO branch.

-Nathan

gcc/
	* lto-function.c (output_expr_operand): Assert that DECL_NAME of a
	TYPE_DECL is NULL, as it should be for function-local TYPE_DECLs.
	(lto_static_init): Reset the bit for TYPE_DECLs in
	lto_flags_needed_for and lto_types_needed_for.
	(generate_early_dwarf_information): Move the setting of
	dwarf2_generate_frame_info_p to...
	(lto_output): ...here.
	* dwarf2out.c (force_decl_die): Don't handle TYPE_DECL.
	(lto_typedecl_ref): Dump a reference to the decl's type instead of
	the decl itself.

gcc/lto/
	* lto.c (lto_read_typedef_DIE): Fix comment typo.
	(lto_resolve_typedecl_ref): Fetch the referred-to type and build a fake
	TYPE_DECL for it.
	* lto-read.c (lto_read_body): Use correct sizes for calculating
	type_decls_offset and types_offset.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 129768)
+++ lto-function-out.c	(working copy)
@@ -1384,7 +1384,10 @@ output_expr_operand (struct output_block
 	new = output_decl_index (ob->main_stream, ob->type_decl_hash_table,
 				 &ob->next_type_decl_index, expr);
 	if (new)
-	  VEC_safe_push (tree, heap, ob->type_decls, expr);
+          {
+            gcc_assert (!DECL_NAME (expr));
+            VEC_safe_push (tree, heap, ob->type_decls, expr);
+          }
       }
       break;
 
@@ -2074,6 +2077,7 @@ lto_static_init (void)
   RESET_BIT (lto_flags_needed_for, PARM_DECL);
   RESET_BIT (lto_flags_needed_for, SSA_NAME);
   RESET_BIT (lto_flags_needed_for, VAR_DECL);
+  RESET_BIT (lto_flags_needed_for, TYPE_DECL);
 
   lto_types_needed_for = sbitmap_alloc (NUM_TREE_CODES);
 
@@ -2094,6 +2098,7 @@ lto_static_init (void)
   RESET_BIT (lto_types_needed_for, SSA_NAME);
   RESET_BIT (lto_types_needed_for, SWITCH_EXPR);
   RESET_BIT (lto_types_needed_for, VAR_DECL);
+  RESET_BIT (lto_types_needed_for, TYPE_DECL);
 #else
   /* These forms will need types, even when the type system is fixed.  */
   SET_BIT (lto_types_needed_for, COMPLEX_CST);
@@ -2154,12 +2159,7 @@ static void
 generate_early_dwarf_information (tree function)
 {
   /* Don't bother with frame information, since we have no RTL.  */
-  dwarf2_generate_frame_info_p = false;
-
   dwarf2out_decl (function);
-
-  /* Later passes, however, will need frame information.  */
-  dwarf2_generate_frame_info_p = true;
 }
 
 /* Output FN.  */
@@ -2273,6 +2273,9 @@ lto_output (void)
 
   lto_static_init_local ();
 
+  /* We have no RTL at this point.  */
+  dwarf2_generate_frame_info_p = false;
+
   /* Process only the fuctions with bodies and only process the master
      ones of them.  */
   for (node = cgraph_nodes; node; node = node->next)
@@ -2290,6 +2293,8 @@ lto_output (void)
   if (saved_section)
     switch_to_section (saved_section);
 
+  dwarf2_generate_frame_info_p = true;
+
   return 0;
 }
 
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 129768)
+++ dwarf2out.c	(working copy)
@@ -13518,7 +13518,6 @@ force_decl_die (tree decl)
 	  DECL_EXTERNAL (decl) = saved_external_flag;
 	  break;
 
-	case TYPE_DECL:
 	case NAMESPACE_DECL:
 	  dwarf2out_decl (decl);
 	  break;
@@ -15160,10 +15159,10 @@ lto_typedecl_ref (tree decl, lto_out_ref
 
   gcc_assert (TREE_CODE (decl) == TYPE_DECL);
 
-  /* Generate the DIE for DECL.  */
-  die = force_decl_die (decl);
-  /* Construct the reference.  */
-  lto_init_ref (ref, die, DECL_CONTEXT (decl));
+  /* These should be nameless decls generated by the front-end for local typedefs.  */
+  gcc_assert (!DECL_NAME (decl));
+  /* Just use the reference to TREE_TYPE.  */
+  lto_type_ref (TREE_TYPE (decl), ref);
 }
 
 #else
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 129768)
+++ lto/lto.c	(working copy)
@@ -2710,7 +2710,7 @@ lto_read_typedef_DIE (lto_info_fd *fd,
   TYPE_NAME (type) = decl;
   DECL_ORIGINAL_TYPE (decl) = base_type;
 
-  /* Store this future references in our children.  */
+  /* Store this for future references in our children.  */
   lto_cache_store_DIE (fd, die, type);
 
   lto_read_child_DIEs (fd, abbrev, context);
@@ -3543,30 +3543,16 @@ lto_resolve_field_ref (lto_info_fd *info
   return field;
 }
 
+/* Fetch the type specified and build a fake TYPE_DECL to represent it.  */
+
 tree 
 lto_resolve_typedecl_ref (lto_info_fd *info_fd,
 			  lto_context *context,
 			  const lto_ref *ref)
 {
-  lto_die_ptr die;
-  lto_context *new_context = context;
-  tree decl;
-
-  /* At present, we only support a single DWARF section.  */
-  if (ref->section != 0)
-    lto_abi_mismatch_error ();
-  /* Map REF to a DIE.  */
-  die = lto_resolve_reference (info_fd, ref->offset, context, &new_context);
-  /* Map DIE to a decl.  */
-  decl = lto_read_DIE_at_ptr (info_fd, context, die);
-  if (!decl || TREE_CODE (decl) != TYPE_DECL)
-    lto_file_corrupt_error ((lto_fd *)info_fd);
-
-  /* Clean up.  */
-  if (new_context != context)
-    XDELETE (new_context);
+  tree type = lto_resolve_type_ref (info_fd, context, ref);
 
-  return decl;
+  return build_decl (TYPE_DECL, NULL_TREE, type);
 }
 
 void
Index: lto/lto-read.c
===================================================================
--- lto/lto-read.c	(revision 129768)
+++ lto/lto-read.c	(working copy)
@@ -1719,9 +1719,9 @@ lto_read_body (lto_info_fd *fd,
   int32_t vars_offset 
     = fns_offset + (header->num_fn_decls * sizeof (lto_ref));
   int32_t type_decls_offset 
-    = vars_offset + (header->num_type_decls * sizeof (lto_ref));
+    = vars_offset + (header->num_var_decls * sizeof (lto_ref));
   int32_t types_offset 
-    = type_decls_offset + (header->num_var_decls * sizeof (lto_ref));
+    = type_decls_offset + (header->num_type_decls * sizeof (lto_ref));
   int32_t named_label_offset 
     = types_offset + (header->num_types * sizeof (lto_ref));
   int32_t ssa_names_offset 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]