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 take advantage of new freedoms


These days, we don't have to be as careful about nested functions
because of garbage collection, and we don't have to be as careful
about blocks because we don't maintain two separate numbering
schemes.  This patch updates various bits of code to take advantage of
that, for the sake of code cleanliness.

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

	* dwarf2out.c (dwarf2out_frame_debug): Add cast to silence warning.
	(dwarf2out_decl): Functions can now have DECL_IGNORED_P.
	(gen_decl_die): Likewise.
	* dwarfout.c (dwarfout_file_scope_decl): Likewise.
	(output_decl): Likewise.

	* toplev.c (rest_of_compilation): Tweak formatting.

cp/:
2000-03-03  Jason Merrill  <jason@casey.cygnus.com>

	* decl2.c (key_method): Break out from...
	(import_export_vtable, import_export_class): ...here.

	* decl.c (finish_function): Don't mess with flag_keep_inline_functions.
	* decl2.c (finish_vtable_vardecl): Don't check decl_function_context.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarf2out.c,v
retrieving revision 1.155
diff -c -p -r1.155 dwarf2out.c
*** dwarf2out.c	2000/02/29 23:33:48	1.155
--- dwarf2out.c	2000/03/03 23:55:50
*************** dwarf2out_frame_debug (insn)
*** 1355,1361 ****
      {
        /* Set up state for generating call frame debug info.  */
        lookup_cfa (&cfa_reg, &cfa_offset);
!       if (cfa_reg != DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM))
  	abort ();
        cfa_reg = STACK_POINTER_REGNUM;
        cfa_store_reg = cfa_reg;
--- 1355,1361 ----
      {
        /* Set up state for generating call frame debug info.  */
        lookup_cfa (&cfa_reg, &cfa_offset);
!       if (cfa_reg != (unsigned long) DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM))
  	abort ();
        cfa_reg = STACK_POINTER_REGNUM;
        cfa_store_reg = cfa_reg;
*************** gen_decl_die (decl, context_die)
*** 9296,9307 ****
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it. But don't 
!      ignore a function definition, since that would screw up our count of
!      blocks, and that in turn will completely screw up the labels we will 
!      reference in subsequent DW_AT_low_pc and DW_AT_high_pc attributes (for
!      subsequent blocks).  */
!   if (DECL_IGNORED_P (decl) && TREE_CODE (decl) != FUNCTION_DECL)
      return;
  
    switch (TREE_CODE (decl))
--- 9296,9303 ----
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  */
!   if (DECL_IGNORED_P (decl))
      return;
  
    switch (TREE_CODE (decl))
*************** dwarf2out_decl (decl)
*** 9460,9480 ****
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  We gotta 
!      hope that the node in question doesn't represent a function definition.
!      If it does, then totally ignoring it is bound to screw up our count of
!      blocks, and that in turn will completely screw up the labels we will 
!      reference in subsequent DW_AT_low_pc and DW_AT_high_pc attributes (for
!      subsequent blocks).  (It's too bad that BLOCK nodes don't carry their
!      own sequence numbers with them!) */
    if (DECL_IGNORED_P (decl))
!     {
!       if (TREE_CODE (decl) == FUNCTION_DECL
!           && DECL_INITIAL (decl) != NULL)
! 	abort ();
! 
!       return;
!     }
  
    switch (TREE_CODE (decl))
      {
--- 9456,9464 ----
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  */
    if (DECL_IGNORED_P (decl))
!     return;
  
    switch (TREE_CODE (decl))
      {
Index: dwarfout.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/dwarfout.c,v
retrieving revision 1.57
diff -c -p -r1.57 dwarfout.c
*** dwarfout.c	2000/03/01 00:02:32	1.57
--- dwarfout.c	2000/03/03 23:55:55
*************** output_decl (decl, containing_scope)
*** 4787,4799 ****
  	      && (TREE_CODE (TYPE_FIELDS (TREE_TYPE (decl))) == ERROR_MARK))))
      return;
    
!   /* If this ..._DECL node is marked to be ignored, then ignore it.
!      But don't ignore a function definition, since that would screw
!      up our count of blocks, and that it turn will completely screw up the
!      labels we will reference in subsequent AT_low_pc and AT_high_pc
!      attributes (for subsequent blocks).  */
  
!   if (DECL_IGNORED_P (decl) && TREE_CODE (decl) != FUNCTION_DECL)
      return;
  
    switch (TREE_CODE (decl))
