1 //===-- xray-graph.h - XRay Function Call Graph Renderer --------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Generate a DOT file to represent the function call graph encountered in
13 //===----------------------------------------------------------------------===//
21 #include "func-id-helper.h"
22 #include "xray-color-helper.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Errc.h"
26 #include "llvm/Support/Program.h"
27 #include "llvm/Support/raw_ostream.h"
28 #include "llvm/XRay/Graph.h"
29 #include "llvm/XRay/Trace.h"
30 #include "llvm/XRay/XRayRecord.h"
35 /// A class encapsulating the logic related to analyzing XRay traces, producting
36 /// Graphs from them and then exporting those graphs for review.
39 /// An enum for enumerating the various statistics gathered on latencies
40 enum class StatType { NONE, COUNT, MIN, MED, PCT90, PCT99, MAX, SUM };
42 /// An inner struct for common timing statistics information
51 std::string getAsString(StatType T) const;
52 double compare(StatType T, const TimeStat &Other) const;
54 typedef uint64_t TimestampT;
56 /// An inner struct for storing edge attributes for our graph. Here the
57 /// attributes are mainly function call statistics.
59 /// FIXME: expand to contain more information eg call latencies.
62 std::vector<TimestampT> Timings;
65 /// An Inner Struct for storing vertex attributes, at the moment just
66 /// SymbolNames, however in future we could store bulk function statistics.
68 /// FIXME: Store more attributes based on instrumentation map.
69 struct FunctionStats {
70 std::string SymbolName;
79 typedef SmallVector<FunctionAttr, 4> FunctionStack;
81 typedef DenseMap<llvm::sys::ProcessInfo::ProcessId, FunctionStack>
82 PerThreadFunctionStackMap;
84 class GraphT : public Graph<FunctionStats, CallStats, int32_t> {
86 TimeStat GraphEdgeMax = {};
87 TimeStat GraphVertexMax = {};
91 typedef typename decltype(G)::VertexIdentifier VertexIdentifier;
92 typedef typename decltype(G)::EdgeIdentifier EdgeIdentifier;
94 /// Use a Map to store the Function stack for each thread whilst building the
97 /// FIXME: Perhaps we can Build this into LatencyAccountant? or vise versa?
98 PerThreadFunctionStackMap PerThreadFunctionStack;
100 /// Usefull object for getting human readable Symbol Names.
101 const FuncIdConversionHelper &FuncIdHelper;
102 bool DeduceSiblingCalls = false;
103 TimestampT CurrentMaxTSC = 0;
105 /// A private function to help implement the statistic generation functions;
106 template <typename U>
107 void getStats(U begin, U end, GraphRenderer::TimeStat &S);
108 void updateMaxStats(const TimeStat &S, TimeStat &M);
110 /// Calculates latency statistics for each edge and stores the data in the
112 void calculateEdgeStatistics();
114 /// Calculates latency statistics for each vertex and stores the data in the
116 void calculateVertexStatistics();
118 /// Normalises latency statistics for each edge and vertex by CycleFrequency;
119 void normalizeStatistics(double CycleFrequency);
121 /// An object to color gradients
125 /// Takes in a reference to a FuncIdHelper in order to have ready access to
127 explicit GraphRenderer(const FuncIdConversionHelper &FuncIdHelper, bool DSC)
128 : FuncIdHelper(FuncIdHelper), DeduceSiblingCalls(DSC),
129 CHelper(ColorHelper::SequentialScheme::OrRd) {
133 /// Process an Xray record and expand the graph.
135 /// This Function will return true on success, or false if records are not
136 /// presented in per-thread call-tree DFS order. (That is for each thread the
137 /// Records should be in order runtime on an ideal system.)
139 /// FIXME: Make this more robust against small irregularities.
140 Error accountRecord(const XRayRecord &Record);
142 const PerThreadFunctionStackMap &getPerThreadFunctionStack() const {
143 return PerThreadFunctionStack;
146 /// Output the Embedded graph in DOT format on \p OS, labeling the edges by
148 void exportGraphAsDOT(raw_ostream &OS, const XRayFileHeader &H,
149 StatType EdgeLabel = StatType::NONE,
150 StatType EdgeColor = StatType::NONE,
151 StatType VertexLabel = StatType::NONE,
152 StatType VertexColor = StatType::NONE);
154 /// Get a reference to the internal graph.
155 const GraphT &getGraph() {
156 calculateEdgeStatistics();
157 calculateVertexStatistics();
164 #endif // XRAY_GRAPH_H