Skip to content
This repository was archived by the owner on Mar 28, 2020. It is now read-only.

Commit b81a1e9

Browse files
committed
[ThinLTO] Emit files for distributed builds for all modules
With the new LTO API in r278338, we stopped emitting the individual index files and imports files for some modules in the distributed backend case (thinlto-index-only plugin option). Specifically, this is when the linker decides not to include a module in the link, because it was in an archive library and did not have a strong reference to it. Not creating the expected output files makes the distributed build system implementation more difficult, in terms of checking for the expected outputs of the thin link, and scheduling the backend jobs. To address this, the gold-plugin will write dummy empty .thinlto.bc and .imports files for modules not included in the link (which LTO never sees). Augmented a gold v1.12+ test, since that version of gold has the handling for notifying on modules not being included in the link. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@282100 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 648d6ac commit b81a1e9

File tree

4 files changed

+77
-21
lines changed

4 files changed

+77
-21
lines changed

include/llvm/LTO/LTO.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ void thinLTOInternalizeAndPromoteInIndex(
8585

8686
namespace lto {
8787

88+
/// Given the original \p Path to an output file, replace any path
89+
/// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
90+
/// resulting directory if it does not yet exist.
91+
std::string getThinLTOOutputFile(const std::string &Path,
92+
const std::string &OldPrefix,
93+
const std::string &NewPrefix);
94+
8895
class LTO;
8996
struct SymbolResolution;
9097
class ThinBackendProc;

lib/LTO/LTO.cpp

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,26 @@ ThinBackend lto::createInProcessThinBackend(unsigned ParallelismLevel) {
609609
};
610610
}
611611

612+
// Given the original \p Path to an output file, replace any path
613+
// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
614+
// resulting directory if it does not yet exist.
615+
std::string lto::getThinLTOOutputFile(const std::string &Path,
616+
const std::string &OldPrefix,
617+
const std::string &NewPrefix) {
618+
if (OldPrefix.empty() && NewPrefix.empty())
619+
return Path;
620+
SmallString<128> NewPath(Path);
621+
llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
622+
StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
623+
if (!ParentPath.empty()) {
624+
// Make sure the new directory exists, creating it if necessary.
625+
if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
626+
llvm::errs() << "warning: could not create directory '" << ParentPath
627+
<< "': " << EC.message() << '\n';
628+
}
629+
return NewPath.str();
630+
}
631+
612632
class WriteIndexesThinBackend : public ThinBackendProc {
613633
std::string OldPrefix, NewPrefix;
614634
bool ShouldEmitImportsFiles;
@@ -627,26 +647,6 @@ class WriteIndexesThinBackend : public ThinBackendProc {
627647
ShouldEmitImportsFiles(ShouldEmitImportsFiles),
628648
LinkedObjectsFileName(LinkedObjectsFileName) {}
629649

630-
/// Given the original \p Path to an output file, replace any path
631-
/// prefix matching \p OldPrefix with \p NewPrefix. Also, create the
632-
/// resulting directory if it does not yet exist.
633-
std::string getThinLTOOutputFile(const std::string &Path,
634-
const std::string &OldPrefix,
635-
const std::string &NewPrefix) {
636-
if (OldPrefix.empty() && NewPrefix.empty())
637-
return Path;
638-
SmallString<128> NewPath(Path);
639-
llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix);
640-
StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str());
641-
if (!ParentPath.empty()) {
642-
// Make sure the new directory exists, creating it if necessary.
643-
if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath))
644-
llvm::errs() << "warning: could not create directory '" << ParentPath
645-
<< "': " << EC.message() << '\n';
646-
}
647-
return NewPath.str();
648-
}
649-
650650
Error start(
651651
unsigned Task, MemoryBufferRef MBRef,
652652
const FunctionImporter::ImportMapTy &ImportList,

test/tools/gold/X86/v1.12/thinlto_emit_linked_objects.ll

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,26 @@
99
; be included in the link, and not %t2.o since it is within
1010
; a library (--start-lib/--end-lib pair) and not strongly referenced.
1111
; Note that the support for detecting this is in gold v1.12.
12+
; RUN: rm -f %t.o.thinlto.bc
13+
; RUN: rm -f %t2.o.thinlto.bc
14+
; RUN: rm -f %t.o.imports
15+
; RUN: rm -f %t2.o.imports
1216
; RUN: %gold -plugin %llvmshlibdir/LLVMgold.so \
1317
; RUN: --plugin-opt=thinlto \
1418
; RUN: --plugin-opt=thinlto-index-only=%t3 \
19+
; RUN: --plugin-opt=thinlto-emit-imports-files \
1520
; RUN: -m elf_x86_64 \
1621
; RUN: -o %t4 \
1722
; RUN: %t.o \
1823
; RUN: --start-lib %t2.o --end-lib
1924

25+
; Ensure that the expected output files are created, even for the file
26+
; the linker decided not to include in the link.
27+
; RUN: ls %t.o.thinlto.bc
28+
; RUN: ls %t2.o.thinlto.bc
29+
; RUN: ls %t.o.imports
30+
; RUN: ls %t2.o.imports
31+
2032
; RUN: cat %t3 | FileCheck %s
2133
; CHECK: thinlto_emit_linked_objects.ll.tmp.o
2234
; CHECK-NOT: thinlto_emit_linked_objects.ll.tmp2.o

tools/gold/gold-plugin.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,34 @@ static std::unique_ptr<LTO> createLTO() {
752752
ParallelCodeGenParallelismLevel);
753753
}
754754