--- 4787,4795 ----
  	      && (TREE_CODE (TYPE_FIELDS (TREE_TYPE (decl))) == ERROR_MARK))))
      return;
    
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  */
  
!   if (DECL_IGNORED_P (decl))
      return;
  
    switch (TREE_CODE (decl))
*************** dwarfout_file_scope_decl (decl, set_fina
*** 5133,5152 ****
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  We
!      gotta hope that the node in question doesn't represent a function
!      definition.  If it does, then totally ignoring it is bound to screw
!      up our count of blocks, and that it turn will completely screw up the
!      labels we will reference in subsequent AT_low_pc and AT_high_pc
!      attributes (for subsequent blocks).  (It's too bad that BLOCK nodes
!      don't carry their own sequence numbers with them!)  */
  
    if (DECL_IGNORED_P (decl))
!     {
!       if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL)
! 	abort ();
!       return;
!     }
  
    switch (TREE_CODE (decl))
      {
--- 5129,5138 ----
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
  
!   /* If this ..._DECL node is marked to be ignored, then ignore it.  */
  
    if (DECL_IGNORED_P (decl))
!     return;
  
    switch (TREE_CODE (decl))
      {
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.297
diff -c -p -r1.297 toplev.c
*** toplev.c	2000/02/29 23:33:48	1.297
--- toplev.c	2000/03/03 23:56:10
*************** rest_of_compilation (decl)
*** 2927,2944 ****
  	 finish_compilation will call rest_of_compilation again
  	 for those functions that need to be output.  Also defer those
  	 functions that we are supposed to defer.  */
- 
-       if (inlinable)
- 	DECL_DEFER_OUTPUT (decl) = 1;
  
!       if (DECL_DEFER_OUTPUT (decl)
  	  || (DECL_INLINE (decl)
  	      && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
  		   && ! flag_keep_inline_functions)
  		  || DECL_EXTERNAL (decl))))
! 	{
! 	  DECL_DEFER_OUTPUT (decl) = 1;
  
  	  /* If -Wreturn-type, we have to do a bit of compilation.
  	     However, if we just fall through we will call
  	     save_for_inline_copying() which results in excessive
--- 2928,2943 ----
  	 finish_compilation will call rest_of_compilation again
  	 for those functions that need to be output.  Also defer those
  	 functions that we are supposed to defer.  */
  
!       if (inlinable
  	  || (DECL_INLINE (decl)
  	      && ((! TREE_PUBLIC (decl) && ! TREE_ADDRESSABLE (decl)
  		   && ! flag_keep_inline_functions)
  		  || DECL_EXTERNAL (decl))))
! 	DECL_DEFER_OUTPUT (decl) = 1;
  
+       if (DECL_DEFER_OUTPUT (decl))
+ 	{
  	  /* If -Wreturn-type, we have to do a bit of compilation.
  	     However, if we just fall through we will call
  	     save_for_inline_copying() which results in excessive
Index: decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.556
diff -c -p -r1.556 decl.c
*** decl.c	2000/03/03 02:27:14	1.556
--- decl.c	2000/03/04 00:30:10
*************** finish_function (lineno, flags)
*** 13888,13908 ****
      {
        int returns_null;
        int returns_value;
-       int saved_flag_keep_inline_functions =
- 	flag_keep_inline_functions;
  
        /* So we can tell if jump_optimize sets it to 1.  */
        can_reach_end = 0;
  
-       if (DECL_CONTEXT (fndecl) != NULL_TREE
- 	  && decl_function_context (fndecl))
- 	/* Trick rest_of_compilation into not deferring output of this
- 	   function, even if it is inline, since the rtl_obstack for
- 	   this function is the function_obstack of the enclosing
- 	   function and will be deallocated when the enclosing
- 	   function is gone.  See save_tree_status.  */
- 	flag_keep_inline_functions = 1;
- 
        /* Before we call rest_of_compilation (which will pop the
  	 CURRENT_FUNCTION), we must save these values.  */
        returns_null = current_function_returns_null;
--- 13888,13897 ----
*************** finish_function (lineno, flags)
*** 13938,13945 ****
        /* Undo the call to ggc_push_context above.  */
        if (function_depth > 1)
  	ggc_pop_context ();
- 
-       flag_keep_inline_functions = saved_flag_keep_inline_functions;
  
        if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl))
  	{
--- 13927,13932 ----
Index: decl2.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl2.c,v
retrieving revision 1.314
diff -c -p -r1.314 decl2.c
*** decl2.c	2000/03/03 02:27:14	1.314
--- decl2.c	2000/03/04 00:30:14
*************** static int generate_ctor_and_dtor_functi
*** 92,97 ****
--- 92,98 ----
  static tree prune_vars_needing_no_initialization PARAMS ((tree));
  static void write_out_vars PARAMS ((tree));
  static void import_export_class	PARAMS ((tree));
+ static tree key_method PARAMS ((tree));
  
  extern int current_class_depth;
  
*************** maybe_make_one_only (decl)
*** 2378,2383 ****
--- 2379,2407 ----
      DECL_COMDAT (decl) = 1;
  }
  
+ /* Returns the virtual function with which the vtable for TYPE is
+    emitted, or NULL_TREE if that heuristic is not applicable to TYPE.  */
+ 
+ static tree
+ key_method (type)
+      tree type;
+ {
+   tree method;
+ 
+   if (TYPE_FOR_JAVA (type)
+       || CLASSTYPE_INTERFACE_KNOWN (type))
+     return NULL_TREE;
+ 
+   for (method = TYPE_METHODS (type); method != NULL_TREE;
+        method = TREE_CHAIN (method))
+     if (DECL_VINDEX (method) != NULL_TREE
+ 	&& ! DECL_THIS_INLINE (method)
+ 	&& ! DECL_PURE_VIRTUAL_P (method))
+       return method;
+ 
+   return NULL_TREE;
+ }
+ 
  /* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL,
     based on TYPE and other static flags.
  
*************** import_export_vtable (decl, type, final)
*** 2409,2430 ****
        /* We can only wait to decide if we have real non-inline virtual
  	 functions in our class, or if we come from a template.  */
  
!       int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type);
  
