From: Rafael Espindola Date: Thu, 6 Mar 2014 22:15:10 +0000 (+0000) Subject: Use llvm.compiler.used instead of llvm.used for objc symbols. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bb46ff589d60c109277728c9f94ff9ce9553eca1;p=clang Use llvm.compiler.used instead of llvm.used for objc symbols. LLVM currently has a hack (shouldEmitUsedDirectiveFor) that causes it to not print no_dead_strip for symbols starting with 'l' or 'L'. These are exactly the ones that the clang's objc codegen is producing. The net result, is that it is equivalent to llvm.compiler.used. The need for putting the private symbol in llvm.compiler.used should be clear (the objc runtime uses them). The reason for also putting the weak symbols in it is for LTO: ld64 will not ask us to preserve the it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@203172 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index 8ce03030b8..46de0e50b3 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -332,7 +332,7 @@ void CodeGenFunction::EmitStaticVarDecl(const VarDecl &D, var->setSection(SA->getName()); if (D.hasAttr()) - CGM.AddUsedGlobal(var); + CGM.addUsedGlobal(var); // We may have to cast the constant because of the initializer // mismatch above. diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 0cb38f27aa..bd7c8bf6e7 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -2676,7 +2676,7 @@ llvm::Constant *CGObjCMac::GetOrEmitProtocol(const ObjCProtocolDecl *PD) { Protocols[PD->getIdentifier()] = Entry; } assertPrivateName(Entry); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); return Entry; } @@ -3156,7 +3156,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { GV->setInitializer(Init); GV->setSection(Section); GV->setAlignment(4); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); } else GV = CreateMetadataVar(Name, Init, Section, 4, true); assertPrivateName(GV); @@ -3229,7 +3229,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, assertPrivateName(GV); GV->setSection("__OBJC,__meta_class,regular,no_dead_strip"); GV->setAlignment(4); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); return GV; } @@ -3446,7 +3446,7 @@ CGObjCCommonMac::CreateMetadataVar(Twine Name, if (Align) GV->setAlignment(Align); if (AddToUsed) - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); return GV; } @@ -5006,7 +5006,7 @@ void CGObjCMac::FinishModule() { assertPrivateName(I->second); I->second->setInitializer(llvm::ConstantStruct::get(ObjCTypes.ProtocolTy, Values)); - CGM.AddUsedGlobal(I->second); + CGM.addCompilerUsedGlobal(I->second); } // Add assembler directives to add lazy undefined symbol references @@ -5534,7 +5534,7 @@ AddModuleClassList(ArrayRef Container, assertPrivateName(GV); GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType())); GV->setSection(SectionName); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); } void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { @@ -5960,7 +5960,7 @@ llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CodeGenFunction &CGF, ProtocolName); PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); - CGM.AddUsedGlobal(PTGV); + CGM.addCompilerUsedGlobal(PTGV); return CGF.Builder.CreateLoad(PTGV); } @@ -6048,7 +6048,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { GCATV->setAlignment( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.CategorynfABITy)); GCATV->setSection("__DATA, __objc_const"); - CGM.AddUsedGlobal(GCATV); + CGM.addCompilerUsedGlobal(GCATV); DefinedCategories.push_back(GCATV); // Determine if this category is also "non-lazy". @@ -6108,7 +6108,7 @@ CGObjCNonFragileABIMac::EmitMethodList(Twine Name, assertPrivateName(GV); GV->setAlignment(CGM.getDataLayout().getABITypeAlignment(Init->getType())); GV->setSection(Section); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); } @@ -6229,7 +6229,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( CGM.getDataLayout().getABITypeAlignment(Init->getType())); GV->setSection("__DATA, __objc_const"); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.IvarListnfABIPtrTy); } @@ -6372,7 +6372,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( Protocols[PD->getIdentifier()] = Entry; } Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); // Use this protocol meta-data to build protocol list table in section // __DATA, __objc_protolist @@ -6384,7 +6384,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ProtocolnfABIPtrTy)); PTGV->setSection("__DATA, __objc_protolist, coalesced, no_dead_strip"); PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); - CGM.AddUsedGlobal(PTGV); + CGM.addCompilerUsedGlobal(PTGV); return Entry; } @@ -6437,7 +6437,7 @@ CGObjCNonFragileABIMac::EmitProtocolList(Twine Name, GV->setSection("__DATA, __objc_const"); GV->setAlignment( CGM.getDataLayout().getABITypeAlignment(Init->getType())); - CGM.AddUsedGlobal(GV); + CGM.addCompilerUsedGlobal(GV); return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); } @@ -6683,7 +6683,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitClassRefFromId(CodeGenFunction &CGF, CGM.getDataLayout().getABITypeAlignment( ObjCTypes.ClassnfABIPtrTy)); Entry->setSection("__DATA, __objc_classrefs, regular, no_dead_strip"); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); } assertPrivateName(Entry); return CGF.Builder.CreateLoad(Entry); @@ -6717,7 +6717,7 @@ CGObjCNonFragileABIMac::EmitSuperClassRef(CodeGenFunction &CGF, CGM.getDataLayout().getABITypeAlignment( ObjCTypes.ClassnfABIPtrTy)); Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); } assertPrivateName(Entry); return CGF.Builder.CreateLoad(Entry); @@ -6742,7 +6742,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitMetaClassRef(CodeGenFunction &CGF, CGM.getDataLayout().getABITypeAlignment(ObjCTypes.ClassnfABIPtrTy)); Entry->setSection("__DATA, __objc_superrefs, regular, no_dead_strip"); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); } assertPrivateName(Entry); @@ -6827,7 +6827,7 @@ llvm::Value *CGObjCNonFragileABIMac::EmitSelector(CodeGenFunction &CGF, Casted, "\01L_OBJC_SELECTOR_REFERENCES_"); Entry->setExternallyInitialized(true); Entry->setSection("__DATA, __objc_selrefs, literal_pointers, no_dead_strip"); - CGM.AddUsedGlobal(Entry); + CGM.addCompilerUsedGlobal(Entry); } assertPrivateName(Entry); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f0265b33f5..9b3e32952e 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -258,7 +258,7 @@ void CodeGenModule::Release() { EmitCtorList(GlobalDtors, "llvm.global_dtors"); EmitGlobalAnnotations(); EmitStaticExternCAliases(); - EmitLLVMUsed(); + emitLLVMUsed(); if (CodeGenOpts.Autolink && (Context.getLangOpts().Modules || !LinkerOptionsMetadata.empty())) { @@ -699,7 +699,7 @@ void CodeGenModule::SetCommonAttributes(const Decl *D, GV->setVisibility(llvm::GlobalValue::DefaultVisibility); if (D->hasAttr()) - AddUsedGlobal(GV); + addUsedGlobal(GV); if (const SectionAttr *SA = D->getAttr()) GV->setSection(SA->getName()); @@ -776,39 +776,51 @@ void CodeGenModule::SetFunctionAttributes(GlobalDecl GD, llvm::Attribute::NoBuiltin); } -void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { +void CodeGenModule::addUsedGlobal(llvm::GlobalValue *GV) { assert(!GV->isDeclaration() && "Only globals with definition can force usage."); LLVMUsed.push_back(GV); } -void CodeGenModule::EmitLLVMUsed() { +void CodeGenModule::addCompilerUsedGlobal(llvm::GlobalValue *GV) { + assert(!GV->isDeclaration() && + "Only globals with definition can force usage."); + LLVMCompilerUsed.push_back(GV); +} + +static void emitUsed(CodeGenModule &CGM, StringRef Name, + std::vector &List) { // Don't create llvm.used if there is no need. - if (LLVMUsed.empty()) + if (List.empty()) return; - // Convert LLVMUsed to what ConstantArray needs. + // Convert List to what ConstantArray needs. SmallVector UsedArray; - UsedArray.resize(LLVMUsed.size()); - for (unsigned i = 0, e = LLVMUsed.size(); i != e; ++i) { + UsedArray.resize(List.size()); + for (unsigned i = 0, e = List.size(); i != e; ++i) { UsedArray[i] = - llvm::ConstantExpr::getBitCast(cast(&*LLVMUsed[i]), - Int8PtrTy); + llvm::ConstantExpr::getBitCast(cast(&*List[i]), + CGM.Int8PtrTy); } if (UsedArray.empty()) return; - llvm::ArrayType *ATy = llvm::ArrayType::get(Int8PtrTy, UsedArray.size()); + llvm::ArrayType *ATy = llvm::ArrayType::get(CGM.Int8PtrTy, UsedArray.size()); llvm::GlobalVariable *GV = - new llvm::GlobalVariable(getModule(), ATy, false, + new llvm::GlobalVariable(CGM.getModule(), ATy, false, llvm::GlobalValue::AppendingLinkage, llvm::ConstantArray::get(ATy, UsedArray), - "llvm.used"); + Name); GV->setSection("llvm.metadata"); } +void CodeGenModule::emitLLVMUsed() { + emitUsed(*this, "llvm.used", LLVMUsed); + emitUsed(*this, "llvm.compiler.used", LLVMCompilerUsed); +} + void CodeGenModule::AppendLinkerOptions(StringRef Opts) { llvm::Value *MDOpts = llvm::MDString::get(getLLVMContext(), Opts); LinkerOptionsMetadata.push_back(llvm::MDNode::get(getLLVMContext(), MDOpts)); @@ -3054,7 +3066,7 @@ void CodeGenModule::EmitStaticExternCAliases() { IdentifierInfo *Name = I->first; llvm::GlobalValue *Val = I->second; if (Val && !getModule().getNamedValue(Name->getName())) - AddUsedGlobal(new llvm::GlobalAlias(Val->getType(), Val->getLinkage(), + addUsedGlobal(new llvm::GlobalAlias(Val->getType(), Val->getLinkage(), Name->getName(), Val, &getModule())); } } diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 151cb33d67..11272fc2ca 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -298,6 +298,7 @@ class CodeGenModule : public CodeGenTypeCache { /// forcing visibility of symbols which may otherwise be optimized /// out. std::vector LLVMUsed; + std::vector LLVMCompilerUsed; /// GlobalCtors - Store the list of global constructors and their respective /// priorities to be emitted when the translation unit is complete. @@ -799,10 +800,11 @@ public: template void MaybeHandleStaticInExternC(const SomeDecl *D, llvm::GlobalValue *GV); - /// AddUsedGlobal - Add a global which should be forced to be - /// present in the object file; these are emitted to the llvm.used - /// metadata global. - void AddUsedGlobal(llvm::GlobalValue *GV); + /// Add a global to a list to be added to the llvm.used metadata. + void addUsedGlobal(llvm::GlobalValue *GV); + + /// Add a global to a list to be added to the llvm.compiler.used metadata. + void addCompilerUsedGlobal(llvm::GlobalValue *GV); /// AddCXXDtorEntry - Add a destructor and object to add to the C++ global /// destructor function. @@ -1104,9 +1106,8 @@ private: /// still have a use for. void EmitDeferredVTables(); - /// EmitLLVMUsed - Emit the llvm.used metadata used to force - /// references to global which may otherwise be optimized out. - void EmitLLVMUsed(); + /// Emit the llvm.used and llvm.compiler.used metadata. + void emitLLVMUsed(); /// \brief Emit the link options introduced by imported modules. void EmitModuleLinkOptions(); diff --git a/test/CodeGenObjC/forward-protocol-metadata-symbols.m b/test/CodeGenObjC/forward-protocol-metadata-symbols.m index c71cecbf5b..2b687d19f9 100644 --- a/test/CodeGenObjC/forward-protocol-metadata-symbols.m +++ b/test/CodeGenObjC/forward-protocol-metadata-symbols.m @@ -23,4 +23,4 @@ int main() { // CHECK: @"\01l_OBJC_LABEL_PROTOCOL_$_P0" = weak hidden global // CHECK: @"\01l_OBJC_PROTOCOL_REFERENCE_$_P0" = weak hidden global -// CHECK: llvm.used = appending global [10 x i8*] {{[^"]*}}"\01L_OBJC_CLASS_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_TYPE_"{{[^"]*}}"\01l_OBJC_$_CLASS_METHODS_A"{{[^"]*}}"\01l_OBJC_CLASS_PROTOCOLS_$_A"{{[^"]*}}"\01L_OBJC_CLASS_NAME_1"{{[^"]*}}"\01l_OBJC_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_LABEL_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_PROTOCOL_REFERENCE_$_P0"{{[^"]*}}"\01L_OBJC_LABEL_CLASS_$"{{[^"]*}} section "llvm.metadata" +// CHECK: llvm.compiler.used = appending global [10 x i8*] {{[^"]*}}"\01L_OBJC_CLASS_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_NAME_"{{[^"]*}}"\01L_OBJC_METH_VAR_TYPE_"{{[^"]*}}"\01l_OBJC_$_CLASS_METHODS_A"{{[^"]*}}"\01l_OBJC_CLASS_PROTOCOLS_$_A"{{[^"]*}}"\01L_OBJC_CLASS_NAME_1"{{[^"]*}}"\01l_OBJC_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_LABEL_PROTOCOL_$_P0"{{[^"]*}}"\01l_OBJC_PROTOCOL_REFERENCE_$_P0"{{[^"]*}}"\01L_OBJC_LABEL_CLASS_$"{{[^"]*}} section "llvm.metadata"