Skip to content

Commit 0f84a7d

Browse files
committedSep 18, 2017
[XRay][tools] Support tail-call exits before we write them in the runtime
Summary: This change adds support for explicit tail-exit records to be written by the XRay runtime. This lets us differentiate the tail exit records/events in the log, and allows us to treat those exit events especially in the future. For now we allow printing those out in YAML (and reading them in). Reviewers: kpw, pelikan Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37964 llvm-svn: 313514
1 parent 7f10a34 commit 0f84a7d

File tree

9 files changed

+26
-12
lines changed

9 files changed

+26
-12
lines changed
 

‎llvm/docs/XRayFDRFormat.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ Function action types are as follows.
165165
+---------------+--------------+-----------------------------------------------+
166166
| Exit | ``1`` | Typical function exit. |
167167
+---------------+--------------+-----------------------------------------------+
168-
| Tail_Exit | ``2`` | An exit from a function due to Tail call |
168+
| Tail_Exit | ``2`` | An exit from a function due to tail call |
169169
| | | optimization. |
170170
+---------------+--------------+-----------------------------------------------+
171171
| Entry_Args | ``3`` | A function entry that records arguments. |

‎llvm/include/llvm/XRay/XRayRecord.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ struct XRayFileHeader {
5353
/// This may or may not correspond to actual record types in the raw trace (as
5454
/// the loader implementation may synthesize this information in the process of
5555
/// of loading).
56-
enum class RecordTypes { ENTER, EXIT };
56+
enum class RecordTypes { ENTER, EXIT, TAIL_EXIT };
5757

5858
struct XRayRecord {
5959
/// The type of record.

‎llvm/include/llvm/XRay/YAMLXRayRecord.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ template <> struct ScalarEnumerationTraits<xray::RecordTypes> {
5454
static void enumeration(IO &IO, xray::RecordTypes &Type) {
5555
IO.enumCase(Type, "function-enter", xray::RecordTypes::ENTER);
5656
IO.enumCase(Type, "function-exit", xray::RecordTypes::EXIT);
57+
IO.enumCase(Type, "function-tail-exit", xray::RecordTypes::TAIL_EXIT);
5758
}
5859
};
5960

‎llvm/lib/XRay/Trace.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Error readBinaryFormatHeader(StringRef Data, XRayFileHeader &FileHeader) {
4848
FileHeader.NonstopTSC = Bitfield & 1uL << 1;
4949
FileHeader.CycleFrequency = HeaderExtractor.getU64(&OffsetPtr);
5050
std::memcpy(&FileHeader.FreeFormData, Data.bytes_begin() + OffsetPtr, 16);
51-
if (FileHeader.Version != 1)
51+
if (FileHeader.Version != 1 && FileHeader.Version != 2)
5252
return make_error<StringError>(
5353
Twine("Unsupported XRay file version: ") + Twine(FileHeader.Version),
5454
std::make_error_code(std::errc::invalid_argument));
@@ -94,6 +94,9 @@ Error loadNaiveFormatLog(StringRef Data, XRayFileHeader &FileHeader,
9494
case 1:
9595
Record.Type = RecordTypes::EXIT;
9696
break;
97+
case 2:
98+
Record.Type = RecordTypes::TAIL_EXIT;
99+
break;
97100
default:
98101
return make_error<StringError>(
99102
Twine("Unknown record type '") + Twine(int{Type}) + "'",
@@ -320,9 +323,11 @@ Error processFDRFunctionRecord(FDRState &State, uint8_t RecordFirstByte,
320323
Record.Type = RecordTypes::ENTER;
321324
break;
322325
case static_cast<uint8_t>(RecordTypes::EXIT):
323-
case 2: // TAIL_EXIT is not yet defined in RecordTypes.
324326
Record.Type = RecordTypes::EXIT;
325327
break;
328+
case static_cast<uint8_t>(RecordTypes::TAIL_EXIT):
329+
Record.Type = RecordTypes::TAIL_EXIT;
330+
break;
326331
default:
327332
// Cast to an unsigned integer to not interpret the record type as a char.
328333
return make_error<StringError>(
@@ -443,7 +448,7 @@ Error loadFDRLog(StringRef Data, XRayFileHeader &FileHeader,
443448
// Having iterated over everything we've been given, we've either consumed
444449
// everything and ended up in the end state, or were told to skip the rest.
445450
bool Finished = State.Expects == FDRState::Token::SCAN_TO_END_OF_THREAD_BUF &&
446-
State.CurrentBufferSize == State.CurrentBufferConsumed;
451+
State.CurrentBufferSize == State.CurrentBufferConsumed;
447452
if (State.Expects != FDRState::Token::NEW_BUFFER_RECORD_OR_EOF && !Finished)
448453
return make_error<StringError>(
449454
Twine("Encountered EOF with unexpected state expectation ") +
@@ -534,9 +539,8 @@ Expected<Trace> llvm::xray::loadTraceFile(StringRef Filename, bool Sort) {
534539
enum BinaryFormatType { NAIVE_FORMAT = 0, FLIGHT_DATA_RECORDER_FORMAT = 1 };
535540

536541
Trace T;
537-
if (Version == 1 && Type == NAIVE_FORMAT) {
538-
if (auto E =
539-
loadNaiveFormatLog(Data, T.FileHeader, T.Records))
542+
if (Type == NAIVE_FORMAT && (Version == 1 || Version == 2)) {
543+
if (auto E = loadNaiveFormatLog(Data, T.FileHeader, T.Records))
540544
return std::move(E);
541545
} else if (Version == 1 && Type == FLIGHT_DATA_RECORDER_FORMAT) {
542546
if (auto E = loadFDRLog(Data, T.FileHeader, T.Records))

‎llvm/test/tools/llvm-xray/X86/convert-fdr-to-yaml.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
; CHECK-NEXT: - { type: 0, func-id: 2, function: '2', cpu: 5, thread: 5, kind: function-exit, tsc: 7238225556407467 }
1717
; CHECK-NEXT: - { type: 0, func-id: 4, function: '4', cpu: 5, thread: 5, kind: function-enter, tsc: 7238225556407492 }
1818
; CHECK-NEXT: - { type: 0, func-id: 5, function: '5', cpu: 5, thread: 5, kind: function-enter, tsc: 7238225556407517 }
19-
; CHECK-NEXT: - { type: 0, func-id: 5, function: '5', cpu: 5, thread: 5, kind: function-exit, tsc: 7238225556407542 }
19+
; CHECK-NEXT: - { type: 0, func-id: 5, function: '5', cpu: 5, thread: 5, kind: function-tail-exit, tsc: 7238225556407542 }
2020
; CHECK-NEXT: - { type: 0, func-id: 268435455, function: '268435455', cpu: 5, thread: 5, kind: function-enter, tsc: 7238225556407552 }
2121
; CHECK-NEXT: - { type: 0, func-id: 268435455, function: '268435455', cpu: 5, thread: 5, kind: function-exit, tsc: 7238225556407562 }
2222
; CHECK-NEXT: - { type: 0, func-id: 6, function: '6', cpu: 6, thread: 5, kind: function-enter, tsc: 7238225556407682 }

‎llvm/tools/llvm-xray/xray-account.cc

+5-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ bool LatencyAccountant::accountRecord(const XRayRecord &Record) {
150150
ThreadStack.emplace_back(Record.FuncId, Record.TSC);
151151
break;
152152
}
153-
case RecordTypes::EXIT: {
153+
case RecordTypes::EXIT:
154+
case RecordTypes::TAIL_EXIT: {
154155
if (ThreadStack.empty())
155156
return false;
156157

@@ -419,6 +420,9 @@ template <> struct format_provider<llvm::xray::RecordTypes> {
419420
case RecordTypes::EXIT:
420421
Stream << "exit";
421422
break;
423+
case RecordTypes::TAIL_EXIT:
424+
Stream << "tail-exit";
425+
break;
422426
}
423427
}
424428
};

‎llvm/tools/llvm-xray/xray-converter.cc

+3
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ void TraceConverter::exportAsRAWv1(const Trace &Records, raw_ostream &OS) {
128128
case RecordTypes::EXIT:
129129
Writer.write(uint8_t{1});
130130
break;
131+
case RecordTypes::TAIL_EXIT:
132+
Writer.write(uint8_t{2});
133+
break;
131134
}
132135
Writer.write(R.FuncId);
133136
Writer.write(R.TSC);

‎llvm/tools/llvm-xray/xray-graph.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,8 @@ Error GraphRenderer::accountRecord(const XRayRecord &Record) {
214214
ThreadStack.push_back({Record.FuncId, Record.TSC});
215215
break;
216216
}
217-
case RecordTypes::EXIT: {
217+
case RecordTypes::EXIT:
218+
case RecordTypes::TAIL_EXIT: {
218219
// FIXME: Refactor this and the account subcommand to reduce code
219220
// duplication
220221
if (ThreadStack.size() == 0 || ThreadStack.back().FuncId != Record.FuncId) {

‎llvm/tools/llvm-xray/xray-stacks.cc

+2-1
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,8 @@ class StackTrie {
352352
}
353353
return AccountRecordStatus::OK;
354354
}
355-
case RecordTypes::EXIT: {
355+
case RecordTypes::EXIT:
356+
case RecordTypes::TAIL_EXIT: {
356357
bool wasLastRecordExit = state->wasLastRecordExit;
357358
state->wasLastRecordExit = true;
358359
// The exit case is more interesting, since we want to be able to deduce

0 commit comments

Comments
 (0)