This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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;