[cfe-commits] r110285 - in /cfe/trunk: lib/CodeGen/CGVTables.cpp test/CodeGenCXX/thunks.cpp

John McCall rjmccall at apple.com
Wed Aug 4 16:46:35 PDT 2010


Author: rjmccall
Date: Wed Aug  4 18:46:35 2010
New Revision: 110285

URL: http://llvm.org/viewvc/llvm-project?rev=110285&view=rev
Log:
Extend the visibility-hidden optimization to linkonce_odr thunks for
functions with in-line definitions, since such thunks will be emitted at any
use of the function.

Completes the feature work for rdar://problem/7523229.


Modified:
    cfe/trunk/lib/CodeGen/CGVTables.cpp
    cfe/trunk/test/CodeGenCXX/thunks.cpp

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=110285&r1=110284&r2=110285&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Wed Aug  4 18:46:35 2010
@@ -2460,6 +2460,56 @@
   return CGF.Builder.CreateBitCast(V, Ptr->getType());
 }
 
+static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
+                               const ThunkInfo &Thunk, llvm::Function *Fn) {
+  CGM.setGlobalVisibility(Fn, MD);
+
+  // If the thunk has weak/linkonce linkage, but the function must be
+  // emitted in every translation unit that references it, then we can
+  // emit its thunks with hidden visibility, since its thunks must be
+  // emitted when the function is.
+
+  // This mostly follows CodeGenModule::setTypeVisibility.
+
+  if ((Fn->getLinkage() != llvm::GlobalVariable::LinkOnceODRLinkage &&
+       Fn->getLinkage() != llvm::GlobalVariable::WeakODRLinkage) ||
+      Fn->getVisibility() != llvm::GlobalVariable::DefaultVisibility)
+    return;
+
+  // Don't override an explicit visibility attribute.
+  if (MD->hasAttr<VisibilityAttr>())
+    return;
+
+  switch (MD->getTemplateSpecializationKind()) {
+  // We have to disable the optimization if this is an EI definition
+  // because there might be EI declarations in other shared objects.
+  case TSK_ExplicitInstantiationDefinition:
+  case TSK_ExplicitInstantiationDeclaration:
+    return;
+
+  // Every use of a non-template or explicitly-specialized class's
+  // type information has to emit it.
+  case TSK_ExplicitSpecialization:
+  case TSK_Undeclared:
+    break;
+
+  // Implicit instantiations can ignore the possibility of an
+  // explicit instantiation declaration because there necessarily
+  // must be an EI definition somewhere with default visibility.
+  case TSK_ImplicitInstantiation:
+    break;
+  }
+
+  // If there's an explicit definition, and that definition is
+  // out-of-line, then we can't assume that all users will have a
+  // definition to emit.
+  const FunctionDecl *Def = 0;
+  if (MD->hasBody(Def) && Def->isOutOfLine())
+    return;
+
+  Fn->setVisibility(llvm::GlobalValue::HiddenVisibility);
+}
+
 void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
                                     const ThunkInfo &Thunk) {
   const CXXMethodDecl *MD = cast<CXXMethodDecl>(GD.getDecl());
@@ -2582,7 +2632,7 @@
   CGM.setFunctionLinkage(MD, Fn);
   
   // Set the right visibility.
-  CGM.setGlobalVisibility(Fn, MD);
+  setThunkVisibility(CGM, MD, Thunk, Fn);
 }
 
 void CodeGenVTables::EmitThunk(GlobalDecl GD, const ThunkInfo &Thunk)

Modified: cfe/trunk/test/CodeGenCXX/thunks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/thunks.cpp?rev=110285&r1=110284&r2=110285&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/thunks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/thunks.cpp Wed Aug  4 18:46:35 2010
@@ -246,8 +246,21 @@
   }
 }
 
+namespace Test10 {
+  struct A { virtual void foo(); };
+  struct B { virtual void foo(); };
+  struct C : A, B { void foo() {} };
+
+  // CHECK: define linkonce_odr void @_ZN6Test101C3fooEv
+  // CHECK: define linkonce_odr hidden void @_ZThn8_N6Test101C3fooEv
+
+  void test() {
+    C c;
+  }
+}
+
 /**** The following has to go at the end of the file ****/
 
 // This is from Test5:
-// CHECK: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv
+// CHECK: define linkonce_odr hidden void @_ZTv0_n24_N5Test51B1fEv
 // CHECK: define internal void @_ZThn8_N12_GLOBAL__N_11C1fEv(





More information about the cfe-commits mailing list