diff options
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 5 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCMac.cpp | 46 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCRuntime.h | 3 | ||||
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 11 | ||||
-rw-r--r-- | test/CodeGenObjC/deadcode_strip_used_var.m | 9 |
5 files changed, 38 insertions, 36 deletions
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 912479f0b0..4f96b8baec 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -139,6 +139,7 @@ public: const ObjCProtocolDecl *PD); virtual void GenerateProtocol(const ObjCProtocolDecl *PD); virtual llvm::Function *ModuleInitFunction(); + virtual void MergeMetadataGlobals(std::vector<llvm::Constant*> &UsedArray); virtual llvm::Function *GetPropertyGetFunction(); virtual llvm::Function *GetPropertySetFunction(); virtual llvm::Function *EnumerationMutationFunction(); @@ -998,6 +999,10 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { Classes.push_back(ClassStruct); } +void CGObjCGNU::MergeMetadataGlobals( + std::vector<llvm::Constant*> &UsedArray) { +} + llvm::Function *CGObjCGNU::ModuleInitFunction() { // Only emit an ObjC load function if no Objective-C stuff has been called if (Classes.empty() && Categories.empty() && ConstantStrings.empty() && diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 6ffca8134a..325b2ccaa2 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -911,6 +911,8 @@ protected: const CallArgList &CallArgs, const ObjCCommonTypesHelper &ObjCTypes); + virtual void MergeMetadataGlobals(std::vector<llvm::Constant*> &UsedArray); + public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } @@ -3426,6 +3428,16 @@ void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, NameOut += ']'; } +void CGObjCCommonMac::MergeMetadataGlobals( + std::vector<llvm::Constant*> &UsedArray) { + llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), + e = UsedGlobals.end(); i != e; ++i) { + UsedArray.push_back(llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(*i), + i8PTy)); + } +} + void CGObjCMac::FinishModule() { EmitModuleInfo(); @@ -3447,22 +3459,6 @@ void CGObjCMac::FinishModule() { Values)); } - std::vector<llvm::Constant*> Used; - for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), - e = UsedGlobals.end(); i != e; ++i) { - Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); - } - - llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); - llvm::GlobalValue *GV = - new llvm::GlobalVariable(AT, false, - llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(AT, Used), - "llvm.used", - &CGM.getModule()); - - GV->setSection("llvm.metadata"); - // Add assembler directives to add lazy undefined symbol references // for classes which are referenced but not defined. This is // important for correct linker interaction. @@ -4111,24 +4107,6 @@ void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { IMGV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); IMGV->setConstant(true); UsedGlobals.push_back(IMGV); - - std::vector<llvm::Constant*> Used; - - for (std::vector<llvm::GlobalVariable*>::iterator i = UsedGlobals.begin(), - e = UsedGlobals.end(); i != e; ++i) { - Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); - } - - llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); - llvm::GlobalValue *GV = - new llvm::GlobalVariable(AT, false, - llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(AT, Used), - "llvm.used", - &CGM.getModule()); - - GV->setSection("llvm.metadata"); - } /// LegacyDispatchedSelector - Returns true if SEL is not in the list of diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index b8cf026b35..0f9cf0606d 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -95,6 +95,9 @@ public: /// this compilation unit with the runtime library. virtual llvm::Function *ModuleInitFunction() = 0; + /// Add metadata globals to the 'used' globals for final output. + virtual void MergeMetadataGlobals(std::vector<llvm::Constant*> &UsedArray) = 0; + /// Get a selector for the specified name and type values. The /// return value should have the LLVM type for pointer-to /// ASTContext::getObjCSelType(). diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index f926c05a99..0a531e9b21 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -406,11 +406,12 @@ void CodeGenModule::AddUsedGlobal(llvm::GlobalValue *GV) { void CodeGenModule::EmitLLVMUsed() { // Don't create llvm.used if there is no need. - if (LLVMUsed.empty()) + // FIXME. Runtime indicates that there might be more 'used' symbols; but not + // necessariy. So, this test is not accurate for emptiness. + if (LLVMUsed.empty() && !Runtime) return; llvm::Type *i8PTy = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, LLVMUsed.size()); // Convert LLVMUsed to what ConstantArray needs. std::vector<llvm::Constant*> UsedArray; @@ -420,6 +421,12 @@ void CodeGenModule::EmitLLVMUsed() { llvm::ConstantExpr::getBitCast(cast<llvm::Constant>(&*LLVMUsed[i]), i8PTy); } + if (Runtime) + Runtime->MergeMetadataGlobals(UsedArray); + if (UsedArray.empty()) + return; + llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedArray.size()); + llvm::GlobalVariable *GV = new llvm::GlobalVariable(ATy, false, llvm::GlobalValue::AppendingLinkage, diff --git a/test/CodeGenObjC/deadcode_strip_used_var.m b/test/CodeGenObjC/deadcode_strip_used_var.m new file mode 100644 index 0000000000..444cf766f7 --- /dev/null +++ b/test/CodeGenObjC/deadcode_strip_used_var.m @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -emit-llvm -o %t -triple i386-apple-darwin10 && +// RUN: grep "llvm.used" %t | count 1 && +// RUN: clang-cc %s -emit-llvm -o %t -triple x86_64-apple-darwin10 && +// RUN: grep "llvm.used" %t | count 1 + + +__attribute__((used)) static int XXXXXX __attribute__ ((section ("__DATA,__Xinterpose"))) ; +__attribute__((used)) static int YYYY __attribute__ ((section ("__DATA,__Xinterpose"))) ; + |