[llvm] r263275 - [ThinLTO] Support for reference graph in per-module and combined summary.
Duncan P. N. Exon Smith via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 17 17:55:35 PDT 2016
> On 2016-Mar-11, at 10:52, Teresa Johnson via llvm-commits <llvm-commits at lists.llvm.org> wrote:
>
> Author: tejohnson
> Date: Fri Mar 11 12:52:24 2016
> New Revision: 263275
>
> URL: http://llvm.org/viewvc/llvm-project?rev=263275&view=rev
> Log:
> [ThinLTO] Support for reference graph in per-module and combined summary.
>
> Summary:
> This patch adds support for including a full reference graph including
> call graph edges and other GV references in the summary.
>
> The reference graph edges can be used to make importing decisions
> without materializing any source modules, can be used in the plugin
> to make file staging decisions for distributed build systems, and is
> expected to have other uses.
>
> The call graph edges are recorded in each function summary in the
> bitcode via a list of <CalleeValueIds, StaticCount> tuples when no PGO
> data exists, or <CalleeValueId, StaticCount, ProfileCount> pairs when
> there is PGO, where the ValueId can be mapped to the function GUID via
> the ValueSymbolTable. In the function index in memory, the call graph
> edges reference the target via the CalleeGUID instead of the
> CalleeValueId.
>
> The reference graph edges are recorded in each summary record with a
> list of referenced value IDs, which can be mapped to value GUID via the
> ValueSymbolTable.
>
> Addtionally, a new summary record type is added to record references
> from global variable initializers. A number of bitcode records and data
> structures have been renamed to reflect the newly expanded scope of the
> summary beyond functions. More cleanup will follow.
>
> Reviewers: joker.eph, davidxl
>
> Subscribers: joker.eph, llvm-commits
>
> Differential Revision: http://reviews.llvm.org/D17212
[snip]
> Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=263275&r1=263274&r2=263275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
> +++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Fri Mar 11 12:52:24 2016
> @@ -2440,34 +2472,61 @@ static void WriteUseListBlock(const Func
> Stream.ExitBlock();
> }
>
> -/// \brief Save information for the given function into the function index.
> -///
> -/// At a minimum this saves the bitcode index of the function record that
> -/// was just written. However, if we are emitting function summary information,
> -/// for example for ThinLTO, then a \a FunctionSummary object is created
> -/// to hold the provided summary information.
> -static void SaveFunctionInfo(
> - const Function &F,
> - DenseMap<const Function *, std::unique_ptr<FunctionInfo>> &FunctionIndex,
> - unsigned NumInsts, uint64_t BitcodeIndex, bool EmitFunctionSummary) {
> - std::unique_ptr<FunctionSummary> FuncSummary;
> - if (EmitFunctionSummary) {
> - FuncSummary = llvm::make_unique<FunctionSummary>(NumInsts);
> - FuncSummary->setFunctionLinkage(F.getLinkage());
> +// 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);
> + }
> }
> - FunctionIndex[&F] =
> - llvm::make_unique<FunctionInfo>(BitcodeIndex, std::move(FuncSummary));
> }
>
> /// Emit a function body to the module stream.
> static void WriteFunction(
> - const Function &F, ValueEnumerator &VE, BitstreamWriter &Stream,
> - DenseMap<const Function *, std::unique_ptr<FunctionInfo>> &FunctionIndex,
> - bool EmitFunctionSummary) {
> + const Function &F, const Module *M, ValueEnumerator &VE,
> + BitstreamWriter &Stream,
> + DenseMap<const Function *, std::unique_ptr<GlobalValueInfo>> &FunctionIndex,
> + bool EmitSummaryIndex) {
> // 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);
This means that writing out bitcode calculates DominatorTree, LoopInfo,
and BlockFrequencyInfo. These are not trivial.
I'm pretty surprised to see these here.
> + }
> +
> Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4);
> VE.incorporateFunction(F);
> Modified: llvm/trunk/lib/Bitcode/Writer/LLVMBuild.txt
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/LLVMBuild.txt?rev=263275&r1=263274&r2=263275&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Bitcode/Writer/LLVMBuild.txt (original)
> +++ llvm/trunk/lib/Bitcode/Writer/LLVMBuild.txt Fri Mar 11 12:52:24 2016
> @@ -19,4 +19,4 @@
> type = Library
> name = BitWriter
> parent = Bitcode
> -required_libraries = Core Support
> +required_libraries = Analysis Core Support
This means that `llvm-as` now has a dependency on lib/Analysis... which
is surprising.
I feel like we've done something fundamentally wrong if we have to
run expensive analyses in order to write out IR.
More information about the llvm-commits
mailing list