From 5c61d97ad442b2c0bbecb617c8f21857ce1fff6d Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 13 Feb 2009 22:08:43 +0000 Subject: [PATCH] IRgen support for attribute used. - PR3566 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64492 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/CGDecl.cpp | 4 +++- lib/CodeGen/CodeGenModule.cpp | 26 +++++++++++++++++++------- lib/CodeGen/CodeGenModule.h | 7 +++++++ test/CodeGen/attr-used.c | 14 ++++++++++++++ 4 files changed, 43 insertions(+), 8 deletions(-) create mode 100644 test/CodeGen/attr-used.c diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp index abcd547be9..ddc68d68c5 100644 --- a/lib/CodeGen/CGDecl.cpp +++ b/lib/CodeGen/CGDecl.cpp @@ -138,6 +138,9 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { if (const SectionAttr *SA = D.getAttr()) GV->setSection(SA->getName()); + if (D.getAttr()) + CGM.AddUsedGlobal(GV); + const llvm::Type *LTy = CGM.getTypes().ConvertTypeForMem(D.getType()); const llvm::Type *LPtrTy = llvm::PointerType::get(LTy, D.getType().getAddressSpace()); @@ -149,7 +152,6 @@ void CodeGenFunction::EmitStaticBlockVarDecl(const VarDecl &D) { DI->setLocation(D.getLocation()); DI->EmitGlobalVariable(static_cast(GV), &D); } - } /// EmitLocalBlockVarDecl - Emit code and set up an entry in LocalDeclMap for a diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index ecfd8c98c3..e60edce213 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -238,11 +238,11 @@ void CodeGenModule::EmitAnnotations() { gv->setSection("llvm.metadata"); } -static void SetGlobalValueAttributes(const Decl *D, - bool IsInternal, - bool IsInline, - llvm::GlobalValue *GV, - bool ForDefinition) { +void CodeGenModule::SetGlobalValueAttributes(const Decl *D, + bool IsInternal, + bool IsInline, + llvm::GlobalValue *GV, + bool ForDefinition) { // FIXME: Set up linkage and many other things. Note, this is a simple // approximation of what we really want. if (!ForDefinition) { @@ -290,6 +290,14 @@ static void SetGlobalValueAttributes(const Decl *D, if (const SectionAttr *SA = D->getAttr()) GV->setSection(SA->getName()); + + // Only add to llvm.used when we see a definition, otherwise we + // might add multiple times or risk the value being replaced by a + // subsequent RAUW. + if (ForDefinition) { + if (D->getAttr()) + AddUsedGlobal(GV); + } } void CodeGenModule::SetFunctionAttributes(const Decl *D, @@ -492,8 +500,9 @@ llvm::Constant *CodeGenModule::EmitAnnotateAttr(llvm::GlobalValue *GV, } bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) { - // Never defer when EmitAllDecls is specified. - if (Features.EmitAllDecls) + // Never defer when EmitAllDecls is specified or the decl has + // attribute used. + if (Features.EmitAllDecls || Global->getAttr()) return false; if (const FunctionDecl *FD = dyn_cast(Global)) { @@ -728,6 +737,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) { if (const SectionAttr *SA = D->getAttr()) GV->setSection(SA->getName()); + if (D->getAttr()) + AddUsedGlobal(GV); + // Emit global variable debug information. CGDebugInfo *DI = getDebugInfo(); if(DI) { diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index 967889a92d..4c2aeb75ac 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -284,6 +284,13 @@ public: private: + /// SetGlobalValueAttributes - Set attributes for a global decl. + void SetGlobalValueAttributes(const Decl *D, + bool IsInternal, + bool IsInline, + llvm::GlobalValue *GV, + bool ForDefinition); + /// SetFunctionAttributesForDefinition - Set function attributes specific to a /// function definition. /// \param D - The ObjCMethodDecl or FunctionDecl defining \arg F. diff --git a/test/CodeGen/attr-used.c b/test/CodeGen/attr-used.c new file mode 100644 index 0000000000..c7f67600c0 --- /dev/null +++ b/test/CodeGen/attr-used.c @@ -0,0 +1,14 @@ +// RUN: clang -emit-llvm -o %t %s && +// RUN: grep '@llvm.used = .*@g0' %t && +// RUN: grep '@llvm.used = .*@f0' %t && +// RUN: grep '@llvm.used = .*@f1.l0' %t + + +int g0 __attribute__((used)); + +static void __attribute__((used)) f0(void) { +} + +void f1() { + static int l0 __attribute__((used)) = 5225; +} -- 2.40.0