[llvm-dev] [RFC] Implementing asm-goto support in Clang/LLVM
Bill Wendling via llvm-dev
llvm-dev at lists.llvm.org
Wed Jan 9 15:21:54 PST 2019
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
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20190109/9303ef29/attachment.html>
More information about the llvm-dev
mailing list