public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Re: Incrementing volatiles?
       [not found] <egcs.199807111302.JAA10664@pincoya.inf.utfsm.cl>
@ 1998-07-13  0:06 ` Todd P. Whitesel
  0 siblings, 0 replies; 27+ messages in thread
From: Todd P. Whitesel @ 1998-07-13  0:06 UTC (permalink / raw)
  To: mlist-egcs

Horst von Brand <vonbrand@inf.utfsm.cl> writes:

>Sorry if I'm being dense... I just don't see any difference here: both are
>fetched, incremented and written back. And if it's "implementation defined",
>gcc is free to optimize this, isn't it?

Sort of. While the language standard that says "implementation defined" does
allow gcc to optimize it, many of the actual _users_ of gcc have a very clear
idea as to what 'volatile' means, and gcc needs to accomodate them.

The unwritten but de facto definition of volatile is that the activity on all
objects declared volatile (number of accesses, whether they are read or write,
the size of them, and the order of them) must remain the same independent of
the optimization level.

On "enough" systems this satisfies the condition that all I/O peripherals and
shared memory devices see the same events in the same time order for each
basic block in the program. Thus, most people's ideas of how to write device
drivers and multi-threaded code continue to work even when heavy optimization
is enabled.

It sounds to me that gcc is using an extremely conservative (but also very
safe, since handling of volatile is in principle very difficult to test!!)
implementation of volatile. I would strongly recommend leaving it the way
it is until a truly serious effort can be made to improve optimization of
volatile objects -- including exhaustive simulation of the target processors
to ensure that the relevant visible 'bus cycles' do not change when
optimization is enabled. Since the sim/ directory would be the first place
tapped for simulator technology, more targets implemented in there would be
A Good Thing.

Todd Whitesel
toddpw @ ugcs.caltech.edu

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
@ 1998-07-17  8:59 Mike Stump
  0 siblings, 0 replies; 27+ messages in thread
From: Mike Stump @ 1998-07-17  8:59 UTC (permalink / raw)
  To: carlo, egcs

> From: Carlo Wood <carlo@runaway.xs4all.nl>
> Date: Thu, 16 Jul 1998 01:43:20 +0200 (CEST)

> Can someone explain to me what exactly the definition
> of 'volatile' is? :)

Sure, what part was unclear?  While there is some hair surrounding
volatile, I think it is fairly straight forward.

The basics: There is an implementation defined observation point of
the abstract machine that implements the required semantics of a
conforming program.  Volatile is the way to `see' what is going on
with the machine.

From a C++ working paper:

1 The semantic descriptions in  this  International  Standard  define  a
  parameterized  nondeterministic  abstract machine.  This International
  Standard  places  no  requirement  on  the  structure  of   conforming
  implementations.   In  particular,  they  need not copy or emulate the
  structure of the abstract machine.  Rather, conforming implementations
  are required to emulate (only) the observable behavior of the abstract
  machine as explained below.3)                                           |
  __________________________
  3) This provision is sometimes  called  the  as-if  rule,  because  an
  implementation is free to disregard any requirement of the Standard as
  long as the result is  as if the requirement had been obeyed,  as  far
  as can be determined from the observable behavior of the program.

6 The observable behavior of the abstract machine  is  its  sequence  of
  reads   and   writes  to  volatile  data  and  calls  to  library  I/O
  functions.4)

That's about it.  There are more details, some of them are
obvious:

	volatile int a; a = 1;

represents a `write', whereas

	   b = a;

represents a read (of a).  Not as obvious are things like, if I have
two CPUs can I do s=++i; where i is a shared volatile between the two
CPUs, can I expect this to work?  The answer is usually no.  I say
usually, because a port maintainer is free to require that it work,
and free to ensure it does work, extending the compiler as necesary.
Though, the program that relies upon such a guarantee by a port, isn't
strictly speaking, portable.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:22           ` Carlo Wood
@ 1998-07-17  4:10             ` Andreas Schwab
  0 siblings, 0 replies; 27+ messages in thread
From: Andreas Schwab @ 1998-07-17  4:10 UTC (permalink / raw)
  To: Carlo Wood; +Cc: egcs

Carlo Wood <carlo@runaway.xs4all.nl> writes:

|> Can someone explain to me what exactly the definition
|> of 'volatile' is? :)

From the C9x draft:

       6.5.3  Type qualifiers

       [#6] An object  that  has  volatile-qualified  type  may  be
       modified in ways unknown to the implementation or have other
       unknown side effects.  Therefore any expression referring to
       such  an object shall be evaluated strictly according to the
       rules of the abstract  machine,  as  described  in  5.1.2.3.
       Furthermore,  at  every sequence point the value last stored
       in the object  shall  agree  with  that  prescribed  by  the
       abstract  machine, except as modified by the unknown factors
       mentioned previously.99  What constitutes an  access  to  an
       object  that  has volatile-qualified type is implementation-
       defined.

Footnote:

       99. A volatile declaration may be used to describe an object
           corresponding to a memory-mapped input/output port or an
           object  accessed  by  an   asynchronously   interrupting
           function.   Actions  on objects so declared shall not be
           ``optimized out''  by  an  implementation  or  reordered
           except   as   permitted  by  the  rules  for  evaluating
           expressions.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:56               ` Bill Currie
  1998-07-15 17:22                 ` Jeffrey A Law
  1998-07-15 17:34                 ` Matthias Urlichs
