[compiler-rt] r313515 - [XRay][compiler-rt] Handle tail-call exits in the XRay runtime

Dean Michael Berris via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 17 23:18:03 PDT 2017


Author: dberris
Date: Sun Sep 17 23:18:03 2017
New Revision: 313515

URL: http://llvm.org/viewvc/llvm-project?rev=313515&view=rev
Log:
[XRay][compiler-rt] Handle tail-call exits in the XRay runtime

Summary:
This change starts differentiating tail exits from normal exits. We also
increase the version number of the "naive" log to version 2, which will
be the starting version where these records start appearing. In FDR mode
we treat the tail exits as normal exits, and are thus subject to the
same treatment with regard to record unwriting.

Updating the version number is important to signal older builds of the
llvm-xray tool that do not deal with the tail exit records must fail
early (and that users should only use the llvm-xray tool built after
the support for tail exits to get accurate handling of these records).

Depends on D37964.

Reviewers: kpw, pelikan

Subscribers: llvm-commits

Differential Revision: https://reviews.llvm.org/D37965

Modified:
    compiler-rt/trunk/include/xray/xray_records.h
    compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
    compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
    compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
    compiler-rt/trunk/test/xray/TestCases/Linux/fdr-mode.cc
    compiler-rt/trunk/test/xray/TestCases/Linux/fdr-thread-order.cc

