Skip to content

Commit

Permalink
[ThinLTO] Move summary computation from BitcodeWriter to new pass
Browse files Browse the repository at this point in the history
Summary:
This is the first step in also serializing the index out to LLVM
assembly.

The per-module summary written to bitcode is moved out of the bitcode
writer and to a new analysis pass (ModuleSummaryIndexWrapperPass).
The pass itself uses a new builder class to compute index, and the
builder class is used directly in places where we don't have a pass
manager (e.g. llvm-as).

Because we are computing summaries outside of the bitcode writer, we no
longer can use value ids created by the bitcode writer's
ValueEnumerator. This required changing the reference graph edge type
to use a new ValueInfo class holding a union between a GUID (combined
index) and Value* (permodule index). The Value* are converted to the
appropriate value ID during bitcode writing.

Also, this enables removal of the BitWriter library's dependence on the
Analysis library that was previously required for the summary computation.

Reviewers: joker.eph

Subscribers: joker.eph, llvm-commits

Differential Revision: http://reviews.llvm.org/D18763

llvm-svn: 265941
teresajohnson committed Apr 11, 2016
1 parent 34ffcbb commit 2d5487c
Showing 17 changed files with 434 additions and 183 deletions.
86 changes: 86 additions & 0 deletions llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//===- ModuleSummaryAnalysis.h - Module summary index builder ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This is the interface to build a ModuleSummaryIndex for a module.
///
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H
#define LLVM_ANALYSIS_MODULESUMMARYANALYSIS_H

#include "llvm/ADT/STLExtras.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/Pass.h"

namespace llvm {

class BlockFrequencyInfo;

/// Class to build a module summary index for the given Module, possibly from
/// a Pass.
class ModuleSummaryIndexBuilder {
/// The index being built
std::unique_ptr<ModuleSummaryIndex> Index;
/// The module for which we are building an index
const Module *M;

public:
/// Default constructor
ModuleSummaryIndexBuilder() = default;

/// Constructor that builds an index for the given Module. An optional
/// callback can be supplied to obtain the frequency info for a function.
ModuleSummaryIndexBuilder(
const Module *M,
std::function<BlockFrequencyInfo *(const Function &F)> Ftor = nullptr);

/// Get a reference to the index owned by builder
ModuleSummaryIndex &getIndex() const { return *Index; }

/// Take ownership of the built index
std::unique_ptr<ModuleSummaryIndex> takeIndex() { return std::move(Index); }

private:
/// Compute info for given function with optional frequency information
void computeFunctionInfo(const Function &F,
BlockFrequencyInfo *BFI = nullptr);

/// Compute info for given variable with optional frequency information
void computeVariableInfo(const GlobalVariable &V);
};

/// Legacy wrapper pass to provide the ModuleSummaryIndex object.
class ModuleSummaryIndexWrapperPass : public ModulePass {
std::unique_ptr<ModuleSummaryIndexBuilder> IndexBuilder;

public:
static char ID;

ModuleSummaryIndexWrapperPass();

/// Get the index built by pass
ModuleSummaryIndex &getIndex() { return IndexBuilder->getIndex(); }
const ModuleSummaryIndex &getIndex() const {
return IndexBuilder->getIndex();
}

bool runOnModule(Module &M) override;
bool doFinalization(Module &M) override;
void getAnalysisUsage(AnalysisUsage &AU) const override;
};

//===--------------------------------------------------------------------===//
//
// createModuleSummaryIndexWrapperPass - This pass builds a ModuleSummaryIndex
// object for the module, to be written to bitcode or LLVM assembly.
//
ModulePass *createModuleSummaryIndexWrapperPass();
}

#endif
2 changes: 1 addition & 1 deletion llvm/include/llvm/Bitcode/ReaderWriter.h
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ namespace llvm {
/// for use in ThinLTO optimization).
void WriteBitcodeToFile(const Module *M, raw_ostream &Out,
bool ShouldPreserveUseListOrder = false,
bool EmitSummaryIndex = false,
const ModuleSummaryIndex *Index = nullptr,
bool GenerateHash = false);

/// Write the specified module summary index to the given raw output stream,
71 changes: 60 additions & 11 deletions llvm/include/llvm/IR/ModuleSummaryIndex.h
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@

#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/IR/Function.h"
@@ -46,6 +47,43 @@ struct CalleeInfo {
}
};