@ 1998-07-17  4:06                 ` Andreas Schwab
  2 siblings, 0 replies; 27+ messages in thread
From: Andreas Schwab @ 1998-07-17  4:06 UTC (permalink / raw)
  To: Bill Currie; +Cc: law, Horst von Brand, Matthias Urlichs, egcs

Bill Currie <bcurrie@tssc.co.nz> writes:

|> alright (and maybe even desirable) to combine rtx's with in a C level
|> atomic operation (eg ++)

There is no such thing as an atomic operation in C, except *reading* an
object of sig_atomic_t.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:34                 ` Matthias Urlichs
  1998-07-15 21:58                   ` Bill Currie
@ 1998-07-16 11:28                   ` Carlo Wood
  1 sibling, 0 replies; 27+ messages in thread
From: Carlo Wood @ 1998-07-16 11:28 UTC (permalink / raw)
  To: egcs

| > bar:
| >     movl  foo,%eax
| >     incl  foo
| >     ret
| > 
| Wrong. The foo++ means "read it, perhaps do something with the value,
| increment the value, put it back". Your assembly code reads the value
| twice.
| 
| > Now, if I'm really off track, can someone please give me some pointers
| > to information that will set me right?
| > 
| "volatile" is massively undefined. My off-the-seat-of-my-pants definition
| is that volatile variables are _always_ accessed exactly as many times, and
| in exactly that order, as described in the C source code.
| 
| How to tell the backend (Intel or otherwise) that sometimes(!) it can
| combine a read-add_one-write insn sequence into one "incr", even if the
| to-be-incremented thing in question is marked as volatile, is an
| interesting question. IMHO, however, "two volatiles never match" is a bit
| too strong.

Thanks for the definition :)

Let us assume that volatile `foo' in the above example is a r/w register
of some hardware IC that generates pseudo random numbers from its own
value every time it is being read; you are allowed to write to it however
to set a 'seed'.  That is an example that would make "volatile" pretty
clear, if I understood it well.  It shows clearly that

 volatile int foo;

 int random(void) {
   return foo++;
 }

Should read one pseudo random number, increment it and write it back as seed.
That means indeed that 

random:
	movl foo,%eax
	incl foo
	ret

is not a correct way of generating the assembly code.
It should be generated like:

random:
	movl foo,%eax
	movl %eax,%edx
	incl %edx
	movl %edx,foo
	ret

Note that currently, with -O9 -fomit-frame-pointer it generates less
optimized code:

random:
	movl foo,%eax
	movl %eax,%edx
	incl %eax
	movl %eax,foo
	movl %edx,%eax
	ret

And without -fomit-frame-pointer it does something totally redundant
things with %ebp and the stack :/

random:
        pushl %ebp		}  Do we want this with -O9 ?
        movl %esp,%ebp		}
        movl foo,%eax
        movl %eax,%edx
        incl %eax
        movl %eax,foo
        movl %edx,%eax
        movl %ebp,%esp		}
        popl %ebp		}
        ret

How hard would it be to optimize:

	movl %eax,%edx
	incl %eax
	movl %eax,foo
	movl %edx,%eax
	ret

to:

	movl %eax,%edx
	incl %edx
	movl %edx,foo
	ret

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:34                 ` Matthias Urlichs
@ 1998-07-15 21:58                   ` Bill Currie
  1998-07-16 11:28                   ` Carlo Wood
  1 sibling, 0 replies; 27+ messages in thread
From: Bill Currie @ 1998-07-15 21:58 UTC (permalink / raw)
  To: Matthias Urlichs; +Cc: law, Andreas Schwab, Horst von Brand, egcs

Matthias Urlichs wrote:
> 
> Hi,
> 
> Bill Currie:
> >
> > and "return foo++" could be
> >
> > bar:
> >     movl  foo,%eax
> >     incl  foo
> >     ret
> >
> Wrong. The foo++ means "read it, perhaps do something with the value,
> increment the value, put it back". Your assembly code reads the value
> twice.

Ah-ha! Thankyou!  Just your analysis of my assembly helps me understand
the problem better.

> "volatile" is massively undefined. 

Could even that be an understatement?:)

> My off-the-seat-of-my-pants definition
> is that volatile variables are _always_ accessed exactly as many times, and
> in exactly that order, as described in the C source code.

That makes extreamly good sense to me, especially with your comments on
my assembly code.  Now, I'm assuming my first case was correct by your
definition (I mention foo twice and the assembly accesses foo twice). 
By this "foo++;return foo" was correct, but "return foo++" should be:

bar:
   movl foo,%edx
   movl %edx,%eax
   incl %edx
   movl %edx,foo
   ret

IMHO, yetch, but I can't think of any better.  I actually got into a
discussion on the `atomicness' of `++' a couple of weeks ago at work.  I
stated that it's difficult if not impossible to acheive, especially for
SMP architectures.  This just shows me I understated the problem:)

> How to tell the backend (Intel or otherwise) that sometimes(!) it can
> combine a read-add_one-write insn sequence into one "incr", even if the
> to-be-incremented thing in question is marked as volatile, is an
> interesting question.

