diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO')
| -rw-r--r-- | llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp index b39e881a2e7..393213f0810 100644 --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -30,11 +30,42 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/FunctionAttrs.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; namespace { +// Produce a unique identifier for this module by taking the MD5 sum of the +// names of the module's strong external symbols. This identifier is +// normally guaranteed to be unique, or the program would fail to link due to +// multiply defined symbols. +// +// If the module has no strong external symbols (such a module may still have a +// semantic effect if it performs global initialization), we cannot produce a +// unique identifier for this module, so we return the empty string, which +// causes the entire module to be written as a regular LTO module. +std::string getModuleId(Module *M) { + MD5 Md5; + bool ExportsSymbols = false; + for (auto &GV : M->global_values()) { + if (GV.isDeclaration() || GV.getName().startswith("llvm.") || + !GV.hasExternalLinkage()) + continue; + ExportsSymbols = true; + Md5.update(GV.getName()); + Md5.update(ArrayRef<uint8_t>{0}); + } + + if (!ExportsSymbols) + return ""; + + MD5::MD5Result R; + Md5.final(R); + + SmallString<32> Str; + MD5::stringifyResult(R, Str); + return ("$" + Str).str(); +} + // Promote each local-linkage entity defined by ExportM and used by ImportM by // changing visibility and appending the given ModuleId. void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId) { @@ -206,7 +237,7 @@ void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) { void splitAndWriteThinLTOBitcode( raw_ostream &OS, raw_ostream *ThinLinkOS, function_ref<AAResults &(Function &)> AARGetter, Module &M) { - std::string ModuleId = getUniqueModuleId(&M); + std::string ModuleId = getModuleId(&M); if (ModuleId.empty()) { // We couldn't generate a module ID for this module, just write it out as a // regular LTO module. |

