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]

Patch to dwarf inline handling


The functions-as-trees changes in the C++ frontend have broken the old
invariant that the out-of-line copy of an inline function (if any)
would be emitted from output_inline_function, so set_decl_origin_self
wasn't being called.  This patch moves that call into the dwarf
backends, improving modularity.  It also limits the division of the
debug info into abstract and concrete instances to actual inlines;
previously we also did this for normal functions that weren't being
emitted immediately for whatever reason.

A couple of other small dwarf bugfixes are included.

2000-04-26  Jason Merrill  <jason@casey.cygnus.com>

	* dwarf2out.c (add_bound_info): Don't crash on an unexpanded SAVE_EXPR.

	* dwarfout.c (output_decl): Ignore NAMESPACE_DECLs.

	* dwarf2out.c (gen_subprogram_die): The class-scope declaration DIE
	is the primary DIE for a member function.
	(gen_decl_die): Call set_decl_origin_self here.
	* dwarfout.c (output_decl): And here.
	* integrate.c (output_inline_function): Not here.
	Don't clear DECL_INLINE until after calling rest_of_compilation.
	(set_decl_origin_self): No longer static.
	* tree.h: Add prototype.
	* toplev.c (note_deferral_of_defined_inline_function): Only write
	out abstract instance for actual inlines.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.170
