Chandler Carruth via llvm-dev
2018-Nov-04 10:24 UTC
[llvm-dev] [RFC] Implementing asm-goto support in Clang/LLVM
(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/20181104/c8b3ae01/attachment-0001.html>
Bill Wendling via llvm-dev
2019-Jan-09 23:21 UTC
[llvm-dev] [RFC] Implementing asm-goto support in Clang/LLVM
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>
Craig Topper via llvm-dev
2019-Jan-23 00:02 UTC
[llvm-dev] [RFC] Implementing asm-goto support in Clang/LLVM
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>