-       if (! found && ! final)
- 	{
- 	  tree method;
- 	  for (method = TYPE_METHODS (type); method != NULL_TREE;
- 	       method = TREE_CHAIN (method))
- 	    if (DECL_VINDEX (method) != NULL_TREE
- 		&& ! DECL_THIS_INLINE (method)
- 		&& ! DECL_PURE_VIRTUAL_P (method))
- 	      {
- 		found = 1;
- 		break;
- 	      }
- 	}
- 
        if (final || ! found)
  	{
  	  comdat_linkage (decl);
--- 2433,2441 ----
        /* We can only wait to decide if we have real non-inline virtual
  	 functions in our class, or if we come from a template.  */
  
!       int found = (CLASSTYPE_TEMPLATE_INSTANTIATION (type)
! 		   || key_method (type));
  
        if (final || ! found)
  	{
  	  comdat_linkage (decl);
*************** import_export_class (ctype)
*** 2482,2504 ****
      import_export = -1;
  
    /* Base our import/export status on that of the first non-inline,
!      non-abstract virtual function, if any.  */
    if (import_export == 0
        && TYPE_POLYMORPHIC_P (ctype)
        && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
      {
!       tree method;
!       for (method = TYPE_METHODS (ctype); method != NULL_TREE;
! 	   method = TREE_CHAIN (method))
! 	{
! 	  if (DECL_VINDEX (method) != NULL_TREE
! 	      && !DECL_THIS_INLINE (method)
! 	      && !DECL_PURE_VIRTUAL_P (method))
! 	    {
! 	      import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
! 	      break;
! 	    }
! 	}
      }
  
  #ifdef MULTIPLE_SYMBOL_SPACES
--- 2493,2506 ----
      import_export = -1;
  
    /* Base our import/export status on that of the first non-inline,
!      non-pure virtual function, if any.  */
    if (import_export == 0
        && TYPE_POLYMORPHIC_P (ctype)
        && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype))
      {
!       tree method = key_method (ctype);
!       if (method)
! 	import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1);
      }
  
  #ifdef MULTIPLE_SYMBOL_SPACES
*************** finish_vtable_vardecl (t, data)
*** 2552,2559 ****
    import_export_vtable (vars, ctype, 1);
  
    if (! DECL_EXTERNAL (vars)
!       && (DECL_NEEDED_P (vars)
! 	  || (decl_function_context (vars) && TREE_USED (vars)))
        && ! TREE_ASM_WRITTEN (vars))
      {
        if (TREE_TYPE (vars) == void_type_node)
--- 2554,2560 ----
    import_export_vtable (vars, ctype, 1);
  
    if (! DECL_EXTERNAL (vars)
!       && DECL_NEEDED_P (vars)
        && ! TREE_ASM_WRITTEN (vars))
      {
        if (TREE_TYPE (vars) == void_type_node)

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