diff -c -p -r1.170 dwarf2out.c
*** dwarf2out.c	2000/04/19 19:26:17	1.170
--- dwarf2out.c	2000/04/26 00:28:00
*************** add_bound_info (subrange_die, bound_attr
*** 7119,7125 ****
  	 We assume that a MEM rtx is safe because gcc wouldn't put the
  	 value there unless it was going to be used repeatedly in the
  	 function, i.e. for cleanups.  */
!       if (! optimize || GET_CODE (SAVE_EXPR_RTL (bound)) == MEM)
  	{
  	  register dw_die_ref ctx = lookup_decl_die (current_function_decl);
  	  register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
--- 7119,7126 ----
  	 We assume that a MEM rtx is safe because gcc wouldn't put the
  	 value there unless it was going to be used repeatedly in the
  	 function, i.e. for cleanups.  */
!       if (! optimize || (SAVE_EXPR_RTL (bound)
! 			 && GET_CODE (SAVE_EXPR_RTL (bound)) == MEM))
  	{
  	  register dw_die_ref ctx = lookup_decl_die (current_function_decl);
  	  register dw_die_ref decl_die = new_die (DW_TAG_variable, ctx);
*************** gen_unspecified_parameters_die (decl_or_
*** 8006,8018 ****
  /* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a
     DW_TAG_unspecified_parameters DIE) to represent the types of the formal
     parameters as specified in some function type specification (except for
!    those which appear as part of a function *definition*).
  
-    Note we must be careful here to output all of the parameter DIEs before*
-    we output any DIEs needed to represent the types of the formal parameters.
-    This keeps svr4 SDB happy because it (incorrectly) thinks that the first
-    non-parameter DIE it sees ends the formal parameter list.  */
- 
  static void
  gen_formal_types_die (function_or_method_type, context_die)
       register tree function_or_method_type;
--- 8007,8014 ----
  /* Generate a list of nameless DW_TAG_formal_parameter DIEs (and perhaps a
     DW_TAG_unspecified_parameters DIE) to represent the types of the formal
     parameters as specified in some function type specification (except for
!    those which appear as part of a function *definition*).  */
  
  static void
  gen_formal_types_die (function_or_method_type, context_die)
       register tree function_or_method_type;
*************** gen_subprogram_die (decl, context_die)
*** 8151,8156 ****
--- 8147,8160 ----
       case, `declaration' takes priority; we'll get back to the abstract
       instance when we're done with the class.  */
  
+   /* The class-scope declaration DIE must be the primary DIE.  */
+   if (origin && declaration && class_scope_p (context_die))
+     {
+       origin = NULL;
+       if (old_die)
+ 	abort ();
+     }
+ 
    if (origin != NULL)
      {
        if (declaration && ! local_scope_p (context_die))
*************** gen_decl_die (decl, context_die)
*** 9322,9331 ****
  	  && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
  	break;
  
!       /* Emit info for the abstract instance first, if we haven't yet.  */
!       origin = decl_ultimate_origin (decl);
!       if (origin)
! 	gen_abstract_function (origin);
  
        if (debug_info_level > DINFO_LEVEL_TERSE)
  	{
--- 9326,9339 ----
  	  && (current_function_decl == NULL_TREE || DECL_ARTIFICIAL (decl)))
  	break;
  
!       /* If we're emitting an out-of-line copy of an inline function,
! 	 emit info for the abstract instance and set up to refer to it.  */
!       if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
! 	  && ! class_scope_p (context_die))
! 	{
! 	  gen_abstract_function (decl);
! 	  set_decl_origin_self (decl);
! 	}
  
        if (debug_info_level > DINFO_LEVEL_TERSE)
  	{
Index: dwarfout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarfout.c,v
retrieving revision 1.63
diff -c -p -r1.63 dwarfout.c
*** dwarfout.c	2000/03/23 00:40:56	1.63
--- dwarfout.c	2000/04/26 00:28:04
*************** output_decl (decl, containing_scope)
*** 4791,4796 ****
--- 4791,4803 ----
  	  output_type (origin, containing_scope);
        }
  
+       /* If we're emitting an out-of-line copy of an inline function,
+ 	 set up to refer to the abstract instance emitted from
+ 	 note_deferral_of_defined_inline_function.  */
+       if (DECL_INLINE (decl) && ! DECL_ABSTRACT (decl)
+ 	  && ! (containing_scope && TYPE_P (containing_scope)))
+ 	set_decl_origin_self (decl);
+ 
        /* If the following DIE will represent a function definition for a
  	 function with "extern" linkage, output a special "pubnames" DIE
  	 label just ahead of the actual DIE.  A reference to this label
*************** output_decl (decl, containing_scope)
*** 5082,5087 ****
--- 5089,5098 ----
  
        output_type (TREE_TYPE (decl), containing_scope);
        output_die (output_formal_parameter_die, decl);
+       break;
+ 
+     case NAMESPACE_DECL:
+       /* Ignore for now.  */
        break;
  
      default:
Index: integrate.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/integrate.c,v
retrieving revision 1.102
diff -c -p -r1.102 integrate.c
*** integrate.c	2000/04/25 21:10:26	1.102
--- integrate.c	2000/04/26 00:28:06
*************** integrate.c		PARAMS 
*** 78,84 ****
  static void subst_constants		PARAMS ((rtx *, rtx,
  						 struct inline_remap *, int));
  static void set_block_origin_self	PARAMS ((tree));
- static void set_decl_origin_self	PARAMS ((tree));
  static void set_block_abstract_flags	PARAMS ((tree, int));
  static void process_reg_param		PARAMS ((struct inline_remap *, rtx,
  						 rtx));
--- 78,83 ----
*************** set_block_origin_self (stmt)
*** 2647,2653 ****
     set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to
     point to themselves.  */
  
! static void
  set_decl_origin_self (decl)
       register tree decl;
  {
--- 2646,2652 ----
     set *their* DECL_ABSTRACT_ORIGIN or BLOCK_ABSTRACT_ORIGIN values to
     point to themselves.  */
  
! void
  set_decl_origin_self (decl)
       register tree decl;
  {
*************** output_inline_function (fndecl)
*** 2738,2753 ****
  
    set_new_last_label_num (f->inl_max_label_num);
  
!   /* We must have already output DWARF debugging information for the
!      original (abstract) inline function declaration/definition, so
!      we want to make sure that the debugging information we generate
!      for this special instance of the inline function refers back to
!      the information we already generated.  To make sure that happens,
!      we simply have to set the DECL_ABSTRACT_ORIGIN for the function
!      node (and for all of the local ..._DECL nodes which are its children)
!      so that they all point to themselves.  */
! 
!   set_decl_origin_self (fndecl);
  
    /* We're not deferring this any longer.  */
    DECL_DEFER_OUTPUT (fndecl) = 0;
--- 2737,2744 ----
  
    set_new_last_label_num (f->inl_max_label_num);
  
!   /* Compile this function all the way down to assembly code.  */
!   rest_of_compilation (fndecl);
  
    /* We're not deferring this any longer.  */
    DECL_DEFER_OUTPUT (fndecl) = 0;
*************** output_inline_function (fndecl)
*** 2755,2763 ****
    /* We can't inline this anymore.  */
    f->inlinable = 0;
    DECL_INLINE (fndecl) = 0;
- 
-   /* Compile this function all the way down to assembly code.  */
-   rest_of_compilation (fndecl);
  
    cfun = old_cfun;
    current_function_decl = old_cfun ? old_cfun->decl : 0;
--- 2746,2751 ----
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.322
diff -c -p -r1.322 toplev.c
*** toplev.c	2000/04/25 10:13:17	1.322
--- toplev.c	2000/04/26 00:28:12
*************** note_deferral_of_defined_inline_function
*** 2727,2733 ****
    /* Generate the DWARF info for the "abstract" instance of a function
       which we may later generate inlined and/or out-of-line instances
       of.  */
!   if (write_symbols == DWARF_DEBUG)
      {
        /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
  	 DWARF code expects it to be set in this case.  Intuitively,
--- 2727,2733 ----
    /* Generate the DWARF info for the "abstract" instance of a function
       which we may later generate inlined and/or out-of-line instances
       of.  */
!   if (write_symbols == DWARF_DEBUG && DECL_INLINE (decl))
      {
        /* The front-end may not have set CURRENT_FUNCTION_DECL, but the
  	 DWARF code expects it to be set in this case.  Intuitively,
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.163
diff -c -p -r1.163 tree.h
*** tree.h	2000/04/25 12:15:25	1.163
--- tree.h	2000/04/26 00:28:14
*************** tree.h	PARAM
*** 2567,2572 ****
--- 2567,2573 ----
  extern void save_for_inline_copying	PARAMS ((tree));
  extern void set_decl_abstract_flags	PARAMS ((tree, int));
  extern void output_inline_function	PARAMS ((tree));
+ extern void set_decl_origin_self	PARAMS ((tree));
  
  /* In c-lex.c */
  extern void set_yydebug			PARAMS ((int));
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.595
diff -c -p -r1.595 decl.c
*** cp/decl.c	2000/04/25 05:59:26	1.595
--- cp/decl.c	2000/04/26 00:28:48
*************** finish_function (flags)
*** 14173,14194 ****
  
        /* Run the optimizers and output the assembler code for this
           function.  */
!       if (DECL_ARTIFICIAL (fndecl))
! 	{
! 	  /* Do we really *want* to inline this synthesized method?  */
! 
! 	  int save_fif = flag_inline_functions;
! 	  flag_inline_functions = 1;
! 
! 	  /* Turn off DECL_INLINE for the moment so function_cannot_inline_p
! 	     will check our size.  */
! 	  DECL_INLINE (fndecl) = 0;
! 
! 	  rest_of_compilation (fndecl);
! 	  flag_inline_functions = save_fif;
! 	}
!       else
! 	rest_of_compilation (fndecl);
  
        /* Undo the call to ggc_push_context above.  */
        if (function_depth > 1)
--- 14173,14179 ----
  
        /* Run the optimizers and output the assembler code for this
           function.  */
!       rest_of_compilation (fndecl);
  
        /* Undo the call to ggc_push_context above.  */
        if (function_depth > 1)

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