2016-03-15 08:04:37 +08:00
|
|
|
//===-- ModuleSummaryIndex.cpp - Module Summary Index ---------------------===//
|
2016-03-15 05:18:10 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file implements the module index and summary classes for the
|
|
|
|
// IR library.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
#include "llvm/IR/ModuleSummaryIndex.h"
|
2016-03-15 05:18:10 +08:00
|
|
|
#include "llvm/ADT/StringMap.h"
|
|
|
|
using namespace llvm;
|
|
|
|
|
|
|
|
// Create the combined module index/summary from multiple
|
|
|
|
// per-module instances.
|
2016-03-15 08:04:37 +08:00
|
|
|
void ModuleSummaryIndex::mergeFrom(std::unique_ptr<ModuleSummaryIndex> Other,
|
|
|
|
uint64_t NextModuleId) {
|
2016-10-08 12:44:18 +08:00
|
|
|
if (Other->modulePaths().empty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
assert(Other->modulePaths().size() == 1 &&
|
|
|
|
"Can only merge from an single-module index at that time");
|
|
|
|
|
|
|
|
StringRef OtherModPath = Other->modulePaths().begin()->first();
|
|
|
|
StringRef ModPath = addModulePath(OtherModPath, NextModuleId,
|
|
|
|
Other->getModuleHash(OtherModPath))
|
|
|
|
->first();
|
2016-03-15 05:18:10 +08:00
|
|
|
|
2016-04-24 22:57:11 +08:00
|
|
|
for (auto &OtherGlobalValSummaryLists : *Other) {
|
|
|
|
GlobalValue::GUID ValueGUID = OtherGlobalValSummaryLists.first;
|
|
|
|
GlobalValueSummaryList &List = OtherGlobalValSummaryLists.second;
|
2016-03-15 05:18:10 +08:00
|
|
|
|
2016-04-24 22:57:11 +08:00
|
|
|
// Assert that the value summary list only has one entry, since we shouldn't
|
2016-03-15 05:18:10 +08:00
|
|
|
// have duplicate names within a single per-module index.
|
|
|
|
assert(List.size() == 1);
|
2016-04-24 22:57:11 +08:00
|
|
|
std::unique_ptr<GlobalValueSummary> Summary = std::move(List.front());
|
2016-03-15 05:18:10 +08:00
|
|
|
|
|
|
|
// Note the module path string ref was copied above and is still owned by
|
|
|
|
// the original per-module index. Reset it to the new module path
|
|
|
|
// string reference owned by the combined index.
|
2016-04-24 22:57:11 +08:00
|
|
|
Summary->setModulePath(ModPath);
|
2016-03-15 05:18:10 +08:00
|
|
|
|
2016-04-24 22:57:11 +08:00
|
|
|
// Add new value summary to existing list. There may be duplicates when
|
2016-03-15 05:18:10 +08:00
|
|
|
// combining GlobalValueMap entries, due to COMDAT values. Any local
|
|
|
|
// values were given unique global IDs.
|
2016-04-24 22:57:11 +08:00
|
|
|
addGlobalValueSummary(ValueGUID, std::move(Summary));
|
2016-03-15 05:18:10 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-15 08:04:37 +08:00
|
|
|
void ModuleSummaryIndex::removeEmptySummaryEntries() {
|
2016-03-15 05:18:10 +08:00
|
|
|
for (auto MI = begin(), MIE = end(); MI != MIE;) {
|
|
|
|
// Only expect this to be called on a per-module index, which has a single
|
|
|
|
// entry per value entry list.
|
|
|
|
assert(MI->second.size() == 1);
|
2016-04-24 22:57:11 +08:00
|
|
|
if (!MI->second[0])
|
2016-03-15 05:18:10 +08:00
|
|
|
MI = GlobalValueMap.erase(MI);
|
|
|
|
else
|
|
|
|
++MI;
|
|
|
|
}
|
|
|
|
}
|
2016-04-05 08:40:16 +08:00
|
|
|
|
2016-04-13 05:13:11 +08:00
|
|
|
// Collect for the given module the list of function it defines
|
|
|
|
// (GUID -> Summary).
|
|
|
|
void ModuleSummaryIndex::collectDefinedFunctionsForModule(
|
2016-04-26 05:09:51 +08:00
|
|
|
StringRef ModulePath, GVSummaryMapTy &GVSummaryMap) const {
|
2016-04-13 05:13:11 +08:00
|
|
|
for (auto &GlobalList : *this) {
|
|
|
|
auto GUID = GlobalList.first;
|
2016-04-24 22:57:11 +08:00
|
|
|
for (auto &GlobSummary : GlobalList.second) {
|
|
|
|
auto *Summary = dyn_cast_or_null<FunctionSummary>(GlobSummary.get());
|
2016-04-13 05:13:11 +08:00
|
|
|
if (!Summary)
|
|
|
|
// Ignore global variable, focus on functions
|
|
|
|
continue;
|
|
|
|
// Ignore summaries from other modules.
|
|
|
|
if (Summary->modulePath() != ModulePath)
|
|
|
|
continue;
|
2016-04-24 22:57:11 +08:00
|
|
|
GVSummaryMap[GUID] = Summary;
|
2016-04-13 05:13:11 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-16 15:02:16 +08:00
|
|
|
// Collect for each module the list of function it defines (GUID -> Summary).
|
|
|
|
void ModuleSummaryIndex::collectDefinedGVSummariesPerModule(
|
2016-04-26 05:09:51 +08:00
|
|
|
StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) const {
|
2016-04-16 15:02:16 +08:00
|
|
|
for (auto &GlobalList : *this) {
|
|
|
|
auto GUID = GlobalList.first;
|
2016-04-24 22:57:11 +08:00
|
|
|
for (auto &Summary : GlobalList.second) {
|
|
|
|
ModuleToDefinedGVSummaries[Summary->modulePath()][GUID] = Summary.get();
|
2016-04-16 15:02:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-24 22:57:11 +08:00
|
|
|
GlobalValueSummary *
|
|
|
|
ModuleSummaryIndex::getGlobalValueSummary(uint64_t ValueGUID,
|
|
|
|
bool PerModuleIndex) const {
|
|
|
|
auto SummaryList = findGlobalValueSummaryList(ValueGUID);
|
|
|
|
assert(SummaryList != end() && "GlobalValue not found in index");
|
|
|
|
assert((!PerModuleIndex || SummaryList->second.size() == 1) &&
|
2016-04-05 17:07:47 +08:00
|
|
|
"Expected a single entry per global value in per-module index");
|
2016-04-24 22:57:11 +08:00
|
|
|
auto &Summary = SummaryList->second[0];
|
|
|
|
return Summary.get();
|
2016-04-05 08:40:16 +08:00
|
|
|
}
|