Index: include/llvm/Bitcode/LLVMBitCodes.h =================================================================== --- include/llvm/Bitcode/LLVMBitCodes.h +++ include/llvm/Bitcode/LLVMBitCodes.h @@ -212,8 +212,8 @@ FS_ALIAS = 7, // COMBINED_ALIAS: [valueid, modid, flags, valueid] FS_COMBINED_ALIAS = 8, - // COMBINED_ORIGINAL_NAME: [original_name_hash] - FS_COMBINED_ORIGINAL_NAME = 9, + // ORIGINAL_NAME: [original_name_hash] + FS_ORIGINAL_NAME = 9, // VERSION of the summary, bumped when adding flags for instance. FS_VERSION = 10, // The list of llvm.type.test type identifiers used by the following function Index: lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- lib/Bitcode/Reader/BitcodeReader.cpp +++ lib/Bitcode/Reader/BitcodeReader.cpp @@ -4803,7 +4803,7 @@ unsigned ValueID = Record[0]; GlobalValue::GUID RefGUID = Record[1]; // The "original name", which is the second value of the pair will be - // overriden later by a FS_COMBINED_ORIGINAL_NAME in the combined index. + // overriden later by a FS_ORIGINAL_NAME in the combined index. ValueIdToValueInfoMap[ValueID] = std::make_pair(TheIndex.getOrInsertValueInfo(RefGUID), RefGUID); break; @@ -5083,6 +5083,8 @@ auto VIAndOriginalGUID = getValueInfoFromValueId(ValueID); FS->setModulePath(addThisModule()->first()); FS->setOriginalName(VIAndOriginalGUID.second); + LastSeenSummary = FS.get(); + LastSeenGUID = getValueInfoFromValueId(ValueID).first.getGUID(); TheIndex.addGlobalValueSummary(VIAndOriginalGUID.first, std::move(FS)); break; } @@ -5113,6 +5115,8 @@ auto GUID = getValueInfoFromValueId(ValueID); AS->setOriginalName(GUID.second); + LastSeenSummary = AS.get(); + LastSeenGUID = getValueInfoFromValueId(ValueID).first.getGUID(); TheIndex.addGlobalValueSummary(GUID.first, std::move(AS)); break; } @@ -5127,6 +5131,8 @@ FS->setModulePath(addThisModule()->first()); auto GUID = getValueInfoFromValueId(ValueID); FS->setOriginalName(GUID.second); + LastSeenSummary = FS.get(); + LastSeenGUID = getValueInfoFromValueId(ValueID).first.getGUID(); TheIndex.addGlobalValueSummary(GUID.first, std::move(FS)); break; } @@ -5212,8 +5218,8 @@ TheIndex.addGlobalValueSummary(VI, std::move(FS)); break; } - // FS_COMBINED_ORIGINAL_NAME: [original_name] - case bitc::FS_COMBINED_ORIGINAL_NAME: { + // FS_ORIGINAL_NAME: [original_name] + case bitc::FS_ORIGINAL_NAME: { uint64_t OriginalName = Record[0]; if (!LastSeenSummary) return error("Name attachment that does not follow a combined record"); Index: lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- lib/Bitcode/Writer/BitcodeWriter.cpp +++ lib/Bitcode/Writer/BitcodeWriter.cpp @@ -127,9 +127,9 @@ /// The start bit of the identification block. uint64_t BitcodeStartBit; - /// Map that holds the correspondence between GUIDs in the summary index, - /// that came from indirect call profiles, and a value id generated by this - /// class to use in the VST and summary block records. + /// Map that holds the correspondence between GUIDs in the summary index + /// and a value id generated by this class to use in the VST and summary + /// block records. std::map<GlobalValue::GUID, unsigned> GUIDToValueIdMap; /// Tracks the last value id recorded in the GUIDToValueMap. @@ -151,25 +151,7 @@ VE(*M, ShouldPreserveUseListOrder), Index(Index), GenerateHash(GenerateHash), ModHash(ModHash), BitcodeStartBit(Stream.GetCurrentBitNo()) { - // Assign ValueIds to any callee values in the index that came from - // indirect call profiles and were recorded as a GUID not a Value* - // (which would have been assigned an ID by the ValueEnumerator). - // The starting ValueId is just after the number of values in the - // ValueEnumerator, so that they can be emitted in the VST. - GlobalValueId = VE.getValues().size(); - if (!Index) - return; - for (const auto &GUIDSummaryLists : *Index) - // Examine all summaries for this GUID. - for (auto &Summary : GUIDSummaryLists.second.SummaryList) - if (auto FS = dyn_cast<FunctionSummary>(Summary.get())) - // For each call in the function summary, see if the call - // is to a GUID (which means it is for an indirect call, - // otherwise we would have a Value for it). If so, synthesize - // a value id. - for (auto &CallEdge : FS->calls()) - if (!CallEdge.first.getValue()) - assignValueId(CallEdge.first.getGUID()); + setGUIDToValueIdMap(); } /// Emit the current module to the bitstream. @@ -316,8 +298,76 @@ return VE.getValueID(VI.getValue()); } std::map<GlobalValue::GUID, unsigned> &valueIds() { return GUIDToValueIdMap; } + void setGUIDToValueIdMap(); }; +void ModuleBitcodeWriter::setGUIDToValueIdMap() { + auto insertToGUIDToValueIdMap = [&](GlobalValue::GUID TheGUID, unsigned TheValueId) { + assert(TheGUID && "No GUID found in GlobalValueSummaryMap."); + GUIDToValueIdMap[TheGUID] = TheValueId; + }; + + for (const Function &F : M) { + insertToGUIDToValueIdMap(F.getGUID(), VE.getValueID(&F)); + ValueInfo VI = Index->getValueInfo(F.getGUID()); + if (!VI || VI.getSummaryList().empty()) { + // Only declarations should not have a summary (a declaration might + // however have a summary if the def was in module level asm). + assert(F.isDeclaration()); + continue; + } + + auto *FS = cast<FunctionSummary>(VI.getSummaryList()[0].get()); + for (auto &RI : FS->refs()) + insertToGUIDToValueIdMap(RI.getGUID(), VE.getValueID(RI.getValue())); + for (auto &ECI : FS->calls()) + insertToGUIDToValueIdMap(ECI.first.getGUID(), getValueId(ECI.first)); + } + + for (const GlobalVariable &G : M.globals()) { + insertToGUIDToValueIdMap(G.getGUID(), VE.getValueID(&G)); + ValueInfo VI = Index->getValueInfo(G.getGUID()); + if (!VI || VI.getSummaryList().empty()) { + // Only declarations should not have a summary (a declaration might + // however have a summary if the def was in module level asm). + assert(G.isDeclaration()); + continue; + } + + auto *VS = cast<GlobalVarSummary>(VI.getSummaryList()[0].get()); + for (auto &RI : VS->refs()) + insertToGUIDToValueIdMap(RI.getGUID(), VE.getValueID(RI.getValue())); + } + + for (const GlobalAlias &A : M.aliases()) { + auto *Aliasee = A.getBaseObject(); + if (!Aliasee->hasName()) + continue; + insertToGUIDToValueIdMap(A.getGUID(), VE.getValueID(&A)); + insertToGUIDToValueIdMap(Aliasee->getGUID(), VE.getValueID(Aliasee)); + } + + // Assign ValueIds to any callee values in the index that came from + // indirect call profiles and were recorded as a GUID not a Value* + // (which would have been assigned an ID by the ValueEnumerator). + // The starting ValueId is just after the number of values in the + // ValueEnumerator, so that they can be emitted in the VST. + GlobalValueId = VE.getValues().size(); + if (!Index) + return; + for (const auto &GUIDSummaryLists : *Index) + // Examine all summaries for this GUID. + for (auto &Summary : GUIDSummaryLists.second.SummaryList) + if (auto FS = dyn_cast<FunctionSummary>(Summary.get())) + // For each call in the function summary, see if the call + // is to a GUID (which means it is for an indirect call, + // otherwise we would have a Value for it). If so, synthesize + // a value id. + for (auto &CallEdge : FS->calls()) + if (!CallEdge.first.getValue()) + assignValueId(CallEdge.first.getGUID()); +} + /// Class to manage the bitcode writing for a combined index. class IndexBitcodeWriter : public BitcodeWriterBase { /// The combined index to write to bitcode. @@ -3383,6 +3433,15 @@ unsigned FSAliasAbbrev = Stream.EmitAbbrev(std::move(Abbv)); SmallVector<uint64_t, 64> NameVals; + // For local linkage, we also emit the original name separately + // immediately after the record. + auto MaybeEmitOriginalName = [&](const GlobalValue &GV) { + if (!GlobalValue::isLocalLinkage(GV.getLinkage())) + return; + NameVals.push_back(GlobalValue::getGUID(GV.getValueName()->getKey())); + Stream.EmitRecord(bitc::FS_ORIGINAL_NAME, NameVals); + NameVals.clear(); + }; // Iterate over the list of functions instead of the Index to // ensure the ordering is stable. for (const Function &F : M) { @@ -3401,12 +3460,15 @@ auto *Summary = VI.getSummaryList()[0].get(); writePerModuleFunctionSummaryRecord(NameVals, Summary, VE.getValueID(&F), FSCallsAbbrev, FSCallsProfileAbbrev, F); + MaybeEmitOriginalName(F); } // Capture references from GlobalVariable initializers, which are outside // of a function scope. - for (const GlobalVariable &G : M.globals()) + for (const GlobalVariable &G : M.globals()) { writeModuleLevelReferences(G, NameVals, FSModRefsAbbrev); + MaybeEmitOriginalName(G); + } for (const GlobalAlias &A : M.aliases()) { auto *Aliasee = A.getBaseObject(); @@ -3422,6 +3484,7 @@ NameVals.push_back(AliaseeId); Stream.EmitRecord(bitc::FS_ALIAS, NameVals, FSAliasAbbrev); NameVals.clear(); + MaybeEmitOriginalName(A); } Stream.ExitBlock(); @@ -3497,7 +3560,7 @@ if (!GlobalValue::isLocalLinkage(S.linkage())) return; NameVals.push_back(S.getOriginalName()); - Stream.EmitRecord(bitc::FS_COMBINED_ORIGINAL_NAME, NameVals); + Stream.EmitRecord(bitc::FS_ORIGINAL_NAME, NameVals); NameVals.clear(); }; Index: tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp =================================================================== --- tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -317,7 +317,7 @@ STRINGIFY_CODE(FS, COMBINED_GLOBALVAR_INIT_REFS) STRINGIFY_CODE(FS, ALIAS) STRINGIFY_CODE(FS, COMBINED_ALIAS) - STRINGIFY_CODE(FS, COMBINED_ORIGINAL_NAME) + STRINGIFY_CODE(FS, ORIGINAL_NAME) STRINGIFY_CODE(FS, VERSION) STRINGIFY_CODE(FS, TYPE_TESTS) STRINGIFY_CODE(FS, TYPE_TEST_ASSUME_VCALLS)