Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 22 May 1995 23:30:54 +1000
From:      Bruce Evans <bde@zeta.org.au>
To:        davidg@freefall.cdrom.com, ylo@cs.hut.fi
Cc:        freebsd-bugs@freefall.cdrom.com
Subject:   Re: Changed information for PR i386/395
Message-ID:  <199505221330.XAA07692@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>> Bruce says that gcc's behavior for inlined functions isn't any
>> different than it is for real functions WRT caching of variables
>> or intermediates...and an analysis of the generated code seems
>> to confirm this. It appears to be a non-problem with the current
>> gcc.

>Well, code like

>   ... some code using variable/expression foo ...
>   x = spl*();
>   ... more code using variable/expression foo ...

>does not recompute foo if spl* is an inline function, and does recompute
>it if it is not (because then the function might have unknown
>side-effects changing foo).

>While I am not sure if spl functions are really used in a way that
>this would cause problems, I think it would be much safer to eliminate

I added __asm __volatile("" : : : "memory") to spl*.  This is supposed
to say that spl* clobber memory, so that all variable/expressions
involving memory get re-evaluated.  I examined all the resulting code
changes for my kernel (but not for the LINT kernel).  There were no
significant changes.

It's not hard to explain why there is no problem.  For there to be a
problem:

1) the variable/expression foo must be incorrectly declared as non-volatile.
This error (?) is very common, but it may not actually be an error, because
if variables are only examined and changed inside appropriate spl's, then
they are sort of nonvolatile.

2) the variable/expression foo must be evaluated before the spl*.  This
should almost never be done.  Code such as (if buf->count == 0) goto done
might be safe if it is known that buf->count >= 0 and that interrupt
handlers only decrease it and that it is loaded atomically, but in general
you can't base decisions based on the values of volatile variables.

A minor change to your example shows a possible problem:

   ... some code using variable/expression foo ...
   splx(x);
   ... more code using variable/expression foo ...

Here it would be reasonable to access foo before the spl.  There is currently
no problem because splx() sometimes calls splz() and gcc doesn't optimize
for the case it isn't called:

	cpl = ipl;
	if (ipending & ~ipl)
		splz();
	/*
	 * gcc always reloads everything here.  There would be a problem i
	 * it generated:
	 *	{ splz(); reload_everything(); }
	 *	} else { dont_reload_anything(); }
	 */

This could be fixed by putting the memory-clobber asm after the if statement.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199505221330.XAA07692>