Skip to content

Commit 6b539f5

Browse files
committed
Reland "[gold] Add preliminary FatLTO support to the Gold plugin""
This changes the definition if isSectionBitcode to only be valid for the .llvm.lto section, since this API is only called from LTO, and the .llvmbc section was not intended to be used for LTO. This allows the gold plugin to keep its existing behavior without introducing any significant changes. Reviewed By: MaskRay, nikic Differential Revision: https://reviews.llvm.org/D152973
1 parent 14e3bec commit 6b539f5

File tree

9 files changed

+165
-27
lines changed

9 files changed

+165
-27
lines changed

llvm/docs/BitCodeFormat.rst

+10-5
Original file line numberDiff line numberDiff line change
@@ -470,13 +470,18 @@ Native Object File Wrapper Format
470470

471471
Bitcode files for LLVM IR may also be wrapped in a native object file
472472
(i.e. ELF, COFF, Mach-O). The bitcode must be stored in a section of the object
473-
file named ``__LLVM,__bitcode`` for MachO and ``.llvmbc`` for the other object
474-
formats. This wrapper format is useful for accommodating LTO in compilation
475-
pipelines where intermediate objects must be native object files which contain
476-
metadata in other sections.
473+
file named ``__LLVM,__bitcode`` for MachO or ``.llvmbc`` for the other object
474+
formats. ELF objects additionally support a ``.llvm.lto`` section for
475+
:doc:`FatLTO`, which contains bitcode suitable for LTO compilation (i.e. bitcode
476+
that has gone through a pre-link LTO pipeline). The ``.llvmbc`` section
477+
predates FatLTO support in LLVM, and may not always contain bitcode that is
478+
suitable for LTO (i.e. from ``-fembed-bitcode``). The wrapper format is useful
479+
for accommodating LTO in compilation pipelines where intermediate objects must
480+
be native object files which contain metadata in other sections.
477481

478482
Not all tools support this format. For example, lld and the gold plugin will
479-
ignore these sections when linking object files.
483+
ignore the ``.llvmbc`` section when linking object files, but can use
484+
``.llvm.lto`` sections when passed the correct command line options.
480485

481486
.. _encoding of LLVM IR:
482487

llvm/lib/Object/ObjectFile.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ uint32_t ObjectFile::getSymbolAlignment(DataRefImpl DRI) const { return 0; }
7979
bool ObjectFile::isSectionBitcode(DataRefImpl Sec) const {
8080
Expected<StringRef> NameOrErr = getSectionName(Sec);
8181
if (NameOrErr)
82-
return *NameOrErr == ".llvmbc" || *NameOrErr == ".llvm.lto";
82+
return *NameOrErr == ".llvm.lto";
8383
consumeError(NameOrErr.takeError());
8484
return false;
8585
}

llvm/test/LTO/X86/Inputs/bcsection.macho.s

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
.asciz "Wrong Section"
33

44
.section __LLVM,__bitcode
5-
.incbin "bcsection.bc"
5+
.incbin "llvm.lto.section.bc"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
.section .llvm.lto
2+
.incbin "llvm.lto.section.bc"

llvm/test/LTO/X86/bcsection.ll

+6-12
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,17 @@
22
; RUN: llvm-as -o %t/bcsection.bc %s
33

44
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-pc-win32 -o %t/bcsection.coff.bco %p/Inputs/bcsection.s
5-
; RUN: llvm-nm %t/bcsection.coff.bco | FileCheck %s
6-
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.coff.o %t/bcsection.coff.bco
7-
; RUN: llvm-nm %t/bcsection.coff.o | FileCheck %s
5+
; RUN: llvm-nm %t/bcsection.coff.bco | FileCheck %s --allow-empty
6+
; RUN: not llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.coff.o %t/bcsection.coff.bco
87

98
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-unknown-linux-gnu -o %t/bcsection.elf.bco %p/Inputs/bcsection.s
10-
; RUN: llvm-nm %t/bcsection.elf.bco | FileCheck %s
11-
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.elf.o %t/bcsection.elf.bco
12-
; RUN: llvm-nm %t/bcsection.elf.o | FileCheck %s
13-
14-
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-apple-darwin11 -o %t/bcsection.macho.bco %p/Inputs/bcsection.macho.s
15-
; RUN: llvm-nm %t/bcsection.macho.bco | FileCheck %s
16-
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.macho.o %t/bcsection.macho.bco
17-
; RUN: llvm-nm %t/bcsection.macho.o | FileCheck %s
9+
; RUN: llvm-nm %t/bcsection.elf.bco | FileCheck %s --allow-empty
10+
; RUN: not llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.elf.o %t/bcsection.elf.bco
1811

1912
target triple = "x86_64-unknown-linux-gnu"
2013

