volatile

Chris Torek chris at mimsy.UUCP
Thu May 19 19:03:37 AEST 1988


In article <659 at garth.UUCP> smryan at garth.UUCP (Steven Ryan) writes:
>A compiler cannot crossreference all modules to detect "volatile":
>    - this is enormously expensive.
>    - it requires access to internals of other modules including 
>      possible binary-only copyrighted libraries, et cetera.
>    - it still won't work.

I grant your second point, but claim that `binary-only' is a red
herring.  There is no reason the `binary' library cannot be a binary
that includes volatility and aliasing information.  As to your first
point, interactive displays---particularly windows on a graphical
bitmapped screen---are also `enormously expensive'.  What is slow
now is fast tomorrow, and though it be slow, we have decided that
it is worth it.

The third point is the key issue.  As with automatic alias detection,
there are some situations in which volatility may be undecidable.
Consider, for instance,

	char *ptr; /* volatile? */
	...
	if (cond) remap_memory(ptr, sharedspace)

If `cond' reduces to the halting problem, the compiler cannot tell
whether a region described by `ptr' is remapped into a shared space.

As with `noalias', the solution is that the compiler be conservative.
Undecidable cases are (I claim) not only extremely rare, but also
bad programming practise.

`volatile' and `noalias' are very similar in this respect.  Both can
be determined automatically in most cases in which they would in
fact make any difference.  Both are relatively expensive to compute.
I claim that both can and should be computed whenever it is feasible.

Given their existence in some language, it is not critical that the
result of the computation always be correct, but it is helpful for
the compiler[*] to diagnose missing or incorrect `volatile' and `noalias'
declarations.  Given their absence in the same language, it is then
essential that the result of the computation be correct or (if `too
hard') conservative.  [*or a diagnostic tool a la `lint']

The critical difference between `volatile' and `noalias' in C is
that an incorrect `volatile' appelation merely inhibits some optimisation,
while an inappropriate `noalias' causes improper operation.  This
is why I do not object to a keyword for `volatile', but do object
to one for `noalias'.  Neither is necessary, but only the latter
can cause grievous harm.

>For example, in CDC NOS, the CIO PP can modify fet fields and the buffer
>while the user program is running in the same address space. IAF can set
>an interrupt flag. RPV can be used to call an arbritrary routine during a
>fault or interrupt.

So?  For any of these to occur, the CIO PP must be told where the
objects reside.  The telling points out the volatility.  It takes a
great deal of cleverness, but a truly smart flow analysis routine will
note that

	dmac->dma_addr = buf;
	dmac->dma_wc = count;
	dmac->dma_csr = DMA_RD | DMA_GO;

causes `count' words at the location given by `buf' to become uncertain
until the interrupt occurs.  It would be nice if, even though someone
forgot to say so, the compiler would complain about the following line:

	if (buf[2 * count - 1] == '\n')

since it may be (and probably is) an error to check the location
after the DMA channel has been started.  Perhaps the programmer
knows that the DMA device cannot have overwritten this location
by the time the test is performed.  More likely it is an error.

>In summary, do not expect an optimiser to magically guess all relations of
>a program. It has worse time understanding a program than the authour ...

I will grant this point if and only if you will grant that sometimes
the compiler is better at finding the relationships in a program[*],
and that with more work, the compiler will improve.  [*If you
disbelieve, take a look at the output from some good compilers.  Even a
weak optimiser like 4BSD /lib/c2 has noticed things I have not.  I once
spent a number of minutes puzzling over a `bug' where c2 had replaced a
constant with a register name, only to realise that all code paths
leading to that instruction happened to leave that value in that
register.]

There are pragmatic reasons not to find all cases of volatility (it may
take too long on a given machine), but it can be done.  When it can be
done, it should be done.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris at mimsy.umd.edu	Path:	uunet!mimsy!chris



More information about the Comp.lang.c mailing list