[clang] 41fba3c - [Metadata] Add 'exclude' metadata to add the exclude flags on globals

Joseph Huber via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 7 09:20:58 PDT 2022


Author: Joseph Huber
Date: 2022-07-07T12:20:40-04:00
New Revision: 41fba3c107a5bc99065f3bf8b9f5b9d52eab2d98

URL: https://github.com/llvm/llvm-project/commit/41fba3c107a5bc99065f3bf8b9f5b9d52eab2d98
DIFF: https://github.com/llvm/llvm-project/commit/41fba3c107a5bc99065f3bf8b9f5b9d52eab2d98.diff

LOG: [Metadata] Add 'exclude' metadata to add the exclude flags on globals

This patchs adds a new metadata kind `exclude` which implies that the
global variable should be given the necessary flags during code
generation to not be included in the final executable. This is done
using the ``SHF_EXCLUDE`` flag on ELF for example. This should make it
easier to specify this flag on a variable without needing to explicitly
check the section name in the target backend.

Depends on D129053 D129052

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D129151

Added: 
    llvm/test/CodeGen/X86/coff-exclude.ll
    llvm/test/CodeGen/X86/elf-exclude.ll

Modified: 
    clang/test/Frontend/embed-object.c
    clang/test/Frontend/embed-object.ll
    llvm/docs/LangRef.rst
    llvm/include/llvm/IR/FixedMetadataKinds.def
    llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/lib/Target/TargetLoweringObjectFile.cpp
    llvm/lib/Transforms/Utils/ModuleUtils.cpp
    llvm/test/CodeGen/X86/offload_sections.ll

Removed: 
    


################################################################################
diff  --git a/clang/test/Frontend/embed-object.c b/clang/test/Frontend/embed-object.c
index 364cb8aad193..febac4272ff8 100644
--- a/clang/test/Frontend/embed-object.c
+++ b/clang/test/Frontend/embed-object.c
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -x c -triple x86_64-unknown-linux-gnu -emit-llvm -fembed-offload-object=%S/Inputs/empty.h -o - %s | FileCheck %s
 
-// CHECK: @[[OBJECT:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8
+// CHECK: @[[OBJECT:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8, !exclude
 // CHECK: @llvm.compiler.used = appending global [1 x ptr] [ptr @[[OBJECT]]], section "llvm.metadata"
 
 void foo(void) {}

diff  --git a/clang/test/Frontend/embed-object.ll b/clang/test/Frontend/embed-object.ll
index bcb56fd55c73..9165d903b975 100644
--- a/clang/test/Frontend/embed-object.ll
+++ b/clang/test/Frontend/embed-object.ll
@@ -3,8 +3,8 @@
 ; RUN:    -fembed-offload-object=%S/Inputs/empty.h -x ir %s -o - \
 ; RUN:    | FileCheck %s -check-prefix=CHECK
 
