blob: b09d2d0e70af6ce91f7bec16f958f14d4373d735 [file] [log] [blame]
David Blaikie87299ad2017-01-16 20:36:26 +00001//===-- xray-graph.h - XRay Function Call Graph Renderer --------*- C++ -*-===//
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// Generate a DOT file to represent the function call graph encountered in
11// the trace.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef XRAY_GRAPH_H
16#define XRAY_GRAPH_H
17
18#include <vector>
19
20#include "func-id-helper.h"
21#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/Support/raw_ostream.h"
Pavel Labath9778921a2017-01-17 09:39:31 +000024#include "llvm/Support/Program.h"
David Blaikie87299ad2017-01-16 20:36:26 +000025#include "llvm/XRay/Trace.h"
26#include "llvm/XRay/XRayRecord.h"
27
28namespace llvm {
29namespace xray {
30
31/// A class encapsulating the logic related to analyzing XRay traces, producting
32/// Graphs from them and then exporting those graphs for review.
33class GraphRenderer {
34public:
35 /// An inner struct for common timing statistics information
36 struct TimeStat {
37 uint64_t Count;
38 double Min;
39 double Median;
40 double Pct90;
41 double Pct99;
42 double Max;
43 double Sum;
44 };
45
46 /// An inner struct for storing edge attributes for our graph. Here the
47 /// attributes are mainly function call statistics.
48 ///
49 /// FIXME: expand to contain more information eg call latencies.
50 struct EdgeAttribute {
51 TimeStat S;
52 std::vector<uint64_t> Timings;
53 };
54
55 /// An Inner Struct for storing vertex attributes, at the moment just
56 /// SymbolNames, however in future we could store bulk function statistics.
57 ///
58 /// FIXME: Store more attributes based on instrumentation map.
59 struct VertexAttribute {
60 std::string SymbolName;
61 TimeStat S;
62 };
63
64private:
65 /// The Graph stored in an edge-list like format, with the edges also having
66 /// An attached set of attributes.
67 DenseMap<int32_t, DenseMap<int32_t, EdgeAttribute>> Graph;
68
69 /// Graph Vertex Attributes. These are presently stored seperate from the
70 /// main graph.
71 DenseMap<int32_t, VertexAttribute> VertexAttrs;
72
73 struct FunctionAttr {
74 int32_t FuncId;
75 uint64_t TSC;
76 };
77
78 /// Use a Map to store the Function stack for each thread whilst building the
79 /// graph.
80 ///
81 /// FIXME: Perhaps we can Build this into LatencyAccountant? or vise versa?
Pavel Labath9778921a2017-01-17 09:39:31 +000082 DenseMap<llvm::sys::ProcessInfo::ProcessId, SmallVector<FunctionAttr, 4>>
83 PerThreadFunctionStack;
David Blaikie87299ad2017-01-16 20:36:26 +000084
85 /// Usefull object for getting human readable Symbol Names.
86 FuncIdConversionHelper &FuncIdHelper;
87 bool DeduceSiblingCalls = false;
88 uint64_t CurrentMaxTSC = 0;
89
90 /// A private function to help implement the statistic generation functions;
91 template <typename U>
92 void getStats(U begin, U end, GraphRenderer::TimeStat &S);
93
94 /// Calculates latency statistics for each edge and stores the data in the
95 /// Graph
96 void calculateEdgeStatistics();
97
98 /// Calculates latency statistics for each vertex and stores the data in the
99 /// Graph
100 void calculateVertexStatistics();
101
102 /// Normalises latency statistics for each edge and vertex by CycleFrequency;
103 void normaliseStatistics(double CycleFrequency);
104
105public:
106 /// Takes in a reference to a FuncIdHelper in order to have ready access to
107 /// Symbol names.
108 explicit GraphRenderer(FuncIdConversionHelper &FuncIdHelper, bool DSC)
109 : FuncIdHelper(FuncIdHelper), DeduceSiblingCalls(DSC) {}
110
111 /// Process an Xray record and expand the graph.
112 ///
113 /// This Function will return true on success, or false if records are not
114 /// presented in per-thread call-tree DFS order. (That is for each thread the
115 /// Records should be in order runtime on an ideal system.)
116 ///
117 /// FIXME: Make this more robust against small irregularities.
118 bool accountRecord(const XRayRecord &Record);
119
120 /// An enum for enumerating the various statistics gathered on latencies
121 enum class StatType { COUNT, MIN, MED, PCT90, PCT99, MAX, SUM };
122
123 /// Output the Embedded graph in DOT format on \p OS, labeling the edges by
124 /// \p T
125 void exportGraphAsDOT(raw_ostream &OS, const XRayFileHeader &H,
126 StatType T = StatType::COUNT);
127};
128}
129}
130
131#endif // XRAY_GRAPH_H