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]

Re: [PATCH][C++] Improve PR15855 (compile-time/memory hog)


This is what I have currently in bootstrapping and testing.  As the patch
got larger anyway I took the opportunity to move the if (init == 1) check
first and not re-emit it for each priority.

Ok for mainline if testing succeeds?  What about 4.0 and 3.4?

Thanks,
Richard.

2005-09-16  Richard Guenther  <rguenther@suse.de>

	PR middle-end/15855
	* decl2.c (do_static_initialization): Remove.
	(do_static_destruction): Likewise.
        (do_static_initialization_or_destruction): New function
	merged from above.  Put initializers with same priority into
	the same if-stmt.
	(start_static_initialization_or_destruction): The init condition
	is now emit in do_static_initialization_or_destruction.
	(cp_finish_file): Use do_static_initialization_or_destruction.

Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.802
diff -c -3 -p -r1.802 decl2.c
*** cp/decl2.c	12 Sep 2005 04:03:46 -0000	1.802
--- cp/decl2.c	16 Sep 2005 21:14:26 -0000
*************** static void finish_objects (int, int, tr
*** 73,80 ****
  static tree start_static_storage_duration_function (unsigned);
  static void finish_static_storage_duration_function (tree);
  static priority_info get_priority_info (int);
! static void do_static_initialization (tree, tree);
! static void do_static_destruction (tree);
  static tree start_static_initialization_or_destruction (tree, int);
  static void finish_static_initialization_or_destruction (tree);
  static void generate_ctor_or_dtor_function (bool, int, location_t *);
--- 73,79 ----
  static tree start_static_storage_duration_function (unsigned);
  static void finish_static_storage_duration_function (tree);
  static priority_info get_priority_info (int);
! static void do_static_initialization_or_destruction (tree, int);
  static tree start_static_initialization_or_destruction (tree, int);
  static void finish_static_initialization_or_destruction (tree);
  static void generate_ctor_or_dtor_function (bool, int, location_t *);
*************** start_static_initialization_or_destructi
*** 2327,2333 ****
    int priority = 0;
    tree cond;
    tree guard;
-   tree init_cond;
    priority_info pi;
  
      /* Figure out the priority for this declaration.  */
--- 2326,2331 ----
*************** start_static_initialization_or_destructi
*** 2374,2384 ****
    cond = cp_build_binary_op (EQ_EXPR,
  			     priority_decl,
  			     build_int_cst (NULL_TREE, priority));
-   init_cond = initp ? integer_one_node : integer_zero_node;
-   init_cond = cp_build_binary_op (EQ_EXPR,
- 				  initialize_p_decl,
- 				  init_cond);
-   cond = cp_build_binary_op (TRUTH_ANDIF_EXPR, cond, init_cond);
  
    /* Assume we don't need a guard.  */
    guard = NULL_TREE;
--- 2372,2377 ----
*************** finish_static_initialization_or_destruct
*** 2454,2508 ****
    DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
  }
  
! /* Generate code to do the initialization of DECL, a VAR_DECL with
!    static storage duration.  The initialization is INIT.  */
  
  static void
! do_static_initialization (tree decl, tree init)
  {
!   tree guard_if_stmt;
  
!   /* Set up for the initialization.  */
!   guard_if_stmt
!     = start_static_initialization_or_destruction (decl,
! 						  /*initp=*/1);
  
!   /* Perform the initialization.  */
!   if (init)
!     finish_expr_stmt (init);
  
!   /* If we're using __cxa_atexit, register a function that calls the
!      destructor for the object.  */
!   if (flag_use_cxa_atexit)
!     finish_expr_stmt (register_dtor_fn (decl));
  
!   /* Finish up.  */
!   finish_static_initialization_or_destruction (guard_if_stmt);
! }
  
- /* Generate code to do the static destruction of DECL.  If DECL may be
-    initialized more than once in different object files, GUARD is the
-    guard variable to check.  PRIORITY is the priority for the
-    destruction.  */
  
! static void
! do_static_destruction (tree decl)
! {
!   tree guard_if_stmt;
  
!   /* If we're using __cxa_atexit, then destructors are registered
!      immediately after objects are initialized.  */
!   gcc_assert (!flag_use_cxa_atexit);
  
!   /* If we don't need a destructor, there's nothing to do.  */
!   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
!     return;
  
!   /* Actually do the destruction.  */
!   guard_if_stmt = start_static_initialization_or_destruction (decl,
! 							      /*initp=*/0);
!   finish_expr_stmt (build_cleanup (decl));
!   finish_static_initialization_or_destruction (guard_if_stmt);
  }
  
  /* VARS is a list of variables with static storage duration which may
--- 2447,2550 ----
    DECL_STATIC_FUNCTION_P (current_function_decl) = 0;
  }
  
! /* Generate code to do the initialization or destruction of the decls in VARS,
!    a TREE_LIST of VAR_DECL with static storage duration.
!    Whether initialization or destruction is performed is specified by INITP.  */
  
  static void
