1 | //===- xray-account.h - XRay Function Call Accounting ---------------------===// |
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 | // This file defines the interface for performing some basic function call |
10 | // accounting from an XRay trace. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | #ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |
14 | #define LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |
15 | |
16 | #include <utility> |
17 | |
18 | #include "func-id-helper.h" |
19 | #include "llvm/ADT/Bitfields.h" |
20 | #include "llvm/Support/Program.h" |
21 | #include "llvm/Support/raw_ostream.h" |
22 | #include "llvm/XRay/XRayRecord.h" |
23 | |
24 | namespace llvm { |
25 | namespace xray { |
26 | |
27 | class LatencyAccountant { |
28 | public: |
29 | typedef llvm::DenseMap<int32_t, llvm::SmallVector<uint64_t, 0>> |
30 | FunctionLatencyMap; |
31 | typedef llvm::DenseMap<uint32_t, std::pair<uint64_t, uint64_t>> |
32 | PerThreadMinMaxTSCMap; |
33 | typedef llvm::DenseMap<uint8_t, std::pair<uint64_t, uint64_t>> |
34 | PerCPUMinMaxTSCMap; |
35 | struct FunctionStack { |
36 | llvm::SmallVector<std::pair<int32_t, uint64_t>, 32> Stack; |
37 | class RecursionStatus { |
38 | uint32_t Storage = 0; |
39 | using Depth = Bitfield::Element<int32_t, 0, 31>; // Low 31 bits. |
40 | using IsRecursive = Bitfield::Element<bool, 31, 1>; // Sign bit. |
41 | public: |
42 | RecursionStatus &operator++(); |
43 | RecursionStatus &operator--(); |
44 | bool isRecursive() const; |
45 | }; |
46 | std::optional<llvm::DenseMap<int32_t, RecursionStatus>> RecursionDepth; |
47 | }; |
48 | typedef llvm::DenseMap<uint32_t, FunctionStack> PerThreadFunctionStackMap; |
49 | |
50 | private: |
51 | PerThreadFunctionStackMap PerThreadFunctionStack; |
52 | FunctionLatencyMap FunctionLatencies; |
53 | PerThreadMinMaxTSCMap PerThreadMinMaxTSC; |
54 | PerCPUMinMaxTSCMap PerCPUMinMaxTSC; |
55 | FuncIdConversionHelper &FuncIdHelper; |
56 | |
57 | bool RecursiveCallsOnly = false; |
58 | bool DeduceSiblingCalls = false; |
59 | uint64_t CurrentMaxTSC = 0; |
60 | |
61 | void recordLatency(int32_t FuncId, uint64_t Latency) { |
62 | FunctionLatencies[FuncId].push_back(Elt: Latency); |
63 | } |
64 | |
65 | public: |
66 | explicit LatencyAccountant(FuncIdConversionHelper &FuncIdHelper, |
67 | bool RecursiveCallsOnly, bool DeduceSiblingCalls) |
68 | : FuncIdHelper(FuncIdHelper), RecursiveCallsOnly(RecursiveCallsOnly), |
69 | DeduceSiblingCalls(DeduceSiblingCalls) {} |
70 | |
71 | const FunctionLatencyMap &getFunctionLatencies() const { |
72 | return FunctionLatencies; |
73 | } |
74 | |
75 | const PerThreadMinMaxTSCMap &getPerThreadMinMaxTSC() const { |
76 | return PerThreadMinMaxTSC; |
77 | } |
78 | |
79 | const PerCPUMinMaxTSCMap &getPerCPUMinMaxTSC() const { |
80 | return PerCPUMinMaxTSC; |
81 | } |
82 | |
83 | /// Returns false in case we fail to account the provided record. This happens |
84 | /// in the following cases: |
85 | /// |
86 | /// - An exit record does not match any entry records for the same function. |
87 | /// If we've been set to deduce sibling calls, we try walking up the stack |
88 | /// and recording times for the higher level functions. |
89 | /// - A record has a TSC that's before the latest TSC that has been |
90 | /// recorded. We still record the TSC for the min-max. |
91 | /// |
92 | bool accountRecord(const XRayRecord &Record); |
93 | |
94 | const PerThreadFunctionStackMap &getPerThreadFunctionStack() const { |
95 | return PerThreadFunctionStack; |
96 | } |
97 | |
98 | // Output Functions |
99 | // ================ |
100 | |
101 | void (raw_ostream &OS, const XRayFileHeader &) const; |
102 | void (raw_ostream &OS, const XRayFileHeader &) const; |
103 | |
104 | private: |
105 | // Internal helper to implement common parts of the exportStatsAs... |
106 | // functions. |
107 | template <class F> void (const XRayFileHeader &, F fn) const; |
108 | }; |
109 | |
110 | } // namespace xray |
111 | } // namespace llvm |
112 | |
113 | #endif // LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |
114 | |