1 //===-- llvm-jitlink-statistics.cpp -- gathers/reports JIT-linking stats --===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the code for enabling, gathering and reporting
10 // llvm-jitlink statistics.
12 //===----------------------------------------------------------------------===//
14 #include "llvm-jitlink.h"
15 #include "llvm/Support/CommandLine.h"
17 #define DEBUG_TYPE "llvm_jitlink"
20 using namespace llvm::jitlink
;
21 using namespace llvm::orc
;
23 static cl::opt
<bool> ShowPrePruneTotalBlockSize(
24 "pre-prune-total-block-size",
25 cl::desc("Total size of all blocks (including zero-fill) in all "
26 "graphs (pre-pruning)"),
29 static cl::opt
<bool> ShowPostFixupTotalBlockSize(
30 "post-fixup-total-block-size",
31 cl::desc("Total size of all blocks (including zero-fill) in all "
32 "graphs (post-fixup)"),
35 class StatsPlugin
: public ObjectLinkingLayer::Plugin
{
37 static void enableIfNeeded(Session
&S
, bool UsingOrcRuntime
) {
38 std::unique_ptr
<StatsPlugin
> Instance
;
39 auto GetStats
= [&]() -> StatsPlugin
& {
41 Instance
.reset(new StatsPlugin(UsingOrcRuntime
));
45 if (ShowPrePruneTotalBlockSize
)
46 GetStats().PrePruneTotalBlockSize
= 0;
48 if (ShowPostFixupTotalBlockSize
)
49 GetStats().PostFixupTotalBlockSize
= 0;
52 S
.ObjLayer
.addPlugin(std::move(Instance
));
55 ~StatsPlugin() { publish(dbgs()); }
57 void publish(raw_ostream
&OS
);
59 void modifyPassConfig(MaterializationResponsibility
&MR
, LinkGraph
&G
,
60 PassConfiguration
&PassConfig
) override
{
61 PassConfig
.PrePrunePasses
.push_back(
62 [this](LinkGraph
&G
) { return recordPrePruneStats(G
); });
63 PassConfig
.PostFixupPasses
.push_back(
64 [this](LinkGraph
&G
) { return recordPostFixupStats(G
); });
67 Error
notifyFailed(MaterializationResponsibility
&MR
) override
{
68 return Error::success();
71 Error
notifyRemovingResources(JITDylib
&JD
, ResourceKey K
) override
{
72 return Error::success();
75 void notifyTransferringResources(JITDylib
&JD
, ResourceKey DstKey
,
76 ResourceKey SrcKey
) override
{}
79 StatsPlugin(bool UsingOrcRuntime
) : UsingOrcRuntime(UsingOrcRuntime
) {}
80 Error
recordPrePruneStats(jitlink::LinkGraph
&G
);
81 Error
recordPostFixupStats(jitlink::LinkGraph
&G
);
86 std::optional
<uint64_t> PrePruneTotalBlockSize
;
87 std::optional
<uint64_t> PostFixupTotalBlockSize
;
88 std::optional
<DenseMap
<size_t, size_t>> EdgeCountDetails
;
91 void StatsPlugin::publish(raw_ostream
&OS
) {
94 OS
<< "Note: Session stats include runtime and entry point lookup, but "
95 "not JITDylib initialization/deinitialization.\n";
97 OS
<< "Statistics:\n";
98 if (PrePruneTotalBlockSize
)
99 OS
<< " Total size of all blocks before pruning: "
100 << *PrePruneTotalBlockSize
<< "\n";
102 if (PostFixupTotalBlockSize
)
103 OS
<< " Total size of all blocks after fixups: "
104 << *PostFixupTotalBlockSize
<< "\n";
107 static uint64_t computeTotalBlockSizes(LinkGraph
&G
) {
108 uint64_t TotalSize
= 0;
109 for (auto *B
: G
.blocks())
110 TotalSize
+= B
->getSize();
114 Error
StatsPlugin::recordPrePruneStats(LinkGraph
&G
) {
115 std::lock_guard
<std::mutex
> Lock(M
);
117 if (PrePruneTotalBlockSize
)
118 *PrePruneTotalBlockSize
+= computeTotalBlockSizes(G
);
120 return Error::success();
123 Error
StatsPlugin::recordPostFixupStats(LinkGraph
&G
) {
124 std::lock_guard
<std::mutex
> Lock(M
);
126 if (PostFixupTotalBlockSize
)
127 *PostFixupTotalBlockSize
+= computeTotalBlockSizes(G
);
128 return Error::success();
132 void enableStatistics(Session
&S
, bool UsingOrcRuntime
) {
133 StatsPlugin::enableIfNeeded(S
, UsingOrcRuntime
);