aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2003-06-11 22:29:41 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2003-06-11 22:29:41 +0000
commit35b4a5768f170959dbe9258b6ea5abf7b6d7c144 (patch)
tree35e1c41a4ecab8f1106a32bf68cea6827d9368ae
parent7fb26bb00173af1f41d3df4b5a7a43be9e3f12db (diff)
downloadgcc-35b4a5768f170959dbe9258b6ea5abf7b6d7c144.zip
gcc-35b4a5768f170959dbe9258b6ea5abf7b6d7c144.tar.gz
gcc-35b4a5768f170959dbe9258b6ea5abf7b6d7c144.tar.bz2
decl2.c (generate_ctor_or_dtor_function): Avoid expanding a global static constructor/destructor if it will be empty, i.e.
* decl2.c (generate_ctor_or_dtor_function): Avoid expanding a global static constructor/destructor if it will be empty, i.e. either doesn't call any ctors/dtors or only calls pure or const ctors/dtors. From-SVN: r67800
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl2.c46
2 files changed, 39 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a4b9bef..03c02c4 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2003-06-11 Roger Sayle <roger@eyesopen.com>
+
+ * decl2.c (generate_ctor_or_dtor_function): Avoid expanding a
+ global static constructor/destructor if it will be empty, i.e.
+ either doesn't call any ctors/dtors or only calls pure or const
+ ctors/dtors.
+
2003-06-11 Mark Mitchell <mark@codesourcery.com>
* mangle.c (tm_p.h): Include it.
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 08a2d66..1413f39 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2467,6 +2467,7 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
{
char function_key;
tree arguments;
+ tree fndecl;
tree body;
size_t i;
@@ -2475,25 +2476,31 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
/* We use `I' to indicate initialization and `D' to indicate
destruction. */
- if (constructor_p)
- function_key = 'I';
- else
- function_key = 'D';
+ function_key = constructor_p ? 'I' : 'D';
- /* Begin the function. */
- body = start_objects (function_key, priority);
+ /* We emit the function lazily, to avoid generating empty
+ global constructors and destructors. */
+ body = NULL_TREE;
/* Call the static storage duration function with appropriate
arguments. */
if (ssdf_decls)
for (i = 0; i < ssdf_decls->elements_used; ++i)
{
- arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
- NULL_TREE);
- arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
- arguments);
- finish_expr_stmt (build_function_call (VARRAY_TREE (ssdf_decls, i),
- arguments));
+ fndecl = VARRAY_TREE (ssdf_decls, i);
+
+ /* Calls to pure or const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ if (! body)
+ body = start_objects (function_key, priority);
+
+ arguments = tree_cons (NULL_TREE, build_int_2 (priority, 0),
+ NULL_TREE);
+ arguments = tree_cons (NULL_TREE, build_int_2 (constructor_p, 0),
+ arguments);
+ finish_expr_stmt (build_function_call (fndecl, arguments));
+ }
}
/* If we're generating code for the DEFAULT_INIT_PRIORITY, throw in
@@ -2506,11 +2513,22 @@ generate_ctor_or_dtor_function (bool constructor_p, int priority,
for (fns = constructor_p ? static_ctors : static_dtors;
fns;
fns = TREE_CHAIN (fns))
- finish_expr_stmt (build_function_call (TREE_VALUE (fns), NULL_TREE));
+ {
+ fndecl = TREE_VALUE (fns);
+
+ /* Calls to pure/const functions will expand to nothing. */
+ if (! (flags_from_decl_or_type (fndecl) & (ECF_CONST | ECF_PURE)))
+ {
+ if (! body)
+ body = start_objects (function_key, priority);
+ finish_expr_stmt (build_function_call (fndecl, NULL_TREE));
+ }
+ }
}
/* Close out the function. */
- finish_objects (function_key, priority, body);
+ if (body)
+ finish_objects (function_key, priority, body);
}
/* Generate constructor and destructor functions for the priority