Patchwork HPPA constructor merge patch, PR middle-end/45388

login
register
mail settings
Submitter Jan Hubicka
Date Dec. 12, 2010, 7:47 p.m.
Message ID <20101212194745.GA26788@atrey.karlin.mff.cuni.cz>
Download mbox | patch
Permalink /patch/75270/
State New
Headers show

Comments

Jan Hubicka - Dec. 12, 2010, 7:47 p.m.
Hi,
this patch implements actually the Richard's idea of not giving constructors
collect2 recognizable names before constructor merging pass.  

I am not aware of any setup I can test the constructors on, but it solves the
problem with covariant3 testcase.

I inspected places where cgraph_build_static_cdtor is used and I think they all
appear before constructor merging pass.  It is possible that some of them (like
profiling or emultls) do constructors late, then we will need to export the
FINAL flag out of the ipa.c and set it correspondingly.

I am testing the patch on x86_64-linux, can you, please, test it at hppa?
Sorry for the delay, I really lost track of this problem.

There is probably easier fix, the code breaks only becaue I droped the code
setting always_inline flag on the constructor generation. I did this because
one can introduce ICE by doing constructors that are actually uninlinable.
So I hope that this fix will solve both problems.

Honza

Patch

Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 167726)
+++ cp/decl2.c	(working copy)
@@ -2691,7 +2691,7 @@  start_objects (int method_type, int init
 {
   tree body;
   tree fndecl;
-  char type[10];
+  char type[14];
 
   /* Make ctor or dtor function.  METHOD_TYPE may be 'I' or 'D'.  */
 
@@ -2705,10 +2705,10 @@  start_objects (int method_type, int init
       joiner = '_';
 #endif
 
-      sprintf (type, "%c%c%.5u", method_type, joiner, initp);
+      sprintf (type, "sub_%c%c%.5u", method_type, joiner, initp);
     }
   else
-    sprintf (type, "%c", method_type);
+    sprintf (type, "sub_%c", method_type);
 
   fndecl = build_lang_decl (FUNCTION_DECL,
 			    get_file_function_name (type),
Index: ipa.c
===================================================================
--- ipa.c	(revision 167726)
+++ ipa.c	(working copy)
@@ -1496,10 +1496,13 @@  struct ipa_opt_pass_d pass_ipa_profile =
 /* Generate and emit a static constructor or destructor.  WHICH must
    be one of 'I' (for a constructor) or 'D' (for a destructor).  BODY
    is a STATEMENT_LIST containing GENERIC statements.  PRIORITY is the
-   initialization priority for this constructor or destructor.  */
+   initialization priority for this constructor or destructor. 
 
-void
-cgraph_build_static_cdtor (char which, tree body, int priority)
+   FINAL specify whether the externally visible name for collect2 should
+   be produced. */
+
+static void
+cgraph_build_static_cdtor_1 (char which, tree body, int priority, bool final)
 {
   static int counter = 0;
   char which_buf[16];
@@ -1508,7 +1511,12 @@  cgraph_build_static_cdtor (char which, t
   /* The priority is encoded in the constructor or destructor name.
      collect2 will sort the names and arrange that they are called at
      program startup.  */
-  sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
+  if (final)
+    sprintf (which_buf, "%c_%.5d_%d", which, priority, counter++);
+  else
+  /* Proudce sane name but one not recognizable by collect2, just for the
+     case we fail to inline the function.  */
+    sprintf (which_buf, "sub_%c_%.5d_%d", which, priority, counter++);
   name = get_file_function_name (which_buf);
 
   decl = build_decl (input_location, FUNCTION_DECL, name,
@@ -1528,7 +1536,7 @@  cgraph_build_static_cdtor (char which, t
   DECL_ARTIFICIAL (decl) = 1;
   DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
   DECL_SAVED_TREE (decl) = body;
-  if (!targetm.have_ctors_dtors)
+  if (!targetm.have_ctors_dtors && final)
     {
       TREE_PUBLIC (decl) = 1;
       DECL_PRESERVE_P (decl) = 1;
@@ -1563,6 +1571,16 @@  cgraph_build_static_cdtor (char which, t
   current_function_decl = NULL;
 }
 
+/* Generate and emit a static constructor or destructor.  WHICH must
+   be one of 'I' (for a constructor) or 'D' (for a destructor).  BODY
+   is a STATEMENT_LIST containing GENERIC statements.  PRIORITY is the
+   initialization priority for this constructor or destructor.  */
+
+void
+cgraph_build_static_cdtor (char which, tree body, int priority)
+{
+  cgraph_build_static_cdtor_1 (which, body, priority, false);
+}
 
 /* A vector of FUNCTION_DECLs declared as static constructors.  */
 static VEC(tree, heap) *static_ctors;
@@ -1648,7 +1666,7 @@  build_cdtor (bool ctor_p, VEC (tree, hea
       gcc_assert (body != NULL_TREE);
       /* Generate a function to call all the function of like
 	 priority.  */
-      cgraph_build_static_cdtor (ctor_p ? 'I' : 'D', body, priority);
+      cgraph_build_static_cdtor_1 (ctor_p ? 'I' : 'D', body, priority, true);
     }
 }