summaryrefslogtreecommitdiffstats
path: root/llvm/tools
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools')
-rw-r--r--llvm/tools/gold/gold-plugin.cpp59
-rw-r--r--llvm/tools/opt/opt.cpp21
2 files changed, 75 insertions, 5 deletions
diff --git a/llvm/tools/gold/gold-plugin.cpp b/llvm/tools/gold/gold-plugin.cpp
index 38674d20717..719c5db050a 100644
--- a/llvm/tools/gold/gold-plugin.cpp
+++ b/llvm/tools/gold/gold-plugin.cpp
@@ -164,6 +164,12 @@ namespace options {
// corresponding bitcode file, will use a path formed by replacing the
// bitcode file's path prefix matching oldprefix with newprefix.
static std::string thinlto_prefix_replace;
+ // Option to control the name of modules encoded in the individual index
+ // files for a distributed backend. This enables the use of minimized
+ // bitcode files for the thin link, assuming the name of the full bitcode
+ // file used in the backend differs just in some part of the file suffix.
+ // If specified, expects a string of the form "oldsuffix:newsuffix".
+ static std::string thinlto_object_suffix_replace;
// Optional path to a directory for caching ThinLTO objects.
static std::string cache_dir;
// Additional options to pass into the code generator.
@@ -206,6 +212,12 @@ namespace options {
thinlto_prefix_replace = opt.substr(strlen("thinlto-prefix-replace="));
if (thinlto_prefix_replace.find(';') == std::string::npos)
message(LDPL_FATAL, "thinlto-prefix-replace expects 'old;new' format");
+ } else if (opt.startswith("thinlto-object-suffix-replace=")) {
+ thinlto_object_suffix_replace =
+ opt.substr(strlen("thinlto-object-suffix-replace="));
+ if (thinlto_object_suffix_replace.find(';') == std::string::npos)
+ message(LDPL_FATAL,
+ "thinlto-object-suffix-replace expects 'old;new' format");
} else if (opt.startswith("cache-dir=")) {
cache_dir = opt.substr(strlen("cache-dir="));
} else if (opt.size() == 2 && opt[0] == 'O') {
@@ -566,8 +578,35 @@ static const void *getSymbolsAndView(claimed_file &F) {
return View;
}
-static void addModule(LTO &Lto, claimed_file &F, const void *View) {
- MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize), F.name);
+/// Parse the thinlto-object-suffix-replace option into the \p OldSuffix and
+/// \p NewSuffix strings, if it was specified.
+static void getThinLTOOldAndNewSuffix(std::string &OldSuffix,
+ std::string &NewSuffix) {
+ assert(options::thinlto_object_suffix_replace.empty() ||
+ options::thinlto_object_suffix_replace.find(";") != StringRef::npos);
+ StringRef SuffixReplace = options::thinlto_object_suffix_replace;
+ std::pair<StringRef, StringRef> Split = SuffixReplace.split(";");
+ OldSuffix = Split.first.str();
+ NewSuffix = Split.second.str();
+}
+
+/// Given the original \p Path to an output file, replace any filename
+/// suffix matching \p OldSuffix with \p NewSuffix.
+static std::string getThinLTOObjectFileName(const std::string Path,
+ const std::string &OldSuffix,
+ const std::string &NewSuffix) {
+ if (OldSuffix.empty() && NewSuffix.empty())
+ return Path;
+ StringRef NewPath = Path;
+ NewPath.consume_back(OldSuffix);
+ std::string NewNewPath = NewPath.str() + NewSuffix;
+ return NewPath.str() + NewSuffix;
+}
+
+static void addModule(LTO &Lto, claimed_file &F, const void *View,
+ StringRef Filename) {
+ MemoryBufferRef BufferRef(StringRef((const char *)View, F.filesize),
+ Filename);
Expected<std::unique_ptr<InputFile>> ObjOrErr = InputFile::create(BufferRef);
if (!ObjOrErr)
@@ -789,19 +828,31 @@ static ld_plugin_status allSymbolsReadHook() {
if (options::thinlto_index_only)
getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix);
+ std::string OldSuffix, NewSuffix;
+ getThinLTOOldAndNewSuffix(OldSuffix, NewSuffix);
+ // Set for owning string objects used as buffer identifiers.
+ StringSet<> ObjectFilenames;
+
for (claimed_file &F : Modules) {
if (options::thinlto && !HandleToInputFile.count(F.leader_handle))
HandleToInputFile.insert(std::make_pair(
F.leader_handle, llvm::make_unique<PluginInputFile>(F.handle)));
const void *View = getSymbolsAndView(F);
+ // In case we are thin linking with a minimized bitcode file, ensure
+ // the module paths encoded in the index reflect where the backends
+ // will locate the full bitcode files for compiling/importing.
+ std::string Identifier =
+ getThinLTOObjectFileName(F.name, OldSuffix, NewSuffix);
+ auto ObjFilename = ObjectFilenames.insert(Identifier);
+ assert(ObjFilename.second);
if (!View) {
if (options::thinlto_index_only)
// Write empty output files that may be expected by the distributed
// build system.
- writeEmptyDistributedBuildOutputs(F.name, OldPrefix, NewPrefix);
+ writeEmptyDistributedBuildOutputs(Identifier, OldPrefix, NewPrefix);
continue;
}
- addModule(*Lto, F, View);
+ addModule(*Lto, F, View, ObjFilename.first->first());
}
SmallString<128> Filename;
diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp
index 48eda15bd1e..40459e55998 100644
--- a/llvm/tools/opt/opt.cpp
+++ b/llvm/tools/opt/opt.cpp
@@ -102,6 +102,11 @@ static cl::opt<bool>
OutputThinLTOBC("thinlto-bc",
cl::desc("Write output as ThinLTO-ready bitcode"));
+static cl::opt<std::string> ThinLinkBitcodeFile(
+ "thin-link-bitcode-file", cl::value_desc("filename"),
+ cl::desc(
+ "A file in which to write minimized bitcode for the thin link only"));
+
static cl::opt<bool>
NoVerify("disable-verify", cl::desc("Do not run the verifier"), cl::Hidden);
@@ -456,6 +461,7 @@ int main(int argc, char **argv) {
// Figure out what stream we are supposed to write to...
std::unique_ptr<tool_output_file> Out;
+ std::unique_ptr<tool_output_file> ThinLinkOut;
if (NoOutput) {
if (!OutputFilename.empty())
errs() << "WARNING: The -o (output filename) option is ignored when\n"
@@ -471,6 +477,15 @@ int main(int argc, char **argv) {
errs() << EC.message() << '\n';
return 1;
}
+
+ if (!ThinLinkBitcodeFile.empty()) {
+ ThinLinkOut.reset(
+ new tool_output_file(ThinLinkBitcodeFile, EC, sys::fs::F_None));
+ if (EC) {
+ errs() << EC.message() << '\n';
+ return 1;
+ }
+ }
}
Triple ModuleTriple(M->getTargetTriple());
@@ -700,7 +715,8 @@ int main(int argc, char **argv) {
report_fatal_error("Text output is incompatible with -module-hash");
Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder));
} else if (OutputThinLTOBC)
- Passes.add(createWriteThinLTOBitcodePass(*OS));
+ Passes.add(createWriteThinLTOBitcodePass(
+ *OS, ThinLinkOut ? &ThinLinkOut->os() : nullptr));
else
Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder,
EmitSummaryIndex, EmitModuleHash));
@@ -747,5 +763,8 @@ int main(int argc, char **argv) {
if (YamlFile)
YamlFile->keep();
+ if (ThinLinkOut)
+ ThinLinkOut->keep();
+
return 0;
}
OpenPOWER on IntegriCloud