![]() System : Linux absol.cf 5.4.0-198-generic #218-Ubuntu SMP Fri Sep 27 20:18:53 UTC 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.33 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, Directory : /usr/include/llvm-10/llvm/XRay/ |
Upload File : |
//===- Profile.h - XRay Profile Abstraction -------------------------------===// // // 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 // //===----------------------------------------------------------------------===// // // Defines the XRay Profile class representing the latency profile generated by // XRay's profiling mode. // //===----------------------------------------------------------------------===// #ifndef LLVM_XRAY_PROFILE_H #define LLVM_XRAY_PROFILE_H #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include <list> #include <utility> #include <vector> namespace llvm { namespace xray { class Profile; // We forward declare the Trace type for turning a Trace into a Profile. class Trace; /// This function will attempt to load an XRay Profiling Mode profile from the /// provided |Filename|. /// /// For any errors encountered in the loading of the profile data from /// |Filename|, this function will return an Error condition appropriately. Expected<Profile> loadProfile(StringRef Filename); /// This algorithm will merge two Profile instances into a single Profile /// instance, aggregating blocks by Thread ID. Profile mergeProfilesByThread(const Profile &L, const Profile &R); /// This algorithm will merge two Profile instances into a single Profile /// instance, aggregating blocks by function call stack. Profile mergeProfilesByStack(const Profile &L, const Profile &R); /// This function takes a Trace and creates a Profile instance from it. Expected<Profile> profileFromTrace(const Trace &T); /// Profile instances are thread-compatible. class Profile { public: using ThreadID = uint64_t; using PathID = unsigned; using FuncID = int32_t; struct Data { uint64_t CallCount; uint64_t CumulativeLocalTime; }; struct Block { ThreadID Thread; std::vector<std::pair<PathID, Data>> PathData; }; /// Provides a sequence of function IDs from a previously interned PathID. /// /// Returns an error if |P| had not been interned before into the Profile. /// Expected<std::vector<FuncID>> expandPath(PathID P) const; /// The stack represented in |P| must be in stack order (leaf to root). This /// will always return the same PathID for |P| that has the same sequence. PathID internPath(ArrayRef<FuncID> P); /// Appends a fully-formed Block instance into the Profile. /// /// Returns an error condition in the following cases: /// /// - The PathData component of the Block is empty /// Error addBlock(Block &&B); Profile() = default; ~Profile() = default; Profile(Profile &&O) noexcept : Blocks(std::move(O.Blocks)), NodeStorage(std::move(O.NodeStorage)), Roots(std::move(O.Roots)), PathIDMap(std::move(O.PathIDMap)), NextID(O.NextID) {} Profile &operator=(Profile &&O) noexcept { Blocks = std::move(O.Blocks); NodeStorage = std::move(O.NodeStorage); Roots = std::move(O.Roots); PathIDMap = std::move(O.PathIDMap); NextID = O.NextID; return *this; } Profile(const Profile &); Profile &operator=(const Profile &); friend void swap(Profile &L, Profile &R) { using std::swap; swap(L.Blocks, R.Blocks); swap(L.NodeStorage, R.NodeStorage); swap(L.Roots, R.Roots); swap(L.PathIDMap, R.PathIDMap); swap(L.NextID, R.NextID); } private: using BlockList = std::list<Block>; struct TrieNode { FuncID Func = 0; std::vector<TrieNode *> Callees{}; TrieNode *Caller = nullptr; PathID ID = 0; }; // List of blocks associated with a Profile. BlockList Blocks; // List of TrieNode elements we've seen. std::list<TrieNode> NodeStorage; // List of call stack roots. SmallVector<TrieNode *, 4> Roots; // Reverse mapping between a PathID to a TrieNode*. DenseMap<PathID, TrieNode *> PathIDMap; // Used to identify paths. PathID NextID = 1; public: using const_iterator = BlockList::const_iterator; const_iterator begin() const { return Blocks.begin(); } const_iterator end() const { return Blocks.end(); } bool empty() const { return Blocks.empty(); } }; } // namespace xray } // namespace llvm #endif