755+
// Write empty files that may be expected by a distributed build
756+
// system when invoked with thinlto_index_only. This is invoked when
757+
// the linker has decided not to include the given module in the
758+
// final link. Frequently the distributed build system will want to
759+
// confirm that all expected outputs are created based on all of the
760+
// modules provided to the linker.
761+
static void writeEmptyDistributedBuildOutputs(std::string &ModulePath,
762+
std::string &OldPrefix,
763+
std::string &NewPrefix) {
764+
std::string NewModulePath =
765+
getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
766+
std::error_code EC;
767+
{
768+
raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
769+
sys::fs::OpenFlags::F_None);
770+
if (EC)
771+
message(LDPL_FATAL, "Failed to write '%s': %s",
772+
(NewModulePath + ".thinlto.bc").c_str(), EC.message().c_str());
773+
}
774+
if (options::thinlto_emit_imports_files) {
775+
raw_fd_ostream OS(NewModulePath + ".imports", EC,
776+
sys::fs::OpenFlags::F_None);
777+
if (EC)
778+
message(LDPL_FATAL, "Failed to write '%s': %s",
779+
(NewModulePath + ".imports").c_str(), EC.message().c_str());
780+
}
781+
}
782+
755783
/// gold informs us that all symbols have been read. At this point, we use
756784
/// get_symbols to see if any of our definitions have been overridden by a
757785
/// native object file. Then, perform optimization and codegen.
@@ -771,13 +799,22 @@ static ld_plugin_status allSymbolsReadHook() {
771799

772800
std::unique_ptr<LTO> Lto = createLTO();
773801

802+
std::string OldPrefix, NewPrefix;
803+
if (options::thinlto_index_only)
804+
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
805+
774806
for (claimed_file &F : Modules) {
775807
if (options::thinlto && !HandleToInputFile.count(F.leader_handle))
776808
HandleToInputFile.insert(std::make_pair(
777809
F.leader_handle, llvm::make_unique<PluginInputFile>(F.handle)));
778810
const void *View = getSymbolsAndView(F);
779-
if (!View)
811+
if (!View) {
812+
if (options::thinlto_index_only)
813+
// Write empty output files that may be expected by the distributed
814+
// build system.
815+
writeEmptyDistributedBuildOutputs(F.name, OldPrefix, NewPrefix);
780816
continue;
817+
}
781818
addModule(*Lto, F, View);
782819
}
783820

0 commit comments

Comments
 (0)