[(questionable but useful) patch] Let codegen write the filename for translation unit initializer functions

Nico Weber thakis at chromium.org
Fri Apr 25 16:17:51 PDT 2014


Hi,

gcc calls the static initialization function for file foo.cc
_GLOBAL__sub_i_foo.cc, while clang always uses _GLOBAL__I_a . Having the
filename in the symbol is useful for finding where static initializers are
from; we use this information in chromium on linux. (On Mac, we look at the
dSYM file instead.)

The attached patch makes clang behave like gcc for initializers. (It
doesn't change the behavior for __D_ functions, not sure if anyone wants
that.)

Opinions? Is this useful for anyone else?

(Drawbacks: slightly longer symbols, which has a (small) binary size cost,
and it looks like __attribute__ ((init_priority(101))) works by naming the
_GLOBAL__ functions _GLOBAL__I_000101 etc, so if you call your source file
000101.cc it might interfere with this patch.

Nico
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140425/627873c3/attachment.html>
-------------- next part --------------
Index: lib/CodeGen/CGDeclCXX.cpp
===================================================================
--- lib/CodeGen/CGDeclCXX.cpp	(revision 207012)
+++ lib/CodeGen/CGDeclCXX.cpp	(working copy)
@@ -17,6 +17,7 @@
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/Support/Path.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -364,6 +365,7 @@
       std::string PrioritySuffix = llvm::utostr(Priority);
       // Priority is always <= 65535 (enforced by sema)..
       PrioritySuffix = std::string(6-PrioritySuffix.size(), '0')+PrioritySuffix;
+      // XXX here too?
       llvm::Function *Fn = 
         CreateGlobalInitOrDestructFunction(*this, FTy,
                                            "_GLOBAL__I_" + PrioritySuffix);
@@ -376,8 +378,11 @@
     }
   }
   
-  llvm::Function *Fn = 
-    CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__I_a");
+  SourceManager &SM = Context.getSourceManager();
+  StringRef FileName = llvm::sys::path::filename(
+      SM.getFileEntryForID(SM.getMainFileID())->getName());
+  llvm::Function *Fn = CreateGlobalInitOrDestructFunction(
+      *this, FTy, llvm::Twine("_GLOBAL__I_", FileName));
 
   CodeGenFunction(*this).GenerateCXXGlobalInitFunc(Fn, CXXGlobalInits);
   AddGlobalCtor(Fn);
@@ -392,6 +397,7 @@
 
   llvm::FunctionType *FTy = llvm::FunctionType::get(VoidTy, false);
 
+  // XXX here too?
   // Create our global destructor function.
   llvm::Function *Fn =
     CreateGlobalInitOrDestructFunction(*this, FTy, "_GLOBAL__D_a");
Index: test/CodeGenCXX/deferred-global-init.cpp
===================================================================
--- test/CodeGenCXX/deferred-global-init.cpp	(revision 207012)
+++ test/CodeGenCXX/deferred-global-init.cpp	(working copy)
@@ -11,6 +11,6 @@
 // CHECK: load i8** @foo
 // CHECK: ret void
 
-// CHECK-LABEL: define internal void @_GLOBAL__I_a
+// CHECK-LABEL: define internal void @_GLOBAL__I_deferred-global-init.cpp
 // CHECK: call void @__cxx_global_var_init()
 // CHECK: ret void
Index: test/CodeGenCXX/global-init.cpp
===================================================================
--- test/CodeGenCXX/global-init.cpp	(revision 207012)
+++ test/CodeGenCXX/global-init.cpp	(working copy)
@@ -195,11 +195,11 @@
 // CHECK-NEXT:   sub
 // CHECK-NEXT:   store i32 {{.*}}, i32* @_ZN5test1L1yE
 
-// CHECK: define internal void @_GLOBAL__I_a() section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK: define internal void @_GLOBAL__I_global-init.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" {
 // CHECK:   call void [[TEST1_Y_INIT]]
 // CHECK:   call void [[TEST1_Z_INIT]]
 
 // rdar://problem/8090834: this should be nounwind
-// CHECK-NOEXC: define internal void @_GLOBAL__I_a() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
+// CHECK-NOEXC: define internal void @_GLOBAL__I_global-init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" {
 
 // CHECK-NOEXC: attributes [[NUW]] = { nounwind }
Index: test/CodeGenCXX/globalinit-loc.cpp
===================================================================
--- test/CodeGenCXX/globalinit-loc.cpp	(revision 207012)
+++ test/CodeGenCXX/globalinit-loc.cpp	(working copy)
@@ -4,9 +4,9 @@
 // Verify that the global init helper function does not get associated
 // with any source location.
 //
-// CHECK: define internal void @_GLOBAL__I_a
+// CHECK: define internal void @_GLOBAL__I_globalinit-loc.cpp
 // CHECK: !dbg ![[DBG:.*]]
