aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-06-23 21:47:46 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-06-23 21:47:46 +0000
commitc38e9affd4519ea199af22419c8c794973cc4b23 (patch)
treeb9670dacb0360172c12aff9ba7218814e73ff4a6
parent2e01cdacc5ecab5a14329405dc481a18ac3ccfdc (diff)
Patch fixes an obscure bug when 'used' attribute is applied to
variables in ObjC's Next runtime mode. Next runtime also implicitly applies 'used' attribute on some of its meta-data. This results in two 'llvm.used' arrays to be generated, and one of them is renamed to 'llvm.used1'. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74008 91177308-0d34-0410-b5e6-96231b3b80d8
-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"))) ;
+