From 35b4a5768f170959dbe9258b6ea5abf7b6d7c144 Mon Sep 17 00:00:00 2001
From: Roger Sayle <roger@eyesopen.com>
Date: Wed, 11 Jun 2003 22:29:41 +0000
Subject: [PATCH] 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
---
 gcc/cp/ChangeLog |  7 +++++++
 gcc/cp/decl2.c   | 46 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index a4b9bef89abc..03c02c4ef599 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 08a2d663b2a3..1413f3944b9b 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
-- 
GitLab