Hmm, would it be possible to mark each `volatile' with some sort of
block such that the compiler can optimise the code within the block as
much as possible, but the block itself must not be deleted, combined
with any other blocks, or moved (significantly?).  Then register life
analysis could determine whether the value of the `volatile' is used
outside of the block.

For "foo++;return foo", there are two volatie blocks, one for each
statement.  The first block (foo++) does not involve assigning the value
of either foo or foo+1 to anything other than foo, thus the value of the
volatile does not leave the block, thus the code sequence for this can
be combined into a single instruction.  The "return foo" is another
block, so it can't be combined with the previous block, but this is
trivial.

However, for "return foo++" or "return ++foo", the value of the volatile
*DOES* leave the block (it gets assigned to the return register) and
thus the instructions cannot be combined as aggressivly.

Now, the question is, how do these blocks get marked and how much effort
is involved in this (probably won't make egcs-1.2 even:).

> IMHO, however, "two volatiles never match" is a bit
> too strong.

I agree with this, but I also agree there probably isn't an easy
solution.

Bill
-- 
Leave others their otherness

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:22             ` Jeffrey A Law
@ 1998-07-15 17:56               ` Bill Currie
  1998-07-15 17:22                 ` Jeffrey A Law
                                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Bill Currie @ 1998-07-15 17:56 UTC (permalink / raw)
  To: law; +Cc: Andreas Schwab, Horst von Brand, Matthias Urlichs, egcs

Jeffrey A Law wrote:
> This is better handled by the standard patterns which can check the
> arguments, and if they are the same produce a 2 operand add.

Ok, I'll have to have a really close look at the i386 rtl generated for
these instructions.  The pa-risc rtl looks ghastly (and optimises as
best as can be expected anyway).

> In general, if you find yourself proposing new RTX codes, or new
> named patterns, then you're probably heading down the wrong path.

Good point, and I accept this point of advice with all seriousness.  I'm
thinking I may have `lost the plot' when Anreas said :

> But that would be an awful special case.  All accesses to a volatile
> variable must be exactly as specified by the user, which means that
> they must never be moved, duplicated or combined.

I took this to mean that insns that refer to a variable must never be
combined, ever.  Now, if they are separate references (ie separate C
expressions(?)) then this restriction makes perfect sense.  However, my
(mis?)understanding of the subject tells me that it would be perfectly
alright (and maybe even desirable) to combine rtx's with in a C level
atomic operation (eg ++) that refers to a volatile variable.  AIUI, one
volatile sequence will never be combined with another sequence (which is
The Right Thing), but nowhere is it stated that instructions *WITHIN* a
volatile sequence cannot be combined.

Also, the statment that volatile accesses cannot be optimised in any way
(you, I think, Jeff), ie the same code must be generated for optimised
and unoptimised generation put me out even more.

The way I see it:

volatile int foo;

int bar()
{
  foo++;
  return foo;
}

Could, with all validity, be compiled as

bar:
    incl  foo
    movl  foo,%eax
    ret

and "return foo++" could be

bar:
    movl  foo,%eax
    incl  foo
    ret

Unless I'm missing something, the volatility of foo is still preserved.

Now, if I'm really off track, can someone please give me some pointers
to information that will set me right?

Bill
-- 
Leave others their otherness

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:56               ` Bill Currie
  1998-07-15 17:22                 ` Jeffrey A Law
@ 1998-07-15 17:34                 ` Matthias Urlichs
  1998-07-15 21:58                   ` Bill Currie
  1998-07-16 11:28                   ` Carlo Wood
  1998-07-17  4:06                 ` Andreas Schwab
  2 siblings, 2 replies; 27+ messages in thread
From: Matthias Urlichs @ 1998-07-15 17:34 UTC (permalink / raw)
  To: Bill Currie, law; +Cc: Andreas Schwab, Horst von Brand, egcs

Hi,

Bill Currie:
> 
> and "return foo++" could be
> 
> bar:
>     movl  foo,%eax
>     incl  foo
>     ret
> 
Wrong. The foo++ means "read it, perhaps do something with the value,
increment the value, put it back". Your assembly code reads the value
twice.

> Now, if I'm really off track, can someone please give me some pointers
> to information that will set me right?
> 
"volatile" is massively undefined. My off-the-seat-of-my-pants definition
is that volatile variables are _always_ accessed exactly as many times, and
in exactly that order, as described in the C source code.

How to tell the backend (Intel or otherwise) that sometimes(!) it can
combine a read-add_one-write insn sequence into one "incr", even if the
to-be-incremented thing in question is marked as volatile, is an
interesting question. IMHO, however, "two volatiles never match" is a bit
too strong.

-- 
Matthias Urlichs
noris network GmbH

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:22           ` Bill Currie
@ 1998-07-15 17:22             ` Jeffrey A Law
  1998-07-15 17:56               ` Bill Currie
  0 siblings, 1 reply; 27+ messages in thread
From: Jeffrey A Law @ 1998-07-15 17:22 UTC (permalink / raw)
  To: Bill Currie; +Cc: Andreas Schwab, Horst von Brand, Matthias Urlichs, egcs

  In message < 35AD22FF.7436@tssc.co.nz >you write:
  > Jeffrey A Law wrote:
  > > But you can not increment without first reading its value.
  > 
  > However, if the CPU supports `atomic' increments (most if not all CISC
  > cpus), then it should be used.
