| //===-- llvm-jitlink-statistics.cpp -- gathers/reports JIT-linking stats --===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file contains the code for enabling, gathering and reporting | |
| // llvm-jitlink statistics. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm-jitlink.h" | |
| #include "llvm/Support/CommandLine.h" | |
| #define DEBUG_TYPE "llvm_jitlink" | |
| using namespace llvm; | |
| using namespace llvm::jitlink; | |
| using namespace llvm::orc; | |
| static cl::opt<bool> ShowPrePruneTotalBlockSize( | |
| "pre-prune-total-block-size", | |
| cl::desc("Total size of all blocks (including zero-fill) in all " | |
| "graphs (pre-pruning)"), | |
| cl::init(false)); | |
| static cl::opt<bool> ShowPostFixupTotalBlockSize( | |
| "post-fixup-total-block-size", | |
| cl::desc("Total size of all blocks (including zero-fill) in all " | |
| "graphs (post-fixup)"), | |
| cl::init(false)); | |
| class StatsPlugin : public ObjectLinkingLayer::Plugin { | |
| public: | |
| static void enableIfNeeded(Session &S, bool UsingOrcRuntime) { | |
| std::unique_ptr<StatsPlugin> Instance; | |
| auto GetStats = [&]() -> StatsPlugin & { | |
| if (!Instance) | |
| Instance.reset(new StatsPlugin(UsingOrcRuntime)); | |
| return *Instance; | |
| }; | |
| if (ShowPrePruneTotalBlockSize) | |
| GetStats().PrePruneTotalBlockSize = 0; | |
| if (ShowPostFixupTotalBlockSize) | |
| GetStats().PostFixupTotalBlockSize = 0; | |
| if (Instance) | |
| S.ObjLayer->addPlugin(std::move(Instance)); | |
| } | |
| ~StatsPlugin() override { publish(dbgs()); } | |
| void publish(raw_ostream &OS); | |
| void modifyPassConfig(MaterializationResponsibility &MR, LinkGraph &G, | |
| PassConfiguration &PassConfig) override { | |
| PassConfig.PrePrunePasses.push_back( | |
| [this](LinkGraph &G) { return recordPrePruneStats(G); }); | |
| PassConfig.PostFixupPasses.push_back( | |
| [this](LinkGraph &G) { return recordPostFixupStats(G); }); | |
| } | |
| Error notifyFailed(MaterializationResponsibility &MR) override { | |
| return Error::success(); | |
| } | |
| Error notifyRemovingResources(JITDylib &JD, ResourceKey K) override { | |
| return Error::success(); | |
| } | |
| void notifyTransferringResources(JITDylib &JD, ResourceKey DstKey, | |
| ResourceKey SrcKey) override {} | |
| private: | |
| StatsPlugin(bool UsingOrcRuntime) : UsingOrcRuntime(UsingOrcRuntime) {} | |
| Error recordPrePruneStats(jitlink::LinkGraph &G); | |
| Error recordPostFixupStats(jitlink::LinkGraph &G); | |
| bool UsingOrcRuntime; | |
| std::mutex M; | |
| std::optional<uint64_t> PrePruneTotalBlockSize; | |
| std::optional<uint64_t> PostFixupTotalBlockSize; | |
| std::optional<DenseMap<size_t, size_t>> EdgeCountDetails; | |
| }; | |
| void StatsPlugin::publish(raw_ostream &OS) { | |
| if (UsingOrcRuntime) | |
| OS << "Note: Session stats include runtime and entry point lookup, but " | |
| "not JITDylib initialization/deinitialization.\n"; | |
| OS << "Statistics:\n"; | |
| if (PrePruneTotalBlockSize) | |
| OS << " Total size of all blocks before pruning: " | |
| << *PrePruneTotalBlockSize << "\n"; | |
| if (PostFixupTotalBlockSize) | |
| OS << " Total size of all blocks after fixups: " | |
| << *PostFixupTotalBlockSize << "\n"; | |
| } | |
| static uint64_t computeTotalBlockSizes(LinkGraph &G) { | |
| uint64_t TotalSize = 0; | |
| for (auto *B : G.blocks()) | |
| TotalSize += B->getSize(); | |
| return TotalSize; | |
| } | |
| Error StatsPlugin::recordPrePruneStats(LinkGraph &G) { | |
| std::lock_guard<std::mutex> Lock(M); | |
| if (PrePruneTotalBlockSize) | |
| *PrePruneTotalBlockSize += computeTotalBlockSizes(G); | |
| return Error::success(); | |
| } | |
| Error StatsPlugin::recordPostFixupStats(LinkGraph &G) { | |
| std::lock_guard<std::mutex> Lock(M); | |
| if (PostFixupTotalBlockSize) | |
| *PostFixupTotalBlockSize += computeTotalBlockSizes(G); | |
| return Error::success(); | |
| } | |
| namespace llvm { | |
| void enableStatistics(Session &S, bool UsingOrcRuntime) { | |
| StatsPlugin::enableIfNeeded(S, UsingOrcRuntime); | |
| } | |
| } // namespace llvm |