Modified: compiler-rt/trunk/include/xray/xray_records.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/xray/xray_records.h?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/include/xray/xray_records.h (original)
+++ compiler-rt/trunk/include/xray/xray_records.h Sun Sep 17 23:18:03 2017
@@ -78,7 +78,10 @@ struct alignas(32) XRayRecord {
   // The CPU where the thread is running. We assume number of CPUs <= 256.
   uint8_t CPU = 0;
 
-  // The type of the event. Usually either ENTER = 0 or EXIT = 1.
+  // The type of the event. One of the following:
+  //   ENTER = 0
+  //   EXIT = 1
+  //   TAIL_EXIT = 2
   uint8_t Type = 0;
 
   // The function ID for the record.

Modified: compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h (original)
+++ compiler-rt/trunk/lib/xray/xray_fdr_logging_impl.h Sun Sep 17 23:18:03 2017
@@ -690,7 +690,6 @@ inline void processFunctionHook(
     TLD.LastFunctionEntryTSC = TSC;
     break;
   case XRayEntryType::TAIL:
-    break;
   case XRayEntryType::EXIT:
     // Break out and write the exit record if we can't erase any functions.
     if (TLD.NumConsecutiveFnEnters == 0 ||

Modified: compiler-rt/trunk/lib/xray/xray_inmemory_log.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_inmemory_log.cc?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_inmemory_log.cc (original)
+++ compiler-rt/trunk/lib/xray/xray_inmemory_log.cc Sun Sep 17 23:18:03 2017
@@ -89,7 +89,7 @@ static int __xray_OpenLogFile() XRAY_NEV
   // header will only be written once, at the start, and let the threads
   // logging do writes which just append.
   XRayFileHeader Header;
-  Header.Version = 1;
+  Header.Version = 2;  // Version 2 includes tail exit records.
   Header.Type = FileTypes::NAIVE_LOG;
   Header.CycleFrequency = CycleFrequency;
 
@@ -117,6 +117,13 @@ void __xray_InMemoryRawLog(int32_t FuncI
       Fd, reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer), Offset);
   thread_local pid_t TId = syscall(SYS_gettid);
 
+  // Use a simple recursion guard, to handle cases where we're already logging
+  // and for one reason or another, this function gets called again in the same
+  // thread.
+  thread_local volatile bool RecusionGuard = false;
+  if (RecusionGuard) return;
+  RecusionGuard = true;
+
   // First we get the useful data, and stuff it into the already aligned buffer
   // through a pointer offset.
   auto &R = reinterpret_cast<__xray::XRayRecord *>(InMemoryBuffer)[Offset];
@@ -133,6 +140,8 @@ void __xray_InMemoryRawLog(int32_t FuncI
                      reinterpret_cast<char *>(RecordBuffer + Offset));
     Offset = 0;
   }
+
+  RecusionGuard = false;
 }
 
 void __xray_InMemoryRawLogRealTSC(int32_t FuncId,

Modified: compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S (original)
+++ compiler-rt/trunk/lib/xray/xray_trampoline_x86_64.S Sun Sep 17 23:18:03 2017
@@ -135,10 +135,6 @@ __xray_FunctionExit:
 	.type __xray_FunctionTailExit, at function
 __xray_FunctionTailExit:
 	.cfi_startproc
-	// Save the important registers as in the entry trampoline, but indicate that
-	// this is an exit. In the future, we will introduce a new entry type that
-	// differentiates between a normal exit and a tail exit, but we'd have to do
-	// this and increment the version number for the header.
 	SAVE_REGISTERS
 
 	movq	_ZN6__xray19XRayPatchedFunctionE(%rip), %rax
@@ -146,7 +142,7 @@ __xray_FunctionTailExit:
 	je	.Ltmp4
 
 	movl	%r10d, %edi
-	movl	$1, %esi
+	movl	$2, %esi
 	callq	*%rax
 
 .Ltmp4:

Modified: compiler-rt/trunk/test/xray/TestCases/Linux/fdr-mode.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Linux/fdr-mode.cc?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Linux/fdr-mode.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Linux/fdr-mode.cc Sun Sep 17 23:18:03 2017
@@ -69,24 +69,24 @@ int main(int argc, char *argv[]) {
 
 // Check that we're able to see two threads, each entering and exiting fA().
 // TRACE-DAG: - { type: 0, func-id: [[FIDA:[0-9]+]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 // TRACE-DAG: - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDA]], function: {{.*fA.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 //
 // Do the same as above for fC()
 // TRACE-DAG: - { type: 0, func-id: [[FIDC:[0-9]+]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 // TRACE-DAG: - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDC]], function: {{.*fC.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 
 // Do the same as above for fB()
 // TRACE-DAG: - { type: 0, func-id: [[FIDB:[0-9]+]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 // TRACE-DAG: - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE:     - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE:     - { type: 0, func-id: [[FIDB]], function: {{.*fB.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-{{exit|tail-exit}}, tsc: {{[0-9]+}} }
 
 // Assert that when unwriting is enabled with a high threshold time, all the function records are erased. A CPU switch could erroneously fail this test, but
 // is unlikely given the test program.
 // UNWRITE: header
 // UNWRITE-NOT: function-enter
-// UNWRITE-NOT: function-exit
+// UNWRITE-NOT: function-{{exit|tail-exit}}

Modified: compiler-rt/trunk/test/xray/TestCases/Linux/fdr-thread-order.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/xray/TestCases/Linux/fdr-thread-order.cc?rev=313515&r1=313514&r2=313515&view=diff
==============================================================================
--- compiler-rt/trunk/test/xray/TestCases/Linux/fdr-thread-order.cc (original)
+++ compiler-rt/trunk/test/xray/TestCases/Linux/fdr-thread-order.cc Sun Sep 17 23:18:03 2017
@@ -37,5 +37,5 @@ int main(int argc, char *argv[]) {
 // We want to make sure that the order of the function log doesn't matter.
 // TRACE-DAG: - { type: 0, func-id: [[FID1:[0-9]+]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
 // TRACE-DAG: - { type: 0, func-id: [[FID2:[0-9]+]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2:[0-9]+]], kind: function-enter, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FID1]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: function-exit, tsc: {{[0-9]+}} }
-// TRACE-DAG: - { type: 0, func-id: [[FID2]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: function-exit, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID1]], function: {{.*f1.*}}, cpu: {{.*}}, thread: [[THREAD1]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }
+// TRACE-DAG: - { type: 0, func-id: [[FID2]], function: {{.*f2.*}}, cpu: {{.*}}, thread: [[THREAD2]], kind: {{function-exit|function-tail-exit}}, tsc: {{[0-9]+}} }




More information about the llvm-commits mailing list