They're already used whenever possible.

  > Hmm, I seem to have been mis-understood.  I was not proposing a change
  > to the meaning of volatile.  What I was saying is that new RTXs should
  > be created for the increment and friends orperators.
  > 
  > Ouch I just realised why I was probably misunderstood.  I mean
  > insn-patterns, not RTXs.  In fact, I don't think new RTXs would be
  > needed.  Maybe an example would help (i386):
  > 
  > (define_expand "incsi"
  >   [(set (match_operand:SI 0 "nonimmediate_operand" "")
  >         (plus:SI (match_dup 0)
  >                  (match_dup 1)))]
  >   ""
This is better handled by the standard patterns which can check the
arguments, and if they are the same produce a 2 operand add.

In general, if you find yourself proposing new RTX codes, or new
named patterns, then you're probably heading down the wrong path.


jeff

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15  1:49         ` Jeffrey A Law
@ 1998-07-15 17:22           ` Bill Currie
  1998-07-15 17:22             ` Jeffrey A Law
  0 siblings, 1 reply; 27+ messages in thread
From: Bill Currie @ 1998-07-15 17:22 UTC (permalink / raw)
  To: law; +Cc: Andreas Schwab, Horst von Brand, Matthias Urlichs, egcs

Jeffrey A Law wrote:
> But you can not increment without first reading its value.

However, if the CPU supports `atomic' increments (most if not all CISC
cpus), then it should be used.

> Note, that we are not going to change the meaning of volatile, so debating
> this point probably isn't worth the time.

Hmm, I seem to have been mis-understood.  I was not proposing a change
to the meaning of volatile.  What I was saying is that new RTXs should
be created for the increment and friends orperators.

Ouch I just realised why I was probably misunderstood.  I mean
insn-patterns, not RTXs.  In fact, I don't think new RTXs would be
needed.  Maybe an example would help (i386):

(define_expand "incsi"
  [(set (match_operand:SI 0 "nonimmediate_operand" "")
        (plus:SI (match_dup 0)
                 (match_dup 1)))]
  ""
  "
{
  operands[1] = const1_rtx;
}")

(define_insn ""
  [(set (match_operand:SI 0 "nonimmediate_operand" "rm")
        (plus:SI (match_dup 0)
                 (match_operand:SI 1 "const1_operand" "")))]
  ""
  "* return AS1(inc%L0,%0);")

[NOTE: const1_operand may be bogus, I just picked a name out of the hat]

For cpus that don't support this, "incsi" can expand into the old
sequence.

Now, (AIUI) no matter what optimisation level is used, the increment
instruction will be used thus preserving the meaning of volatile to the
limits of the CPU.  Anyway, it's faster (and smaller) than an explicit
read/modify/write.

Unless I misunderstood some of the previous arguments, this is really a
win-win situations.  Yes, I know, there's still the problem of getting
the compiler to USE `incsi' and the others, but it could be worth it in
the long run (I don't think cpu's with `inc' instructions are going to
disappear anytime soon).

Bill
-- 
Leave others their otherness

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15 17:56               ` Bill Currie
@ 1998-07-15 17:22                 ` Jeffrey A Law
  1998-07-15 17:34                 ` Matthias Urlichs
  1998-07-17  4:06                 ` Andreas Schwab
  2 siblings, 0 replies; 27+ messages in thread
From: Jeffrey A Law @ 1998-07-15 17:22 UTC (permalink / raw)
  To: Bill Currie; +Cc: Andreas Schwab, Horst von Brand, Matthias Urlichs, egcs

  In message < 35AD374A.7E72@tssc.co.nz >you write:
  > Jeffrey A Law wrote:
  > > This is better handled by the standard patterns which can check the
  > > arguments, and if they are the same produce a 2 operand add.
  > 
  > Ok, I'll have to have a really close look at the i386 rtl generated for
  > these instructions.  The pa-risc rtl looks ghastly (and optimises as
  > best as can be expected anyway).
B believe the x86 will generate "inc" instructions whenever possible.

Note that since the x86 is a two operand machine typically one of the
source operands will match the destination operand.

  > I took this to mean that insns that refer to a variable must never be
  > combined, ever.
I'm not 100% sure it's that strict.

