mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-13 14:35:54 +00:00
c7e2e6d999
Second try after fixing a code san problem with iterator reference types. This change introduces a subcommand to the llvm-xray tool called "stacks" which allows for analysing XRay traces provided as inputs and accounting time to stacks instead of just individual functions. This gives us a more precise view of where in a program the latency is actually attributed. The tool uses a trie data structure to keep track of the caller-callee relationships as we process the XRay traces. In particular, we keep track of the function call stack as we enter functions. While we're doing this we're adding nodes in a trie and indicating a "calls" relatinship between the caller (current top of the stack) and the callee (the new top of the stack). When we push function ids onto the stack, we keep track of the timestamp (TSC) for the enter event. When exiting functions, we are able to account the duration by getting the difference between the timestamp of the exit event and the corresponding entry event in the stack. This works even if we somehow miss the exit events for intermediary functions (i.e. if the exit event is not cleanly associated with the enter event at the top of the stack). The output of the tool currently provides just the top N leaf functions that contribute the most latency, and the top N stacks that have the most frequency. In the future we can provide more sophisticated query mechanisms and potentially an export to database feature to make offline analysis of the stack traces possible with existing tools. Differential revision: D34863 llvm-svn: 312733
103 lines
2.8 KiB
C++
103 lines
2.8 KiB
C++
//===- xray-record-yaml.h - XRay Record YAML Support Definitions ----------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Types and traits specialisations for YAML I/O of XRay log entries.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
#ifndef LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
|
|
#define LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
|
|
|
|
#include <type_traits>
|
|
|
|
#include "xray-record.h"
|
|
#include "llvm/Support/YAMLTraits.h"
|
|
|
|
namespace llvm {
|
|
namespace xray {
|
|
|
|
struct YAMLXRayFileHeader {
|
|
uint16_t Version;
|
|
uint16_t Type;
|
|
bool ConstantTSC;
|
|
bool NonstopTSC;
|
|
uint64_t CycleFrequency;
|
|
};
|
|
|
|
struct YAMLXRayRecord {
|
|
uint16_t RecordType;
|
|
uint8_t CPU;
|
|
RecordTypes Type;
|
|
int32_t FuncId;
|
|
std::string Function;
|
|
uint64_t TSC;
|
|
uint32_t TId;
|
|
};
|
|
|
|
struct YAMLXRayTrace {
|
|
YAMLXRayFileHeader Header;
|
|
std::vector<YAMLXRayRecord> Records;
|
|
};
|
|
|
|
using XRayRecordStorage =
|
|
std::aligned_storage<sizeof(XRayRecord), alignof(XRayRecord)>::type;
|
|
|
|
} // namespace xray
|
|
|
|
namespace yaml {
|
|
|
|
// YAML Traits
|
|
// -----------
|
|
template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
|
|
static void enumeration(IO &IO, xray::RecordTypes &Type) {
|
|
IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER);
|
|
IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT);
|
|
}
|
|
};
|
|
|
|
template <> struct MappingTraits<xray::YAMLXRayFileHeader> {
|
|
static void mapping(IO &IO, xray::YAMLXRayFileHeader &Header) {
|
|
IO.mapRequired("version", Header.Version);
|
|
IO.mapRequired("type", Header.Type);
|
|
IO.mapRequired("constant-tsc", Header.ConstantTSC);
|
|
IO.mapRequired("nonstop-tsc", Header.NonstopTSC);
|
|
IO.mapRequired("cycle-frequency", Header.CycleFrequency);
|
|
}
|
|
};
|
|
|
|
template <> struct MappingTraits<xray::YAMLXRayRecord> {
|
|
static void mapping(IO &IO, xray::YAMLXRayRecord &Record) {
|
|
// FIXME: Make this type actually be descriptive
|
|
IO.mapRequired("type", Record.RecordType);
|
|
IO.mapRequired("func-id", Record.FuncId);
|
|
IO.mapOptional("function", Record.Function);
|
|
IO.mapRequired("cpu", Record.CPU);
|
|
IO.mapRequired("thread", Record.TId);
|
|
IO.mapRequired("kind", Record.Type);
|
|
IO.mapRequired("tsc", Record.TSC);
|
|
}
|
|
|
|
static constexpr bool flow = true;
|
|
};
|
|
|
|
template <> struct MappingTraits<xray::YAMLXRayTrace> {
|
|
static void mapping(IO &IO, xray::YAMLXRayTrace &Trace) {
|
|
// A trace file contains two parts, the header and the list of all the
|
|
// trace records.
|
|
IO.mapRequired("header", Trace.Header);
|
|
IO.mapRequired("records", Trace.Records);
|
|
}
|
|
};
|
|
|
|
} // namespace yaml
|
|
} // namespace llvm
|
|
|
|
LLVM_YAML_IS_SEQUENCE_VECTOR(xray::YAMLXRayRecord)
|
|
|
|
#endif // LLVM_TOOLS_LLVM_XRAY_XRAY_RECORD_YAML_H
|