[llvm-dev] XRay: Demo on x86_64/Linux almost done; some questions.
Dean Michael Berris via llvm-dev
llvm-dev at lists.llvm.org
Fri Jul 29 23:45:21 PDT 2016
> On 30 Jul 2016, at 05:07, Serge Rogatch via llvm-dev <llvm-dev at lists.llvm.org> wrote:
> Thanks for pointing this out, Tim. Then maybe this approach is not the best choice for x86, though ideally measuring is needed, it is just that on ARM the current x86 approach is not applicable because ARM doesn't have a single return instruction (such as RETQ on x86_64), furthermore, the return instructions on ARM can be conditional.
I think this is a flaw in the current implementation. I long suspected that other platforms didn't have a single return instruction like x86, and I think it's worth changing this.
In an early version of the implementation that made it into LLVM, I made the determination whether an instruction was a return instruction, and make that determination per-platform.
We should make that happen so we can easier support ARM.
> I have another question: what happens if the instrumented function (or its callees) throws an exception and doesn't catch? I understood that currently XRay will not report an exit from this function in such case because the function doesn't return with RETQ, but rather the stack unwinder jumps through functions calling the destructors of local variable objects.
> If so, why not to instrument the functions by placing a tracing object as the first local variable, with its constructor calling __xray_FunctionEntry and destructor calling __xray_FunctionExit ? Perhaps this approach requires changes in the front-end (C++ compiler, before emitting IR).
That's right -- the approach I've been thinking about (but haven't gotten to implementing yet, because of other priorities) has been to have special instrumentation at the throw and catch points. Similarly understanding things like tail call exits and sibling call optimisations and instrumenting those exit points is another thing that is yet to be implemented.
Unfortunately changing the front-end to add an RAII or guard object will cause a whole lot of problems too. For instance, optimisations on the IR can move instructions before/after the guard object initialisation and then we end up with less accurate instrumentation. This also introduces potentially unwanted semantics and changes the stack layout and affecting the performance of an application with XRay sleds but instrumentation not enabled.
> On 29 July 2016 at 21:00, Tim Northover <t.p.northover at gmail.com> wrote:
> On 28 July 2016 at 16:14, Serge Rogatch via llvm-dev
> <llvm-dev at lists.llvm.org> wrote:
> > Can I ask you why you chose to patch both function entrances and exits,
> > rather than just patching the entrances and (in the patches) pushing on the
> > stack the address of __xray_FunctionExit , so that the user function returns
> > normally (with RETQ or POP RIP or whatever else instruction) rather than
> > jumping into __xray_FunctionExit?
> > This approach should also be faster because smaller code better fits in CPU
> > cache, and patching itself should run faster (because there is less code to
> > modify).
> It may well be slower. Larger CPUs tend to track the call stack in
> hardware and returning to an address pushed manually is an inevitable
> branch mispredict in those cases.
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
More information about the llvm-dev