forked from OSchip/llvm-project
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. llvm-svn: 110285
This commit is contained in:
parent
6b67ee425d
commit
c8bd9c277b
|
@ -2460,6 +2460,56 @@ static llvm::Value *PerformTypeAdjustment(CodeGenFunction &CGF,
|
|||
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 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD,
|
|||
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)
|
||||
|
|
|
@ -246,8 +246,21 @@ namespace Test9 {
|
|||
}
|
||||
}
|
||||
|
||||
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(
|
||||
|
|
Loading…
Reference in New Issue