[llvm-dev] [inline-asm][asm-goto] Supporting "asm goto" in inline assembly

Chandler Carruth via llvm-dev llvm-dev at lists.llvm.org
Tue Apr 4 09:26:40 PDT 2017


On Tue, Apr 4, 2017 at 6:07 AM Yatsina, Marina via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Asm goto feature was introduces to GCC in order to optimize the support
> for tracepoints in Linux kernel (it can be used for other things that do
> nop patching).
>
>
>
> GCC documentation describes their motivating example here:
>
>
> https://gcc.gnu.org/onlinedocs/gcc-4.8.4/gcc/Extended-Asm.html
>
>
>
>      #define TRACE1(NUM)                         \
>
>        do {                                      \
>
>          asm goto ("0: nop;"                     \
>
>                    ".pushsection trace_table;"   \
>
>                    ".long 0b, %l0;"              \
>
>                    ".popsection"                 \
>
>                    : : : : trace#NUM);           \
>
>          if (0) { trace#NUM: trace(); }          \
>
>        } while (0)
>
>      #define TRACE  TRACE1(__COUNTER__)
>
> In this example (which in fact inspired the asm goto feature) we want on
> rare occasions to call the trace function; on other occasions we'd like
> to keep the overhead to the absolute minimum. The normal code path consists
> of a single nop instruction. However, we record the address of this nop
> together with the address of a label that calls the trace function. This
> allows the nop instruction to be patched at run time to be an
> unconditional branch to the stored label. It is assumed that an optimizing
> compiler moves the labeled block out of line, to optimize the fall through
> path from the asm.
>
> Here is the Linux kernel RFC which discusses the old C way of implementing
> it and the performance issues that were noticed.
>
> It also states some performance numbers of the old C code vs. the asm goto:
>
> https://lwn.net/Articles/350714/
>
>
>
> This LTTng (Linux Trace Toolkit Next Generation) presentation talks about using this feature as a way of optimize static tracepoints (slides 3-4)
>
>
> https://www.computer.org/cms/ComputingNow/HomePage/2011/0111/rW_SW_UsingTracing.pdf
>
> This presentation also mentions that a lot of other Linux applications use this tracing mechanism.
>
> Thanks, this is exactly the kind of discussion that I think will help make
progress here.

I think this feature makes a lot of sense and is a really nice feature.
However, I think implementing it with inline assembly imposes a lot of
really unfortunate constraints on compilation -- it requires asm goto,
pushsection and popsection, etc.

I would much rather provide a much more direct way to represent a patchable
nop and the addresses of label within a function. For example, I could
imagine something like:

```
  if (0) { trace_call: /* code to call the trace function */ }
  patch: __builtin_patchable_nop()
  __builtin_save_labels(trace_call, patch)
```

But someone can probably design a much better way to represent this in
Clang. The advantages I see here (admittedly, mostly for the implementation
in Clang and LLVM):

1) It allows Clang and LLVM to model this with running an assembler over
anything.
2) It doesn't require new terminators in LLVM's IR
3) We already have intrinsics in LLVM's IR that could easily be extended to
produce a nop.
4) It would be portable -- each backend could select an appropriate sized
nop to patch a jump into

Would this make sense?


>
>
> I believe we already have much of the infrastructure in place (using the
> indirecbr instruction infrastructure).
>
> We do need to make sure MachineBlockPlacement optimizes the fall through
> path to make sure we can gain the performance for the nop patching.
>
>
>
> Thanks,
>
> Marina
>
>
>
> *From:* Chandler Carruth [mailto:chandlerc at gmail.com]
> *Sent:* Thursday, March 30, 2017 23:22
> *To:* Yatsina, Marina <marina.yatsina at intel.com>; llvm-dev at lists.llvm.org;
> rnk at google.com; jyknight at google.com; ehsan at mozilla.com; rjmccall at apple.com;
> mehdi.amini at apple.com; matze at braunis.de; Tayree, Coby <
> coby.tayree at intel.com>
>
>
> *Subject:* Re: [llvm-dev] [inline-asm][asm-goto] Supporting "asm goto" in
> inline assembly
>
>
>
> Just responding to the motivation stuff as that remains an open question:
>
>
>
> On Thu, Mar 30, 2017 at 4:44 PM Yatsina, Marina <marina.yatsina at intel.com>
> wrote:
>
> Linux kernel is using the “asm goto” feature,
>
>
>
> But your original email indicated they have an alternative code path for
> compilers that don't support it?
>
>
>
> What might be compelling would be if there are serious performance
> problems when using the other code path that cannot be addressed by less
> invasive (and more general) improvements to LLVM. If this is the *only* way
> to get comparable performance from the Linux Kernel, then I think that
> might be an interesting discussion. But it would take a very careful and
> detailed analysis of why IMO.
>
>
>
> other projects probably use it as well.
>
>
>
> This is entirely possible, but I'd like to understand which projects and
> why they use it rather than any of the alternatives before we impose the
> implementation complexity on LLVM. At least that's my two cents.
>
>
>
> -Chandler
>
> ---------------------------------------------------------------------
> Intel Israel (74) Limited
>
> This e-mail and any attachments may contain confidential material for
> the sole use of the intended recipient(s). Any review or distribution
> by others is strictly prohibited. If you are not the intended
> recipient, please contact the sender and delete all copies.
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20170404/cd28b8a7/attachment.html>


More information about the llvm-dev mailing list