Skip to content

Commit

Permalink
[Metadata] Add 'exclude' metadata to add the exclude flags on globals
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jhuber6 committed Jul 7, 2022
1 parent 82a0adf commit 41fba3c
Show file tree
Hide file tree
Showing 10 changed files with 70 additions and 8 deletions.
2 changes: 1 addition & 1 deletion 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) {}
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Frontend/embed-object.ll
Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions llvm/docs/LangRef.rst
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
1 change: 1 addition & 0 deletions llvm/include/llvm/IR/FixedMetadataKinds.def
Expand Up @@ -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)
3 changes: 0 additions & 3 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Expand Up @@ -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.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/Target/TargetLoweringObjectFile.cpp
Expand Up @@ -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()) {
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Transforms/Utils/ModuleUtils.cpp
Expand Up @@ -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);
}
18 changes: 18 additions & 0 deletions llvm/test/CodeGen/X86/coff-exclude.ll
@@ -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 = !{}
18 changes: 18 additions & 0 deletions llvm/test/CodeGen/X86/elf-exclude.ll
@@ -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 = !{}
6 changes: 4 additions & 2 deletions 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 = !{}

; CHECK-ELF: .section .llvm.offloading,"e",@llvm_offloading
; CHECK-COFF: .section .llvm.offloading,"dr"
; CHECK-COFF: .section .llvm.offloading,"ynD"

0 comments on commit 41fba3c

Please sign in to comment.