From 0919a84071e55190643eb6e833a51755692b0d29 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Wed, 10 Feb 2016 18:57:54 +0000 Subject: [PATCH] [ThinLTO] Use MD5 hash in function index. Summary: This patch uses the lower 64-bits of the MD5 hash of a function name as a GUID in the function index, instead of storing function names. Any local functions are first given a global name by prepending the original source file name. This is the same naming scheme and GUID used by PGO in the indexed profile format. This change has a couple of benefits. The primary benefit is size reduction in the combined index file, for example 483.xalancbmk's combined index file was reduced by around 70%. It should also result in memory savings for the index file in memory, as the in-memory map is also indexed by the hash instead of the string. Second, this enables integration with indirect call promotion, since the indirect call profile targets are recorded using the same global naming convention and hash. This will enable the function importer to easily locate function summaries for indirect call profile targets to enable their import and subsequent promotion. The original source file name is recorded in the bitcode in a new module-level record for use in the ThinLTO backend pipeline. Reviewers: davidxl, joker.eph Subscribers: llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D17028 llvm-svn: 260408 --- llvm/include/llvm/Bitcode/LLVMBitCodes.h | 5 +- llvm/include/llvm/IR/Function.h | 7 ++ llvm/include/llvm/IR/FunctionInfo.h | 19 +++- llvm/include/llvm/IR/Module.h | 11 +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 54 +++++++++-- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 124 ++++++++++++------------- llvm/lib/IR/FunctionInfo.cpp | 17 +--- llvm/lib/IR/Module.cpp | 2 +- llvm/lib/Transforms/IPO/FunctionImport.cpp | 18 ++-- llvm/test/Bitcode/Inputs/source-filename.bc | Bin 0 -> 792 bytes llvm/test/Bitcode/source-filename.test | 2 + llvm/test/tools/gold/X86/thinlto.ll | 6 +- llvm/test/tools/llvm-lto/thinlto.ll | 6 +- llvm/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 1 + 14 files changed, 168 insertions(+), 104 deletions(-) create mode 100644 llvm/test/Bitcode/Inputs/source-filename.bc create mode 100644 llvm/test/Bitcode/source-filename.test diff --git a/llvm/include/llvm/Bitcode/LLVMBitCodes.h b/llvm/include/llvm/Bitcode/LLVMBitCodes.h index b27bc12..c7fa0dd 100644 --- a/llvm/include/llvm/Bitcode/LLVMBitCodes.h +++ b/llvm/include/llvm/Bitcode/LLVMBitCodes.h @@ -105,6 +105,9 @@ enum { BITCODE_CURRENT_EPOCH = 0 }; // METADATA_VALUES: [numvals] MODULE_CODE_METADATA_VALUES = 15, + + // SOURCE_FILENAME: [namechar x N] + MODULE_CODE_SOURCE_FILENAME = 16, }; /// PARAMATTR blocks have code for defining a parameter attribute set. @@ -172,7 +175,7 @@ enum { BITCODE_CURRENT_EPOCH = 0 }; VST_CODE_ENTRY = 1, // VST_ENTRY: [valueid, namechar x N] VST_CODE_BBENTRY = 2, // VST_BBENTRY: [bbid, namechar x N] VST_CODE_FNENTRY = 3, // VST_FNENTRY: [valueid, offset, namechar x N] - // VST_COMBINED_FNENTRY: [offset, namechar x N] + // VST_COMBINED_FNENTRY: [funcsumoffset, funcguid] VST_CODE_COMBINED_FNENTRY = 4 }; diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h index c00f80f..e441dc2 100644 --- a/llvm/include/llvm/IR/Function.h +++ b/llvm/include/llvm/IR/Function.h @@ -27,6 +27,7 @@ #include "llvm/IR/GlobalObject.h" #include "llvm/IR/OperandTraits.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/MD5.h" namespace llvm { @@ -650,6 +651,12 @@ public: GlobalValue::LinkageTypes Linkage, StringRef FileName); + /// Return a 64-bit global unique ID constructed from global function name + /// (i.e. returned by getGlobalIdentifier). + static uint64_t getGUID(StringRef GlobalFuncName) { + return MD5Hash(GlobalFuncName); + } + private: void allocHungoffUselist(); template void setHungoffOperand(Constant *C); diff --git a/llvm/include/llvm/IR/FunctionInfo.h b/llvm/include/llvm/IR/FunctionInfo.h index 41d407a..b724c54 100644 --- a/llvm/include/llvm/IR/FunctionInfo.h +++ b/llvm/include/llvm/IR/FunctionInfo.h @@ -18,6 +18,7 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/Function.h" #include "llvm/IR/Module.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/raw_ostream.h" @@ -146,8 +147,12 @@ public: /// COMDAT functions of the same name. typedef std::vector> FunctionInfoList; -/// Map from function name to corresponding function info structures. -typedef StringMap FunctionInfoMapTy; +/// Map from function GUID to corresponding function info structures. +/// Use a std::map rather than a DenseMap since it will likely incur +/// less overhead, as the value type is not very small and the size +/// of the map is unknown, resulting in inefficiencies due to repeated +/// insertions and resizing. +typedef std::map FunctionInfoMapTy; /// Type used for iterating through the function info map. typedef FunctionInfoMapTy::const_iterator const_funcinfo_iterator; @@ -184,17 +189,21 @@ public: /// Get the list of function info objects for a given function. const FunctionInfoList &getFunctionInfoList(StringRef FuncName) { - return FunctionMap[FuncName]; + return FunctionMap[Function::getGUID(FuncName)]; } /// Get the list of function info objects for a given function. const const_funcinfo_iterator findFunctionInfoList(StringRef FuncName) const { - return FunctionMap.find(FuncName); + return FunctionMap.find(Function::getGUID(FuncName)); } /// Add a function info for a function of the given name. void addFunctionInfo(StringRef FuncName, std::unique_ptr Info) { - FunctionMap[FuncName].push_back(std::move(Info)); + FunctionMap[Function::getGUID(FuncName)].push_back(std::move(Info)); + } + + void addFunctionInfo(uint64_t FuncGUID, std::unique_ptr Info) { + FunctionMap[FuncGUID].push_back(std::move(Info)); } /// Iterator to allow writer to walk through table during emission. diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h index 942f685..483f837 100644 --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -170,6 +170,8 @@ private: std::unique_ptr Materializer; ///< Used to materialize GlobalValues std::string ModuleID; ///< Human readable identifier for the module + std::string SourceFileName; ///< Original source file name for module, + ///< recorded in bitcode. std::string TargetTriple; ///< Platform target triple Module compiled on ///< Format: (arch)(sub)-(vendor)-(sys0-(abi) void *NamedMDSymTab; ///< NamedMDNode names. @@ -195,6 +197,12 @@ public: /// @returns the module identifier as a string const std::string &getModuleIdentifier() const { return ModuleID; } + /// Get the module's original source file name. When compiling from + /// bitcode, this is taken from a bitcode record where it was recorded. + /// For other compiles it is the same as the ModuleID, which would + /// contain the source file name. + const std::string &getSourceFileName() const { return SourceFileName; } + /// \brief Get a short "name" for the module. /// /// This is useful for debugging or logging. It is essentially a convenience @@ -240,6 +248,9 @@ public: /// Set the module identifier. void setModuleIdentifier(StringRef ID) { ModuleID = ID; } + /// Set the module's original source file name. + void setSourceFileName(StringRef Name) { SourceFileName = Name; } + /// Set the data layout void setDataLayout(StringRef Desc); void setDataLayout(const DataLayout &Other); diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 36eff13..8183a37 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -458,6 +458,9 @@ class FunctionIndexBitcodeReader { /// summary records. DenseMap ModuleIdMap; + /// Original source file name recorded in a bitcode record. + std::string SourceFileName; + public: std::error_code error(BitcodeError E, const Twine &Message); std::error_code error(BitcodeError E); @@ -3697,6 +3700,13 @@ std::error_code BitcodeReader::parseModule(uint64_t ResumeBit, assert(MetadataList.size() == 0); MetadataList.resize(NumModuleMDs); break; + /// MODULE_CODE_SOURCE_FILENAME: [namechar x N] + case bitc::MODULE_CODE_SOURCE_FILENAME: + SmallString<128> ValueName; + if (convertToString(Record, 0, ValueName)) + return error("Invalid record"); + TheModule->setSourceFileName(ValueName); + break; } Record.clear(); } @@ -5454,24 +5464,31 @@ std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable() { return error("Invalid record"); unsigned ValueID = Record[0]; uint64_t FuncOffset = Record[1]; - std::unique_ptr FuncInfo = - llvm::make_unique(FuncOffset); - if (foundFuncSummary() && !IsLazy) { + assert(!IsLazy && "Lazy summary read only supported for combined index"); + // Gracefully handle bitcode without a function summary section, + // which will simply not populate the index. + if (foundFuncSummary()) { DenseMap>::iterator SMI = SummaryMap.find(ValueID); assert(SMI != SummaryMap.end() && "Summary info not found"); + std::unique_ptr FuncInfo = + llvm::make_unique(FuncOffset); FuncInfo->setFunctionSummary(std::move(SMI->second)); + assert(!SourceFileName.empty()); + TheIndex->addFunctionInfo( + Function::getGlobalIdentifier( + ValueName, FuncInfo->functionSummary()->getFunctionLinkage(), + SourceFileName), + std::move(FuncInfo)); } - TheIndex->addFunctionInfo(ValueName, std::move(FuncInfo)); ValueName.clear(); break; } case bitc::VST_CODE_COMBINED_FNENTRY: { - // VST_CODE_FNENTRY: [offset, namechar x N] - if (convertToString(Record, 1, ValueName)) - return error("Invalid record"); + // VST_CODE_COMBINED_FNENTRY: [offset, funcguid] uint64_t FuncSummaryOffset = Record[0]; + uint64_t FuncGUID = Record[1]; std::unique_ptr FuncInfo = llvm::make_unique(FuncSummaryOffset); if (foundFuncSummary() && !IsLazy) { @@ -5480,7 +5497,7 @@ std::error_code FunctionIndexBitcodeReader::parseValueSymbolTable() { assert(SMI != SummaryMap.end() && "Summary info not found"); FuncInfo->setFunctionSummary(std::move(SMI->second)); } - TheIndex->addFunctionInfo(ValueName, std::move(FuncInfo)); + TheIndex->addFunctionInfo(FuncGUID, std::move(FuncInfo)); ValueName.clear(); break; @@ -5499,6 +5516,8 @@ std::error_code FunctionIndexBitcodeReader::parseModule() { if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) return error("Invalid record"); + SmallVector Record; + // Read the function index for this module. while (1) { BitstreamEntry Entry = Stream.advance(); @@ -5551,7 +5570,24 @@ std::error_code FunctionIndexBitcodeReader::parseModule() { continue; case BitstreamEntry::Record: - Stream.skipRecord(Entry.ID); + // Once we find the single record of interest, skip the rest. + if (!SourceFileName.empty()) + Stream.skipRecord(Entry.ID); + else { + Record.clear(); + auto BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: + break; // Default behavior, ignore unknown content. + /// MODULE_CODE_SOURCE_FILENAME: [namechar x N] + case bitc::MODULE_CODE_SOURCE_FILENAME: + SmallString<128> ValueName; + if (convertToString(Record, 0, ValueName)) + return error("Invalid record"); + SourceFileName = ValueName.c_str(); + break; + } + } continue; } } diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 2d0a7cf..0bca53a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -618,6 +618,24 @@ static uint64_t WriteValueSymbolTableForwardDecl(const ValueSymbolTable &VST, return Stream.GetCurrentBitNo() - 32; } +enum StringEncoding { SE_Char6, SE_Fixed7, SE_Fixed8 }; + +/// Determine the encoding to use for the given string name and length. +static StringEncoding getStringEncoding(const char *Str, unsigned StrLen) { + bool isChar6 = true; + for (const char *C = Str, *E = C + StrLen; C != E; ++C) { + if (isChar6) + isChar6 = BitCodeAbbrevOp::isChar6(*C); + if ((unsigned char)*C & 128) + // don't bother scanning the rest. + return SE_Fixed8; + } + if (isChar6) + return SE_Char6; + else + return SE_Fixed7; +} + /// Emit top-level description of module, including target triple, inline asm, /// descriptors for global variables, and function prototype info. /// Returns the bit offset to backpatch with the location of the real VST. @@ -791,13 +809,40 @@ static uint64_t WriteModuleInfo(const Module *M, const ValueEnumerator &VE, // function importing where we lazy load the metadata as a postpass, // we want to avoid parsing the module-level metadata before parsing // the imported functions. - BitCodeAbbrev *Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_METADATA_VALUES)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); - unsigned MDValsAbbrev = Stream.EmitAbbrev(Abbv); - Vals.push_back(VE.numMDs()); - Stream.EmitRecord(bitc::MODULE_CODE_METADATA_VALUES, Vals, MDValsAbbrev); - Vals.clear(); + { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_METADATA_VALUES)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + unsigned MDValsAbbrev = Stream.EmitAbbrev(Abbv); + Vals.push_back(VE.numMDs()); + Stream.EmitRecord(bitc::MODULE_CODE_METADATA_VALUES, Vals, MDValsAbbrev); + Vals.clear(); + } + + // Emit the module's source file name. + { + StringEncoding Bits = + getStringEncoding(M->getName().data(), M->getName().size()); + BitCodeAbbrevOp AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8); + if (Bits == SE_Char6) + AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Char6); + else if (Bits == SE_Fixed7) + AbbrevOpToUse = BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7); + + // MODULE_CODE_SOURCE_FILENAME: [namechar x N] + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_SOURCE_FILENAME)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(AbbrevOpToUse); + unsigned FilenameAbbrev = Stream.EmitAbbrev(Abbv); + + for (const auto P : M->getSourceFileName()) + Vals.push_back((unsigned char)P); + + // Emit the finished record. + Stream.EmitRecord(bitc::MODULE_CODE_SOURCE_FILENAME, Vals, FilenameAbbrev); + Vals.clear(); + } uint64_t VSTOffsetPlaceholder = WriteValueSymbolTableForwardDecl(M->getValueSymbolTable(), Stream); @@ -2195,24 +2240,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Vals.clear(); } -enum StringEncoding { SE_Char6, SE_Fixed7, SE_Fixed8 }; - -/// Determine the encoding to use for the given string name and length. -static StringEncoding getStringEncoding(const char *Str, unsigned StrLen) { - bool isChar6 = true; - for (const char *C = Str, *E = C + StrLen; C != E; ++C) { - if (isChar6) - isChar6 = BitCodeAbbrevOp::isChar6(*C); - if ((unsigned char)*C & 128) - // don't bother scanning the rest. - return SE_Fixed8; - } - if (isChar6) - return SE_Char6; - else - return SE_Fixed7; -} - /// Emit names for globals/functions etc. The VSTOffsetPlaceholder, /// BitcodeStartBit and FunctionIndex are only passed for the module-level /// VST, where we are including a function bitcode index and need to @@ -2352,51 +2379,24 @@ static void WriteCombinedValueSymbolTable(const FunctionInfoIndex &Index, BitstreamWriter &Stream) { Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); - // 8-bit fixed-width VST_CODE_COMBINED_FNENTRY function strings. BitCodeAbbrev *Abbv = new BitCodeAbbrev(); Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); - unsigned FnEntry8BitAbbrev = Stream.EmitAbbrev(Abbv); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcsumoffset + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcguid + unsigned FnEntryAbbrev = Stream.EmitAbbrev(Abbv); - // 7-bit fixed width VST_CODE_COMBINED_FNENTRY function strings. - Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); - unsigned FnEntry7BitAbbrev = Stream.EmitAbbrev(Abbv); - - // 6-bit char6 VST_CODE_COMBINED_FNENTRY function strings. - Abbv = new BitCodeAbbrev(); - Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_COMBINED_FNENTRY)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // funcoffset - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); - unsigned FnEntry6BitAbbrev = Stream.EmitAbbrev(Abbv); - - // FIXME: We know if the type names can use 7-bit ascii. - SmallVector NameVals; + SmallVector NameVals; for (const auto &FII : Index) { - for (const auto &FI : FII.getValue()) { + for (const auto &FI : FII.second) { NameVals.push_back(FI->bitcodeIndex()); - StringRef FuncName = FII.first(); - - // Figure out the encoding to use for the name. - StringEncoding Bits = getStringEncoding(FuncName.data(), FuncName.size()); + uint64_t FuncGUID = FII.first; - // VST_CODE_COMBINED_FNENTRY: [funcsumoffset, namechar x N] - unsigned AbbrevToUse = FnEntry8BitAbbrev; - if (Bits == SE_Char6) - AbbrevToUse = FnEntry6BitAbbrev; - else if (Bits == SE_Fixed7) - AbbrevToUse = FnEntry7BitAbbrev; + // VST_CODE_COMBINED_FNENTRY: [funcsumoffset, funcguid] + unsigned AbbrevToUse = FnEntryAbbrev; - for (const auto P : FuncName) - NameVals.push_back((unsigned char)P); + NameVals.push_back(FuncGUID); // Emit the finished record. Stream.EmitRecord(bitc::VST_CODE_COMBINED_FNENTRY, NameVals, AbbrevToUse); @@ -2855,7 +2855,7 @@ static void WriteCombinedFunctionSummary(const FunctionInfoIndex &I, SmallVector NameVals; for (const auto &FII : I) { - for (auto &FI : FII.getValue()) { + for (auto &FI : FII.second) { FunctionSummary *FS = FI->functionSummary(); assert(FS); diff --git a/llvm/lib/IR/FunctionInfo.cpp b/llvm/lib/IR/FunctionInfo.cpp index e5f3dbb..2460239 100644 --- a/llvm/lib/IR/FunctionInfo.cpp +++ b/llvm/lib/IR/FunctionInfo.cpp @@ -23,7 +23,7 @@ void FunctionInfoIndex::mergeFrom(std::unique_ptr Other, StringRef ModPath; for (auto &OtherFuncInfoLists : *Other) { - std::string FuncName = OtherFuncInfoLists.getKey(); + uint64_t FuncGUID = OtherFuncInfoLists.first; FunctionInfoList &List = OtherFuncInfoLists.second; // Assert that the func info list only has one entry, since we shouldn't @@ -49,20 +49,9 @@ void FunctionInfoIndex::mergeFrom(std::unique_ptr Other, // string reference owned by the combined index. Info->functionSummary()->setModulePath(ModPath); - // If it is a local function, rename it. - if (GlobalValue::isLocalLinkage( - Info->functionSummary()->getFunctionLinkage())) { - // Any local functions are virtually renamed when being added to the - // combined index map, to disambiguate from other functions with - // the same name. The symbol table created for the combined index - // file should contain the renamed symbols. - FuncName = - FunctionInfoIndex::getGlobalNameForLocal(FuncName, NextModuleId); - } - // Add new function info to existing list. There may be duplicates when // combining FunctionMap entries, due to COMDAT functions. Any local - // functions were virtually renamed above. - addFunctionInfo(FuncName, std::move(Info)); + // functions were given unique global IDs. + addFunctionInfo(FuncGUID, std::move(Info)); } } diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index ac578d6..fc3f9d0 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -47,7 +47,7 @@ template class llvm::SymbolTableListTraits; // Module::Module(StringRef MID, LLVMContext &C) - : Context(C), Materializer(), ModuleID(MID), DL("") { + : Context(C), Materializer(), ModuleID(MID), SourceFileName(MID), DL("") { ValSymTab = new ValueSymbolTable(); NamedMDSymTab = new StringMap(); Context.addModule(this); diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp index e402f93..a33216d 100644 --- a/llvm/lib/Transforms/IPO/FunctionImport.cpp +++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp @@ -126,7 +126,11 @@ static void findExternalCalls(const Module &DestModule, Function &F, if (CalledFunction->hasInternalLinkage()) { ImportedName = Renamed; } - auto It = CalledFunctions.insert(ImportedName); + // Compute the global identifier used in the function index. + auto CalledFunctionGlobalID = Function::getGlobalIdentifier( + CalledFunction->getName(), CalledFunction->getLinkage(), + CalledFunction->getParent()->getSourceFileName()); + auto It = CalledFunctions.insert(CalledFunctionGlobalID); if (!It.second) { // This is a call to a function we already considered, skip. continue; @@ -213,14 +217,12 @@ static void GetImportList(Module &DestModule, GlobalValue *SGV = SrcModule.getNamedValue(CalledFunctionName); if (!SGV) { - // The destination module is referencing function using their renamed name - // when importing a function that was originally local in the source - // module. The source module we have might not have been renamed so we try - // to remove the suffix added during the renaming to recover the original + // The function is referenced by a global identifier, which has the + // source file name prepended for functions that were originally local + // in the source module. Strip any prepended name to recover the original // name in the source module. - std::pair Split = - CalledFunctionName.split(".llvm."); - SGV = SrcModule.getNamedValue(Split.first); + std::pair Split = CalledFunctionName.split(":"); + SGV = SrcModule.getNamedValue(Split.second); assert(SGV && "Can't find function to import in source module"); } if (!SGV) { diff --git a/llvm/test/Bitcode/Inputs/source-filename.bc b/llvm/test/Bitcode/Inputs/source-filename.bc new file mode 100644 index 0000000000000000000000000000000000000000..3f327f4bf3c4990dceaf2d35836c045ebaf392cd GIT binary patch literal 792 zcmYjOT}V@582;wj_D#3WPP$;)IqR$pgo?%_+d3`UPKlBilQ4{moTeC2oc*-Tt&20a z__P+BWfzOOaL_N^D0bn6ggU7uONK;f40C8hLPh!^gD(1#F1q-h7vA^bdEWQ=9Q^pg zAsqk;06@FORNZv;RdMa-u>&o4C`AVMjT!*P@J!vyf)ZRS@Pm;(342D~sHDu+yRw*O zuR>L6kl$_>WEC8ig)4aPu#a_B8A7CHFFf7GVlCHd|H?EFVH&JpzhAE)JbYq<0HWl1pwC))U zw8B6Tg#}dChI|4FjiWjX3_L^II-TUz92vqWk^bW_)CPSyWl@B}Aat`Zm{YEcFhoKB zAoQ~TrXv*eh_HND#+g&OJXP;LUH>(jH$R>442)jz-}z<&U#C`W$cSL4S4ZQH4BND@rL?Y5Cv%5M*u7v;V^*7E_@|L-|)sN?AGt>E% zC-SYEhV=lP!P>Pdk)A5hT{@YqkGI6qafb+dg3z0EYl=X-Mv>n|vR30TOinN}DZ0y~ z*rG*uW(iw{x5WutHW>E_Fsy<-4M-4RNFe+{B(SJ5yPaH>$bw0G&7@u0AUB+3Ej7g~ z80k49GwCvPnfkf0D3{}{FNvdL(W5bf%WmlWZ7|#o4|gLEMiB`T6561@2KqM@ST-P{ ziz?*SBTo|bBqRIRH^}ux^2a#2Y9iV*DSA0YXSXo#qNk1YRD_v!DL+WOHN#tzTR57w z+~X~M1a~ie5S#w)<=zwAP+IfmG7?&mM~M2mVG#eT9{C1Q<;-dAI?#S~lFJggbX;3t z$yIy>Tf^ih43l=ltdY(~4EaTRxxjpp8M^e%mLdMg!zhPyeU9^0gK)}oPFF)|Ai3}yrH2V{sFZ~y=R literal 0 HcmV?d00001 diff --git a/llvm/test/Bitcode/source-filename.test b/llvm/test/Bitcode/source-filename.test new file mode 100644 index 0000000..d12cd3b --- /dev/null +++ b/llvm/test/Bitcode/source-filename.test @@ -0,0 +1,2 @@ +; RUN: llvm-bcanalyzer -dump %p/Inputs/source-filename.bc | FileCheck %s +; CHECK: