[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