All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vladimir Makarov <vmakarov@redhat.com>
To: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Jakub Jelinek <jakub@redhat.com>,
	Richard Henderson <rth@redhat.com>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	Thomas Gleixner <tglx@linutronix.de>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
	Borislav Petkov <bp@alien8.de>
Subject: Re: [PATCH] x86: Optimize variable_test_bit()
Date: Fri, 01 May 2015 18:22:46 -0400	[thread overview]
Message-ID: <5543FCB6.8060003@redhat.com> (raw)
In-Reply-To: <CA+55aFxOd6mJcezgoLHN9Zgds-CsJqsx4Jgkp9OP1xUf11727Q@mail.gmail.com>



On 01/05/15 04:49 PM, Linus Torvalds wrote:
> On Fri, May 1, 2015 at 12:02 PM, Vladimir Makarov <vmakarov@redhat.com> wrote:
>>    GCC RA is a major reason to prohibit output operands for asm goto.
> Hmm.. Thinking some more about it, I think that what would actually
> work really well at least for the kernel is:
>
> (a) allow *memory* operands (ie "=m") as outputs and having them be
> meaningful even at any output labels (obviously with the caveat that
> the asm instructions that write to memory would have to happen before
> the branch ;)
>
> This covers the somewhat common case of having magic instructions that
> result in conditions that can't be tested at a C level. Things like
> "bit clear and test" on x86 (with or without the lock) .
>
>   (b) allow other operands to be meaningful onlty for the fallthrough case.
>
>  From a register allocation standpoint, these should be the easy cases.
> (a) doesn't need any register allocation of the output (only on the
> input to set up the effective address of the memory location), and (b)
> would explicitly mean that an "asm goto" would leave any non-memory
> outputs undefined in any of the goto cases, so from a RA standpoint it
> ends up being equivalent to a non-goto asm..
Thanks for explanation what you need in the most common case.

Big part of GCC RA (at least local register allocators -- reload pass 
and LRA) besides assigning hard registers to pseudos is to make 
transformations to satisfy insn constraints.  If there is not enough 
hard registers, a pseudo can be allocated to a stack slot and if insn 
using the pseudo needs a hard register, load or/and store should be 
generated before/after the insn.  And the problem for the old (reload 
pass) and new RA (LRA) is that they were not designed to put new insns 
after an insn changing control flow.  Assigning hard registers itself is 
not an issue for asm goto case.

If I understood you correctly, you assume that just permitting =m will 
make GCC generates the correct code. Unfortunately, it is more 
complicated.  The operand can be not a memory or memory not satisfying 
memory constraint 'm'.  So still insns for moving memory satisfying 'm' 
into output operand location might be necessary after the asm goto.

We could make asm goto semantics requiring that a user should provide 
memory for such output operand (e.g. a pointer dereferrencing in your 
case) and generate an error otherwise.  By the way the same could be 
done for output *register* operand.  And user to avoid the error should 
use a local register variable (a GCC extension) as an operand. But it 
might be a bad idea with code performance point of view.

Unfortunately, the operand can be substituted by an equiv. value during 
different transformations and even if an user think it will be a memory 
before RA, it might be wrong.  Although I believe there are some cases 
where we can be sure that it will be memory (e.g. dereferrencing pointer 
which is a function argument and is not used anywhere else in 
function).  Still it makes asm goto semantics complicated imho.

We could prevent equiv. substitution for output memory operand of asm 
goto through all the optimizations but it is probably even harder task 
than implementing output reloads in *reload* pass (it is 28-year old 
pass with so many changes during its life that practically nobody can 
understand it now well and change w/o introducing a new bug).  As for 
LRA, I wrote implementing output reloads is a double task.

> Hmm?
>
> So as an example of something that the kernel does and which wants to
> have an output register. is to do a load from user space that can
> fault. When it faults, we obviously simply don't *have* an actual
> result, and we return an error. But for the successful fallthrough
> case, we get a value in a register.
>
> I'd love to be able to write it as (this is simplified, and doesn't
> worry about all the different access sizes, or the "stac/clac"
> sequence to enable user accesses on modern Intel CPU's):
>
>          asm goto(
>              "1:"
>              "\tmovl %0,%1\n"
>              _ASM_EXTABLE(1b,%l[error])
>              : "=r" (val)
>              : "m" (*userptr)
>              : : error);
>
> where that "_ASM_EXTABLE()" is our magic macro for generating an
> exception entry for that instruction, so that if the load takes an
> exception, it will instead to to the "error" label.
>
> But if it goes to the error label, the "val" output register really
> doesn't contain anything, so we wouldn't even *want* gcc to try to do
> any register allocation for the "jump to label from assembly" case.
>
> So at least for one of the major cases that I'd like to use "asm goto"
> with an output, I actually don't *want* any register allocation for
> anything but the fallthrough case. And I suspect that's a
> not-too-uncommon pattern - it's probably often about error handling.
>
>
As I wrote already if we implement output reloads after the control flow 
insn, it does not matter what operand constraint should be (memory or 
register).  Implementing it only for fall-through case simplify the task 
but not so much.  For LRA it is doable and I can do this, for reload 
pass it is very hard (requirement only memory operand can simplify the 
implementation in reload although I am not sure about it).

But may be somebody will agree to do it for reload, sorry only not me -- 
i can not think about this without flinching.


  reply	other threads:[~2015-05-01 22:22 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-01 15:16 [PATCH] x86: Optimize variable_test_bit() Peter Zijlstra
2015-05-01 16:03 ` Linus Torvalds
2015-05-01 16:16   ` Peter Zijlstra
2015-05-01 16:29     ` Peter Zijlstra
2015-05-01 16:18   ` Peter Zijlstra
2015-05-01 16:33   ` Jakub Jelinek
2015-05-01 16:45     ` Linus Torvalds
2015-05-01 16:46     ` Peter Zijlstra
2015-05-01 17:17       ` Ingo Molnar
2015-05-01 19:02     ` Vladimir Makarov
2015-05-01 20:49       ` Linus Torvalds
2015-05-01 22:22         ` Vladimir Makarov [this message]
2015-05-02 12:39         ` Peter Zijlstra
2015-05-04 15:37           ` Richard Henderson
2015-05-04 19:33           ` [RFC] Design for flag bit outputs from asms Richard Henderson
2015-05-04 20:14             ` H. Peter Anvin
2015-05-04 20:27               ` H. Peter Anvin
2015-05-04 20:33               ` Richard Henderson
2015-05-04 20:45                 ` Linus Torvalds
2015-05-04 20:57                   ` Richard Henderson
2015-05-04 21:23                     ` H. Peter Anvin
2015-05-04 20:35               ` Linus Torvalds
2015-05-04 20:42                 ` H. Peter Anvin
2015-05-05  9:01             ` Gabriel Paubert
2015-05-05 13:50             ` Segher Boessenkool
2015-05-05 15:37               ` Linus Torvalds
2015-05-05 16:10                 ` Segher Boessenkool
2015-05-02 12:43       ` [PATCH] x86: Optimize variable_test_bit() Peter Zijlstra
2015-05-04 18:07         ` Vladimir Makarov
2015-05-04 20:14           ` H. Peter Anvin
2015-05-04 13:42 ` Peter Zijlstra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5543FCB6.8060003@redhat.com \
    --to=vmakarov@redhat.com \
    --cc=bp@alien8.de \
    --cc=hpa@zytor.com \
    --cc=jakub@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=peterz@infradead.org \
    --cc=rth@redhat.com \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.