-; CHECK: @[[OBJECT_1:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8
-; CHECK: @[[OBJECT_2:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8
+; CHECK: @[[OBJECT_1:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8, !exclude
+; CHECK: @[[OBJECT_2:.+]] = private constant [0 x i8] zeroinitializer, section ".llvm.offloading", align 8, !exclude
 ; CHECK: @llvm.compiler.used = appending global [3 x ptr] [ptr @x, ptr @[[OBJECT_1]], ptr @[[OBJECT_2]]], section "llvm.metadata"
 
 @x = private constant i8 1

diff  --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index e74aaa8d77cf..a333c6f7a3da 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -6396,6 +6396,24 @@ final ``i1 true``).
     !1 = !{i64 2, i64 -1, i64 -1, i1 true}
     !0 = !{!1}
 
+'``exclude``' Metadata
+^^^^^^^^^^^^^^^^^^^^^^
+
+``exclude`` metadata may be attached to a global variable to signify that its
+section should not be included in the final executable or shared library. This
+option is only valid for global variables with an explicit section targeting ELF
+or COFF. 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. Additionally, this metadata is only used as a flag, so the associated
+node must be empty. The explicit section should not conflict with any other
+sections that the user does not want removed after linking.
+
+.. code-block:: text
+
+  @object = private constant [1 x i8] c"\00", section ".foo" !exclude !0
+
+  ...
+  !0 = !{}
 
 '``unpredictable``' Metadata
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/llvm/include/llvm/IR/FixedMetadataKinds.def b/llvm/include/llvm/IR/FixedMetadataKinds.def
index 7c32c5d13760..1d24f527df7b 100644
--- a/llvm/include/llvm/IR/FixedMetadataKinds.def
+++ b/llvm/include/llvm/IR/FixedMetadataKinds.def
@@ -44,3 +44,4 @@ LLVM_FIXED_MD_KIND(MD_noundef, "noundef", 29)
 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
index dbac47495ea2..2badbe34ae6a 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -449,9 +449,6 @@ static SectionKind getELFKindForNamedSection(StringRef Name, SectionKind K) {
       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
index 8f633adbb9ef..29cc2840310d 100644
--- a/llvm/lib/Target/TargetLoweringObjectFile.cpp
+++ b/llvm/lib/Target/TargetLoweringObjectFile.cpp
@@ -240,6 +240,13 @@ SectionKind TargetLoweringObjectFile::getKindForGlobal(const GlobalObject *GO,
     return SectionKind::getBSS();
   }
 
+  // Global variables with '!exclude' should get the exclude section kind if
+  // they have an explicit section and no other metadata.
+  if (GVar->hasSection())
+    if (MDNode *MD = GVar->getMetadata(LLVMContext::MD_exclude))
+      if (!MD->getNumOperands())
+        return SectionKind::getExclude();
+
   // If the global is marked constant, we can put it into a mergable section,
   // a mergable string section, or general .data if it contains relocations.
   if (GVar->isConstant()) {

diff  --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
index a3529bfd2e43..4dcba65f6ec1 100644
--- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp
+++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp
@@ -281,6 +281,7 @@ void llvm::embedBufferInModule(Module &M, MemoryBufferRef Buf,
                         MDString::get(Ctx, SectionName)};
 
   MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
+  GV->setMetadata(LLVMContext::MD_exclude, llvm::MDNode::get(Ctx, {}));
 
   appendToCompilerUsed(M, GV);
 }

diff  --git a/llvm/test/CodeGen/X86/coff-exclude.ll b/llvm/test/CodeGen/X86/coff-exclude.ll
new file mode 100644
index 000000000000..35ab756a066b
--- /dev/null
+++ b/llvm/test/CodeGen/X86/coff-exclude.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple x86_64-win32-gnu < %s | FileCheck %s
+
+ at a = global i32 1
+ at b = global i32 1, !exclude !0
+ at c = global i32 1, section "aaa"
+; CHECK-DAG: c
+; CHECK-DAG: 	.section	aaa,"dw"
+ at d = global i32 1, section "bbb", !exclude !0
+; CHECK-DAG: d
+; CHECK-DAG: 	.section	bbb,"ynD"
+ at e = global i32 1, section "bbb", !exclude !0
+; CHECK-DAG: e
+ at f = global i32 1, section "ccc", !exclude !0
+ at g = global i32 1, section "ccc"
+; CHECK-DAG: f
+; CHECK-DAG:	.section	ccc,"ynD"
+
+!0 = !{}

diff  --git a/llvm/test/CodeGen/X86/elf-exclude.ll b/llvm/test/CodeGen/X86/elf-exclude.ll
new file mode 100644
index 000000000000..50006dfa8a52
--- /dev/null
+++ b/llvm/test/CodeGen/X86/elf-exclude.ll
@@ -0,0 +1,18 @@
+; RUN: llc -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
+
+ at a = global i32 1
+ at b = global i32 1, !exclude !0
+ at c = global i32 1, section "aaa"
+; CHECK-DAG: .type	c, at object
+; CHECK-DAG: 	.section	aaa,"aw", at progbits
+ at d = global i32 1, section "bbb", !exclude !0
+; CHECK-DAG: .type	d, at object
+; CHECK-DAG: 	.section	bbb,"e", at progbits
+ at e = global i32 1, section "bbb", !exclude !0
+; CHECK-DAG: .type	e, at object
+ at f = global i32 1, section "ccc", !exclude !0
+ at g = global i32 1, section "ccc"
+; CHECK-DAG:	.type	f, at object
+; CHECK-DAG:	.section	ccc,"e", at progbits
+
+!0 = !{}

diff  --git a/llvm/test/CodeGen/X86/offload_sections.ll b/llvm/test/CodeGen/X86/offload_sections.ll
index c3ad26be8cd6..e912dc42dff0 100644
--- 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
 
- at llvm.embedded.object = private constant [1 x i8] c"\00", section ".llvm.offloading"
+ at 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 = !{}
+
 ; CHECK-ELF: .section	.llvm.offloading,"e", at llvm_offloading
-; CHECK-COFF: .section	.llvm.offloading,"dr"
+; CHECK-COFF: .section	.llvm.offloading,"ynD"


        


More information about the cfe-commits mailing list