! do_static_initialization_or_destruction (tree vars, int initp)
  {
!   tree node, init_if_stmt, init_cond;
  
!   /* If we're using __cxa_atexit, then destructors are registered
!      immediately after objects are initialized.  */
!   gcc_assert (initp || !flag_use_cxa_atexit);
  
!   if (!vars)
!     return;
  
!   /* Build the outer if-stmt to check for initialization or destruction.  */
!   init_if_stmt = begin_if_stmt ();
!   init_cond = initp ? integer_one_node : integer_zero_node;
!   init_cond = cp_build_binary_op (EQ_EXPR,
! 				  initialize_p_decl,
! 				  init_cond);
!   finish_if_stmt_cond (init_cond, init_if_stmt);
  
!   for (node = vars; node;)
!     {
!       tree decl = TREE_VALUE (node);
!       tree init = TREE_PURPOSE (node);
!       tree guard_if_stmt;
!       int priority = 0, opriority;
!       bool guard_p, oguard_p;
  
  
!       /* If we don't need a destructor, there's nothing to do.  */
!       if (!initp && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
! 	{
! 	  node = TREE_CHAIN (node);
! 	  continue;
! 	}
  
!       /* Set up for the initialization.  */
!       guard_if_stmt
!         = start_static_initialization_or_destruction (decl, initp);
! 
!       if (DECL_HAS_INIT_PRIORITY_P (decl))
!         priority = DECL_INIT_PRIORITY (decl);
!       if (!priority)
!         priority = DEFAULT_INIT_PRIORITY;
!       guard_p = TREE_PUBLIC (decl) && (DECL_COMMON (decl)
! 				       || DECL_ONE_ONLY (decl)
! 				       || DECL_WEAK (decl));
! 
!       do {
! 	/* Perform the initialization.  */
! 	if (initp)
! 	  {
! 	    if (init)
! 	      finish_expr_stmt (init);
  
! 	    /* If we're using __cxa_atexit, register a function that calls the
! 	       destructor for the object.  */
! 	    if (flag_use_cxa_atexit)
! 	      finish_expr_stmt (register_dtor_fn (decl));
! 	  }
!         /* Perform the destruction.  */
! 	else
! 	  finish_expr_stmt (build_cleanup (decl));
! 
! 	/* Advance to the next node.  */
! 	do {
!           node = TREE_CHAIN (node);
! 	} while (node && !initp
! 		 && TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (TREE_VALUE (node))));
! 	if (!node)
! 	  break;
! 	decl = TREE_VALUE (node);
! 	init = TREE_PURPOSE (node);
! 
! 	/* Check, if we can stick the next constructor in the same
! 	   if-stmt body.  */
! 	opriority = priority;
! 	priority = 0;
! 	if (DECL_HAS_INIT_PRIORITY_P (decl))
! 	  priority = DECL_INIT_PRIORITY (decl);
! 	if (!priority)
! 	  priority = DEFAULT_INIT_PRIORITY;
! 	oguard_p = guard_p;
! 	guard_p = TREE_PUBLIC (decl) && (DECL_COMMON (decl)
! 					 || DECL_ONE_ONLY (decl)
! 					 || DECL_WEAK (decl));
!       } while (priority == opriority && !oguard_p && !guard_p);
  
!       /* Finish up one if-stmt body.  */
!       finish_static_initialization_or_destruction (guard_if_stmt);
!     }
! 
!   finish_then_clause (init_if_stmt);
!   finish_if_stmt (init_if_stmt);
  }
  
  /* VARS is a list of variables with static storage duration which may
*************** cp_finish_file (void)
*** 2900,2907 ****
  
        if (vars)
  	{
- 	  tree v;
- 
  	  /* We need to start a new initialization function each time
  	     through the loop.  That's because we need to know which
  	     vtables have been referenced, and TREE_SYMBOL_REFERENCED
--- 2942,2947 ----
*************** cp_finish_file (void)
*** 2920,2928 ****
  	  write_out_vars (vars);
  
  	  /* First generate code to do all the initializations.  */
! 	  for (v = vars; v; v = TREE_CHAIN (v))
! 	    do_static_initialization (TREE_VALUE (v),
! 				      TREE_PURPOSE (v));
  
  	  /* Then, generate code to do all the destructions.  Do these
  	     in reverse order so that the most recently constructed
--- 2960,2966 ----
  	  write_out_vars (vars);
  
  	  /* First generate code to do all the initializations.  */
! 	  do_static_initialization_or_destruction (vars, 1);
  
  	  /* Then, generate code to do all the destructions.  Do these
  	     in reverse order so that the most recently constructed
*************** cp_finish_file (void)
*** 2933,2940 ****
  	  if (!flag_use_cxa_atexit)
  	    {
  	      vars = nreverse (vars);
! 	      for (v = vars; v; v = TREE_CHAIN (v))
! 		do_static_destruction (TREE_VALUE (v));
  	    }
  	  else
  	    vars = NULL_TREE;
--- 2971,2977 ----
  	  if (!flag_use_cxa_atexit)
  	    {
  	      vars = nreverse (vars);
! 	      do_static_initialization_or_destruction (vars, 0);
  	    }
  	  else
  	    vars = NULL_TREE;


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