1 //===- Profile.h - XRay Profile Abstraction -------------------------------===//
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 // Defines the XRay Profile class representing the latency profile generated by
10 // XRay's profiling mode.
12 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_XRAY_PROFILE_H
14 #define LLVM_XRAY_PROFILE_H
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/SmallVector.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Support/Error.h"
29 // We forward declare the Trace type for turning a Trace into a Profile.
32 /// This function will attempt to load an XRay Profiling Mode profile from the
33 /// provided |Filename|.
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
);
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
);
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
);
47 /// This function takes a Trace and creates a Profile instance from it.
48 Expected
<Profile
> profileFromTrace(const Trace
&T
);
50 /// Profile instances are thread-compatible.
53 using ThreadID
= uint64_t;
54 using PathID
= unsigned;
55 using FuncID
= int32_t;
59 uint64_t CumulativeLocalTime
;
64 std::vector
<std::pair
<PathID
, Data
>> PathData
;
67 /// Provides a sequence of function IDs from a previously interned PathID.
69 /// Returns an error if |P| had not been interned before into the Profile.
71 Expected
<std::vector
<FuncID
>> expandPath(PathID P
) const;
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
);
77 /// Appends a fully-formed Block instance into the Profile.
79 /// Returns an error condition in the following cases:
81 /// - The PathData component of the Block is empty
83 Error
addBlock(Block
&&B
);
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
)),
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
);
102 Profile(const Profile
&);
103 Profile
&operator=(const Profile
&);
105 friend void swap(Profile
&L
, Profile
&R
) {
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
);
115 using BlockList
= std::list
<Block
>;
119 std::vector
<TrieNode
*> Callees
{};
120 TrieNode
*Caller
= nullptr;
124 // List of blocks associated with a Profile.
127 // List of TrieNode elements we've seen.
128 std::list
<TrieNode
> NodeStorage
;
130 // List of call stack roots.
131 SmallVector
<TrieNode
*, 4> Roots
;
133 // Reverse mapping between a PathID to a TrieNode*.
134 DenseMap
<PathID
, TrieNode
*> PathIDMap
;
136 // Used to identify paths.
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(); }