- //===- 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 
-