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

Alberto Barbaro via llvm-dev llvm-dev at lists.llvm.org
Tue Jan 22 23:06:50 PST 2019


Hi,
Really cool! I'm happy to help with the testing whenever useful.

Is the kernel patch available? I'd like to try to compile the kernel as
well.

Thanks

On Wed, Jan 23, 2019, 00:02 Craig Topper via llvm-dev <
llvm-dev at lists.llvm.org wrote:

> 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
>>
> _______________________________________________
> 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/20190123/f6c02f9f/attachment.html>


More information about the llvm-dev mailing list