aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp5
-rw-r--r--lib/CodeGen/CGObjCMac.cpp46
-rw-r--r--lib/CodeGen/CGObjCRuntime.h3
-rw-r--r--lib/CodeGen/CodeGenModule.cpp11
-rw-r--r--test/CodeGenObjC/deadcode_strip_used_var.m9
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"))) ;
+