[PATCH] D25030: [XRay] Support for for tail calls for ARM no-Thumb

Serge Rogatch via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 28 08:45:41 PDT 2016


rSerge created this revision.
rSerge added reviewers: dberris, rnk, sanjoy, echristo.
rSerge added subscribers: llvm-commits, iid_iunknown.
Herald added subscribers: dberris, samparker, mehdi_amini, rengolin, aemerson.

This patch adds simplified support for tail calls on ARM with XRay instrumentation.

Known issue: compiled with generic flags: `-O3 -g -fxray-instrument -Wall -std=c++14  -ffunction-sections -fdata-sections` (this list doesn't include my specific flags like `--target=armv7-linux-gnueabihf` etc.), the following program
```
#include <cstdio>
#include <cassert>
#include <xray/xray_interface.h>

[[clang::xray_always_instrument]] void __attribute__ ((noinline)) fC() { 
  std::printf("In fC()\n");
}

[[clang::xray_always_instrument]] void __attribute__ ((noinline)) fB() { 
  std::printf("In fB()\n");
  fC();
}

[[clang::xray_always_instrument]] void __attribute__ ((noinline)) fA() { 
  std::printf("In fA()\n");
  fB();
}

// Avoid infinite recursion in case the logging function is instrumented (so calls logging
//   function again).
[[clang::xray_never_instrument]] void simplyPrint(int32_t functionId, XRayEntryType xret)
{
  printf("XRay: functionId=%d type=%d.\n", int(functionId), int(xret));
}

int main(int argc, char* argv[]) {
  __xray_set_handler(simplyPrint);

  printf("Patching...\n");
  __xray_patch();
  fA();

  printf("Unpatching...\n");
  __xray_unpatch();       
  fA();

  return 0;
}
```
gives the following output:
```
Patching...
XRay: functionId=3 type=0.
In fA()
XRay: functionId=3 type=1.
XRay: functionId=2 type=0.
In fB()
XRay: functionId=2 type=1.
XRay: functionId=1 type=0.
XRay: functionId=1 type=1.
In fC()
Unpatching...
In fA()
In fB()
In fC()
```
So for function `fC()` the exit sled seems to be called too much before function exit: before printing `In fC()`.
Debugging shows that the above happens because `printf` from `fC` is also called as a tail call. So first the exit sled of `fC` is executed, and only then `printf` is jumped into. So it seems we can't do anything about this with the current approach (i.e. within the simplification described in https://reviews.llvm.org/D23988 ).


https://reviews.llvm.org/D25030

Files:
  lib/CodeGen/XRayInstrumentation.cpp

Index: lib/CodeGen/XRayInstrumentation.cpp
===================================================================
--- lib/CodeGen/XRayInstrumentation.cpp
+++ lib/CodeGen/XRayInstrumentation.cpp
@@ -95,7 +95,13 @@
 {
   for (auto &MBB : MF) {
     for (auto &T : MBB.terminators()) {
-      if (T.isReturn()) {
+      if (T.isReturn()
+        // So far we handle tail calls as normal function exits. No special
+        //   sleds are emitted, and XRayEntryType::TAIL is not passed to the
+        //   handler. This leads to an effect that A()-->B()-->C() tail calls
+        //   look in XRay tracing like A(),B(),C() calls from the caller of
+        //   function A.
+        || TII->isTailCall(T)) {
         // Prepend the return instruction with PATCHABLE_FUNCTION_EXIT
         BuildMI(MBB, T, T.getDebugLoc(),
                 TII->get(TargetOpcode::PATCHABLE_FUNCTION_EXIT));


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D25030.72832.patch
Type: text/x-patch
Size: 897 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160928/72c4c258/attachment.bin>


More information about the llvm-commits mailing list