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]

Empty constructor removal


Hi,
this patch implements removal of pure static constructors and destructors as
discussed in PR45307.

The main part of patch makes DECL_STATIC_CONSTRUCTOR/DECL_STATIC_DESTRUCTOR to
no longer imply needed flag that makes it neccesary to handle them correctly at
few places.  Motivation for this change was not the empty constructor removal
idea, but I need it to implement constructor merging pass that is intended to
speedup mozilla (and other large C++ projects) startup times with LTO.

Bootstrapped/regtested x86_64-linux, will commit it tonight if there are no
complains.

	PR c++/45307
	* cgraph.h (cgraph_only_called_directly_p,
	cgraph_can_remove_if_no_direct_calls_and_refs_p): Handle
	static cdtors.
	* cgraphunit.c (cgraph_decide_is_function_needed): Static cdtors
	are not needed.
	(cgraph_finalize_function): Static cdtors are reachable.
	(cgraph_mark_functions_to_output): Use cgraph_only_called_directly_p.

	* gcc.dg/ipa/ctor-empty-1.c: Add testcase.
Index: cgraph.h
===================================================================
*** cgraph.h	(revision 163398)
--- cgraph.h	(working copy)
*************** varpool_node_set_nonempty_p (varpool_nod
*** 903,909 ****
  static inline bool
  cgraph_only_called_directly_p (struct cgraph_node *node)
  {
!   return !node->needed && !node->address_taken && !node->local.externally_visible;
  }
  
  /* Return true when function NODE can be removed from callgraph
--- 903,912 ----
  static inline bool
  cgraph_only_called_directly_p (struct cgraph_node *node)
  {
!   return (!node->needed && !node->address_taken
! 	  && !DECL_STATIC_CONSTRUCTOR (node->decl)
! 	  && !DECL_STATIC_DESTRUCTOR (node->decl)
! 	  && !node->local.externally_visible);
  }
  
  /* Return true when function NODE can be removed from callgraph
*************** cgraph_only_called_directly_p (struct cg
*** 912,919 ****
  static inline bool
  cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
  {
!   return (!node->needed && !node->reachable_from_other_partition
!   	  && (DECL_COMDAT (node->decl) || !node->local.externally_visible));
  }
  
  /* Return true when function NODE can be removed from callgraph
--- 915,938 ----
  static inline bool
  cgraph_can_remove_if_no_direct_calls_and_refs_p (struct cgraph_node *node)
  {
!   /* When function is needed, we can not remove it.  */
!   if (node->needed || node->reachable_from_other_partition)
!     return false;
!   /* Only COMDAT functions can be removed if externally visible.  */
!   if (node->local.externally_visible
!       && (!DECL_COMDAT (node->decl) || node->local.used_from_object_file))
!     return false;
!   /* Constructors and destructors are executed by the runtime, however
!      we can get rid of all pure constructors and destructors.  */
!   if (DECL_STATIC_CONSTRUCTOR (node->decl)
!       || DECL_STATIC_DESTRUCTOR (node->decl))
!     {
!       int flags = flags_from_decl_or_type (node->decl);
!       if (!(flags & (ECF_CONST | ECF_PURE))
! 	  || (flags & ECF_LOOPING_CONST_OR_PURE))
! 	return false;
!     }
!   return true;
  }
  
  /* Return true when function NODE can be removed from callgraph
Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 163398)
--- cgraphunit.c	(working copy)
*************** cgraph_decide_is_function_needed (struct
*** 367,377 ****
        && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
      return true;
  
-   /* Constructors and destructors are reachable from the runtime by
-      some mechanism.  */
-   if (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl))
-     return true;
- 
    return false;
  }
  
--- 367,372 ----
*************** cgraph_finalize_function (tree decl, boo
*** 532,538 ****
    /* Since we reclaim unreachable nodes at the end of every language
       level unit, we need to be conservative about possible entry points
       there.  */
!   if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl)))
      cgraph_mark_reachable_node (node);
  
    /* If we've not yet emitted decl, tell the debug info about it.  */
--- 527,535 ----
    /* Since we reclaim unreachable nodes at the end of every language
       level unit, we need to be conservative about possible entry points
       there.  */
!   if ((TREE_PUBLIC (decl) && !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
!       || DECL_STATIC_CONSTRUCTOR (decl)
!       || DECL_STATIC_DESTRUCTOR (decl))
      cgraph_mark_reachable_node (node);
  
    /* If we've not yet emitted decl, tell the debug info about it.  */
*************** cgraph_mark_functions_to_output (void)
*** 1219,1226 ****
  	 outside the current compilation unit.  */
        if (node->analyzed
  	  && !node->global.inlined_to
! 	  && (node->needed || node->reachable_from_other_partition
! 	      || node->address_taken
  	      || (e && node->reachable))
  	  && !TREE_ASM_WRITTEN (decl)
  	  && !DECL_EXTERNAL (decl))
--- 1216,1222 ----
  	 outside the current compilation unit.  */
        if (node->analyzed
  	  && !node->global.inlined_to
! 	  && (!cgraph_only_called_directly_p (node)
  	      || (e && node->reachable))
  	  && !TREE_ASM_WRITTEN (decl)
  	  && !DECL_EXTERNAL (decl))
Index: testsuite/gcc.dg/ipa/ctor-empty-1.c
===================================================================
*** testsuite/gcc.dg/ipa/ctor-empty-1.c	(revision 0)
--- testsuite/gcc.dg/ipa/ctor-empty-1.c	(revision 0)
***************
*** 0 ****
--- 1,8 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O3 -c -fdump-ipa-inline"  } */
+ __attribute__((constructor))
+ void empty_constructor()
+ {
+ }
+ /* { dg-final { scan-ipa-dump-not "empty_constructor"  "inline"  } } */
+ /* { dg-final { cleanup-ipa-dump "inline" } } */


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