21-
; CHECK: main
14+
;; The .llvmbc section is not intended for use with LTO, so there should be nothing here
15+
; CHECK-NOT: main
2216
define i32 @main() {
2317
ret i32 0
2418
}

llvm/test/LTO/X86/llvm.lto.section.ll

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: rm -rf %t && mkdir -p %t
2+
; RUN: llvm-as -o %t/llvm.lto.section.bc %s
3+
4+
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-pc-win32 -o %t/llvm.lto.section.coff.bco %p/Inputs/llvm.lto.section.s
5+
; RUN: llvm-nm %t/llvm.lto.section.coff.bco | FileCheck %s
6+
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/llvm.lto.section.coff.o %t/llvm.lto.section.coff.bco
7+
; RUN: llvm-nm %t/llvm.lto.section.coff.o | FileCheck %s
8+
9+
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-unknown-linux-gnu -o %t/llvm.lto.section.elf.bco %p/Inputs/llvm.lto.section.s
10+
; RUN: llvm-nm %t/llvm.lto.section.elf.bco | FileCheck %s
11+
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/llvm.lto.section.elf.o %t/llvm.lto.section.elf.bco
12+
; RUN: llvm-nm %t/llvm.lto.section.elf.o | FileCheck %s
13+
14+
15+
; RUN: llvm-mc -I=%t -filetype=obj -triple=x86_64-apple-darwin11 -o %t/bcsection.macho.bco %p/Inputs/bcsection.macho.s
16+
; RUN: llvm-nm %t/bcsection.macho.bco | FileCheck %s
17+
; RUN: llvm-lto -exported-symbol=main -exported-symbol=_main -o %t/bcsection.macho.o %t/bcsection.macho.bco
18+
; RUN: llvm-nm %t/bcsection.macho.o | FileCheck %s
19+
20+
target triple = "x86_64-unknown-linux-gnu"
21+
22+
; CHECK: main
23+
define i32 @main() {
24+
ret i32 0
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# REQUIRES: x86_64-linux
2+
3+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
4+
# RUN: not %gold -plugin %llvmshlibdir/LLVMgold%shlibext %t -o /dev/null 2>&1 | FileCheck %s
5+
6+
# CHECK: error:{{.*}} Invalid bitcode signature
7+
8+
.section .llvm.lto,"e",@progbits
9+
.Lllvm.embedded.object:
10+
.asciz "BC\300\3365\000"
11+
.size .Lllvm.embedded.object, 12
+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
;; Basic FatLTO tests.
2+
; REQUIRES: x86_64-linux
3+
4+
; RUN: rm -rf %t && split-file %s %t
5+
6+
;; Ensure that input files contain .llvm.lto section
7+
; RUN: llc %t/a-LTO.ll --filetype=obj -o %t/a-fatLTO.o
8+
; RUN: opt --module-summary %t/a-LTO.ll -o %t/a-fatLTO.bc
9+
; RUN: llvm-objcopy --add-section=.llvm.lto=%t/a-fatLTO.bc %t/a-fatLTO.o
10+
; RUN: llvm-objcopy --set-section-flags=.llvm.lto=readonly,exclude %t/a-fatLTO.o
11+
; RUN: llvm-readobj -S %t/a-fatLTO.o | FileCheck --check-prefix=CHECK-A %s
12+
13+
; CHECK-A: Name: .llvm.lto
14+
15+
; RUN: llc %t/main-LTO.ll --filetype=obj -o %t/main-fatLTO.o
16+
; RUN: opt --module-summary %t/main-LTO.ll -o %t/main-fatLTO.bc
17+
; RUN: llvm-objcopy --add-section=.llvm.lto=%t/main-fatLTO.bc %t/main-fatLTO.o
18+
; RUN: llvm-objcopy --set-section-flags=.llvm.lto=readonly,exclude %t/main-fatLTO.o
19+
; RUN: llvm-readobj -S %t/main-fatLTO.o | FileCheck --check-prefix=CHECK-MAIN %s
20+
21+
; CHECK-MAIN: Name: .llvm.lto
22+
23+
;; Final executable should not have .llvm.lto section no matter what the target is
24+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -o %t/foo-fatLTO %t/a-fatLTO.o %t/main-fatLTO.o
25+
; RUN: llvm-readobj -S %t/foo-fatLTO | FileCheck --check-prefix=CHECK-LTO-TARGET %s
26+
27+
;; Check that fat objects work w/ s=--start-lib
28+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -o %t/foo-fatLTO.start_lib --start-lib %t/a-fatLTO.o %t/main-fatLTO.o --end-lib
29+
; RUN: llvm-readobj -S %t/foo-fatLTO.start_lib | FileCheck --check-prefix=CHECK-LTO-TARGET %s
30+
31+
;; Check if .llvm.lto section gets aggregated in LTO target
32+
; CHECK-LTO-TARGET-NOT: Name: .llvm.lto
33+
34+
;; Final executable should not have .llvm.lto section no matter what the target is
35+
; RUN: %gold -o %t/foo-fatNoLTO %t/a-fatLTO.o %/t/main-fatLTO.o
36+
; RUN: llvm-readobj -S %t/foo-fatNoLTO | FileCheck --check-prefix=CHECK-NON-LTO-TARGET %s
37+
38+
;; Check if .llvm.lto section gets aggregated in non-LTO target
39+
; CHECK-NON-LTO-TARGET-NOT: Name: .llvm.lto
40+
41+
;; Check if the LTO target executable produced from FatLTO object file is
42+
;; identical to the one produced from LTO modules
43+
; RUN: opt --module-summary %t/a-LTO.ll -o %t/a-LTO.bc
44+
; RUN: opt --module-summary %t/main-LTO.ll -o %t/main-LTO.bc
45+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -o %t/foo-LTO %t/a-LTO.bc %t/main-LTO.bc
46+
; RUN: cmp %t/foo-fatLTO %t/foo-LTO
47+
48+
;; Check if the no-LTO target executable produced from FatLTO object file is
49+
;; identical to the one produced from regular object files
50+
51+
; RUN: llc %t/a-LTO.ll --filetype=obj -o %t/a.o
52+
; RUN: llc %t/main-LTO.ll --filetype=obj -o %t/main.o
53+
54+
; RUN: %gold -o %t/foo-noLTO %t/a.o %t/main.o
55+
; RUN: cmp %t/foo-fatNoLTO %t/foo-noLTO
56+
57+
;; Check archive support
58+
; RUN: llvm-ar rcs %t/a.a %t/a-fatLTO.o
59+
; RUN: %gold -plugin %llvmshlibdir/LLVMgold%shlibext -o %t/foo-fatLTO.archive %t/main-LTO.bc %t/a.a
60+
; RUN: cmp %t/foo-fatLTO.archive %t/foo-LTO
61+
62+
;--- a-LTO.ll
63+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
64+
target triple = "x86_64-unknown-linux-gnu"
65+
66+
; Function Attrs: noinline nounwind uwtable
67+
define dso_local i32 @_start() #0 {
68+
entry:
69+
ret i32 0
70+
}
71+
72+
attributes #0 = { noinline nounwind uwtable }
73+
74+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
75+
76+
!0 = !{i32 1, !"wchar_size", i32 4}
77+
!1 = !{i32 7, !"PIC Level", i32 2}
78+
!2 = !{i32 7, !"PIE Level", i32 2}
79+
!3 = !{i32 7, !"uwtable", i32 2}
80+
!4 = !{i32 7, !"frame-pointer", i32 2}
81+
!5 = !{i32 1, !"ThinLTO", i32 0}
82+
!6 = !{i32 1, !"EnableSplitLTOUnit", i32 1}
83+
84+
;--- main-LTO.ll
85+
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
86+
target triple = "x86_64-unknown-linux-gnu"
87+
88+
; Function Attrs: noinline nounwind uwtable
89+
define dso_local i32 @main() #0 {
90+
entry:
91+
%retval = alloca i32, align 4
92+
store i32 0, ptr %retval, align 4
93+
%call = call i32 (...) @_start()
94+
ret i32 %call
95+
}
96+
97+
declare i32 @_start(...)
98+
99+
attributes #0 = { noinline nounwind uwtable }
100+
101+
!llvm.module.flags = !{!0, !1, !2, !3, !4, !5, !6}
102+
103+
!0 = !{i32 1, !"wchar_size", i32 4}
104+
!1 = !{i32 7, !"PIC Level", i32 2}
105+
!2 = !{i32 7, !"PIE Level", i32 2}
106+
!3 = !{i32 7, !"uwtable", i32 2}
107+
!4 = !{i32 7, !"frame-pointer", i32 2}
108+
!5 = !{i32 1, !"ThinLTO", i32 0}
109+
!6 = !{i32 1, !"EnableSplitLTOUnit", i32 1}

llvm/tools/gold/gold-plugin.cpp

-8
Original file line numberDiff line numberDiff line change
@@ -538,14 +538,6 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
538538
BufferRef = Buffer->getMemBufferRef();
539539
}
540540

541-
// Only use bitcode files for LTO. InputFile::create() will load bitcode
542-
// from the .llvmbc section within a binary object, this bitcode is typically
543-
// generated by -fembed-bitcode and is not to be used by LLVMgold.so for LTO.
544-
if (identify_magic(BufferRef.getBuffer()) != file_magic::bitcode) {
545-
*claimed = 0;
546-
return LDPS_OK;
547-
}
548-
549541
*claimed = 1;
550542

551543
Expected<std::unique_ptr<InputFile>> ObjOrErr = InputFile::create(BufferRef);

0 commit comments

Comments
 (0)