[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
This commit is contained in:
Joseph Huber 2022-07-05 12:55:36 -04:00
parent 82a0adf0f7
commit 41fba3c107
10 changed files with 70 additions and 8 deletions

View file

@ -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) {}

View file

@ -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

View file

@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -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)

View file

@ -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.

View file

@ -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()) {

View file

@ -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);
}

View file

@ -0,0 +1,18 @@
; RUN: llc -mtriple x86_64-win32-gnu < %s | FileCheck %s
@a = global i32 1
@b = global i32 1, !exclude !0
@c = global i32 1, section "aaa"
; CHECK-DAG: c
; CHECK-DAG: .section aaa,"dw"
@d = global i32 1, section "bbb", !exclude !0
; CHECK-DAG: d
; CHECK-DAG: .section bbb,"ynD"
@e = global i32 1, section "bbb", !exclude !0
; CHECK-DAG: e
@f = global i32 1, section "ccc", !exclude !0
@g = global i32 1, section "ccc"
; CHECK-DAG: f
; CHECK-DAG: .section ccc,"ynD"
!0 = !{}

View file

@ -0,0 +1,18 @@
; RUN: llc -mtriple x86_64-pc-linux-gnu < %s | FileCheck %s
@a = global i32 1
@b = global i32 1, !exclude !0
@c = global i32 1, section "aaa"
; CHECK-DAG: .type c,@object
; CHECK-DAG: .section aaa,"aw",@progbits
@d = global i32 1, section "bbb", !exclude !0
; CHECK-DAG: .type d,@object
; CHECK-DAG: .section bbb,"e",@progbits
@e = global i32 1, section "bbb", !exclude !0
; CHECK-DAG: .type e,@object
@f = global i32 1, section "ccc", !exclude !0
@g = global i32 1, section "ccc"
; CHECK-DAG: .type f,@object
; CHECK-DAG: .section ccc,"e",@progbits
!0 = !{}

View file

@ -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 = !{}
; CHECK-ELF: .section .llvm.offloading,"e",@llvm_offloading
; CHECK-COFF: .section .llvm.offloading,"dr"
; CHECK-COFF: .section .llvm.offloading,"ynD"