Consider a volatile hunk of memory -- the address to access that memory
may (I haven't checked) be subject to cse, combine and other opts.

  > alright (and maybe even desirable) to combine rtx's with in a C level
  > atomic operation (eg ++) that refers to a volatile variable.
You may be able to find cases where you can do this, but I believe that 
you'll end up breaking  other aspects of volatile in the process.

Generally, I don't think we should be making any changes to attempt
to optimize volatile expressions any more than we currently are.  Such
changes are dangerous and are likely to lead to very obscure and difficuilt
to find problems later.  Better safe than sorry.

jeff

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-15  3:14         ` Andreas Schwab
@ 1998-07-15 17:22           ` Carlo Wood
  1998-07-17  4:10             ` Andreas Schwab
  0 siblings, 1 reply; 27+ messages in thread
From: Carlo Wood @ 1998-07-15 17:22 UTC (permalink / raw)
  To: egcs

Can someone explain to me what exactly the definition
of 'volatile' is? :)

-- 
 Carlo Wood  <carlo@runaway.xs4all.nl>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  8:48       ` Joe Buck
@ 1998-07-15  6:45         ` Andi Kleen
  0 siblings, 0 replies; 27+ messages in thread
From: Andi Kleen @ 1998-07-15  6:45 UTC (permalink / raw)
  To: Joe Buck; +Cc: Philippe De Muyter, egcs

Joe Buck <jbuck@Synopsys.COM> writes:

> 
> How do the Linux/ppc people deal with this?  I see no "eieio" instructions
> in the arch/ppc part of the 2.0.30 kernel.

Look in include/asm-ppc/io.h

-Andi

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-14 18:59       ` Bill Currie
  1998-07-15  1:49         ` Jeffrey A Law
  1998-07-15  3:14         ` Andreas Schwab
@ 1998-07-15  3:14         ` Joern Rennecke
  2 siblings, 0 replies; 27+ messages in thread
From: Joern Rennecke @ 1998-07-15  3:14 UTC (permalink / raw)
  To: Bill Currie; +Cc: schwab, vonbrand, smurf, egcs

> Maybe gcc should have some rtxs for incrementing/decrementing a pseudo
> (both ++/-- and +=/-=, so that even unoptimised code gets the
> `optimised' version).  Actualy, rtxs should be defined for *ALL* <op>=

We already have POST_INC, so if we wrap it in something with a mode,
we could express it, e.g.:

(use:QI (post_inc:SI (reg:SI 123)))

However, handling this properly in all the passes would probably be a major
amount of work - maybe more than it's worth.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-14 18:59       ` Bill Currie
  1998-07-15  1:49         ` Jeffrey A Law
@ 1998-07-15  3:14         ` Andreas Schwab
  1998-07-15 17:22           ` Carlo Wood
  1998-07-15  3:14         ` Joern Rennecke
  2 siblings, 1 reply; 27+ messages in thread
From: Andreas Schwab @ 1998-07-15  3:14 UTC (permalink / raw)
  To: Bill Currie; +Cc: Horst von Brand, Matthias Urlichs, egcs

Bill Currie <bcurrie@tssc.co.nz> writes:

|> Andreas Schwab wrote:
|> > But that would be an awful special case.  All accesses to a volatile
|> > variable must be exactly as specified by the user, which means that they
|> > must never be moved, duplicated or combined.
|> 
|> Eh?  The user said `increment bar', not `grab bar, add one to it and
|> stuff the value back into bar'.  By your definition above, gcc is
|> broken.

Incrementing a variable *is* `read value, add one, write value'.  That's
how the standard defines it.  The only difference between `foo += 1' and
`foo = foo + 1' is that foo is evaluated only once, but this has nothing
to do with volatile, because that does not change the fact that there are
exactly two accesses to foo.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-14 18:59       ` Bill Currie
@ 1998-07-15  1:49         ` Jeffrey A Law
  1998-07-15 17:22           ` Bill Currie
  1998-07-15  3:14         ` Andreas Schwab
  1998-07-15  3:14         ` Joern Rennecke
  2 siblings, 1 reply; 27+ messages in thread
From: Jeffrey A Law @ 1998-07-15  1:49 UTC (permalink / raw)
  To: Bill Currie; +Cc: Andreas Schwab, Horst von Brand, Matthias Urlichs, egcs

  In message < 35ABFE52.70F0@tssc.co.nz >you write:
  > Andreas Schwab wrote:
  > > But that would be an awful special case.  All accesses to a volatile
  > > variable must be exactly as specified by the user, which means that they
  > > must never be moved, duplicated or combined.
  > 
  > Eh?  The user said `increment bar', not `grab bar, add one to it and
  > stuff the value back into bar'.  By your definition above, gcc is
  > broken.
But you can not increment without first reading its value.

Note, that we are not going to change the meaning of volatile, so debating
this point probably isn't worth the time.

jeff

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  1:48     ` Andreas Schwab
@ 1998-07-14 18:59       ` Bill Currie
  1998-07-15  1:49         ` Jeffrey A Law
                           ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Bill Currie @ 1998-07-14 18:59 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Horst von Brand, Matthias Urlichs, egcs

Andreas Schwab wrote:
> But that would be an awful special case.  All accesses to a volatile
> variable must be exactly as specified by the user, which means that they
> must never be moved, duplicated or combined.

Eh?  The user said `increment bar', not `grab bar, add one to it and
stuff the value back into bar'.  By your definition above, gcc is
broken.

Maybe gcc should have some rtxs for incrementing/decrementing a pseudo
(both ++/-- and +=/-=, so that even unoptimised code gets the
`optimised' version).  Actualy, rtxs should be defined for *ALL* <op>=
operations.  This way, if the cpu supports the stated op, the correct
asm can be generated, otherwise the rtx expands into the current form
(the whole purpose of define_expand AIUI).

Hmm.. I might look into this myself and see how far I get as I too am
interested in this issue.

Bill
-- 
Leave others their otherness

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  2:36     ` Philippe De Muyter
  1998-07-13  2:40       ` Andreas Schwab
  1998-07-13  8:48       ` Joe Buck
@ 1998-07-13 12:40       ` Franz Sirl
  2 siblings, 0 replies; 27+ messages in thread
From: Franz Sirl @ 1998-07-13 12:40 UTC (permalink / raw)
  To: Philippe De Muyter; +Cc: John Vickers, schwab, smurf, egcs

At 11:36 13.07.98 , Philippe De Muyter wrote:
>Sorry to be slightly off-topic, but this discussion reminds me a problem
>I encountered some months ago when writing a driver for a VME board in
>an AIX powerpc environment.  Although I had declared all the registers
>of the chips on the board as volatile, and compiled my driver with gcc,
>I saw with a logic analyser on the VME bus that the accesses to the
>register on the board were not done in the order I had written them.
>To solve that problem, I had to manually add asm("eieio") after each
>access to a volatile register.  Should gcc not do that for me ?

volatile has nothing to do with hardware instruction reordering.
asm("eieio") is an old-style asm and is an extremely strong barrier. I'm
currently testing this more optimization friendly solution in Linux/PPC, it
seems to work fine. 

extern inline int in_8(volatile unsigned char *addr)
{
        int ret;

        __asm__ __volatile__ ("" : "=m" (*addr) : "0" (*addr));
        ret = *addr;
        __asm__ __volatile__ ("eieio" : "=m" (*addr) : "0" (*addr));
        return ret;
}

extern inline void out_8(volatile unsigned char *addr, int val)
{
        __asm__ __volatile__ ("" : "=m" (*addr) : "0" (*addr));
        *addr = val;
        __asm__ __volatile__ ("eieio" : "=m" (*addr) : "0" (*addr));
}

Franz.


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  2:36     ` Philippe De Muyter
  1998-07-13  2:40       ` Andreas Schwab
@ 1998-07-13  8:48       ` Joe Buck
  1998-07-15  6:45         ` Andi Kleen
  1998-07-13 12:40       ` Franz Sirl
  2 siblings, 1 reply; 27+ messages in thread
From: Joe Buck @ 1998-07-13  8:48 UTC (permalink / raw)
  To: Philippe De Muyter; +Cc: egcs

> eieio stands for "Enforce In-Order Execution of I/O".

... and it is definitely my favorite name for an assembly language
instruction (the non-native-English speakers on the list presumably
don't know the childhood song "Old McDonald had a farm, E-I-E-I-O").

> Without it a powerpc
> processor assumes that it may reorder the load and stores to memory-mapped
> I/O registers.

It would seem that on processors with this property, yes, you should get
an eieio in cases where otherwise, the I/O order might change, at least
where it is really needed.

How do the Linux/ppc people deal with this?  I see no "eieio" instructions
in the arch/ppc part of the 2.0.30 kernel.




^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  2:40       ` Andreas Schwab
@ 1998-07-13  4:36         ` Philippe De Muyter
  0 siblings, 0 replies; 27+ messages in thread
From: Philippe De Muyter @ 1998-07-13  4:36 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: jvickers, smurf, egcs

> |> Sorry to be slightly off-topic, but this discussion reminds me a problem
> |> I encountered some months ago when writing a driver for a VME board in
> |> an AIX powerpc environment.  Although I had declared all the registers
> |> of the chips on the board as volatile, and compiled my driver with gcc,
> |> I saw with a logic analyser on the VME bus that the accesses to the
> |> register on the board were not done in the order I had written them.
> |> To solve that problem, I had to manually add asm("eieio") after each
> |> access to a volatile register.  Should gcc not do that for me ?
> 
> I don't think so.  It's the responsibility of the system software to
> make sure that accesses to hardware registers are uncached and serialized.

Actually, the accesses were uncached, but the powerpc processor itself
does not respect the order of the instructions for memory loads and stores,
and the only way to force it to follow the requested order is to issue
an `eieio' or a `sync' instruction between the instructions that must
be executed 'before' and the ones that must come 'after'.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-13  2:36     ` Philippe De Muyter
@ 1998-07-13  2:40       ` Andreas Schwab
  1998-07-13  4:36         ` Philippe De Muyter
  1998-07-13  8:48       ` Joe Buck
  1998-07-13 12:40       ` Franz Sirl
  2 siblings, 1 reply; 27+ messages in thread
From: Andreas Schwab @ 1998-07-13  2:40 UTC (permalink / raw)
  To: Philippe De Muyter; +Cc: John Vickers, smurf, egcs

"Philippe De Muyter" <phdm@macqel.be> writes:

|> Sorry to be slightly off-topic, but this discussion reminds me a problem
|> I encountered some months ago when writing a driver for a VME board in
|> an AIX powerpc environment.  Although I had declared all the registers
|> of the chips on the board as volatile, and compiled my driver with gcc,
|> I saw with a logic analyser on the VME bus that the accesses to the
|> register on the board were not done in the order I had written them.
|> To solve that problem, I had to manually add asm("eieio") after each
|> access to a volatile register.  Should gcc not do that for me ?

I don't think so.  It's the responsibility of the system software to
make sure that accesses to hardware registers are uncached and serialized.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-10 21:04   ` John Vickers
@ 1998-07-13  2:36     ` Philippe De Muyter
  1998-07-13  2:40       ` Andreas Schwab
                         ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Philippe De Muyter @ 1998-07-13  2:36 UTC (permalink / raw)
  To: John Vickers; +Cc: schwab, smurf, egcs

Sorry to be slightly off-topic, but this discussion reminds me a problem
I encountered some months ago when writing a driver for a VME board in
an AIX powerpc environment.  Although I had declared all the registers
of the chips on the board as volatile, and compiled my driver with gcc,
I saw with a logic analyser on the VME bus that the accesses to the
register on the board were not done in the order I had written them.
To solve that problem, I had to manually add asm("eieio") after each
access to a volatile register.  Should gcc not do that for me ?

eieio stands for "Enforce In-Order Execution of I/O".  Without it a powerpc
processor assumes that it may reorder the load and stores to memory-mapped
I/O registers.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-11  6:03   ` Horst von Brand
@ 1998-07-13  1:48     ` Andreas Schwab
  1998-07-14 18:59       ` Bill Currie
  0 siblings, 1 reply; 27+ messages in thread
From: Andreas Schwab @ 1998-07-13  1:48 UTC (permalink / raw)
  To: Horst von Brand; +Cc: Matthias Urlichs, egcs

Horst von Brand <vonbrand@inf.utfsm.cl> writes:

|> Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> said:
|> > "Matthias Urlichs" <smurf@noris.de> writes:
|> > 
|> > |> Hi,
|> > |> 
|> > |> The following code, using egcs-current -O2 -fomit-frame-pointer
|> > |> 
|> > |>          unsigned int foo;    afoo() { foo++; }
|> > |> volatile unsigned int bar;    abar() { bar++; }
|> > |> 
|> > |>   compiles, on ix86, to
|> > |> 
|> > |> afoo:   incl foo
|> > |>         ret
|> > |> abar:   movl bar,%eax
|> > |>         incl %eax
|> > |>         movl %eax,bar
|> > |>         ret
|> > |> 
|> > |> But actually, it should be perfectly valid to compile both to code using
|> > |> "incr". After all, both versions read the variable, do something with it,
|> > |> and then write it out.
|> > |> 
|> > |> Is there a way to convince the optimizer to do this?
|> 
|> > No.  volatile prevents all attempts to combine instructions, because any
|> > two references to a volatile variable never match.  This is how gcc
|> > implements the implementation defined aspects of volatile.
|> 
|> Sorry if I'm being dense... I just don't see any difference here: both are
|> fetched, incremented and written back. And if it's "implementation defined",
|> gcc is free to optimize this, isn't it?

But that would be an awful special case.  All accesses to a volatile
variable must be exactly as specified by the user, which means that they
must never be moved, duplicated or combined.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-10  6:04 ` Andreas Schwab
  1998-07-10 21:04   ` John Vickers
@ 1998-07-11  6:03   ` Horst von Brand
  1998-07-13  1:48     ` Andreas Schwab
  1 sibling, 1 reply; 27+ messages in thread
From: Horst von Brand @ 1998-07-11  6:03 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Matthias Urlichs, egcs

Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> said:
> "Matthias Urlichs" <smurf@noris.de> writes:
> 
> |> Hi,
> |> 
> |> The following code, using egcs-current -O2 -fomit-frame-pointer
> |> 
> |>          unsigned int foo;    afoo() { foo++; }
> |> volatile unsigned int bar;    abar() { bar++; }
> |> 
> |>   compiles, on ix86, to
> |> 
> |> afoo:   incl foo
> |>         ret
> |> abar:   movl bar,%eax
> |>         incl %eax
> |>         movl %eax,bar
> |>         ret
> |> 
> |> But actually, it should be perfectly valid to compile both to code using
> |> "incr". After all, both versions read the variable, do something with it,
> |> and then write it out.
> |> 
> |> Is there a way to convince the optimizer to do this?

> No.  volatile prevents all attempts to combine instructions, because any
> two references to a volatile variable never match.  This is how gcc
> implements the implementation defined aspects of volatile.

Sorry if I'm being dense... I just don't see any difference here: both are
fetched, incremented and written back. And if it's "implementation defined",
gcc is free to optimize this, isn't it?
-- 
Dr. Horst H. von Brand                       mailto:vonbrand@inf.utfsm.cl
Departamento de Informatica                     Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria              +56 32 654239
Casilla 110-V, Valparaiso, Chile                Fax:  +56 32 797513

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-10  6:04 ` Andreas Schwab
@ 1998-07-10 21:04   ` John Vickers
  1998-07-13  2:36     ` Philippe De Muyter
  1998-07-11  6:03   ` Horst von Brand
  1 sibling, 1 reply; 27+ messages in thread
From: John Vickers @ 1998-07-10 21:04 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Matthias Urlichs, egcs, Andreas Schwab

Andreas Schwab wrote:
> 
> "Matthias Urlichs" <smurf@noris.de> writes:
> 
> |> Hi,
> |>
> |> The following code, using egcs-current -O2 -fomit-frame-pointer
> |>
> |>          unsigned int foo;    afoo() { foo++; }
> |> volatile unsigned int bar;    abar() { bar++; }
[...]
> |> abar:   movl bar,%eax
> |>         incl %eax
> |>         movl %eax,bar
> |>         ret
> |>
> |> But actually, it should be perfectly valid to compile both to code using
> |> "incr". After all, both versions read the variable, do something with it,
> |> and then write it out.
> |>
> |> Is there a way to convince the optimizer to do this?
> 
> No.  volatile prevents all attempts to combine instructions, because any
> two references to a volatile variable never match.  This is how gcc
> implements the implementation defined aspects of volatile.

But this is a reason for changing the compiler.

To me, it seems that combining the references into a single instruction
would only be likely to lead to unexpected behaviour if the cpu did
something like:
	read low 16-bits of bar
	write low 16 bits of bar
	read high 16-bits of bar
	write high 16 bits of bar

On machines with insns for m <op>= ri, combining (not necessarily in
"combine")
the volatile memrefs gives very much denser code.  This can make a big
difference in some device drivers.

I don't know the history of this (someone please tell me!) - I
understand that once upon a time gcc did allow volatile memrefs outside
moves, and that when
this changed, it broke a whole load of code which assumed that
certain operations were going to be uninterruptible.  The people
who wrote that code shouldn't have been too suprised when their code
broke.
I guess a decision was made that it was easier to restrict the rtl which
could be generated for volatiles than to fix all the insns in all the
targets to make sure that they handled volatiles in a predictable and
unsuprising way.

It's probably not a great solution, but having a working dead_or_set_p()
after reload would let this be done with peepholes, and also allow some
complex insns to generate better code.  Once upon a time the doc said
that using dead_or_set_p() after reload
was A Good Thing.  The doc wasn't quite right, because the reg notes
weren't reliable.
Maybe they could be made reliable.


John.

(If I don't reply to any further correspondence on this, it's because
I'm on
holiday!)


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: Incrementing volatiles?
  1998-07-08 14:20 Matthias Urlichs
@ 1998-07-10  6:04 ` Andreas Schwab
  1998-07-10 21:04   ` John Vickers
  1998-07-11  6:03   ` Horst von Brand
  0 siblings, 2 replies; 27+ messages in thread
From: Andreas Schwab @ 1998-07-10  6:04 UTC (permalink / raw)
  To: Matthias Urlichs; +Cc: egcs

"Matthias Urlichs" <smurf@noris.de> writes:

|> Hi,
|> 
|> The following code, using egcs-current -O2 -fomit-frame-pointer
|> 
|>          unsigned int foo;    afoo() { foo++; }
|> volatile unsigned int bar;    abar() { bar++; }
|> 
|>   compiles, on ix86, to
|> 
|> afoo:   incl foo
|>         ret
|> abar:   movl bar,%eax
|>         incl %eax
|>         movl %eax,bar
|>         ret
|> 
|> But actually, it should be perfectly valid to compile both to code using
|> "incr". After all, both versions read the variable, do something with it,
|> and then write it out.
|> 
|> Is there a way to convince the optimizer to do this?

No.  volatile prevents all attempts to combine instructions, because any
two references to a volatile variable never match.  This is how gcc
implements the implementation defined aspects of volatile.

-- 
Andreas Schwab                                      "And now for something
schwab@issan.informatik.uni-dortmund.de              completely different"
schwab@gnu.org

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Incrementing volatiles?
@ 1998-07-08 14:20 Matthias Urlichs
  1998-07-10  6:04 ` Andreas Schwab
  0 siblings, 1 reply; 27+ messages in thread
From: Matthias Urlichs @ 1998-07-08 14:20 UTC (permalink / raw)
  To: egcs

Hi,

The following code, using egcs-current -O2 -fomit-frame-pointer

         unsigned int foo;    afoo() { foo++; }
volatile unsigned int bar;    abar() { bar++; }

  compiles, on ix86, to

afoo:   incl foo
        ret
abar:   movl bar,%eax
        incl %eax
        movl %eax,bar
        ret

But actually, it should be perfectly valid to compile both to code using
"incr". After all, both versions read the variable, do something with it,
and then write it out.

Is there a way to convince the optimizer to do this?

(The obvious solution, i.e. "(*(unsigned int *)&bar)++", doesn't count. ;-)

-- 
Matthias Urlichs
noris network GmbH

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~1998-07-17  8:59 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <egcs.199807111302.JAA10664@pincoya.inf.utfsm.cl>
1998-07-13  0:06 ` Incrementing volatiles? Todd P. Whitesel
1998-07-17  8:59 Mike Stump
  -- strict thread matches above, loose matches on Subject: below --
1998-07-08 14:20 Matthias Urlichs
1998-07-10  6:04 ` Andreas Schwab
1998-07-10 21:04   ` John Vickers
1998-07-13  2:36     ` Philippe De Muyter
1998-07-13  2:40       ` Andreas Schwab
1998-07-13  4:36         ` Philippe De Muyter
1998-07-13  8:48       ` Joe Buck
1998-07-15  6:45         ` Andi Kleen
1998-07-13 12:40       ` Franz Sirl
1998-07-11  6:03   ` Horst von Brand
1998-07-13  1:48     ` Andreas Schwab
1998-07-14 18:59       ` Bill Currie
1998-07-15  1:49         ` Jeffrey A Law
1998-07-15 17:22           ` Bill Currie
1998-07-15 17:22             ` Jeffrey A Law
1998-07-15 17:56               ` Bill Currie
1998-07-15 17:22                 ` Jeffrey A Law
1998-07-15 17:34                 ` Matthias Urlichs
1998-07-15 21:58                   ` Bill Currie
1998-07-16 11:28                   ` Carlo Wood
1998-07-17  4:06                 ` Andreas Schwab
1998-07-15  3:14         ` Andreas Schwab
1998-07-15 17:22           ` Carlo Wood
1998-07-17  4:10             ` Andreas Schwab
1998-07-15  3:14         ` Joern Rennecke

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).