/// Struct to hold value either by GUID or Value*, depending on whether this
/// is a combined or per-module index, respectively.
struct ValueInfo {
/// The value representation used in this instance.
enum ValueInfoKind {
VI_GUID,
VI_Value,
};

/// Union of the two possible value types.
union ValueUnion {
GlobalValue::GUID Id;
const Value *V;
ValueUnion(GlobalValue::GUID Id) : Id(Id) {}
ValueUnion(const Value *V) : V(V) {}
};

/// The value being represented.
ValueUnion TheValue;
/// The value representation.
ValueInfoKind Kind;
/// Constructor for a GUID value
ValueInfo(GlobalValue::GUID Id = 0) : TheValue(Id), Kind(VI_GUID) {}
/// Constructor for a Value* value
ValueInfo(const Value *V) : TheValue(V), Kind(VI_Value) {}
/// Accessor for GUID value
GlobalValue::GUID getGUID() const {
assert(Kind == VI_GUID && "Not a GUID type");
return TheValue.Id;
}
/// Accessor for Value* value
const Value *getValue() const {
assert(Kind == VI_Value && "Not a Value type");
return TheValue.V;
}
};

/// \brief Function and variable summary information to aid decisions and
/// implementation of importing.
///
@@ -78,11 +116,11 @@ class GlobalValueSummary {
/// types based on global summary-based analysis.
GlobalValue::LinkageTypes Linkage;

/// List of GUIDs of values referenced by this global value's definition
/// List of values referenced by this global value's definition
/// (either by the initializer of a global variable, or referenced
/// from within a function). This does not include functions called, which
/// are listed in the derived FunctionSummary object.
std::vector<GlobalValue::GUID> RefEdgeList;
std::vector<ValueInfo> RefEdgeList;

protected:
/// GlobalValueSummary constructor.
@@ -109,31 +147,35 @@ class GlobalValueSummary {
/// by \p RefGUID.
void addRefEdge(GlobalValue::GUID RefGUID) { RefEdgeList.push_back(RefGUID); }

/// Record a reference from this global value to the global value identified
/// by \p RefV.
void addRefEdge(const Value *RefV) { RefEdgeList.push_back(RefV); }

/// Record a reference from this global value to each global value identified
/// in \p RefEdges.
void addRefEdges(DenseSet<unsigned> &RefEdges) {
void addRefEdges(DenseSet<const Value *> &RefEdges) {
for (auto &RI : RefEdges)
addRefEdge(RI);
}

/// Return the list of GUIDs referenced by this global value definition.
std::vector<GlobalValue::GUID> &refs() { return RefEdgeList; }
const std::vector<GlobalValue::GUID> &refs() const { return RefEdgeList; }
/// Return the list of values referenced by this global value definition.
std::vector<ValueInfo> &refs() { return RefEdgeList; }
const std::vector<ValueInfo> &refs() const { return RefEdgeList; }
};

/// \brief Function summary information to aid decisions and implementation of
/// importing.
class FunctionSummary : public GlobalValueSummary {
public:
/// <CalleeGUID, CalleeInfo> call edge pair.
typedef std::pair<GlobalValue::GUID, CalleeInfo> EdgeTy;
/// <CalleeValueInfo, CalleeInfo> call edge pair.
typedef std::pair<ValueInfo, CalleeInfo> EdgeTy;

private:
/// Number of instructions (ignoring debug instructions, e.g.) computed
/// during the initial compile step when the summary index is first built.
unsigned InstCount;

/// List of <CalleeGUID, CalleeInfo> call edge pairs from this function.
/// List of <CalleeValueInfo, CalleeInfo> call edge pairs from this function.
std::vector<EdgeTy> CallGraphEdgeList;

public:
@@ -156,14 +198,21 @@ class FunctionSummary : public GlobalValueSummary {
CallGraphEdgeList.push_back(std::make_pair(CalleeGUID, Info));
}

/// Record a call graph edge from this function to the function identified
/// by \p CalleeV, with \p CalleeInfo including the cumulative profile
/// count (across all calls from this function) or 0 if no PGO.
void addCallGraphEdge(const Value *CalleeV, CalleeInfo Info) {
CallGraphEdgeList.push_back(std::make_pair(CalleeV, Info));
}

/// Record a call graph edge from this function to each function recorded
/// in \p CallGraphEdges.
void addCallGraphEdges(DenseMap<unsigned, CalleeInfo> &CallGraphEdges) {
void addCallGraphEdges(DenseMap<const Value *, CalleeInfo> &CallGraphEdges) {
for (auto &EI : CallGraphEdges)
addCallGraphEdge(EI.first, EI.second);
}

/// Return the list of <CalleeGUID, ProfileCount> pairs.
/// Return the list of <CalleeValueInfo, CalleeInfo> pairs.
std::vector<EdgeTy> &calls() { return CallGraphEdgeList; }
const std::vector<EdgeTy> &calls() const { return CallGraphEdgeList; }
};
2 changes: 2 additions & 0 deletions llvm/include/llvm/InitializePasses.h
Original file line number Diff line number Diff line change
@@ -198,6 +198,7 @@ void initializeMachineBlockPlacementPass(PassRegistry&);
void initializeMachineBlockPlacementStatsPass(PassRegistry&);
void initializeMachineBranchProbabilityInfoPass(PassRegistry&);
void initializeMachineCSEPass(PassRegistry&);
void initializeModuleSummaryIndexWrapperPassPass(PassRegistry &);
void initializeImplicitNullChecksPass(PassRegistry&);
void initializeMachineDominatorTreePass(PassRegistry&);
void initializeMachineDominanceFrontierPass(PassRegistry&);
@@ -314,6 +315,7 @@ void initializeMachineCombinerPass(PassRegistry &);
void initializeLoadCombinePass(PassRegistry&);
void initializeRewriteSymbolsPass(PassRegistry&);
void initializeWinEHPreparePass(PassRegistry&);
void initializeWriteBitcodePassPass(PassRegistry &);
void initializePlaceBackedgeSafepointsImplPass(PassRegistry&);
void initializePlaceSafepointsPass(PassRegistry&);
void initializeDwarfEHPreparePass(PassRegistry&);
1 change: 1 addition & 0 deletions llvm/lib/Analysis/Analysis.cpp
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ void llvm::initializeAnalysis(PassRegistry &Registry) {
initializeMemDerefPrinterPass(Registry);
initializeMemoryDependenceWrapperPassPass(Registry);
initializeModuleDebugInfoPrinterPass(Registry);
initializeModuleSummaryIndexWrapperPassPass(Registry);
initializeObjCARCAAWrapperPassPass(Registry);
initializePostDominatorTreeWrapperPassPass(Registry);
initializeRegionInfoPassPass(Registry);
1 change: 1 addition & 0 deletions llvm/lib/Analysis/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -49,6 +49,7 @@ add_llvm_library(LLVMAnalysis
MemoryDependenceAnalysis.cpp
MemoryLocation.cpp
ModuleDebugInfoPrinter.cpp
ModuleSummaryAnalysis.cpp
ObjCARCAliasAnalysis.cpp
ObjCARCAnalysisUtils.cpp
ObjCARCInstKind.cpp
186 changes: 186 additions & 0 deletions llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
Original file line number Diff line number Diff line change
@@ -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>();
}
196 changes: 43 additions & 153 deletions llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Large diffs are not rendered by default.

32 changes: 29 additions & 3 deletions llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
Original file line number Diff line number Diff line change
@@ -12,14 +12,19 @@
//===----------------------------------------------------------------------===//

#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"
#include "llvm/Pass.h"
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,
2 changes: 1 addition & 1 deletion llvm/lib/Bitcode/Writer/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -19,4 +19,4 @@
type = Library
name = BitWriter
parent = Bitcode
required_libraries = Analysis Core Support
required_libraries = Core Support
4 changes: 3 additions & 1 deletion llvm/lib/LTO/ThinLTOCodeGenerator.cpp
Original file line number Diff line number Diff line change
@@ -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));
}
7 changes: 4 additions & 3 deletions llvm/lib/Transforms/IPO/FunctionImport.cpp
Original file line number Diff line number Diff line change
@@ -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);
}
4 changes: 3 additions & 1 deletion llvm/test/Bitcode/thinlto-function-summary.ll
Original file line number Diff line number Diff line change
@@ -7,7 +7,6 @@
; BC: <GLOBALVAL_SUMMARY_BLOCK
; BC-NEXT: <PERMODULE {{.*}} op0=1 op1=0
; BC-NEXT: <PERMODULE {{.*}} op0=2 op1=0
; BC-NEXT: <PERMODULE {{.*}} op0=4 op1=3
; BC-NEXT: </GLOBALVAL_SUMMARY_BLOCK
; BC-NEXT: <VALUE_SYMTAB
; BC-NEXT: <FNENTRY {{.*}} op0=1 {{.*}}> record string = 'foo'
@@ -37,6 +36,9 @@ entry:
ret i32 %x
}

