summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Analysis/Analysis.cpp1
-rw-r--r--llvm/lib/Analysis/CMakeLists.txt1
-rw-r--r--llvm/lib/Analysis/ModuleSummaryAnalysis.cpp186
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp196
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp32
-rw-r--r--llvm/lib/Bitcode/Writer/LLVMBuild.txt2
-rw-r--r--llvm/lib/LTO/ThinLTOCodeGenerator.cpp4
-rw-r--r--llvm/lib/Transforms/IPO/FunctionImport.cpp7
8 files changed, 268 insertions, 161 deletions
diff --git a/llvm/lib/Analysis/Analysis.cpp b/llvm/lib/Analysis/Analysis.cpp
index 77d89dcd7b5..63292b2464a 100644
--- a/llvm/lib/Analysis/Analysis.cpp
+++ b/llvm/lib/Analysis/Analysis.cpp
@@ -60,6 +60,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeMemDerefPrinterPass(Registry);
initializeMemoryDependenceWrapperPassPass(Registry);
initializeModuleDebugInfoPrinterPass(Registry);
+ initializeModuleSummaryIndexWrapperPassPass(Registry);
initializeObjCARCAAWrapperPassPass(Registry);
initializePostDominatorTreeWrapperPassPass(Registry);
initializeRegionInfoPassPass(Registry);
diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 72669289b08..0ec27443d8a 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -49,6 +49,7 @@ add_llvm_library(LLVMAnalysis
MemoryDependenceAnalysis.cpp
MemoryLocation.cpp
ModuleDebugInfoPrinter.cpp
+ ModuleSummaryAnalysis.cpp
ObjCARCAliasAnalysis.cpp
ObjCARCAnalysisUtils.cpp
ObjCARCInstKind.cpp
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
new file mode 100644
index 00000000000..5c8b0aab193
--- /dev/null
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -0,0 +1,186 @@
+//===- ModuleSummaryAnalysis.cpp - Module summary index builder -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass builds a ModuleSummaryIndex object for the module, to be written
+// to bitcode or LLVM assembly.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ModuleSummaryAnalysis.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
+#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
+#include "llvm/Analysis/BranchProbabilityInfo.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/Dominators.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/ValueSymbolTable.h"
+#include "llvm/Pass.h"
+using namespace llvm;
+
+#define DEBUG_TYPE "module-summary-analysis"
+
+// Walk through the operands of a given User via worklist iteration and populate
+// the set of GlobalValue references encountered. Invoked either on an
+// Instruction or a GlobalVariable (which walks its initializer).
+static void findRefEdges(const User *CurUser, DenseSet<const Value *> &RefEdges,
+ SmallPtrSet<const User *, 8> &Visited) {
+ SmallVector<const User *, 32> Worklist;
+ Worklist.push_back(CurUser);
+
+ while (!Worklist.empty()) {
+ const User *U = Worklist.pop_back_val();
+
+ if (!Visited.insert(U).second)
+ continue;
+
+ ImmutableCallSite CS(U);
+
+ for (const auto &OI : U->operands()) {
+ const User *Operand = dyn_cast<User>(OI);
+ if (!Operand)
+ continue;
+ if (isa<BlockAddress>(Operand))
+ continue;
+ if (isa<GlobalValue>(Operand)) {
+ // We have a reference to a global value. This should be added to
+ // the reference set unless it is a callee. Callees are handled
+ // specially by WriteFunction and are added to a separate list.
+ if (!(CS && CS.isCallee(&OI)))
+ RefEdges.insert(Operand);
+ continue;
+ }
+ Worklist.push_back(Operand);
+ }
+ }
+}
+
+void ModuleSummaryIndexBuilder::computeFunctionInfo(const Function &F,
+ BlockFrequencyInfo *BFI) {
+ // Summary not currently supported for anonymous functions, they must
+ // be renamed.
+ if (!F.hasName())
+ return;
+
+ unsigned NumInsts = 0;
+ // Map from callee ValueId to profile count. Used to accumulate profile
+ // counts for all static calls to a given callee.
+ DenseMap<const Value *, CalleeInfo> CallGraphEdges;
+ DenseSet<const Value *> RefEdges;
+
+ SmallPtrSet<const User *, 8> Visited;
+ for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E;
+ ++I) {
+ if (!isa<DbgInfoIntrinsic>(I))
+ ++NumInsts;
+
+ if (auto CS = ImmutableCallSite(&*I)) {
+ auto *CalledFunction = CS.getCalledFunction();
+ if (CalledFunction && CalledFunction->hasName() &&
+ !CalledFunction->isIntrinsic()) {
+ auto ScaledCount = BFI ? BFI->getBlockProfileCount(&*BB) : None;
+ auto *CalleeId =
+ M->getValueSymbolTable().lookup(CalledFunction->getName());
+ CallGraphEdges[CalleeId] +=
+ (ScaledCount ? ScaledCount.getValue() : 0);
+ }
+ }
+ findRefEdges(&*I, RefEdges, Visited);
+ }
+
+ std::unique_ptr<FunctionSummary> FuncSummary =
+ llvm::make_unique<FunctionSummary>(F.getLinkage(), NumInsts);
+ FuncSummary->addCallGraphEdges(CallGraphEdges);
+ FuncSummary->addRefEdges(RefEdges);
+ std::unique_ptr<GlobalValueInfo> GVInfo =
+ llvm::make_unique<GlobalValueInfo>(0, std::move(FuncSummary));
+ Index->addGlobalValueInfo(F.getName(), std::move(GVInfo));
+}
+
+void ModuleSummaryIndexBuilder::computeVariableInfo(const GlobalVariable &V) {
+ DenseSet<const Value *> RefEdges;
+ SmallPtrSet<const User *, 8> Visited;
+ findRefEdges(&V, RefEdges, Visited);
+ std::unique_ptr<GlobalVarSummary> GVarSummary =
+ llvm::make_unique<GlobalVarSummary>(V.getLinkage());
+ GVarSummary->addRefEdges(RefEdges);
+ std::unique_ptr<GlobalValueInfo> GVInfo =
+ llvm::make_unique<GlobalValueInfo>(0, std::move(GVarSummary));
+ Index->addGlobalValueInfo(V.getName(), std::move(GVInfo));
+}
+
+ModuleSummaryIndexBuilder::ModuleSummaryIndexBuilder(
+ const Module *M,
+ std::function<BlockFrequencyInfo *(const Function &F)> Ftor)
+ : Index(llvm::make_unique<ModuleSummaryIndex>()), M(M) {
+ // Compute summaries for all functions defined in module, and save in the
+ // index.
+ for (auto &F : *M) {
+ if (F.isDeclaration())
+ continue;
+
+ BlockFrequencyInfo *BFI = nullptr;
+ std::unique_ptr<BlockFrequencyInfo> BFIPtr;
+ if (Ftor)
+ BFI = Ftor(F);
+ else if (F.getEntryCount().hasValue()) {
+ LoopInfo LI{DominatorTree(const_cast<Function &>(F))};
+ BranchProbabilityInfo BPI{F, LI};
+ BFIPtr = llvm::make_unique<BlockFrequencyInfo>(F, BPI, LI);
+ BFI = BFIPtr.get();
+ }
+
+ computeFunctionInfo(F, BFI);
+ }
+
+ // Compute summaries for all variables defined in module, and save in the
+ // index.
+ for (const GlobalVariable &G : M->globals()) {
+ if (G.isDeclaration())
+ continue;
+ computeVariableInfo(G);
+ }
+}
+
+char ModuleSummaryIndexWrapperPass::ID = 0;
+INITIALIZE_PASS_BEGIN(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
+ "Module Summary Analysis", false, true)
+INITIALIZE_PASS_DEPENDENCY(BlockFrequencyInfoWrapperPass)
+INITIALIZE_PASS_END(ModuleSummaryIndexWrapperPass, "module-summary-analysis",
+ "Module Summary Analysis", false, true)
+
+ModulePass *llvm::createModuleSummaryIndexWrapperPass() {
+ return new ModuleSummaryIndexWrapperPass();
+}
+
+ModuleSummaryIndexWrapperPass::ModuleSummaryIndexWrapperPass()
+ : ModulePass(ID) {
+ initializeModuleSummaryIndexWrapperPassPass(*PassRegistry::getPassRegistry());
+}
+
+bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
+ IndexBuilder = llvm::make_unique<ModuleSummaryIndexBuilder>(
+ &M, [this](const Function &F) {
+ return &(this->getAnalysis<BlockFrequencyInfoWrapperPass>(
+ *const_cast<Function *>(&F))
+ .getBFI());
+ });
+ return false;
+}
+
+bool ModuleSummaryIndexWrapperPass::doFinalization(Module &M) {
+ IndexBuilder.reset();
+ return false;
+}
+
+void ModuleSummaryIndexWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<BlockFrequencyInfoWrapperPass>();
+}
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index d9a4de5ddbd..262dad652fc 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -13,12 +13,7 @@
#include "ValueEnumerator.h"
#include "llvm/ADT/StringExtras.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Analysis/BlockFrequencyInfo.h"
-#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
-#include "llvm/Analysis/BranchProbabilityInfo.h"
-#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Bitcode/BitstreamWriter.h"
#include "llvm/Bitcode/LLVMBitCodes.h"
#include "llvm/Bitcode/ReaderWriter.h"
@@ -26,10 +21,8 @@
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
-#include "llvm/IR/Dominators.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
-#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
@@ -2282,8 +2275,7 @@ static void WriteValueSymbolTable(
const ValueSymbolTable &VST, const ValueEnumerator &VE,
BitstreamWriter &Stream, uint64_t VSTOffsetPlaceholder = 0,
uint64_t BitcodeStartBit = 0,
- DenseMap<const Function *, std::unique_ptr<GlobalValueInfo>> *
- GlobalValueIndex = nullptr) {
+ DenseMap<const Function *, uint64_t> *FunctionToBitcodeIndex = nullptr) {
if (VST.empty()) {
// WriteValueSymbolTableForwardDecl should have returned early as
// well. Ensure this handling remains in sync by asserting that
@@ -2372,13 +2364,12 @@ static void WriteValueSymbolTable(
// Must be the module-level VST, where we pass in the Index and
// have a VSTOffsetPlaceholder. The function-level VST should not
// contain any Function symbols.
- assert(GlobalValueIndex);
+ assert(FunctionToBitcodeIndex);
assert(VSTOffsetPlaceholder > 0);
// Save the word offset of the function (from the start of the
// actual bitcode written to the stream).
- uint64_t BitcodeIndex =
- (*GlobalValueIndex)[F]->bitcodeIndex() - BitcodeStartBit;
+ uint64_t BitcodeIndex = (*FunctionToBitcodeIndex)[F] - BitcodeStartBit;
assert((BitcodeIndex & 31) == 0 && "function block not 32-bit aligned");
NameVals.push_back(BitcodeIndex / 32);
@@ -2500,61 +2491,14 @@ static void WriteUseListBlock(const Function *F, ValueEnumerator &VE,
Stream.ExitBlock();
}
-// Walk through the operands of a given User via worklist iteration and populate
-// the set of GlobalValue references encountered. Invoked either on an
-// Instruction or a GlobalVariable (which walks its initializer).
-static void findRefEdges(const User *CurUser, const ValueEnumerator &VE,
- DenseSet<unsigned> &RefEdges,
- SmallPtrSet<const User *, 8> &Visited) {
- SmallVector<const User *, 32> Worklist;
- Worklist.push_back(CurUser);
-
- while (!Worklist.empty()) {
- const User *U = Worklist.pop_back_val();
-
- if (!Visited.insert(U).second)
- continue;
-
- ImmutableCallSite CS(U);
-
- for (const auto &OI : U->operands()) {
- const User *Operand = dyn_cast<User>(OI);
- if (!Operand)
- continue;
- if (isa<BlockAddress>(Operand))
- continue;
- if (isa<GlobalValue>(Operand)) {
- // We have a reference to a global value. This should be added to
- // the reference set unless it is a callee. Callees are handled
- // specially by WriteFunction and are added to a separate list.
- if (!(CS && CS.isCallee(&OI)))
- RefEdges.insert(VE.getValueID(Operand));
- continue;
- }
- Worklist.push_back(Operand);
- }
- }
-}
-
/// Emit a function body to the module stream.
static void
WriteFunction(const Function &F, const Module *M, ValueEnumerator &VE,
BitstreamWriter &Stream,
- DenseMap<const Function *, std::unique_ptr<GlobalValueInfo>> &
- GlobalValueIndex,
- bool EmitSummaryIndex) {
+ DenseMap<const Function *, uint64_t> &FunctionToBitcodeIndex) {
// Save the bitcode index of the start of this function block for recording
// in the VST.
- uint64_t BitcodeIndex = Stream.GetCurrentBitNo();
-
- bool HasProfileData = F.getEntryCount().hasValue();
- std::unique_ptr<BlockFrequencyInfo> BFI;
- if (EmitSummaryIndex && HasProfileData) {
- Function &Func = const_cast<Function &>(F);
- LoopInfo LI{DominatorTree(Func)};
- BranchProbabilityInfo BPI{Func, LI};
- BFI = llvm::make_unique<BlockFrequencyInfo>(Func, BPI, LI);
- }
+ FunctionToBitcodeIndex[&F] = Stream.GetCurrentBitNo();
Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
VE.incorporateFunction(F);
@@ -2581,40 +2525,15 @@ WriteFunction(const Function &F, const Module *M, ValueEnumerator &VE,
bool NeedsMetadataAttachment = F.hasMetadata();
DILocation *LastDL = nullptr;
- unsigned NumInsts = 0;
- // Map from callee ValueId to profile count. Used to accumulate profile
- // counts for all static calls to a given callee.
- DenseMap<unsigned, CalleeInfo> CallGraphEdges;
- DenseSet<unsigned> RefEdges;
-
- SmallPtrSet<const User *, 8> Visited;
// Finally, emit all the instructions, in order.
for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end();
I != E; ++I) {
WriteInstruction(*I, InstID, VE, Stream, Vals);
- if (!isa<DbgInfoIntrinsic>(I))
- ++NumInsts;
-
if (!I->getType()->isVoidTy())
++InstID;
- if (EmitSummaryIndex) {
- if (auto CS = ImmutableCallSite(&*I)) {
- auto *CalledFunction = CS.getCalledFunction();
- if (CalledFunction && CalledFunction->hasName() &&
- !CalledFunction->isIntrinsic()) {
- auto ScaledCount = BFI ? BFI->getBlockProfileCount(&*BB) : None;
- unsigned CalleeId = VE.getValueID(
- M->getValueSymbolTable().lookup(CalledFunction->getName()));
- CallGraphEdges[CalleeId] +=
- (ScaledCount ? ScaledCount.getValue() : 0);
- }
- }
- findRefEdges(&*I, VE, RefEdges, Visited);
- }
-
// If the instruction has metadata, write a metadata attachment later.
NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc();
@@ -2639,15 +2558,6 @@ WriteFunction(const Function &F, const Module *M, ValueEnumerator &VE,
LastDL = DL;
}
- std::unique_ptr<FunctionSummary> FuncSummary;
- if (EmitSummaryIndex) {
- FuncSummary = llvm::make_unique<FunctionSummary>(F.getLinkage(), NumInsts);
- FuncSummary->addCallGraphEdges(CallGraphEdges);
- FuncSummary->addRefEdges(RefEdges);
- }
- GlobalValueIndex[&F] =
- llvm::make_unique<GlobalValueInfo>(BitcodeIndex, std::move(FuncSummary));
-
// Emit names for all the instructions etc.
WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream);
@@ -2915,21 +2825,22 @@ static void WriteModStrings(const ModuleSummaryIndex &I,
// Helper to emit a single function summary record.
static void WritePerModuleFunctionSummaryRecord(
- SmallVector<uint64_t, 64> &NameVals, FunctionSummary *FS, unsigned ValueID,
- unsigned FSCallsAbbrev, unsigned FSCallsProfileAbbrev,
- BitstreamWriter &Stream, const Function &F) {
- assert(FS);
+ SmallVector<uint64_t, 64> &NameVals, GlobalValueInfo *Info,
+ unsigned ValueID, const ValueEnumerator &VE, unsigned FSCallsAbbrev,
+ unsigned FSCallsProfileAbbrev, BitstreamWriter &Stream, const Function &F) {
NameVals.push_back(ValueID);
+
+ FunctionSummary *FS = cast<FunctionSummary>(Info->summary());
NameVals.push_back(getEncodedLinkage(FS->linkage()));
NameVals.push_back(FS->instCount());
NameVals.push_back(FS->refs().size());
for (auto &RI : FS->refs())
- NameVals.push_back(RI);
+ NameVals.push_back(VE.getValueID(RI.getValue()));
bool HasProfileData = F.getEntryCount().hasValue();
for (auto &ECI : FS->calls()) {
- NameVals.push_back(ECI.first);
+ NameVals.push_back(VE.getValueID(ECI.first.getValue()));
assert(ECI.second.CallsiteCount > 0 && "Expected at least one callsite");
NameVals.push_back(ECI.second.CallsiteCount);
if (HasProfileData)
@@ -2948,6 +2859,7 @@ static void WritePerModuleFunctionSummaryRecord(
// Collect the global value references in the given variable's initializer,
// and emit them in a summary record.
static void WriteModuleLevelReferences(const GlobalVariable &V,
+ const ModuleSummaryIndex &Index,
const ValueEnumerator &VE,
SmallVector<uint64_t, 64> &NameVals,
unsigned FSModRefsAbbrev,
@@ -2955,14 +2867,12 @@ static void WriteModuleLevelReferences(const GlobalVariable &V,
// Only interested in recording variable defs in the summary.
if (V.isDeclaration())
return;
- DenseSet<unsigned> RefEdges;
- SmallPtrSet<const User *, 8> Visited;
- findRefEdges(&V, VE, RefEdges, Visited);
NameVals.push_back(VE.getValueID(&V));
NameVals.push_back(getEncodedLinkage(V.getLinkage()));
- for (auto RefId : RefEdges) {
- NameVals.push_back(RefId);
- }
+ auto *Info = Index.getGlobalValueInfo(V);
+ GlobalVarSummary *VS = cast<GlobalVarSummary>(Info->summary());
+ for (auto Ref : VS->refs())
+ NameVals.push_back(VE.getValueID(Ref.getValue()));
Stream.EmitRecord(bitc::FS_PERMODULE_GLOBALVAR_INIT_REFS, NameVals,
FSModRefsAbbrev);
NameVals.clear();
@@ -2970,10 +2880,10 @@ static void WriteModuleLevelReferences(const GlobalVariable &V,
/// Emit the per-module summary section alongside the rest of
/// the module's bitcode.
-static void WritePerModuleGlobalValueSummary(
- DenseMap<const Function *, std::unique_ptr<GlobalValueInfo>> &
- GlobalValueIndex,
- const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) {
+static void WritePerModuleGlobalValueSummary(const Module *M,
+ const ModuleSummaryIndex &Index,
+ const ValueEnumerator &VE,
+ BitstreamWriter &Stream) {
if (M->empty())
return;
@@ -3013,7 +2923,7 @@ static void WritePerModuleGlobalValueSummary(
unsigned FSModRefsAbbrev = Stream.EmitAbbrev(Abbv);
SmallVector<uint64_t, 64> NameVals;
- // Iterate over the list of functions instead of the GlobalValueIndex map to
+ // Iterate over the list of functions instead of the Index to
// ensure the ordering is stable.
for (const Function &F : *M) {
if (F.isDeclaration())
@@ -3023,39 +2933,17 @@ static void WritePerModuleGlobalValueSummary(
if (!F.hasName())
continue;
- assert(GlobalValueIndex.count(&F) == 1);
-
+ auto *Info = Index.getGlobalValueInfo(F);
WritePerModuleFunctionSummaryRecord(
- NameVals, cast<FunctionSummary>(GlobalValueIndex[&F]->summary()),
- VE.getValueID(M->getValueSymbolTable().lookup(F.getName())),
+ NameVals, Info,
+ VE.getValueID(M->getValueSymbolTable().lookup(F.getName())), VE,
FSCallsAbbrev, FSCallsProfileAbbrev, Stream, F);
}
- for (const GlobalAlias &A : M->aliases()) {
- if (!A.getBaseObject())
- continue;
- const Function *F = dyn_cast<Function>(A.getBaseObject());
- if (!F || F->isDeclaration())
- continue;
-
- assert(GlobalValueIndex.count(F) == 1);
- FunctionSummary *FS = cast<FunctionSummary>(GlobalValueIndex[F]->summary());
- // Add the alias to the reference list of aliasee function.
- FS->addRefEdge(
- VE.getValueID(M->getValueSymbolTable().lookup(A.getName())));
- WritePerModuleFunctionSummaryRecord(
- NameVals, FS,
- VE.getValueID(M->getValueSymbolTable().lookup(A.getName())),
- FSCallsAbbrev, FSCallsProfileAbbrev, Stream, *F);
- }
-
// Capture references from GlobalVariable initializers, which are outside
// of a function scope.
for (const GlobalVariable &G : M->globals())
- WriteModuleLevelReferences(G, VE, NameVals, FSModRefsAbbrev, Stream);
- for (const GlobalAlias &A : M->aliases())
- if (auto *GV = dyn_cast<GlobalVariable>(A.getBaseObject()))
- WriteModuleLevelReferences(*GV, VE, NameVals, FSModRefsAbbrev, Stream);
+ WriteModuleLevelReferences(G, Index, VE, NameVals, FSModRefsAbbrev, Stream);
Stream.ExitBlock();
}
@@ -3110,11 +2998,11 @@ static void WriteCombinedGlobalValueSummary(
NameVals.push_back(Index.getModuleId(VS->modulePath()));
NameVals.push_back(getEncodedLinkage(VS->linkage()));
for (auto &RI : VS->refs()) {
- const auto &VMI = GUIDToValueIdMap.find(RI);
+ const auto &VMI = GUIDToValueIdMap.find(RI.getGUID());
unsigned RefId;
// If this GUID doesn't have an entry, assign one.
if (VMI == GUIDToValueIdMap.end()) {
- GUIDToValueIdMap[RI] = ++GlobalValueId;
+ GUIDToValueIdMap[RI.getGUID()] = ++GlobalValueId;
RefId = GlobalValueId;
} else {
RefId = VMI->second;
@@ -3142,11 +3030,11 @@ static void WriteCombinedGlobalValueSummary(
NameVals.push_back(FS->refs().size());
for (auto &RI : FS->refs()) {
- const auto &VMI = GUIDToValueIdMap.find(RI);
+ const auto &VMI = GUIDToValueIdMap.find(RI.getGUID());
unsigned RefId;
// If this GUID doesn't have an entry, assign one.
if (VMI == GUIDToValueIdMap.end()) {
- GUIDToValueIdMap[RI] = ++GlobalValueId;
+ GUIDToValueIdMap[RI.getGUID()] = ++GlobalValueId;
RefId = GlobalValueId;
} else {
RefId = VMI->second;
@@ -3162,7 +3050,7 @@ static void WriteCombinedGlobalValueSummary(
}
for (auto &EI : FS->calls()) {
- const auto &VMI = GUIDToValueIdMap.find(EI.first);
+ const auto &VMI = GUIDToValueIdMap.find(EI.first.getGUID());
// If this GUID doesn't have an entry, it doesn't have a function
// summary and we don't need to record any calls to it.
if (VMI == GUIDToValueIdMap.end())
@@ -3243,8 +3131,9 @@ static void writeModuleHash(BitstreamWriter &Stream,
/// WriteModule - Emit the specified module to the bitstream.
static void WriteModule(const Module *M, BitstreamWriter &Stream,
bool ShouldPreserveUseListOrder,
- uint64_t BitcodeStartBit, bool EmitSummaryIndex,
- bool GenerateHash, SmallVectorImpl<char> &Buffer) {
+ uint64_t BitcodeStartBit,
+ const ModuleSummaryIndex *Index, bool GenerateHash,
+ SmallVectorImpl<char> &Buffer) {
Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3);
size_t BlockStartPos = Buffer.size();
@@ -3290,19 +3179,19 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream,
WriteOperandBundleTags(M, Stream);
// Emit function bodies.
- DenseMap<const Function *, std::unique_ptr<GlobalValueInfo>> GlobalValueIndex;
+ DenseMap<const Function *, uint64_t> FunctionToBitcodeIndex;
for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)
if (!F->isDeclaration())
- WriteFunction(*F, M, VE, Stream, GlobalValueIndex, EmitSummaryIndex);
+ WriteFunction(*F, M, VE, Stream, FunctionToBitcodeIndex);
// Need to write after the above call to WriteFunction which populates
// the summary information in the index.
- if (EmitSummaryIndex)
- WritePerModuleGlobalValueSummary(GlobalValueIndex, M, VE, Stream);
+ if (Index)
+ WritePerModuleGlobalValueSummary(M, *Index, VE, Stream);
WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream,
VSTOffsetPlaceholder, BitcodeStartBit,
- &GlobalValueIndex);
+ &FunctionToBitcodeIndex);
if (GenerateHash) {
writeModuleHash(Stream, Buffer, BlockStartPos);
@@ -3392,7 +3281,8 @@ static void WriteBitcodeHeader(BitstreamWriter &Stream) {
/// stream.
void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder,
- bool EmitSummaryIndex, bool GenerateHash) {
+ const ModuleSummaryIndex *Index,
+ bool GenerateHash) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256*1024);
@@ -3417,8 +3307,8 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out,
WriteIdentificationBlock(M, Stream);
// Emit the module.
- WriteModule(M, Stream, ShouldPreserveUseListOrder, BitcodeStartBit,
- EmitSummaryIndex, GenerateHash, Buffer);
+ WriteModule(M, Stream, ShouldPreserveUseListOrder, BitcodeStartBit, Index,
+ GenerateHash, Buffer);
}
if (TT.isOSDarwin() || TT.isOSBinFormatMachO())
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index 7dbede4a847..2eeeb5d272c 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
@@ -19,7 +20,11 @@
using namespace llvm;
PreservedAnalyses BitcodeWriterPass::run(Module &M) {
- WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitSummaryIndex, EmitModuleHash);
+ std::unique_ptr<ModuleSummaryIndex> Index;
+ if (EmitSummaryIndex)
+ Index = ModuleSummaryIndexBuilder(&M).takeIndex();
+ WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, Index.get(),
+ EmitModuleHash);
return PreservedAnalyses::all();
}
@@ -32,22 +37,43 @@ namespace {
public:
static char ID; // Pass identification, replacement for typeid
+ WriteBitcodePass() : ModulePass(ID), OS(dbgs()) {
+ initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
+ }
+
explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder,
bool EmitSummaryIndex, bool EmitModuleHash)
: ModulePass(ID), OS(o),
ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
- EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {}
+ EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {
+ initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
+ }
const char *getPassName() const override { return "Bitcode Writer"; }
bool runOnModule(Module &M) override {
- WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, EmitSummaryIndex, EmitModuleHash);
+ const ModuleSummaryIndex *Index =
+ EmitSummaryIndex
+ ? &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex())
+ : nullptr;
+ WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder, Index,
+ EmitModuleHash);
return false;
}
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ if (EmitSummaryIndex)
+ AU.addRequired<ModuleSummaryIndexWrapperPass>();
+ }
};
}
char WriteBitcodePass::ID = 0;
+INITIALIZE_PASS_BEGIN(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
+ true)
+INITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass)
+INITIALIZE_PASS_END(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
+ true)
ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
bool ShouldPreserveUseListOrder,
diff --git a/llvm/lib/Bitcode/Writer/LLVMBuild.txt b/llvm/lib/Bitcode/Writer/LLVMBuild.txt
index a450b38fba2..7d9e1de771b 100644
--- a/llvm/lib/Bitcode/Writer/LLVMBuild.txt
+++ b/llvm/lib/Bitcode/Writer/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Library
name = BitWriter
parent = Bitcode
-required_libraries = Analysis Core Support
+required_libraries = Core Support
diff --git a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
index b60668dc670..fea1c7fb8fa 100644
--- a/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/ThinLTOCodeGenerator.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
@@ -326,7 +327,8 @@ ProcessThinLTOModule(Module &TheModule, const ModuleSummaryIndex &Index,
SmallVector<char, 128> OutputBuffer;
{
raw_svector_ostream OS(OutputBuffer);
- WriteBitcodeToFile(&TheModule, OS, true, true);
+ ModuleSummaryIndexBuilder IndexBuilder(&TheModule);
+ WriteBitcodeToFile(&TheModule, OS, true, &IndexBuilder.getIndex());
}
return make_unique<ObjectMemoryBuffer>(std::move(OutputBuffer));
}
diff --git a/llvm/lib/Transforms/IPO/FunctionImport.cpp b/llvm/lib/Transforms/IPO/FunctionImport.cpp
index 32853b93f28..63b2e974419 100644
--- a/llvm/lib/Transforms/IPO/FunctionImport.cpp
+++ b/llvm/lib/Transforms/IPO/FunctionImport.cpp
@@ -145,7 +145,7 @@ static void computeImportForFunction(
FunctionImporter::ImportMapTy &ImportsForModule,
StringMap<FunctionImporter::ExportSetTy> &ExportLists) {
for (auto &Edge : Summary.calls()) {
- auto GUID = Edge.first;
+ auto GUID = Edge.first.getGUID();
DEBUG(dbgs() << " edge -> " << GUID << " Threshold:" << Threshold << "\n");
if (DefinedFunctions.count(GUID)) {
@@ -181,11 +181,12 @@ static void computeImportForFunction(
// Mark all functions and globals referenced by this function as exported to
// the outside if they are defined in the same source module.
for (auto &Edge : CalleeSummary->calls()) {
- auto CalleeGUID = Edge.first;
+ auto CalleeGUID = Edge.first.getGUID();
if (isGlobalExported(Index, ExportModulePath, CalleeGUID))
ExportList.insert(CalleeGUID);
}
- for (auto &GUID : CalleeSummary->refs()) {
+ for (auto &Ref : CalleeSummary->refs()) {
+ auto GUID = Ref.getGUID();
if (isGlobalExported(Index, ExportModulePath, GUID))
ExportList.insert(GUID);
}
OpenPOWER on IntegriCloud