[llvm-dev] [RFC] Implementing asm-goto support in Clang/LLVM

Craig Topper via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 22 16:02:00 PST 2019


Here's a quick update for those not watching the patch on llvm-commits.
I've picked up the patch from Alexander Ivchenko.

LLVM patch here(same link as previously):https://reviews.llvm.org/D53765
Clang side patch has been posted to phab: https://reviews.llvm.org/D56571

LLVM patch has been rebased after the TerminatorInst removal and the
removal of CRTP from CallBase. This reduced some code in the CallBrInst as
expected and simplified a few other places.

A few bugs found during testing have been fixed.

Nick Desaulniers from google has reported some success compiling, linking,
and booting linux using clang with these patches and a special kernel patch.

I welcome any feedback on the patches. We're hoping to get this landed in
trunk soon to make testing easier even if its not completely bug free.

~Craig


On Wed, Jan 9, 2019 at 3:22 PM Bill Wendling via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> I wanted to check and see what the status of this is.
>
> On Sun, Nov 4, 2018 at 2:24 AM Chandler Carruth <chandlerc at google.com>
> wrote:
>
>> (and FWIW, I'm currently trying to finish the patch that makes this a
>> reality... mostly hard because it has to unwind a loooot of complexity
>> we've built up due to not having this)
>>
>> On Sat, Nov 3, 2018 at 5:47 PM Jeremy Lakeman via llvm-dev <
>> llvm-dev at lists.llvm.org> wrote:
>>
>>> http://lists.llvm.org/pipermail/llvm-dev/2018-May/123407.html
>>>
>>> TLDR; CallInst & InvokeInst should share lots of code and would be
>>> useful to share a base type, compared to terminators that don't really
>>> share much code.
>>>
>>> On 3 November 2018 at 19:06, Bill Wendling via llvm-dev <
>>> llvm-dev at lists.llvm.org> wrote:
>>>
>>>> I've been out of the loop for awhile. Is there an email thread about
>>>> the "removing terminators as a thing" concept?
>>>>
>>>> On Wed, Oct 31, 2018, 10:13 PM Chris Lattner via llvm-dev <
>>>> llvm-dev at lists.llvm.org wrote:
>>>>
>>>>> FWIW, I’m generally supporting of this direction, and would love to
>>>>> see asm goto support.
>>>>>
>>>>> Could you compare and contrast asmbr to a couple other options?
>>>>>
>>>>>  - There is an effort to eliminate "terminators as a thing”, that
>>>>> would allow merging call and invoke.  How does asmbr intersect with that
>>>>> work, in the short and long term?  If asmbr is a short term thing, is there
>>>>> a clean migration path?
>>>>>
>>>>>  - Have you thought about or scoped the idea of having an asm
>>>>> instruction that is not a call?  In the shortest term, it could always be a
>>>>> terminator (similar to invoke) but as the call/invoke work comes together
>>>>> it could be relaxed to being a non-terminator when not an “asm goto”.  The
>>>>> rationale for this approach (which I’m not particularly attached to, just
>>>>> want to see what other’s think about it) is that asms are pretty different
>>>>> in some ways from other instructions, and if you’re introducing a new
>>>>> instruction (asmbr) anyway, we might as well consider moving them away from
>>>>> call completely.
>>>>>
>>>>> -Chris
>>>>>
>>>>>
>>>>>
>>>>> On Oct 25, 2018, at 1:58 PM, Ivchenko, Alexander via llvm-dev <
>>>>> llvm-dev at lists.llvm.org> wrote:
>>>>>
>>>>> There have been quite a few discussions around asm-goto support in
>>>>> Clang and LLVM.
>>>>> After working with several members of our community, this is a
>>>>> proposal that, in our opinion, strikes a reasonable balance and finally
>>>>> addresses the lack of implementation.
>>>>>
>>>>>
>>>>> Justification
>>>>> -----------------
>>>>>
>>>>> One of the main motivations for inline assembly support in the
>>>>> compiler comes from the need to directly access hardware-specific
>>>>> instructions either not explicitly representable by the higher-level
>>>>> languages or not supported by the compiler in any form. The latter includes
>>>>> the case of early stages of hardware development when having a full
>>>>> compiler/toolchain support is not feasible. Introducing the control flow
>>>>> capabilities of inline assembly into the compiler will reasonably expand
>>>>> the prototyping/experimenting opportunities for the developers.
>>>>>
>>>>> Having this feature will also allow us to support the software that
>>>>> already uses asm-goto. E.g. Linux Kernel, for which (at least for x86) the
>>>>> asm-goto is a mandatory requirement for the compiler. The other way of
>>>>> looking on that is having the compatibility with GCC.
>>>>>
>>>>>
>>>>> Current support for inline assembly in LLVM
>>>>> -----------------
>>>>>
>>>>> LLVM supports inline assembler (
>>>>> https://llvm.org/docs/LangRef.html#inline-assembler-expressions)
>>>>> expression through the use of a special value – the asm expression.
>>>>>
>>>>> An example inline assembler expression is:
>>>>>
>>>>>                 i32 (i32) asm "bswap $0", "=r,r"
>>>>>
>>>>> Inline assembler expressions may only be used as the callee operand of
>>>>> a call or an invoke instruction. Thus, typically we have:
>>>>>
>>>>>                 %X = call i32 asm "bswap $0", "=r,r"(i32 %Y)
>>>>>
>>>>>
>>>>> Labels in inline-assembly are already supported in LLVM, so the only
>>>>> problem is the control-flow:
>>>>>
>>>>> The IR instruction for "asm-goto" must be represented via a terminator
>>>>> instruction in the basic block with specially denoted successor parameters,
>>>>> for this reason the "call" instruction is not suitable. "invoke" is a
>>>>> terminator, but a very specific one - there is a "normal" control flow
>>>>> successor and an "exceptional" one. The "exceptional" one is required to be
>>>>> a landing pad. On the contrary, "asm-goto" can support many output labels
>>>>> in addition to fall through one and those labels represent regular code,
>>>>> not landing pads.
>>>>>
>>>>> Hence, there is a need for introducing a new IR instruction.
>>>>>
>>>>>
>>>>> The callbr instruction
>>>>> -----------------
>>>>>
>>>>> Our proposed approach is to introduce a new IR instruction named
>>>>> callbr with the following syntax:
>>>>>
>>>>>                 callbr <return_type> <callee> (<argtype1> <arg1>, ...)
>>>>> to label %normal or jump [label %transfer1, label %transfer2...]
>>>>>
>>>>> This syntax indicates that the callee may transfer the control flow to
>>>>> a “normal” successor (generally the fallthrough in the source language
>>>>> code), denoted by the label after the keyword “to”, or to any of the
>>>>> “exceptional” successors (which are expected to be normal basic blocks)
>>>>> denoted by labels in the "or jump" list.
>>>>>
>>>>> The CallBrInst class implementing the instruction is a subclass of
>>>>> CallBase and is used as a terminator.
>>>>>
>>>>> Support for asm-goto is implemented by using “void asm” as the callee
>>>>> expression:
>>>>>
>>>>>                 callbr void asm sideeffect <flags> "<asm string>",
>>>>> "<constraints>"(<argtype1> <arg1>, …, i8* blockaddress(<function>,
>>>>> %transfer1), i8* blockaddress(<function>, %transfer2), ...) to label
>>>>> %normal or jump [label %transfer1, label %transfer2...]
>>>>>
>>>>> For example, the asm-goto call:
>>>>>
>>>>>                 int example1(…) {
>>>>>>>>>>                   asm goto("testl %0, %0; jne %l1;" ::
>>>>> "r"(cond)::label_true);
>>>>>>>>>>                 label_true:
>>>>>>>>>>                 }
>>>>>
>>>>> is represented as:
>>>>>
>>>>>                 define i32 @example1(…) {
>>>>>>>>>>                   callbr void asm sideeffect "testl $0, $0; jne
>>>>> ${1:l}",
>>>>>                                 "r,X,~{dirflag},~{fpsr},~{flags}"(i32
>>>>> %5,
>>>>>                                 i8* blockaddress(@example1,
>>>>> %label_true))
>>>>>                                 to label %normal or jump [label
>>>>> %label_true]
>>>>>
>>>>>                 normal:
>>>>>>>>>>                 label_true:
>>>>>>>>>>                 }
>>>>>
>>>>>
>>>>>
>>>>> The labels from the label list of an asm-goto statement are used by
>>>>> the inline asm as data arguments. To avoid errors in asm parsing and CFG
>>>>> recognition, the labels are passed as arguments to the inline asm using
>>>>> additional “X” input constraints and blockaddress statements while also
>>>>> being used directly as elements of the jump list.
>>>>>
>>>>> Implementing the callbr instruction and asm-goto requires some
>>>>> adaptation of the existing passes:
>>>>>
>>>>> * All passes that deal with the CFG must consider all potential
>>>>> successors of the callbr instruction to be possible. This means that no
>>>>> passes that simplify the CFG based on any assumptions can work with callbr
>>>>>
>>>>> * Due to the way successor and predecessor detection works, some CFG
>>>>> simplifications such as trivial block elimination may be blocked if they
>>>>> would result in duplicate successors for the callbr instruction, as such
>>>>> duplicate successors are incorrectly processed in the IR and cannot be
>>>>> removed due to being used by the callee
>>>>>
>>>>> * The indirectbr expansion pass may destroy blockaddress expressions
>>>>> if the basic blocks they reference are possible successors of an
>>>>> indirectbr. It may have to be reworked to support this new usage of the
>>>>> blockaddress expression
>>>>>
>>>>> Some other notes on the instruction and asm-goto implementation:
>>>>>
>>>>> * The special status of the “normal” destination label allows to
>>>>> specifically adjust its transition probability to make it likely to become
>>>>> a fallthrough successor
>>>>> * While the initial implementation of asm-goto won’t allow outputs,
>>>>> the instruction’s syntax supports them in principle, so the support for
>>>>> this can be added at a later date
>>>>> * The general syntax of the callbr instruction allows to use it to
>>>>> implement the control flow tracking for setjmp/longjmp, but that is beyond
>>>>> the scope of this RFC
>>>>>
>>>>>
>>>>> I would like to kindly ask for your comments and thoughts on that. I
>>>>> will also submit the prototype patch implementing the proposal to
>>>>> phabricator.
>>>>>
>>>>> And the most important part, we would like to say huge thanks to
>>>>> Chandler Carruth, Reid Kleckner, James Y Knight, Bill Wendling, Eric
>>>>> Christopher, Richard Smith, Matthias Braun, Nick Desaulniers and others who
>>>>> contributed to this RFC - without you it would not be possible.
>>>>>
>>>>>
>>>>> Alexander Ivchenko, Mikhail Dvoretckii
>>>>>
>>>>>
>>>>> Links
>>>>> -----------------
>>>>>
>>>>> [1] asm-goto feature request tracker (
>>>>> https://bugs.llvm.org/show_bug.cgi?id=9295)
>>>>>
>>>>> [2] Discussion in llvm community about asm-goto (
>>>>> https://groups.google.com/forum/#!topic/llvm-dev/v9_oGrBeE9s)
>>>>>
>>>>> [3] Recent discussion in LKML that resurrected the discussion (
>>>>> https://lkml.org/lkml/2018/2/13/1049)
>>>>>
>>>>> [4] asm-goto was made mandatory for x86 in January of this year: (
>>>>> https://github.com/ClangBuiltLinux/linux/commit/e501ce957a786ecd076ea0cfb10b114e6e4d0f40
>>>>> )
>>>>>
>>>>> [5] GCC documentation describes their motivating example here:
>>>>> (https://gcc.gnu.org/onlinedocs/gcc-4.8.4/gcc/Extended-Asm.html)
>>>>>
>>>>> [6] Linux kernel RFC which discusses the old C way of implementing
>>>>> tracepoints 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/)
>>>>>
>>>>> [7] LTTng (Linux Trace Toolkit Next Generation) presentation talks
>>>>> about using asm-goto feature as a way of optimize static tracepoints
>>>>> (slides 3-4) (
>>>>> https://www.computer.org/cms/ComputingNow/HomePage/2011/0111/rW_SW_UsingTracing.pdf
>>>>> )
>>>>>
>>>>> [8] A link to the gcc thread introducing this feature (
>>>>> http://gcc.gnu.org/ml/gcc-patches/2009-07/msg01556.htm)
>>>>> _______________________________________________
>>>>> LLVM Developers mailing list
>>>>> llvm-dev at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> LLVM Developers mailing list
>>>>> llvm-dev at lists.llvm.org
>>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>>
>>>>
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> llvm-dev at lists.llvm.org
>>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>>
>>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> llvm-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>>
>> _______________________________________________
> 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/20190122/35c41e63/attachment-0001.html>


More information about the llvm-dev mailing list