[cfe-commits] r104581 - in /cfe/trunk: lib/CodeGen/CGCXX.cpp lib/CodeGen/CGDecl.cpp lib/CodeGen/CGVTables.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGenCXX/static-init.cpp

John McCall rjmccall at apple.com
Mon May 24 21:30:21 PDT 2010


Author: rjmccall
Date: Mon May 24 23:30:21 2010
New Revision: 104581

URL: http://llvm.org/viewvc/llvm-project?rev=104581&view=rev
Log:
If a function definition has any sort of weak linkage, its static local
variables should have that linkage.  Otherwise, its static local
variables should have internal linkage.  To avoid computing this excessively,
set a function's linkage before we emit code for it.

Previously we were assigning weak linkage to the static variables of
static inline functions in C++, with predictably terrible results.  This
fixes that and also gives better linkage than 'weak' when merging is required.


Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGDecl.cpp
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/test/CodeGenCXX/static-init.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Mon May 24 23:30:21 2010
@@ -206,6 +206,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXConstructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 
@@ -269,6 +270,7 @@
     return;
 
   llvm::Function *Fn = cast<llvm::Function>(GetAddrOfCXXDestructor(D, Type));
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(GlobalDecl(D, Type), Fn);
 

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon May 24 23:30:21 2010
@@ -114,14 +114,14 @@
     llvm::GlobalValue::LinkageTypes Linkage = 
       llvm::GlobalValue::InternalLinkage;
 
-    // If this is a static declaration inside an inline function, it must have
-    // weak linkage so that the linker will merge multiple definitions of it.
-    if (getContext().getLangOptions().CPlusPlus) {
-      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurFuncDecl)) {
-        if (FD->isInlined())
-          Linkage = llvm::GlobalValue::WeakAnyLinkage;
-      }
-    }
+    // If the function definition has some sort of weak linkage, its
+    // static variables should also be weak so that they get properly
+    // uniqued.  We can't do this in C, though, because there's no
+    // standard way to agree on which variables are the same (i.e.
+    // there's no mangling).
+    if (getContext().getLangOptions().CPlusPlus)
+      if (llvm::GlobalValue::isWeakForLinker(CurFn->getLinkage()))
+        Linkage = CurFn->getLinkage();
     
     return EmitStaticBlockVarDecl(D, Linkage);
   }

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Mon May 24 23:30:21 2010
@@ -2723,7 +2723,7 @@
   CXXThisDecl->Destroy(getContext());
   
   // Set the right linkage.
-  Fn->setLinkage(CGM.getFunctionLinkage(MD));
+  CGM.setFunctionLinkage(MD, Fn);
   
   // Set the right visibility.
   CGM.setGlobalVisibility(Fn, MD);

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon May 24 23:30:21 2010
@@ -361,7 +361,6 @@
 /// variables (these details are set in EmitGlobalVarDefinition for variables).
 void CodeGenModule::SetFunctionDefinitionAttributes(const FunctionDecl *D,
                                                     llvm::GlobalValue *GV) {
-  GV->setLinkage(getFunctionLinkage(D));
   SetCommonAttributes(D, GV);
 }
 
@@ -1330,6 +1329,7 @@
   }
 
   llvm::Function *Fn = cast<llvm::Function>(Entry);
+  setFunctionLinkage(D, Fn);
 
   CodeGenFunction(*this).GenerateCode(D, Fn);
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Mon May 24 23:30:21 2010
@@ -436,6 +436,10 @@
   llvm::GlobalVariable::LinkageTypes
   getFunctionLinkage(const FunctionDecl *FD);
 
+  void setFunctionLinkage(const FunctionDecl *FD, llvm::GlobalValue *V) {
+    V->setLinkage(getFunctionLinkage(FD));
+  }
+
   /// getVTableLinkage - Return the appropriate linkage for the vtable, VTT,
   /// and type information of the given class.
   static llvm::GlobalVariable::LinkageTypes 

Modified: cfe/trunk/test/CodeGenCXX/static-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-init.cpp?rev=104581&r1=104580&r2=104581&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/static-init.cpp Mon May 24 23:30:21 2010
@@ -2,8 +2,9 @@
 
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 
-// CHECK: @_ZZ2h2vE1i = weak global i32 0
-// CHECK: @_ZGVZ2h2vE1i = weak global i64 0
+// CHECK: @_ZZN5test16getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 4
+// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
+// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
 
 struct A {
   A();
@@ -47,3 +48,13 @@
     static A r;
   }
 }
+
+namespace test1 {
+  // CHECK: define internal i32 @_ZN5test16getvarEi(
+  static inline int getvar(int index) {
+    static const int var[] = { 1, 0, 2, 4 };
+    return var[index];
+  }
+
+  void test() { (void) getvar(2); }
+}





More information about the cfe-commits mailing list