diff options
Diffstat (limited to 'llvm/tools/gold/gold-plugin.cpp')
| -rw-r--r-- | llvm/tools/gold/gold-plugin.cpp | 59 |
1 files changed, 55 insertions, 4 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; |

