diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -6396,6 +6396,18 @@ !1 = !{i64 2, i64 -1, i64 -1, i1 true} !0 = !{!1} +'``exclude``' Metadata +^^^^^^^^^^^^^^^^^^^^^^^ + +``exclude`` metadata may be attached to a global variables to signify that it +should not be included in the final executable or shared library. This is done +using the ``SHF_EXCLUDE`` flag on ELF targets and the ``IMAGE_SCN_LNK_REMOVE`` +and ``IMAGE_SCN_MEM_DISCARDABLE`` flags for COFF targets. This option is only +valid for global variables with an explicit section targeting ELF or COFF. + +.. code-block:: text + + @object = private constant [1 x i8] c"\00", section ".foo" !exclude !0 '``unpredictable``' Metadata ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def --- a/llvm/include/llvm/IR/FixedMetadataKinds.def +++ b/llvm/include/llvm/IR/FixedMetadataKinds.def @@ -44,3 +44,4 @@ LLVM_FIXED_MD_KIND(MD_annotation, "annotation", 30) LLVM_FIXED_MD_KIND(MD_nosanitize, "nosanitize", 31) LLVM_FIXED_MD_KIND(MD_func_sanitize, "func_sanitize", 32) +LLVM_FIXED_MD_KIND(MD_exclude, "exclude", 33) diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -449,9 +449,6 @@ Name == ".llvmbc" || Name == ".llvmcmd") return SectionKind::getMetadata(); - if (Name == ".llvm.offloading") - return SectionKind::getExclude(); - if (Name.empty() || Name[0] != '.') return K; // Default implementation based on some magic section names. diff --git a/llvm/lib/Target/TargetLoweringObjectFile.cpp b/llvm/lib/Target/TargetLoweringObjectFile.cpp --- a/llvm/lib/Target/TargetLoweringObjectFile.cpp +++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp @@ -213,6 +213,9 @@ // Global variables require more detailed analysis. const auto *GVar = cast(GO); + if (GVar->hasSection() && GVar->hasMetadata(LLVMContext::MD_exclude)) + return SectionKind::getExclude(); + // Handle thread-local data first. if (GVar->isThreadLocal()) { if (isSuitableForBSS(GVar) && !TM.Options.NoZerosInBSS) { diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -281,6 +281,7 @@ MDString::get(Ctx, SectionName)}; MD->addOperand(llvm::MDNode::get(Ctx, MDVals)); + GV->setMetadata(LLVMContext::MD_exclude, llvm::MDNode::get(Ctx, MDVals)); appendToCompilerUsed(M, GV); } diff --git a/llvm/test/CodeGen/X86/offload_sections.ll b/llvm/test/CodeGen/X86/offload_sections.ll --- a/llvm/test/CodeGen/X86/offload_sections.ll +++ b/llvm/test/CodeGen/X86/offload_sections.ll @@ -1,8 +1,10 @@ ; RUN: llc < %s -mtriple=x86_64-unknown-linux-gnu | FileCheck %s --check-prefix=CHECK-ELF ; RUN: llc < %s -mtriple=x86_64-win32-gnu | FileCheck %s --check-prefix=CHECK-COFF -@llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading" +@llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading", align 8, !exclude !0 @llvm.compiler.used = appending global [1 x ptr] [ptr @llvm.embedded.object], section "llvm.metadata" +!0 = !{ptr @llvm.embedded.object, !".llvm.offloading"} + ; CHECK-ELF: .section .llvm.offloading,"e",@llvm_offloading -; CHECK-COFF: .section .llvm.offloading,"dr" +; CHECK-COFF: .section .llvm.offloading,"ynD"