Mercurial > hg > CbC > CbC_llvm
comparison include/llvm/XRay/Profile.h @ 148:63bd29f05246
merged
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 14 Aug 2019 19:46:37 +0900 |
parents | c2174574ed3a |
children |
comparison
equal
deleted
inserted
replaced
146:3fc4d5c3e21e | 148:63bd29f05246 |
---|---|
1 //===- Profile.h - XRay Profile Abstraction -------------------------------===// | |
2 // | |
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 | |
6 // | |
7 //===----------------------------------------------------------------------===// | |
8 // | |
9 // Defines the XRay Profile class representing the latency profile generated by | |
10 // XRay's profiling mode. | |
11 // | |
12 //===----------------------------------------------------------------------===// | |
13 #ifndef LLVM_XRAY_PROFILE_H | |
14 #define LLVM_XRAY_PROFILE_H | |
15 | |
16 #include "llvm/ADT/DenseMap.h" | |
17 #include "llvm/ADT/SmallVector.h" | |
18 #include "llvm/ADT/StringRef.h" | |
19 #include "llvm/Support/Error.h" | |
20 #include <list> | |
21 #include <utility> | |
22 #include <vector> | |
23 | |
24 namespace llvm { | |
25 namespace xray { | |
26 | |
27 class Profile; | |
28 | |
29 // We forward declare the Trace type for turning a Trace into a Profile. | |
30 class Trace; | |
31 | |
32 /// This function will attempt to load an XRay Profiling Mode profile from the | |
33 /// provided |Filename|. | |
34 /// | |
35 /// For any errors encountered in the loading of the profile data from | |
36 /// |Filename|, this function will return an Error condition appropriately. | |
37 Expected<Profile> loadProfile(StringRef Filename); | |
38 | |
39 /// This algorithm will merge two Profile instances into a single Profile | |
40 /// instance, aggregating blocks by Thread ID. | |
41 Profile mergeProfilesByThread(const Profile &L, const Profile &R); | |
42 | |
43 /// This algorithm will merge two Profile instances into a single Profile | |
44 /// instance, aggregating blocks by function call stack. | |
45 Profile mergeProfilesByStack(const Profile &L, const Profile &R); | |
46 | |
47 /// This function takes a Trace and creates a Profile instance from it. | |
48 Expected<Profile> profileFromTrace(const Trace &T); | |
49 | |
50 /// Profile instances are thread-compatible. | |
51 class Profile { | |
52 public: | |
53 using ThreadID = uint64_t; | |
54 using PathID = unsigned; | |
55 using FuncID = int32_t; | |
56 | |
57 struct Data { | |
58 uint64_t CallCount; | |
59 uint64_t CumulativeLocalTime; | |
60 }; | |
61 | |
62 struct Block { | |
63 ThreadID Thread; | |
64 std::vector<std::pair<PathID, Data>> PathData; | |
65 }; | |
66 | |
67 /// Provides a sequence of function IDs from a previously interned PathID. | |
68 /// | |
69 /// Returns an error if |P| had not been interned before into the Profile. | |
70 /// | |
71 Expected<std::vector<FuncID>> expandPath(PathID P) const; | |
72 | |
73 /// The stack represented in |P| must be in stack order (leaf to root). This | |
74 /// will always return the same PathID for |P| that has the same sequence. | |
75 PathID internPath(ArrayRef<FuncID> P); | |
76 | |
77 /// Appends a fully-formed Block instance into the Profile. | |
78 /// | |
79 /// Returns an error condition in the following cases: | |
80 /// | |
81 /// - The PathData component of the Block is empty | |
82 /// | |
83 Error addBlock(Block &&B); | |
84 | |
85 Profile() = default; | |
86 ~Profile() = default; | |
87 | |
88 Profile(Profile &&O) noexcept | |
89 : Blocks(std::move(O.Blocks)), NodeStorage(std::move(O.NodeStorage)), | |
90 Roots(std::move(O.Roots)), PathIDMap(std::move(O.PathIDMap)), | |
91 NextID(O.NextID) {} | |
92 | |
93 Profile &operator=(Profile &&O) noexcept { | |
94 Blocks = std::move(O.Blocks); | |
95 NodeStorage = std::move(O.NodeStorage); | |
96 Roots = std::move(O.Roots); | |
97 PathIDMap = std::move(O.PathIDMap); | |
98 NextID = O.NextID; | |
99 return *this; | |
100 } | |
101 | |
102 Profile(const Profile &); | |
103 Profile &operator=(const Profile &); | |
104 | |
105 friend void swap(Profile &L, Profile &R) { | |
106 using std::swap; | |
107 swap(L.Blocks, R.Blocks); | |
108 swap(L.NodeStorage, R.NodeStorage); | |
109 swap(L.Roots, R.Roots); | |
110 swap(L.PathIDMap, R.PathIDMap); | |
111 swap(L.NextID, R.NextID); | |
112 } | |
113 | |
114 private: | |
115 using BlockList = std::list<Block>; | |
116 | |
117 struct TrieNode { | |
118 FuncID Func = 0; | |
119 std::vector<TrieNode *> Callees{}; | |
120 TrieNode *Caller = nullptr; | |
121 PathID ID = 0; | |
122 }; | |
123 | |
124 // List of blocks associated with a Profile. | |
125 BlockList Blocks; | |
126 | |
127 // List of TrieNode elements we've seen. | |
128 std::list<TrieNode> NodeStorage; | |
129 | |
130 // List of call stack roots. | |
131 SmallVector<TrieNode *, 4> Roots; | |
132 | |
133 // Reverse mapping between a PathID to a TrieNode*. | |
134 DenseMap<PathID, TrieNode *> PathIDMap; | |
135 | |
136 // Used to identify paths. | |
137 PathID NextID = 1; | |
138 | |
139 public: | |
140 using const_iterator = BlockList::const_iterator; | |
141 const_iterator begin() const { return Blocks.begin(); } | |
142 const_iterator end() const { return Blocks.end(); } | |
143 bool empty() const { return Blocks.empty(); } | |
144 }; | |
145 | |
146 } // namespace xray | |
147 } // namespace llvm | |
148 | |
149 #endif |