summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/XRay/XRayRecord.h5
-rw-r--r--llvm/include/llvm/XRay/YAMLXRayRecord.h13
-rw-r--r--llvm/lib/XRay/Trace.cpp29
-rw-r--r--llvm/test/tools/llvm-xray/X86/Inputs/fdr-log-arg1.xraybin0 -> 288 bytes
-rw-r--r--llvm/test/tools/llvm-xray/X86/convert-fdr-arg1-to-yaml.txt13
-rw-r--r--llvm/tools/llvm-xray/xray-account.cc3
-rw-r--r--llvm/tools/llvm-xray/xray-converter.cc3
-rw-r--r--llvm/tools/llvm-xray/xray-graph.cc3
8 files changed, 63 insertions, 6 deletions
diff --git a/llvm/include/llvm/XRay/XRayRecord.h b/llvm/include/llvm/XRay/XRayRecord.h
index eb1f26eb19d..27e90ea0bb4 100644
--- a/llvm/include/llvm/XRay/XRayRecord.h
+++ b/llvm/include/llvm/XRay/XRayRecord.h
@@ -53,7 +53,7 @@ struct XRayFileHeader {
/// This may or may not correspond to actual record types in the raw trace (as
/// the loader implementation may synthesize this information in the process of
/// of loading).
-enum class RecordTypes { ENTER, EXIT, TAIL_EXIT };
+enum class RecordTypes { ENTER, EXIT, TAIL_EXIT, ENTER_ARG };
struct XRayRecord {
/// The type of record.
@@ -73,6 +73,9 @@ struct XRayRecord {
/// The thread ID for the currently running thread.
uint32_t TId;
+
+ /// The function call arguments.
+ std::vector<uint64_t> CallArgs;
};
} // namespace xray
diff --git a/llvm/include/llvm/XRay/YAMLXRayRecord.h b/llvm/include/llvm/XRay/YAMLXRayRecord.h
index 792323ca555..122b88497af 100644
--- a/llvm/include/llvm/XRay/YAMLXRayRecord.h
+++ b/llvm/include/llvm/XRay/YAMLXRayRecord.h
@@ -37,6 +37,7 @@ struct YAMLXRayRecord {
std::string Function;
uint64_t TSC;
uint32_t TId;
+ std::vector<uint64_t> CallArgs;
};
struct YAMLXRayTrace {
@@ -55,6 +56,7 @@ template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER);
IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT);
IO.enumCase(Type, "function-tail-exit", xray::RecordTypes::TAIL_EXIT);
+ IO.enumCase(Type, "function-enter-arg", xray::RecordTypes::ENTER_ARG);
}
};
@@ -74,6 +76,7 @@ template <> struct MappingTraits<xray::YAMLXRayRecord> {
IO.mapRequired("type", Record.RecordType);
IO.mapRequired("func-id", Record.FuncId);
IO.mapOptional("function", Record.Function);
+ IO.mapOptional("args", Record.CallArgs);
IO.mapRequired("cpu", Record.CPU);
IO.mapRequired("thread", Record.TId);
IO.mapRequired("kind", Record.Type);
@@ -83,6 +86,16 @@ template <> struct MappingTraits<xray::YAMLXRayRecord> {
static constexpr bool flow = true;
};
+template <> struct SequenceTraits<std::vector<uint64_t>> {
+ static constexpr bool flow = true;
+ static size_t size(IO &IO, std::vector<uint64_t> &V) { return V.size(); }
+ static uint64_t &element(IO &IO, std::vector<uint64_t> &V, size_t Index) {
+ if (Index >= V.size())
+ V.resize(Index + 1);
+ return V[Index];
+ }
+};
+
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
diff --git a/llvm/lib/XRay/Trace.cpp b/llvm/lib/XRay/Trace.cpp
index 131c7807b1b..7f8846cbd6f 100644
--- a/llvm/lib/XRay/Trace.cpp
+++ b/llvm/lib/XRay/Trace.cpp
@@ -128,6 +128,7 @@ struct FDRState {
FUNCTION_SEQUENCE,
SCAN_TO_END_OF_THREAD_BUF,
CUSTOM_EVENT_DATA,
+ CALL_ARGUMENT,
};
Token Expects;
@@ -151,6 +152,8 @@ const char *fdrStateToTwine(const FDRState::Token &state) {
return "SCAN_TO_END_OF_THREAD_BUF";
case FDRState::Token::CUSTOM_EVENT_DATA:
return "CUSTOM_EVENT_DATA";
+ case FDRState::Token::CALL_ARGUMENT:
+ return "CALL_ARGUMENT";
}
return "UNKNOWN";
}
@@ -238,6 +241,22 @@ Error processCustomEventMarker(FDRState &State, uint8_t RecordFirstByte,
return Error::success();
}
+/// State transition when a CallArgumentRecord is encountered.
+Error processFDRCallArgumentRecord(FDRState &State, uint8_t RecordFirstByte,
+ DataExtractor &RecordExtractor,
+ std::vector<XRayRecord> &Records) {
+ uint32_t OffsetPtr = 1; // Read starting after the first byte.
+ auto &Enter = Records.back();
+
+ if (Enter.Type != RecordTypes::ENTER)
+ return make_error<StringError>(
+ "CallArgument needs to be right after a function entry",
+ std::make_error_code(std::errc::executable_format_error));
+ Enter.Type = RecordTypes::ENTER_ARG;
+ Enter.CallArgs.emplace_back(RecordExtractor.getU64(&OffsetPtr));
+ return Error::success();
+}
+
/// Advances the state machine for reading the FDR record type by reading one
/// Metadata Record and updating the State appropriately based on the kind of
/// record encountered. The RecordKind is encoded in the first byte of the
@@ -245,7 +264,8 @@ Error processCustomEventMarker(FDRState &State, uint8_t RecordFirstByte,
/// to determine that this is a metadata record as opposed to a function record.
Error processFDRMetadataRecord(FDRState &State, uint8_t RecordFirstByte,
DataExtractor &RecordExtractor,
- size_t &RecordSize) {
+ size_t &RecordSize,
+ std::vector<XRayRecord> &Records) {
// The remaining 7 bits are the RecordKind enum.
uint8_t RecordKind = RecordFirstByte >> 1;
switch (RecordKind) {
@@ -279,6 +299,11 @@ Error processFDRMetadataRecord(FDRState &State, uint8_t RecordFirstByte,
RecordExtractor, RecordSize))
return E;
break;
+ case 6: // CallArgument
+ if (auto E = processFDRCallArgumentRecord(State, RecordFirstByte,
+ RecordExtractor, Records))
+ return E;
+ break;
default:
// Widen the record type to uint16_t to prevent conversion to char.
return make_error<StringError>(
@@ -434,7 +459,7 @@ Error loadFDRLog(StringRef Data, XRayFileHeader &FileHeader,
if (isMetadataRecord) {
RecordSize = 16;
if (auto E = processFDRMetadataRecord(State, BitField, RecordExtractor,
- RecordSize))
+ RecordSize, Records))
return E;
} else { // Process Function Record
RecordSize = 8;
diff --git a/llvm/test/tools/llvm-xray/X86/Inputs/fdr-log-arg1.xray b/llvm/test/tools/llvm-xray/X86/Inputs/fdr-log-arg1.xray
new file mode 100644
index 00000000000..cd311cd0eb1
--- /dev/null
+++ b/llvm/test/tools/llvm-xray/X86/Inputs/fdr-log-arg1.xray
Binary files differ
diff --git a/llvm/test/tools/llvm-xray/X86/convert-fdr-arg1-to-yaml.txt b/llvm/test/tools/llvm-xray/X86/convert-fdr-arg1-to-yaml.txt
new file mode 100644
index 00000000000..06b5eb8904e
--- /dev/null
+++ b/llvm/test/tools/llvm-xray/X86/convert-fdr-arg1-to-yaml.txt
@@ -0,0 +1,13 @@
+; RUN: llvm-xray convert %S/Inputs/fdr-log-arg1.xray -f=yaml -o - | FileCheck %s
+
+; CHECK: ---
+; CHECK-NEXT: header:
+; CHECK-NEXT: version: 1
+; CHECK-NEXT: type: 1
+; CHECK-NEXT: constant-tsc: true
+; CHECK-NEXT: nonstop-tsc: true
+; CHECK-NEXT: cycle-frequency: 3500000000
+; CHECK-NEXT: records:
+; CHECK-NEXT: - { type: 0, func-id: 1, function: '1', args: [ 1 ], cpu: 49, thread: 14648, kind: function-enter-arg, tsc: 18828908666543318 }
+; CHECK-NEXT: - { type: 0, func-id: 1, function: '1', cpu: 49, thread: 14648, kind: function-exit, tsc: 18828908666595604 }
+; CHECK-NEXT: ...
diff --git a/llvm/tools/llvm-xray/xray-account.cc b/llvm/tools/llvm-xray/xray-account.cc
index 74907044848..0ba6cad5cca 100644
--- a/llvm/tools/llvm-xray/xray-account.cc
+++ b/llvm/tools/llvm-xray/xray-account.cc
@@ -146,7 +146,8 @@ bool LatencyAccountant::accountRecord(const XRayRecord &Record) {
auto &ThreadStack = PerThreadFunctionStack[Record.TId];
switch (Record.Type) {
- case RecordTypes::ENTER: {
+ case RecordTypes::ENTER:
+ case RecordTypes::ENTER_ARG: {
ThreadStack.emplace_back(Record.FuncId, Record.TSC);
break;
}
diff --git a/llvm/tools/llvm-xray/xray-converter.cc b/llvm/tools/llvm-xray/xray-converter.cc
index 4769186a19e..f1aec65bc67 100644
--- a/llvm/tools/llvm-xray/xray-converter.cc
+++ b/llvm/tools/llvm-xray/xray-converter.cc
@@ -86,7 +86,7 @@ void TraceConverter::exportAsYAML(const Trace &Records, raw_ostream &OS) {
Trace.Records.push_back({R.RecordType, R.CPU, R.Type, R.FuncId,
Symbolize ? FuncIdHelper.SymbolOrNumber(R.FuncId)
: llvm::to_string(R.FuncId),
- R.TSC, R.TId});
+ R.TSC, R.TId, R.CallArgs});
}
Output Out(OS, nullptr, 0);
Out << Trace;
@@ -123,6 +123,7 @@ void TraceConverter::exportAsRAWv1(const Trace &Records, raw_ostream &OS) {
Writer.write(static_cast<uint8_t>(R.CPU));
switch (R.Type) {
case RecordTypes::ENTER:
+ case RecordTypes::ENTER_ARG:
Writer.write(uint8_t{0});
break;
case RecordTypes::EXIT:
diff --git a/llvm/tools/llvm-xray/xray-graph.cc b/llvm/tools/llvm-xray/xray-graph.cc
index da2d04cf0b9..9a2f837e6a3 100644
--- a/llvm/tools/llvm-xray/xray-graph.cc
+++ b/llvm/tools/llvm-xray/xray-graph.cc
@@ -208,7 +208,8 @@ Error GraphRenderer::accountRecord(const XRayRecord &Record) {
auto &ThreadStack = PerThreadFunctionStack[Record.TId];
switch (Record.Type) {
- case RecordTypes::ENTER: {
+ case RecordTypes::ENTER:
+ case RecordTypes::ENTER_ARG: {
if (Record.FuncId != 0 && G.count(Record.FuncId) == 0)
G[Record.FuncId].SymbolName = FuncIdHelper.SymbolOrNumber(Record.FuncId);
ThreadStack.push_back({Record.FuncId, Record.TSC});
OpenPOWER on IntegriCloud