mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
[ThinLTO/gold] Support for getting list of included objects from gold
Summary: In the distributed backend case, the ThinLink step and the final native object link are separate processes. This can be problematic when archive libraries are involved in the link (e.g. via --start-lib/--end-lib pairs). The linker only includes objects from libraries when there is a strong reference to them, and depending on the intervening ThinLTO backend processes' importing/inlining, the strong references may appear different in the two link steps. See D22356 and D22467 for two scenarios where this causes issues. To ensure that the final link includes the same objects, this patch adds support for an "=filename" form of the thinlto-index-only plugin option, in which case objects gold included in the link are emitted to the given filename. This should be used as input to the final link (e.g. via the @filename option to gold), instead of listing all the objects within --start-lib/--end-lib pairs again. Note that the support for the gold callback that identifies included objects was added in gold version 1.12. Reviewers: davidxl, mehdi_amini Subscribers: llvm-commits, mehdi_amini Differential Revision: https://reviews.llvm.org/D22677 llvm-svn: 276450
This commit is contained in:
parent
95c770abfc
commit
00cb55d094
@ -0,0 +1,7 @@
|
|||||||
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
define void @foo() {
|
||||||
|
entry:
|
||||||
|
ret void
|
||||||
|
}
|
45
test/tools/gold/X86/thinlto_emit_linked_objects.ll
Normal file
45
test/tools/gold/X86/thinlto_emit_linked_objects.ll
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
; First generate bitcode with a module summary index for each file
|
||||||
|
; RUN: opt -module-summary %s -o %t.o
|
||||||
|
; RUN: opt -module-summary %p/Inputs/thinlto_emit_linked_objects.ll -o %t2.o
|
||||||
|
|
||||||
|
; Next do the ThinLink step, specifying thinlto-index-only so that the gold
|
||||||
|
; plugin exits after generating individual indexes. The objects the linker
|
||||||
|
; decided to include in the link should be emitted into the file specified
|
||||||
|
; after 'thinlto-index-only='. Note that in this test both files should
|
||||||
|
; be included in the link, but in a case where there was an object in
|
||||||
|
; a library that had no strongly referenced symbols, that file would not
|
||||||
|
; be included in the link and listed in the emitted file. However, this
|
||||||
|
; requires gold version 1.12.
|
||||||
|
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||||
|
; RUN: --plugin-opt=thinlto \
|
||||||
|
; RUN: --plugin-opt=thinlto-index-only=%t3 \
|
||||||
|
; RUN: -o %t5 \
|
||||||
|
; RUN: %t.o \
|
||||||
|
; RUN: --start-lib %t2.o --end-lib
|
||||||
|
|
||||||
|
; Do the same check for a thin archive (note that non-thin archives don't play
|
||||||
|
; well with thinlto-index-only because we need to have an object file to
|
||||||
|
; import from in the distributed ThinLTO backends).
|
||||||
|
; RUN: llvm-ar Tr %t2.a %t2.o
|
||||||
|
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
|
||||||
|
; RUN: --plugin-opt=thinlto \
|
||||||
|
; RUN: --plugin-opt=thinlto-index-only=%t4 \
|
||||||
|
; RUN: -o %t5 \
|
||||||
|
; RUN: %t.o \
|
||||||
|
; RUN: %t2.a
|
||||||
|
|
||||||
|
; RUN: cat %t3 | FileCheck %s
|
||||||
|
; RUN: cat %t4 | FileCheck %s
|
||||||
|
; CHECK: thinlto_emit_linked_objects.ll.tmp.o
|
||||||
|
; CHECK: thinlto_emit_linked_objects.ll.tmp2.o
|
||||||
|
|
||||||
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||||
|
target triple = "x86_64-unknown-linux-gnu"
|
||||||
|
|
||||||
|
define i32 @main() {
|
||||||
|
entry:
|
||||||
|
call void (...) @foo()
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
declare void @foo(...)
|
@ -188,6 +188,16 @@ namespace options {
|
|||||||
// the import decisions, and exit afterwards. The assumption is
|
// the import decisions, and exit afterwards. The assumption is
|
||||||
// that the build system will launch the backend processes.
|
// that the build system will launch the backend processes.
|
||||||
static bool thinlto_index_only = false;
|
static bool thinlto_index_only = false;
|
||||||
|
// If non-empty, holds the name of a file in which to write the list of
|
||||||
|
// oject files gold selected for inclusion in the link after symbol
|
||||||
|
// resolution (i.e. they had selected symbols). This will only be non-empty
|
||||||
|
// in the thinlto_index_only case. It is used to identify files, which may
|
||||||
|
// have originally been within archive libraries specified via
|
||||||
|
// --start-lib/--end-lib pairs, that should be included in the final
|
||||||
|
// native link process (since intervening function importing and inlining
|
||||||
|
// may change the symbol resolution detected in the final link and which
|
||||||
|
// files to include out of --start-lib/--end-lib libraries as a result).
|
||||||
|
static std::string thinlto_linked_objects_file;
|
||||||
// If true, when generating individual index files for distributed backends,
|
// If true, when generating individual index files for distributed backends,
|
||||||
// also generate a "${bitcodefile}.imports" file at the same location for each
|
// also generate a "${bitcodefile}.imports" file at the same location for each
|
||||||
// bitcode file, listing the files it imports from in plain text. This is to
|
// bitcode file, listing the files it imports from in plain text. This is to
|
||||||
@ -233,6 +243,9 @@ namespace options {
|
|||||||
thinlto = true;
|
thinlto = true;
|
||||||
} else if (opt == "thinlto-index-only") {
|
} else if (opt == "thinlto-index-only") {
|
||||||
thinlto_index_only = true;
|
thinlto_index_only = true;
|
||||||
|
} else if (opt.startswith("thinlto-index-only=")) {
|
||||||
|
thinlto_index_only = true;
|
||||||
|
thinlto_linked_objects_file = opt.substr(strlen("thinlto-index-only="));
|
||||||
} else if (opt == "thinlto-emit-imports-files") {
|
} else if (opt == "thinlto-emit-imports-files") {
|
||||||
thinlto_emit_imports_files = true;
|
thinlto_emit_imports_files = true;
|
||||||
} else if (opt.startswith("thinlto-prefix-replace=")) {
|
} else if (opt.startswith("thinlto-prefix-replace=")) {
|
||||||
@ -1409,6 +1422,18 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
|
|||||||
std::string OldPrefix, NewPrefix;
|
std::string OldPrefix, NewPrefix;
|
||||||
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
|
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
|
||||||
|
|
||||||
|
// If the user requested a list of objects gold included in the link,
|
||||||
|
// create and open the requested file.
|
||||||
|
raw_fd_ostream *ObjFileOS = nullptr;
|
||||||
|
if (!options::thinlto_linked_objects_file.empty()) {
|
||||||
|
std::error_code EC;
|
||||||
|
ObjFileOS = new raw_fd_ostream(options::thinlto_linked_objects_file, EC,
|
||||||
|
sys::fs::OpenFlags::F_None);
|
||||||
|
if (EC)
|
||||||
|
message(LDPL_FATAL, "Unable to open %s for writing: %s",
|
||||||
|
options::thinlto_linked_objects_file.c_str(),
|
||||||
|
EC.message().c_str());
|
||||||
|
}
|
||||||
// For each input bitcode file, generate an individual index that
|
// For each input bitcode file, generate an individual index that
|
||||||
// contains summaries only for its own global values, and for any that
|
// contains summaries only for its own global values, and for any that
|
||||||
// should be imported.
|
// should be imported.
|
||||||
@ -1417,6 +1442,18 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
|
|||||||
|
|
||||||
std::string NewModulePath =
|
std::string NewModulePath =
|
||||||
getThinLTOOutputFile(F.name, OldPrefix, NewPrefix);
|
getThinLTOOutputFile(F.name, OldPrefix, NewPrefix);
|
||||||
|
|
||||||
|
if (!options::thinlto_linked_objects_file.empty()) {
|
||||||
|
// If gold included any symbols from ths file in the link, emit path
|
||||||
|
// to the final object file, which should be included in the final
|
||||||
|
// native link.
|
||||||
|
if (get_symbols(F.handle, F.syms.size(), F.syms.data()) !=
|
||||||
|
LDPS_NO_SYMS) {
|
||||||
|
assert(ObjFileOS);
|
||||||
|
*ObjFileOS << NewModulePath << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
raw_fd_ostream OS((Twine(NewModulePath) + ".thinlto.bc").str(), EC,
|
raw_fd_ostream OS((Twine(NewModulePath) + ".thinlto.bc").str(), EC,
|
||||||
sys::fs::OpenFlags::F_None);
|
sys::fs::OpenFlags::F_None);
|
||||||
if (EC)
|
if (EC)
|
||||||
@ -1438,6 +1475,9 @@ static ld_plugin_status thinLTOLink(raw_fd_ostream *ApiFile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ObjFileOS)
|
||||||
|
ObjFileOS->close();
|
||||||
|
|
||||||
cleanup_hook();
|
cleanup_hook();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user