-// CHECK: "_GLOBAL__I_a", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def]
+// CHECK: "_GLOBAL__I_globalinit-loc.cpp", i32 0, {{.*}}, i32 0} ; [ DW_TAG_subprogram ] [line 0] [local] [def]
 // CHECK: ![[DBG]] = metadata !{i32 0, i32 0,
 # 99 "someheader.h"
 class A {
Index: test/CodeGenCXX/init-priority-attr.cpp
===================================================================
--- test/CodeGenCXX/init-priority-attr.cpp	(revision 207012)
+++ test/CodeGenCXX/init-priority-attr.cpp	(working copy)
@@ -27,7 +27,7 @@
 
 A C::a = A();
 
-// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK: @llvm.global_ctors = appending global [3 x { i32, void ()* }] [{ i32, void ()* } { i32 200, void ()* @_GLOBAL__I_000200 }, { i32, void ()* } { i32 300, void ()* @_GLOBAL__I_000300 }, { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_init-priority-attr.cpp }]
 
 // CHECK: _GLOBAL__I_000200()
 // CHECK: _Z3fooi(i32 3)
@@ -38,7 +38,7 @@
 // CHECK-NEXT: _Z3fooi(i32 1)
 // CHECK-NEXT: ret void
 
-// CHECK: _GLOBAL__I_a()
+// CHECK: _GLOBAL__I_init-priority-attr.cpp()
 // CHECK: _Z3fooi(i32 1)
 // CHECK-NEXT: _Z3fooi(i32 4)
 // CHECK-NEXT: ret void
Index: test/CodeGenCXX/microsoft-abi-static-initializers.cpp
===================================================================
--- test/CodeGenCXX/microsoft-abi-static-initializers.cpp	(revision 207012)
+++ test/CodeGenCXX/microsoft-abi-static-initializers.cpp	(working copy)
@@ -2,7 +2,7 @@
 
 // CHECK: @llvm.global_ctors = appending global [2 x { i32, void ()* }]
 // CHECK: [{ i32, void ()* } { i32 65535, void ()* @"\01??__Efoo@?$B at H@@2VA@@A at YAXXZ"
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_microsoft-abi-static-initializers.cpp }]
 
 struct S {
   S();
@@ -160,7 +160,7 @@
 // CHECK: call x86_thiscallcc void @"\01??1A@@QAE at XZ"{{.*}}foo
 // CHECK: ret void
 
-// CHECK: define internal void @_GLOBAL__I_a() [[NUW]] {
+// CHECK: define internal void @_GLOBAL__I_microsoft-abi-static-initializers.cpp() [[NUW]] {
 // CHECK: call void @"\01??__Es@@YAXXZ"()
 // CHECK: ret void
 
Index: test/CodeGenCXX/runtimecc.cpp
===================================================================
--- test/CodeGenCXX/runtimecc.cpp	(revision 207012)
+++ test/CodeGenCXX/runtimecc.cpp	(working copy)
@@ -45,7 +45,7 @@
 
 // CHECK: declare arm_aapcscc void @__cxa_throw(i8*, i8*, i8*)
 
-// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__I_a()
+// CHECK-LABEL: define internal arm_aapcscc void @_GLOBAL__I_runtimecc.cpp()
 // CHECK:   call arm_aapcscc void @__cxx_global_var_init()
 
 
Index: test/CodeGenCXX/static-member-variable-explicit-specialization.cpp
===================================================================
--- test/CodeGenCXX/static-member-variable-explicit-specialization.cpp	(revision 207012)
+++ test/CodeGenCXX/static-member-variable-explicit-specialization.cpp	(working copy)
@@ -19,14 +19,14 @@
 // CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered4:[^ ]*]] },
 // CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered5:[^ ]*]] },
 // CHECK:  { i32, void ()* } { i32 65535, void ()* @[[unordered6:[^ ]*]] },
-// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_a }]
+// CHECK:  { i32, void ()* } { i32 65535, void ()* @_GLOBAL__I_static-member-variable-explicit-specialization.cpp }]
 
 template int A<short>::a;  // Unordered
 int b = foo();
 int c = foo();
 int d = A<void>::a; // Unordered
 
-// An explicit specialization is ordered, and goes in __GLOBAL_I_a.
+// An explicit specialization is ordered, and goes in __GLOBAL_I_static-member-variable-explicit-specialization.cpp.
 template<> struct A<int> { static int a; };
 int A<int>::a = foo();
 
@@ -82,7 +82,7 @@
 // CHECK: store {{.*}} @_Z1xIcE
 // CHECK: ret
 
-// CHECK: define internal void @_GLOBAL__I_a()
+// CHECK: define internal void @_GLOBAL__I_static-member-variable-explicit-specialization.cpp()
 //   We call unique stubs for every ordered dynamic initializer in the TU.
 // CHECK: call
 // CHECK: call


More information about the cfe-commits mailing list