; FIXME: Anonymous function and alias not currently in summary until
; follow on fixes to rename anonymous functions and emit alias summary
; entries are committed.
; Check an anonymous function as well, since in that case only the alias
; ends up in the value symbol table and having a summary.
@f = alias void (), void ()* @0 ; <void ()*> [#uses=0]
8 changes: 3 additions & 5 deletions llvm/test/Transforms/FunctionImport/funcimport.ll
Original file line number Diff line number Diff line change
@@ -34,12 +34,10 @@ declare void @weakalias(...) #1
; CHECK-DAG: declare void @analias
declare void @analias(...) #1

; FIXME: Add this checking back when follow on fix to add alias summary
; records is committed.
; Aliases import the aliasee function
declare void @linkoncealias(...) #1
; INSTLIMDEF-DAG: Import linkoncealias
; INSTLIMDEF-DAG: Import linkoncefunc
; CHECK-DAG: define linkonce_odr void @linkoncefunc()
; CHECK-DAG: @linkoncealias = alias void (...), bitcast (void ()* @linkoncefunc to void (...)*

; INSTLIMDEF-DAG: Import referencestatics
; INSTLIMDEF-DAG: define available_externally i32 @referencestatics(i32 %i)
@@ -89,7 +87,7 @@ declare void @weakfunc(...) #1
; INSTLIM5-DAG: declare hidden void @funcwithpersonality.llvm.2()

; INSTLIMDEF-DAG: Import globalfunc2
; INSTLIMDEF-DAG: 11 function-import - Number of functions imported
; INSTLIMDEF-DAG: 9 function-import - Number of functions imported

; The actual GUID values will depend on path to test.
; GUID-DAG: GUID {{.*}} is weakalias
1 change: 1 addition & 0 deletions llvm/tools/llvm-as/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
set(LLVM_LINK_COMPONENTS
Analysis
AsmParser
BitWriter
Core
2 changes: 1 addition & 1 deletion llvm/tools/llvm-as/LLVMBuild.txt
Original file line number Diff line number Diff line change
@@ -19,4 +19,4 @@
type = Tool
name = llvm-as
parent = Tools
required_libraries = AsmParser BitWriter
required_libraries = Analysis AsmParser BitWriter
12 changes: 9 additions & 3 deletions llvm/tools/llvm-as/llvm-as.cpp
Original file line number Diff line number Diff line change
@@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/AsmParser/Parser.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/IR/LLVMContext.h"
@@ -83,9 +84,14 @@ static void WriteOutputFile(const Module *M) {
exit(1);
}

if (Force || !CheckBitcodeOutputToConsole(Out->os(), true))
WriteBitcodeToFile(M, Out->os(), PreserveBitcodeUseListOrder,
EmitSummaryIndex, EmitModuleHash);
if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) {
std::unique_ptr<ModuleSummaryIndex> Index;
if (EmitSummaryIndex)
Index = ModuleSummaryIndexBuilder(M).takeIndex();

WriteBitcodeToFile(M, Out->os(), PreserveBitcodeUseListOrder, Index.get(),
EmitModuleHash);
}

// Declare success.
Out->keep();

0 comments on commit 2d5487c

Please sign in to comment.