This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Combine versus volatile (Was: Re: Performance of Integer Multiplication on PIII)
- To: Linus Torvalds <torvalds at transmeta dot com>, gcc at gcc dot gnu dot org
- Subject: Combine versus volatile (Was: Re: Performance of Integer Multiplication on PIII)
- From: Jan Hubicka <jh at suse dot cz>
- Date: Thu, 8 Nov 2001 15:10:59 +0100
- Cc: Jan Hubicka <jh at suse dot cz>
- References: <20011106154912.C26344@atrey.karlin.mff.cuni.cz> <Pine.LNX.4.33.0111070938330.10650-100000@penguin.transmeta.com>
>
> Jan,
> I have another question for you..
>
> In the kernel, we have "set_bit()" being defined as:
>
...
> static __inline__ void set_bit(int nr, volatile void * addr)
> {
> __asm__ __volatile__( LOCK_PREFIX
> "btsl %1,%0"
> :"=m" (ADDR)
> :"Ir" (nr));
> }
>
> and when gcc generates code for this, it will _never_ use an immediate
> value for the bit number.
>
> I chased it down to the "ADDR" being marked "volatile" - if I remove that
> volatile, gcc will generate
>
> btsl $1,addr
>
> but with the volatile in place it will generate
>
> movl $1,%eax
> btsl %eax,addr
...
Debugging my simple testcase shows that it is due to code in general_operand
that refuse to recognize volatile memory operands when volatile_ok variable
is not set.
Combine constructs the combined pattern, but as it contains volatile memory
references the pattern is not recognized properly.
Unfortunately I am not at all sure if it is needed in combine - I am not
able to come with counterexample where it can cause problems. Combine,
in worst case, IMO can change the size of memory read and I am not
quite sure if we require this to not change in our volatile definition.
The comment about volatile_ok does not make this cleaner:
/* Nonzero means allow operands to be volatile.
This should be 0 if you are generating rtl, such as if you are calling
the functions in optabs.c and expmed.c (most of the time).
This should be 1 if all valid insns need to be recognized,
such as in regclass.c and final.c and reload.c.
init_recog and init_recog_no_volatile are responsible for setting this. */
int volatile_ok;
So what others think? Does it make sense to set volatile_ok for combine?
Also on related note - if you are concerned about speed with constant
bit offsets, why you just don't use builtin_constant_p to get two versions,
one with or doing the change that executes faster on most cases.
Does the semantic of or with lock prefix differ from btsl?
Honza