blob: 8b0e20825204ff4512bb878eca38797c7d603e65 [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
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000018#include <string>
David Blaikie87299ad2017-01-16 20:36:26 +000019#include <vector>
20
21#include "func-id-helper.h"
22#include "llvm/ADT/DenseMap.h"
23#include "llvm/ADT/SmallVector.h"
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000024#include "llvm/Support/Errc.h"
Pavel Labath9778921a2017-01-17 09:39:31 +000025#include "llvm/Support/Program.h"
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000026#include "llvm/Support/raw_ostream.h"
David Blaikie87299ad2017-01-16 20:36:26 +000027#include "llvm/XRay/Trace.h"
28#include "llvm/XRay/XRayRecord.h"
29
30namespace llvm {
31namespace xray {
32
33/// A class encapsulating the logic related to analyzing XRay traces, producting
34/// Graphs from them and then exporting those graphs for review.
35class GraphRenderer {
36public:
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000037 /// An enum for enumerating the various statistics gathered on latencies
38 enum class StatType { NONE, COUNT, MIN, MED, PCT90, PCT99, MAX, SUM };
39
David Blaikie87299ad2017-01-16 20:36:26 +000040 /// An inner struct for common timing statistics information
41 struct TimeStat {
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000042 uint64_t Count = 0;
43 double Min = 0;
44 double Median = 0;
45 double Pct90 = 0;
46 double Pct99 = 0;
47 double Max = 0;
48 double Sum = 0;
49 std::string getAsString(StatType T) const;
50 double compare(StatType T, const TimeStat &Other) const;
David Blaikie87299ad2017-01-16 20:36:26 +000051 };
52
53 /// An inner struct for storing edge attributes for our graph. Here the
54 /// attributes are mainly function call statistics.
55 ///
56 /// FIXME: expand to contain more information eg call latencies.
57 struct EdgeAttribute {
58 TimeStat S;
59 std::vector<uint64_t> Timings;
60 };
61
62 /// An Inner Struct for storing vertex attributes, at the moment just
63 /// SymbolNames, however in future we could store bulk function statistics.
64 ///
65 /// FIXME: Store more attributes based on instrumentation map.
66 struct VertexAttribute {
67 std::string SymbolName;
68 TimeStat S;
69 };
70
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000071 struct FunctionAttr {
72 int32_t FuncId;
73 uint64_t TSC;
74 };
75
76 typedef SmallVector<FunctionAttr, 4> FunctionStack;
77
78 typedef DenseMap<llvm::sys::ProcessInfo::ProcessId, FunctionStack>
79 PerThreadFunctionStackMap;
80
David Blaikie87299ad2017-01-16 20:36:26 +000081private:
82 /// The Graph stored in an edge-list like format, with the edges also having
83 /// An attached set of attributes.
84 DenseMap<int32_t, DenseMap<int32_t, EdgeAttribute>> Graph;
85
86 /// Graph Vertex Attributes. These are presently stored seperate from the
87 /// main graph.
88 DenseMap<int32_t, VertexAttribute> VertexAttrs;
89
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000090 TimeStat GraphEdgeMax;
91 TimeStat GraphVertexMax;
David Blaikie87299ad2017-01-16 20:36:26 +000092
93 /// Use a Map to store the Function stack for each thread whilst building the
94 /// graph.
95 ///
96 /// FIXME: Perhaps we can Build this into LatencyAccountant? or vise versa?
Dean Michael Berrisd09bf192017-01-25 07:14:43 +000097 PerThreadFunctionStackMap PerThreadFunctionStack;
David Blaikie87299ad2017-01-16 20:36:26 +000098
99 /// Usefull object for getting human readable Symbol Names.
100 FuncIdConversionHelper &FuncIdHelper;
101 bool DeduceSiblingCalls = false;
102 uint64_t CurrentMaxTSC = 0;
103
104 /// A private function to help implement the statistic generation functions;
105 template <typename U>
106 void getStats(U begin, U end, GraphRenderer::TimeStat &S);
Dean Michael Berrisd09bf192017-01-25 07:14:43 +0000107 void updateMaxStats(const TimeStat &S, TimeStat &M);
David Blaikie87299ad2017-01-16 20:36:26 +0000108
109 /// Calculates latency statistics for each edge and stores the data in the
110 /// Graph
111 void calculateEdgeStatistics();
112
113 /// Calculates latency statistics for each vertex and stores the data in the
114 /// Graph
115 void calculateVertexStatistics();
116
117 /// Normalises latency statistics for each edge and vertex by CycleFrequency;
Dean Michael Berrisd09bf192017-01-25 07:14:43 +0000118 void normalizeStatistics(double CycleFrequency);
David Blaikie87299ad2017-01-16 20:36:26 +0000119
120public:
121 /// Takes in a reference to a FuncIdHelper in order to have ready access to
122 /// Symbol names.
123 explicit GraphRenderer(FuncIdConversionHelper &FuncIdHelper, bool DSC)
124 : FuncIdHelper(FuncIdHelper), DeduceSiblingCalls(DSC) {}
125
126 /// Process an Xray record and expand the graph.
127 ///
128 /// This Function will return true on success, or false if records are not
129 /// presented in per-thread call-tree DFS order. (That is for each thread the
130 /// Records should be in order runtime on an ideal system.)
131 ///
132 /// FIXME: Make this more robust against small irregularities.
Dean Michael Berrisd09bf192017-01-25 07:14:43 +0000133 Error accountRecord(const XRayRecord &Record);
David Blaikie87299ad2017-01-16 20:36:26 +0000134
Dean Michael Berrisd09bf192017-01-25 07:14:43 +0000135 const PerThreadFunctionStackMap getPerThreadFunctionStack() const {
136 return PerThreadFunctionStack;
137 }
David Blaikie87299ad2017-01-16 20:36:26 +0000138
139 /// Output the Embedded graph in DOT format on \p OS, labeling the edges by
140 /// \p T
141 void exportGraphAsDOT(raw_ostream &OS, const XRayFileHeader &H,
Dean Michael Berrisd09bf192017-01-25 07:14:43 +0000142 StatType EdgeLabel = StatType::NONE,
143 StatType EdgeColor = StatType::NONE,
144 StatType VertexLabel = StatType::NONE,
145 StatType VertexColor = StatType::NONE);
David Blaikie87299ad2017-01-16 20:36:26 +0000146};
147}
148}
149
150#endif // XRAY_GRAPH_H