From mboxrd@z Thu Jan 1 00:00:00 1970 From: Bill Currie To: Matthias Urlichs Cc: law@cygnus.com, Andreas Schwab , Horst von Brand , egcs@cygnus.com Subject: Re: Incrementing volatiles? Date: Wed, 15 Jul 1998 21:58:00 -0000 Message-id: <35AD55CF.2629@tssc.co.nz> References: <21583.900542629@hurl.cygnus.com> <35AD374A.7E72@tssc.co.nz> <19980716023528.D6101@noris.de> X-SW-Source: 1998-07/msg00549.html 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