#include <algorithm>
#include <cassert>
#include <numeric>
#include <system_error>
#include <utility>
#include "xray-account.h"
#include "xray-registry.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormatVariadic.h"
#include "llvm/XRay/InstrumentationMap.h"
#include "llvm/XRay/Trace.h"
#include <cmath>
usingnamespacellvm;
usingnamespacellvm::xray;
static cl::SubCommand Account("account", "Function call accounting");
static cl::opt<std::string> AccountInput(cl::Positional,
cl::desc("<xray log file>"),
cl::Required, cl::sub(Account));
static cl::opt<bool>
AccountKeepGoing("keep-going", cl::desc("Keep going on errors encountered"),
cl::sub(Account), cl::init(false));
static cl::alias AccountKeepGoing2("k", cl::aliasopt(AccountKeepGoing),
cl::desc("Alias for -keep_going"));
static cl::opt<bool> AccountRecursiveCallsOnly(
"recursive-calls-only", cl::desc("Only count the calls that are recursive"),
cl::sub(Account), cl::init(false));
static cl::opt<bool> AccountDeduceSiblingCalls(
"deduce-sibling-calls",
cl::desc("Deduce sibling calls when unrolling function call stacks"),
cl::sub(Account), cl::init(false));
static cl::alias
AccountDeduceSiblingCalls2("d", cl::aliasopt(AccountDeduceSiblingCalls),
cl::desc("Alias for -deduce_sibling_calls"));
static cl::opt<std::string>
AccountOutput("output", cl::value_desc("output file"), cl::init("-"),
cl::desc("output file; use '-' for stdout"),
cl::sub(Account));
static cl::alias AccountOutput2("o", cl::aliasopt(AccountOutput),
cl::desc("Alias for -output"));
enum class AccountOutputFormats { … };
static cl::opt<AccountOutputFormats>
AccountOutputFormat("format", cl::desc("output format"),
cl::values(clEnumValN(AccountOutputFormats::TEXT,
"text", "report stats in text"),
clEnumValN(AccountOutputFormats::CSV, "csv",
"report stats in csv")),
cl::sub(Account));
static cl::alias AccountOutputFormat2("f", cl::desc("Alias of -format"),
cl::aliasopt(AccountOutputFormat));
enum class SortField { … };
static cl::opt<SortField> AccountSortOutput(
"sort", cl::desc("sort output by this field"), cl::value_desc("field"),
cl::sub(Account), cl::init(SortField::FUNCID),
cl::values(clEnumValN(SortField::FUNCID, "funcid", "function id"),
clEnumValN(SortField::COUNT, "count", "function call counts"),
clEnumValN(SortField::MIN, "min", "minimum function durations"),
clEnumValN(SortField::MED, "med", "median function durations"),
clEnumValN(SortField::PCT90, "90p", "90th percentile durations"),
clEnumValN(SortField::PCT99, "99p", "99th percentile durations"),
clEnumValN(SortField::MAX, "max", "maximum function durations"),
clEnumValN(SortField::SUM, "sum", "sum of call durations"),
clEnumValN(SortField::FUNC, "func", "function names")));
static cl::alias AccountSortOutput2("s", cl::aliasopt(AccountSortOutput),
cl::desc("Alias for -sort"));
enum class SortDirection { … };
static cl::opt<SortDirection> AccountSortOrder(
"sortorder", cl::desc("sort ordering"), cl::init(SortDirection::ASCENDING),
cl::values(clEnumValN(SortDirection::ASCENDING, "asc", "ascending"),
clEnumValN(SortDirection::DESCENDING, "dsc", "descending")),
cl::sub(Account));
static cl::alias AccountSortOrder2("r", cl::aliasopt(AccountSortOrder),
cl::desc("Alias for -sortorder"));
static cl::opt<int> AccountTop("top", cl::desc("only show the top N results"),
cl::value_desc("N"), cl::sub(Account),
cl::init(-1));
static cl::alias AccountTop2("p", cl::desc("Alias for -top"),
cl::aliasopt(AccountTop));
static cl::opt<std::string>
AccountInstrMap("instr_map",
cl::desc("binary with the instrumentation map, or "
"a separate instrumentation map"),
cl::value_desc("binary with xray_instr_map"),
cl::sub(Account), cl::init(""));
static cl::alias AccountInstrMap2("m", cl::aliasopt(AccountInstrMap),
cl::desc("Alias for -instr_map"));
namespace {
template <class T, class U> void setMinMax(std::pair<T, T> &MM, U &&V) { … }
template <class T> T diff(T L, T R) { … }
}
RecursionStatus;
RecursionStatus &RecursionStatus::operator++() { … }
RecursionStatus &RecursionStatus::operator--() { … }
bool RecursionStatus::isRecursive() const { … }
bool LatencyAccountant::accountRecord(const XRayRecord &Record) { … }
namespace {
struct ResultRow { … };
ResultRow getStats(MutableArrayRef<uint64_t> Timings) { … }
}
TupleType;
template <typename F>
static void sortByKey(std::vector<TupleType> &Results, F Fn) { … }
template <class F>
void LatencyAccountant::exportStats(const XRayFileHeader &Header, F Fn) const { … }
void LatencyAccountant::exportStatsAsText(raw_ostream &OS,
const XRayFileHeader &Header) const { … }
void LatencyAccountant::exportStatsAsCSV(raw_ostream &OS,
const XRayFileHeader &Header) const { … }
usingnamespacellvm::xray;
namespace llvm {
template <> struct format_provider<llvm::xray::RecordTypes> { … };
}
static CommandRegistration Unused(&Account, []() -> Error { … });