[google/gcc-4_9] Fix static var promotion handling for LIPO

Sharad Singhai singhai@google.com
Mon Sep 15 20:44:00 GMT 2014


This patch is for the google/gcc-4_9 branch to fix a LIPO issue.

This patch addresses handling for static initializer data during
static variable promotion in LIPO optimize phase. This is useful for
those targets which access initializer data via TOC, such as powerpc.

After static var promotion in two different modules, we have the
following which leads to multiple definition of ._41" error during
link time.

Module 1                     Module 2
     .hidden ._41.cmo.1           .hidden ._41.cmo.3
     .globl ._41                  .globl ._41
._41:                        ._41:
  ...                          ...


Instead we should use the appropriate unique names for initializer
data as in the following.

Module 1                     Module 2
     .hidden ._41.cmo.1           .hidden ._41.cmo.3
     .globl ._41.cmo.1            .globl ._41.cmo.3
._41.cmo.1:                  ._41.cmo.3:
...                          ...


Tested on powerpc as well as ran manual tests. Okay for google/4_9 branch?

Thanks,
Sharad
-------------- next part --------------
2014-09-15  Sharad Singhai  <singhai@google.com>

	Google Ref b/17114943

	* l-ipo.c (promote_static_var_func): Update RTL with the unique name.

testsuite/ChangeLog:
	* g++.dg/tree-prof/lipo/static1_0.C: New test.
	* g++.dg/tree-prof/lipo/static1_1.C: New file.
	* g++.dg/tree-prof/lipo/static1_2.C: New file.


Index: l-ipo.c
===================================================================
--- l-ipo.c	(revision 215144)
+++ l-ipo.c	(working copy)
@@ -47,6 +47,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "timevar.h"
 #include "vec.h"
 #include "params.h"
+#include "rtl.h"
+#include "varasm.h"
 
 unsigned ggc_total_memory; /* in KB */
 
@@ -1909,6 +1911,9 @@ promote_static_var_func (unsigned module_id, tree
         }
       varpool_link_node (node);
       insert_to_assembler_name_hash (node, false);
+      /* Possibly update the RTL name as well. */
+      if (DECL_RTL_SET_P (decl))
+        XSTR (XEXP (DECL_RTL (decl), 0), 0) = IDENTIFIER_POINTER (assemb_id);
     }
 
   if (is_extern)
Index: testsuite/g++.dg/tree-prof/lipo/static1_0.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/static1_0.C	(revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/static1_0.C	(working copy)
@@ -0,0 +1,48 @@
+// { dg-options "-std=c++11 -O2" }
+
+// A test case for static var promotion on targets like powerpc, where
+// the static initializer data is loaded via indirection through
+// TOC. Ensure that the global label for static initializer data is
+// unique via *.cmo* suffix.
+
+// Bug: after static var promotion in two different modules, we have
+// the following which leads to multiple definition of ._41" error during
+// link time.
+
+// Module 1                     Module 2
+//      .hidden ._41.cmo.1           .hidden ._41.cmo.3
+//      .globl ._41                  .globl ._41
+// ._41:                        ._41:
+//   ...                          ...
+
+
+// Instead we should use the appropriate unique names for initializer
+// data as in the following.
+
+// Module 1                     Module 2
+//      .hidden ._41.cmo.1           .hidden ._41.cmo.3
+//      .globl ._41.cmo.1            .globl ._41.cmo.3
+// ._41.cmo.1:                  ._41.cmo.3:
+// ...                          ...
+
+class A {
+ public:
+  int f(int x) const;
+};
+
+class B {
+ public:
+  int f(int x) const;
+};
+
+int main()
+{
+  A *a = new A();
+  B *b = new B();
+  int total = 0;
+  for (int i=0; i<3; ++i) {
+    total += a->f(1);
+    total += b->f(1);
+  }
+  return (total > 0) ? 0 : 1;
+}
Index: testsuite/g++.dg/tree-prof/lipo/static1_1.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/static1_1.C	(revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/static1_1.C	(working copy)
@@ -0,0 +1,14 @@
+/* { dg-options "-std=c++11 -O2" } */
+
+#include <vector>
+
+class A {
+ public:
+  int f(int x) const;
+};
+
+static const std::vector<int> point1_{42};
+
+int A::f(int x) const {
+  return x+1;
+}
Index: testsuite/g++.dg/tree-prof/lipo/static1_2.C
===================================================================
--- testsuite/g++.dg/tree-prof/lipo/static1_2.C	(revision 0)
+++ testsuite/g++.dg/tree-prof/lipo/static1_2.C	(working copy)
@@ -0,0 +1,14 @@
+/* { dg-options "-std=c++11 -O2" } */
+
+#include <vector>
+
+class B {
+ public:
+  int f(int x) const;
+};
+
+static const std::vector<int> point2_{43};
+
+int B::f(int x) const {
+  return x+1;
+}


More information about the Gcc-patches mailing list