Dean Michael Berris | c4416a6 | 2017-01-12 07:38:13 +0000 | [diff] [blame] | 1 | //===- xray-account.h - XRay Function Call Accounting ---------------------===// |
| 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines the interface for performing some basic function call |
| 11 | // accounting from an XRay trace. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | #ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |
| 15 | #define LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |
| 16 | |
| 17 | #include <map> |
| 18 | #include <utility> |
| 19 | #include <vector> |
| 20 | |
| 21 | #include "func-id-helper.h" |
Simon Pilgrim | e821446 | 2017-01-12 11:13:51 +0000 | [diff] [blame] | 22 | #include "llvm/Support/Program.h" |
Dean Michael Berris | c4416a6 | 2017-01-12 07:38:13 +0000 | [diff] [blame] | 23 | #include "llvm/Support/raw_ostream.h" |
| 24 | #include "llvm/XRay/XRayRecord.h" |
| 25 | |
| 26 | namespace llvm { |
| 27 | namespace xray { |
| 28 | |
| 29 | class LatencyAccountant { |
| 30 | public: |
| 31 | typedef std::map<int32_t, std::vector<uint64_t>> FunctionLatencyMap; |
Zachary Turner | 370ce5a | 2018-06-08 15:16:25 +0000 | [diff] [blame] | 32 | typedef std::map<llvm::sys::procid_t, std::pair<uint64_t, uint64_t>> |
Simon Pilgrim | e821446 | 2017-01-12 11:13:51 +0000 | [diff] [blame] | 33 | PerThreadMinMaxTSCMap; |
Dean Michael Berris | c4416a6 | 2017-01-12 07:38:13 +0000 | [diff] [blame] | 34 | typedef std::map<uint8_t, std::pair<uint64_t, uint64_t>> PerCPUMinMaxTSCMap; |
| 35 | typedef std::vector<std::pair<int32_t, uint64_t>> FunctionStack; |
Zachary Turner | 370ce5a | 2018-06-08 15:16:25 +0000 | [diff] [blame] | 36 | typedef std::map<llvm::sys::procid_t, FunctionStack> |
Simon Pilgrim | e821446 | 2017-01-12 11:13:51 +0000 | [diff] [blame] | 37 | PerThreadFunctionStackMap; |
Dean Michael Berris | c4416a6 | 2017-01-12 07:38:13 +0000 | [diff] [blame] | 38 | |
| 39 | private: |
| 40 | PerThreadFunctionStackMap PerThreadFunctionStack; |
| 41 | FunctionLatencyMap FunctionLatencies; |
| 42 | PerThreadMinMaxTSCMap PerThreadMinMaxTSC; |
| 43 | PerCPUMinMaxTSCMap PerCPUMinMaxTSC; |
| 44 | FuncIdConversionHelper &FuncIdHelper; |
| 45 | |
| 46 | bool DeduceSiblingCalls = false; |
| 47 | uint64_t CurrentMaxTSC = 0; |
| 48 | |
| 49 | void recordLatency(int32_t FuncId, uint64_t Latency) { |
| 50 | FunctionLatencies[FuncId].push_back(Latency); |
| 51 | } |
| 52 | |
| 53 | public: |
| 54 | explicit LatencyAccountant(FuncIdConversionHelper &FuncIdHelper, |
| 55 | bool DeduceSiblingCalls) |
| 56 | : FuncIdHelper(FuncIdHelper), DeduceSiblingCalls(DeduceSiblingCalls) {} |
| 57 | |
| 58 | const FunctionLatencyMap &getFunctionLatencies() const { |
| 59 | return FunctionLatencies; |
| 60 | } |
| 61 | |
| 62 | const PerThreadMinMaxTSCMap &getPerThreadMinMaxTSC() const { |
| 63 | return PerThreadMinMaxTSC; |
| 64 | } |
| 65 | |
| 66 | const PerCPUMinMaxTSCMap &getPerCPUMinMaxTSC() const { |
| 67 | return PerCPUMinMaxTSC; |
| 68 | } |
| 69 | |
| 70 | /// Returns false in case we fail to account the provided record. This happens |
| 71 | /// in the following cases: |
| 72 | /// |
| 73 | /// - An exit record does not match any entry records for the same function. |
| 74 | /// If we've been set to deduce sibling calls, we try walking up the stack |
| 75 | /// and recording times for the higher level functions. |
| 76 | /// - A record has a TSC that's before the latest TSC that has been |
| 77 | /// recorded. We still record the TSC for the min-max. |
| 78 | /// |
| 79 | bool accountRecord(const XRayRecord &Record); |
| 80 | |
Zachary Turner | 370ce5a | 2018-06-08 15:16:25 +0000 | [diff] [blame] | 81 | const FunctionStack *getThreadFunctionStack(llvm::sys::procid_t TId) const { |
Dean Michael Berris | c4416a6 | 2017-01-12 07:38:13 +0000 | [diff] [blame] | 82 | auto I = PerThreadFunctionStack.find(TId); |
| 83 | if (I == PerThreadFunctionStack.end()) |
| 84 | return nullptr; |
| 85 | return &I->second; |
| 86 | } |
| 87 | |
| 88 | const PerThreadFunctionStackMap &getPerThreadFunctionStack() const { |
| 89 | return PerThreadFunctionStack; |
| 90 | } |
| 91 | |
| 92 | // Output Functions |
| 93 | // ================ |
| 94 | |
| 95 | void exportStatsAsText(raw_ostream &OS, const XRayFileHeader &Header) const; |
| 96 | void exportStatsAsCSV(raw_ostream &OS, const XRayFileHeader &Header) const; |
| 97 | |
| 98 | private: |
| 99 | // Internal helper to implement common parts of the exportStatsAs... |
| 100 | // functions. |
| 101 | template <class F> void exportStats(const XRayFileHeader &Header, F fn) const; |
| 102 | }; |
| 103 | |
| 104 | } // namespace xray |
| 105 | } // namespace llvm |
| 106 | |
| 107 | #endif // LLVM_TOOLS_LLVM_XRAY_XRAY_ACCOUNT_H |