[lld] r331405 - Added support for ThinLTO plugin options : thinlto-index-only and thinlto-prefix-replace
Rumeet Dhindsa via llvm-commits
llvm-commits at lists.llvm.org
Wed May 2 14:40:07 PDT 2018
Author: rdhindsa
Date: Wed May 2 14:40:07 2018
New Revision: 331405
URL: http://llvm.org/viewvc/llvm-project?rev=331405&view=rev
Log:
Added support for ThinLTO plugin options : thinlto-index-only and thinlto-prefix-replace
Differential Revision: https://reviews.llvm.org/D46034
Added:
lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll
lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/InputFiles.cpp
lld/trunk/ELF/InputFiles.h
lld/trunk/ELF/LTO.cpp
lld/trunk/ELF/LTO.h
lld/trunk/ELF/SymbolTable.cpp
lld/trunk/test/ELF/lto/thinlto.ll
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed May 2 14:40:07 2018
@@ -94,6 +94,8 @@ struct Configuration {
llvm::StringRef SoName;
llvm::StringRef Sysroot;
llvm::StringRef ThinLTOCacheDir;
+ llvm::StringRef ThinLTOIndexOnlyObjectsFile;
+ llvm::StringRef ThinLTOPrefixReplace;
std::string Rpath;
std::vector<VersionDefinition> VersionDefinitions;
std::vector<llvm::StringRef> AuxiliaryList;
@@ -156,6 +158,7 @@ struct Configuration {
bool SysvHash = false;
bool Target1Rel;
bool Trace;
+ bool ThinLTOIndexOnly;
bool UndefinedVersion;
bool WarnBackrefs;
bool WarnCommon;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed May 2 14:40:07 2018
@@ -777,27 +777,37 @@ void LinkerDriver::readConfigs(opt::Inpu
// Parse LTO plugin-related options for compatibility with gold.
for (auto *Arg : Args.filtered(OPT_plugin_opt)) {
StringRef S = Arg->getValue();
- if (S == "disable-verify")
+ if (S == "disable-verify") {
Config->DisableVerify = true;
- else if (S == "save-temps")
+ } else if (S == "save-temps") {
Config->SaveTemps = true;
- else if (S.startswith("O"))
+ } else if (S.startswith("O")) {
Config->LTOO = parseInt(S.substr(1), Arg);
- else if (S.startswith("lto-partitions="))
+ } else if (S.startswith("lto-partitions=")) {
Config->LTOPartitions = parseInt(S.substr(15), Arg);
- else if (S.startswith("jobs="))
+ } else if (S.startswith("jobs=")) {
Config->ThinLTOJobs = parseInt(S.substr(5), Arg);
- else if (S.startswith("mcpu="))
+ } else if (S.startswith("mcpu=")) {
parseClangOption(Saver.save("-" + S), Arg->getSpelling());
- else if (S == "new-pass-manager")
+ } else if (S == "new-pass-manager") {
Config->LTONewPassManager = true;
- else if (S == "debug-pass-manager")
+ } else if (S == "debug-pass-manager") {
Config->LTODebugPassManager = true;
- else if (S.startswith("sample-profile="))
- Config->LTOSampleProfile = S.substr(strlen("sample-profile="));
- else if (!S.startswith("/") && !S.startswith("-fresolution=") &&
- !S.startswith("-pass-through=") && !S.startswith("thinlto"))
+ } else if (S.startswith("sample-profile=")) {
+ Config->LTOSampleProfile = S.substr(15);
+ } else if (S == "thinlto-index-only") {
+ Config->ThinLTOIndexOnly = true;
+ } else if (S.startswith("thinlto-index-only=")) {
+ Config->ThinLTOIndexOnly = true;
+ Config->ThinLTOIndexOnlyObjectsFile = S.substr(19);
+ } else if (S.startswith("thinlto-prefix-replace=")) {
+ Config->ThinLTOPrefixReplace = S.substr(23);
+ if (!Config->ThinLTOPrefixReplace.contains(';'))
+ error("thinlto-prefix-replace expects 'old;new' format");
+ } else if (!S.startswith("/") && !S.startswith("-fresolution=") &&
+ !S.startswith("-pass-through=") && !S.startswith("thinlto")) {
parseClangOption(S, Arg->getSpelling());
+ }
}
// Parse -mllvm options.
Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Wed May 2 14:40:07 2018
@@ -42,6 +42,7 @@ bool InputFile::IsInGroup;
uint32_t InputFile::NextGroupId;
std::vector<BinaryFile *> elf::BinaryFiles;
std::vector<BitcodeFile *> elf::BitcodeFiles;
+std::vector<LazyObjFile *> elf::LazyObjFiles;
std::vector<InputFile *> elf::ObjectFiles;
std::vector<InputFile *> elf::SharedFiles;
@@ -1024,9 +1025,10 @@ BitcodeFile::BitcodeFile(MemoryBufferRef
// this causes a collision which result in only one of the objects being
// taken into consideration at LTO time (which very likely causes undefined
// symbols later in the link stage).
- MemoryBufferRef MBRef(MB.getBuffer(),
- Saver.save(ArchiveName + MB.getBufferIdentifier() +
- utostr(OffsetInArchive)));
+ MemoryBufferRef MBRef(
+ MB.getBuffer(),
+ Saver.save(ArchiveName + MB.getBufferIdentifier() +
+ (ArchiveName.empty() ? "" : utostr(OffsetInArchive))));
Obj = CHECK(lto::InputFile::create(MBRef), this);
Triple T(Obj->getTargetTriple());
@@ -1128,11 +1130,6 @@ void BinaryFile::parse() {
Data.size(), 0, STB_GLOBAL, nullptr, nullptr);
}
-static bool isBitcode(MemoryBufferRef MB) {
- using namespace sys::fs;
- return identify_magic(MB.getBuffer()) == file_magic::bitcode;
-}
-
InputFile *elf::createObjectFile(MemoryBufferRef MB, StringRef ArchiveName,
uint64_t OffsetInArchive) {
if (isBitcode(MB))
@@ -1168,9 +1165,9 @@ InputFile *elf::createSharedFile(MemoryB
}
MemoryBufferRef LazyObjFile::getBuffer() {
- if (Seen)
+ if (AddedToLink)
return MemoryBufferRef();
- Seen = true;
+ AddedToLink = true;
return MB;
}
Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Wed May 2 14:40:07 2018
@@ -259,11 +259,11 @@ public:
template <class ELFT> void parse();
MemoryBufferRef getBuffer();
InputFile *fetch();
+ bool AddedToLink = false;
private:
template <class ELFT> void addElfSymbols();
- bool Seen = false;
uint64_t OffsetInArchive;
};
@@ -351,8 +351,13 @@ InputFile *createObjectFile(MemoryBuffer
uint64_t OffsetInArchive = 0);
InputFile *createSharedFile(MemoryBufferRef MB, StringRef DefaultSoName);
+inline bool isBitcode(MemoryBufferRef MB) {
+ return identify_magic(MB.getBuffer()) == llvm::file_magic::bitcode;
+}
+
extern std::vector<BinaryFile *> BinaryFiles;
extern std::vector<BitcodeFile *> BitcodeFiles;
+extern std::vector<LazyObjFile *> LazyObjFiles;
extern std::vector<InputFile *> ObjectFiles;
extern std::vector<InputFile *> SharedFiles;
Modified: lld/trunk/ELF/LTO.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.cpp?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.cpp (original)
+++ lld/trunk/ELF/LTO.cpp Wed May 2 14:40:07 2018
@@ -20,6 +20,8 @@
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/ELF.h"
+#include "llvm/Bitcode/BitcodeReader.h"
+#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/LTO/Caching.h"
#include "llvm/LTO/Config.h"
@@ -29,7 +31,6 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cstddef>
#include <memory>
@@ -66,7 +67,57 @@ static void checkError(Error E) {
[&](ErrorInfoBase &EIB) { error(EIB.message()); });
}
-static std::unique_ptr<lto::LTO> createLTO() {
+// With the ThinLTOIndexOnly option, only the thin link is performed, and will
+// generate index files for the ThinLTO backends in a distributed build system.
+// The distributed build system may expect that index files are created for all
+// input bitcode objects provided to the linker for the thin link. However,
+// index files will not normally be created for input bitcode objects that
+// either aren't selected by the linker (i.e. in a static library and not
+// needed), or because they don't have a summary. Therefore we need to create
+// empty dummy index file outputs in those cases.
+// If SkipModule is true then .thinlto.bc should contain just
+// SkipModuleByDistributedBackend flag which requests distributed backend
+// to skip the compilation of the corresponding module and produce an empty
+// object file.
+static void writeEmptyDistributedBuildOutputs(const std::string &ModulePath,
+ const std::string &OldPrefix,
+ const std::string &NewPrefix,
+ bool SkipModule) {
+ std::string NewModulePath =
+ lto::getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix);
+ std::error_code EC;
+
+ raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC,
+ sys::fs::OpenFlags::F_None);
+ if (EC)
+ error("failed to write " + NewModulePath + ".thinlto.bc" + ": " +
+ EC.message());
+
+ if (SkipModule) {
+ ModuleSummaryIndex Index(false);
+ Index.setSkipModuleByDistributedBackend();
+ WriteIndexToFile(Index, OS);
+ }
+}
+
+// Creates and returns output stream with a list of object files for final
+// linking of distributed ThinLTO.
+static std::unique_ptr<raw_fd_ostream> createLinkedObjectsFile() {
+ if (Config->ThinLTOIndexOnlyObjectsFile.empty())
+ return nullptr;
+ std::error_code EC;
+ auto LinkedObjectsFile = llvm::make_unique<raw_fd_ostream>(
+ Config->ThinLTOIndexOnlyObjectsFile, EC, sys::fs::OpenFlags::F_None);
+ if (EC)
+ error("cannot create " + Config->ThinLTOIndexOnlyObjectsFile + ": " +
+ EC.message());
+ return LinkedObjectsFile;
+}
+
+// Creates instance of LTO.
+// LinkedObjectsFile is an output stream to write the list of object files for
+// the final ThinLTO linking. Can be nullptr.
+static std::unique_ptr<lto::LTO> createLTO(raw_fd_ostream *LinkedObjectsFile) {
lto::Config Conf;
// LLD supports the new relocations.
@@ -105,6 +156,13 @@ static std::unique_ptr<lto::LTO> createL
if (Config->ThinLTOJobs != -1u)
Backend = lto::createInProcessThinBackend(Config->ThinLTOJobs);
+ if (Config->ThinLTOIndexOnly) {
+ std::string OldPrefix, NewPrefix;
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');
+ Backend = lto::createWriteIndexesThinBackend(OldPrefix, NewPrefix, true,
+ LinkedObjectsFile, nullptr);
+ }
+
Conf.SampleProfile = Config->LTOSampleProfile;
Conf.UseNewPM = Config->LTONewPassManager;
Conf.DebugPassManager = Config->LTODebugPassManager;
@@ -113,7 +171,9 @@ static std::unique_ptr<lto::LTO> createL
Config->LTOPartitions);
}
-BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) {
+BitcodeCompiler::BitcodeCompiler() {
+ LinkedObjects = createLinkedObjectsFile();
+ LTOObj = createLTO(LinkedObjects.get());
for (Symbol *Sym : Symtab->getSymbols()) {
StringRef Name = Sym->getName();
for (StringRef Prefix : {"__start_", "__stop_"})
@@ -131,6 +191,13 @@ static void undefine(Symbol *S) {
void BitcodeCompiler::add(BitcodeFile &F) {
lto::InputFile &Obj = *F.Obj;
+
+ std::string OldPrefix, NewPrefix;
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');
+
+ // Create the empty files which, if indexed, will be overwritten later.
+ writeEmptyDistributedBuildOutputs(Obj.getName(), OldPrefix, NewPrefix, false);
+
unsigned SymNum = 0;
std::vector<Symbol *> Syms = F.getSymbols();
std::vector<lto::SymbolResolution> Resols(Syms.size());
@@ -188,6 +255,12 @@ std::vector<InputFile *> BitcodeCompiler
Buff.resize(MaxTasks);
Files.resize(MaxTasks);
+ // If LazyObjFile has not been added to link, emit empty index files
+ if (Config->ThinLTOIndexOnly)
+ for (LazyObjFile *F : LazyObjFiles)
+ if (!F->AddedToLink && isBitcode(F->MB))
+ addLazyObjFile(F);
+
// The --thinlto-cache-dir option specifies the path to a directory in which
// to cache native object files for ThinLTO incremental builds. If a path was
// specified, configure LTO to use it as the cache directory.
@@ -222,9 +295,24 @@ std::vector<InputFile *> BitcodeCompiler
Ret.push_back(Obj);
}
+ // ThinLTO with index only option is required to generate only the index
+ // files. After that, we exit from linker and ThinLTO backend runs in a
+ // distributed environment.
+ if (Config->ThinLTOIndexOnly)
+ exit(0);
+
for (std::unique_ptr<MemoryBuffer> &File : Files)
if (File)
Ret.push_back(createObjectFile(*File));
return Ret;
}
+
+// For lazy object files not added to link, adds empty index files
+void BitcodeCompiler::addLazyObjFile(LazyObjFile *File) {
+ StringRef Identifier = File->getBuffer().getBufferIdentifier();
+ std::string OldPrefix, NewPrefix;
+ std::tie(OldPrefix, NewPrefix) = Config->ThinLTOPrefixReplace.split(';');
+ writeEmptyDistributedBuildOutputs(Identifier, OldPrefix, NewPrefix,
+ /* SkipModule */ true);
+}
Modified: lld/trunk/ELF/LTO.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LTO.h?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/LTO.h (original)
+++ lld/trunk/ELF/LTO.h Wed May 2 14:40:07 2018
@@ -24,6 +24,7 @@
#include "lld/Common/LLVM.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/Support/raw_ostream.h"
#include <memory>
#include <vector>
@@ -38,6 +39,7 @@ namespace elf {
class BitcodeFile;
class InputFile;
+class LazyObjFile;
class BitcodeCompiler {
public:
@@ -46,12 +48,14 @@ public:
void add(BitcodeFile &F);
std::vector<InputFile *> compile();
+ void addLazyObjFile(LazyObjFile *File);
private:
std::unique_ptr<llvm::lto::LTO> LTOObj;
std::vector<SmallString<0>> Buff;
std::vector<std::unique_ptr<MemoryBuffer>> Files;
llvm::DenseSet<StringRef> UsedStartStop;
+ std::unique_ptr<llvm::raw_fd_ostream> LinkedObjects;
};
} // namespace elf
} // namespace lld
Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Wed May 2 14:40:07 2018
@@ -82,6 +82,7 @@ template <class ELFT> void SymbolTable::
// Lazy object file
if (auto *F = dyn_cast<LazyObjFile>(File)) {
+ LazyObjFiles.push_back(F);
F->parse<ELFT>();
return;
}
Added: lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll?rev=331405&view=auto
==============================================================================
--- lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll (added)
+++ lld/trunk/test/ELF/lto/Inputs/thinlto_empty.ll Wed May 2 14:40:07 2018
@@ -0,0 +1,2 @@
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
Modified: lld/trunk/test/ELF/lto/thinlto.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/thinlto.ll?rev=331405&r1=331404&r2=331405&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/thinlto.ll (original)
+++ lld/trunk/test/ELF/lto/thinlto.ll Wed May 2 14:40:07 2018
@@ -1,7 +1,37 @@
; REQUIRES: x86
+
+; First ensure that the ThinLTO handling in lld handles
+; bitcode without summary sections gracefully and generates index file.
+; RUN: llvm-as %s -o %t.o
+; RUN: llvm-as %p/Inputs/thinlto.ll -o %t2.o
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only -shared %t.o %t2.o -o %t3
+; RUN: ls %t2.o.thinlto.bc
+; RUN: not test -e %t3
+; RUN: ld.lld -m elf_x86_64 -shared %t.o %t2.o -o %t4
+; RUN: llvm-nm %t4 | FileCheck %s --check-prefix=NM
+
; Basic ThinLTO tests.
; RUN: opt -module-summary %s -o %t.o
; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.o
+; RUN: opt -module-summary %p/Inputs/thinlto_empty.ll -o %t4.o
+
+; Ensure lld generates an index and not a binary if requested.
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only -shared %t.o %t2.o -o %t3
+; RUN: llvm-bcanalyzer -dump %t.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND1
+; RUN: llvm-bcanalyzer -dump %t2.o.thinlto.bc | FileCheck %s --check-prefix=BACKEND2
+; RUN: not test -e %t3
+
+; Ensure lld generates an index even if the file is wrapped in --start-lib/--end-lib
+; RUN: rm -f %t2.o.thinlto.bc
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only -shared %t.o %t4.o --start-lib %t2.o --end-lib -o %t5
+; RUN: ls %t2.o.thinlto.bc
+
+; Ensure lld generates error if unable to write to index file
+; RUN: rm -f %t4.o.thinlto.bc
+; RUN: touch %t4.o.thinlto.bc
+; RUN: chmod 400 %t4.o.thinlto.bc
+; RUN: ld.lld -m elf_x86_64 --plugin-opt=thinlto-index-only -shared %t.o %t4.o -o %t5 2>&1 | FileCheck %s --check-prefix=ERR
+; ERR: failed to write {{.*}}4.o.thinlto.bc: Permission denied
; First force single-threaded mode
; RUN: rm -f %t.lto.o %t1.lto.o
@@ -15,16 +45,43 @@
; RUN: llvm-nm %t21.lto.o | FileCheck %s --check-prefix=NM1
; RUN: llvm-nm %t22.lto.o | FileCheck %s --check-prefix=NM2
-; NM1: T f
-; NM1-NOT: U g
-
-; NM2: T g
-
; Then check without --thinlto-jobs (which currently default to hardware_concurrency)
; We just check that we don't crash or fail (as it's not sure which tests are
; stable on the final output file itself.
; RUN: ld.lld -shared %t.o %t2.o -o %t2
+; NM: T f
+; NM1: T f
+; NM1-NOT: U g
+; NM2: T g
+
+; The backend index for this module contains summaries from itself and
+; Inputs/thinlto.ll, as it imports from the latter.
+; BACKEND1: <MODULE_STRTAB_BLOCK
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.o'
+; BACKEND1-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.o'
+; BACKEND1-NEXT: </MODULE_STRTAB_BLOCK
+; BACKEND1: <GLOBALVAL_SUMMARY_BLOCK
+; BACKEND1: <VERSION
+; BACKEND1: <FLAGS
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
+; BACKEND1: <VALUE_GUID op0={{1|2}} op1={{-3706093650706652785|-5300342847281564238}}
+; BACKEND1: <COMBINED
+; BACKEND1: <COMBINED
+; BACKEND1: </GLOBALVAL_SUMMARY_BLOCK
+
+; The backend index for Input/thinlto.ll contains summaries from itself only,
+; as it does not import anything.
+; BACKEND2: <MODULE_STRTAB_BLOCK
+; BACKEND2-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp2.o'
+; BACKEND2-NEXT: </MODULE_STRTAB_BLOCK
+; BACKEND2-NEXT: <GLOBALVAL_SUMMARY_BLOCK
+; BACKEND2-NEXT: <VERSION
+; BACKEND2-NEXT: <FLAGS
+; BACKEND2-NEXT: <VALUE_GUID op0=1 op1=-5300342847281564238
+; BACKEND2-NEXT: <COMBINED
+; BACKEND2-NEXT: </GLOBALVAL_SUMMARY_BLOCK
+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
Added: lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll?rev=331405&view=auto
==============================================================================
--- lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll (added)
+++ lld/trunk/test/ELF/lto/thinlto_prefix_replace.ll Wed May 2 14:40:07 2018
@@ -0,0 +1,23 @@
+; REQUIRES: x86
+; Check that changing the output path via thinlto-prefix-replace works
+; RUN: mkdir -p %t/oldpath
+; RUN: opt -module-summary %s -o %t/oldpath/thinlto_prefix_replace.o
+
+; Ensure that there is no existing file at the new path, so we properly
+; test the creation of the new file there.
+; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+; RUN: ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/;%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace
+; RUN: ls %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+
+; Ensure that lld generates error if prefix replace option does not have 'old;new' format
+; RUN: rm -f %t/newpath/thinlto_prefix_replace.o.thinlto.bc
+; RUN: not ld.lld --plugin-opt=thinlto-index-only --plugin-opt=thinlto-prefix-replace="%t/oldpath/:%t/newpath/" -shared %t/oldpath/thinlto_prefix_replace.o -o %t/thinlto_prefix_replace 2>&1 | FileCheck %s --check-prefix=ERR
+; ERR: thinlto-prefix-replace expects 'old;new' format
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @f() {
+entry:
+ ret void
+}
More information about the llvm-commits
mailing list