summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp196
1 files changed, 43 insertions, 153 deletions
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())
OpenPOWER on IntegriCloud