[net.lang.c] Register functions ?

kpmartin@watmath.UUCP (Kevin Martin) (09/02/84)

>	As long as I'm twiddling the semantics of the language, I'd like to
>	propose "register" functions like these:
>
>		static register int func (arg, arg2) {...}
>		static register void func ....
>
>	The purpose of the "register" (even for void !) is to prevent the
>	programmer from taking the address of the function.
>			teltone!warren
I have had some thoughts about 'register' too. I see it as being a storage
class modifier which tells the compiler that the value will not be changed in
any 'sneaky' manner.
If you think about it, this is its current meaning.

For extern's, it becomes a promise that the named variable will not be changed
by any functions I call.
For functions it means it returns the same value if called with the
same args, and has no side effects.

One problem with this extension is that the compiler cannot enforce
your promises in the same manner as it prevents sneak access to auto
register variables (by preventing you from &'ing them).
The other problem is due to interpreting 'register' as part of the
storage class... What if I want a pointer to a "register function"?
There is no syntax that fits... The only possible syntax is already used up
by "register pointer" to "regular function"...

                               Kevin Martin, UofW Software Development Group

jejones@ea.UUCP (09/05/84)

#R:watmath:-883600:ea:5700014:000:114
ea!jejones    Sep  5 13:38:00 1984

Well put. I have often wondered why one couldn't declare externals to
be register variables...

						James Jones

tim@callan.UUCP (09/06/84)

To all of us who used to use PDP-10s, it is clear that

	register foo() {

should mean that foo is a small function that should move itself
into the registers for speed! ( on the 10, the registers were
mapped into the lower 16 words of your address space.  Thus,
it was both reasonable to take the address of a register variable,
and it was reasonable to put code in the registers, because it
would run faster there.)
-- 
					Tim Smith
			ihnp4!wlbr!callan!tim or ihnp4!cithep!tim

haapanen@watdcsu.UUCP (Tom Haapanen [DCS]) (09/13/84)

Now, on a 68020,

register foo() { ...

makes a lot of sense.  The 68020 has a 64-longword on-chip instruction
cache, and this instruction could be used to force a small function
into the cache *and keeping it there*.  I am not certain of the exact
cache locking mechanism used (but I know there is one!), since a
friend just borrowed my MC68020 manual...  

Naturally you couldn't do that to large functions, but it could make
small ones execute like a bat out of h*ll!  (especiall with the 68020
having clock speeds of up to 16.67 MHz...)

Tom Haapanen
{allegra,clyde,decvax,ihnp4,utzoo}!watmath!watdcsu!haapanen

G.EGK@SU-SCORE.ARPA (09/15/84)

From:  Edjik <G.EGK@SU-SCORE.ARPA>

RE: PDP-10s and registers

Running code in the registers was faster on the PDP-6 and KA.  These
processors are quite obsolete.  On the successors to the KA, namely the
KI and KL-10, it is a lot SLOWER to run code in the registers and should
be avoided.

--Edjik
-------

rcd@opus.UUCP (Dick Dunn) (09/18/84)

>As long as we're proposing strange constructs, how about unnamed variables?
>For example, at the top level:
>
>	char[] = "This is a string";

That's hardly strange.  Actually, the form of a type name without any
associated list of variables occurs in other languages (and I believe in
the emerging C standard) in a formal parameter list.  I've also seen it
used for alignment information in a structure--a structure field which is
given a type but no name occupies the amount of storage required for the
type but is otherwise inaccessible--e.g., in C-ish syntax you might have:
	struct {
		short bletch;
		int garg:3;
		int :2;		/* unused and inaccessible space */
		int blip:3;
	}
-- 
Dick Dunn	{hao,ucbvax,allegra}!nbires!rcd		(303)444-5710 x3086
   ...Never offend with style when you can offend with substance.

gwyn@BRL-VLD.ARPA (09/18/84)

From:      Doug Gwyn (VLD/VMB) <gwyn@BRL-VLD.ARPA>

Actually, the most likely candidates for small register functions
would be things like csav and cret, in which case the system could
give ALL C functions improved performance rather than just the one
or two that a user would specify.

warren@tikal.UUCP (warren) (09/21/84)

	As the recent originator of the topic of "Register Functions",
	I would like to mention that executing code in registers was not
	what I meant.  I am not opposed to it, I just meant something else.

	Let me cast the idea in clearer form:

	C would benefit from a new storage class, I hereby dub "private".
	Private storage items, whether const or variable, would be not
	exportable.  It would be impermissable to take the address, declare
	as external, or otherwise export a private item.  One clear win
	is the "private function", which in this case means VERY STATIC.

	The privacy of an item means the optimizer in the compiler can take
	further liberties, for example, generating whatever form of function
	call it deems useful, short calls, inline functions (lets say an
	ordinary (outline ?) function is called exactly once -- which happens),
	and so forth.   The "private" declaration is intended to get around
	the "aliasing" problem in C, where two expressions (say, "x" and
	"*y") cannot be assumed to point at different objects (they could
	both point to the same place).   If x is declared "private", then
	y must point somewhere else.

	Note that the compiler is free to treat the "private" declaration as
	a comment, merely declining to optimize.

	Private variables could not be modified by a call to an external function,
	because its address could not be passed, even passing a pointer to a
	pointer to it (the private variable) would not happen, because its 
	address is "secret".  This means that if its value was in a register
	that is protected by function calls then its also valid there afterwards.
	Whereas today, a called function could have received the address of a
	static variable on a previous call, kept it, and then, as a "side
	effect",  modified it on the latest call.  The value in the register
	is then corrupted.

	------------------------------------------------------------------------

	Related but different topic -- varargs.

	A major advantage of making a varargs scheme part of the LANGUAGE
	is that the compiler could KNOW that other functions were not
	varargs, and could generate tighter code.  If you declare it
	wrong (e.g. "extern printf" instead of "extern varargs printf" then
	its your funeral, which is true already.  Note also that the compiler
	is free to treat the "varargs" declaration as yet another comment,
	perhaps by building into the preprocesor "#define varargs <newline>",
	and so forth.

	On architectures where no such scheme is possible, most systems 
	written in C would simply fail anyway.  On any architecture, the
	implementation of varargs must be taken into account by the
	compiler writers, in order generate function calls.  It seems
	only fair to the compiler writers to give them full control of
	varargs, relieving them of the burden of writing a compiler that
	has to be compatible with a varargs package written by somebody else,
	someplace else, in the future !  If varargs can't be implemented by
	the compiler writer, chances are nobody else can either...

	On systems where only a half-hearted varargs can be built, and where
	the coder of printf, say, has to explicitly hack in argument counting
	or something, the compiler writers can still sneak in an extra
	argument (argc) to help the coder (but only if users declare it
	as varargs - which they can suppress with a #define - even if
	its a reserved word).  Making varargs part of the language costs
	us little, and offers clear benefits.  

				teltone!warren

jab@uokvax.UUCP (09/24/84)

/***** uokvax:net.lang.c / tikal!warren /  8:33 pm  Sep 21, 1984 */

	C would benefit from a new storage class, I hereby dub "private".
	Private storage items, whether const or variable, would be not
	exportable.  The "private" declaration is intended to get around
	the "aliasing" problem in C, where two expressions (say, "x" and
	"*y") cannot be assumed to point at different objects (they could
	both point to the same place).   If x is declared "private", then
	y must point somewhere else.

/* ---------- */

"must point somewhere else"?

The idea of a "PRIVATE/LOCAL" variable is nifty, and gets rid of
many "aliasing" problems, I'm sure. In a language such as "C", in
which a pointer can contain ANY valid address (where "valid" refers
to "hardware address space" and not "external variable") you
won't get what you really want.

I suspect that the way to get that might be to change a pointer to be type-
specific, and for locations to contain "datum" and "type information on that
datum", with checks performed by the hardware. Anyone want to venture to guess
what the overhead would be?

	Jeff Bowles
	Lisle, IL

guy@rlgvax.UUCP (Guy Harris) (09/25/84)

> Now, on a 68020,
> 
> register foo() { ...
> 
> makes a lot of sense.  The 68020 has a 64-longword on-chip instruction
> cache, and this instruction could be used to force a small function
> into the cache *and keeping it there*.  I am not certain of the exact
> cache locking mechanism used (but I know there is one!), since a
> friend just borrowed my MC68020 manual...  

Acccording to Section 7, "On-Chip Cache Memory", of the 68020 manual,
you can turn on the "freeze cache" bit in the Cache Control Register
with the MOVEC (Move Control) instruction; however, only system code
can do that on a system which has supervisor and user states because
the instruction is privileged.  They say that "This bit (the Freeze
Cache bit) can be used by emulators to freeze the cache during
emulation function execution"; I think they are referring to code that
handles the "line F" coprocessor instructions in software.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

stew@harvard.ARPA (Stew Rubenstein) (09/30/84)

> 	C would benefit from a new storage class, I hereby dub "private".
> 	Private storage items, whether const or variable, would be not
> 	exportable.  It would be impermissable to take the address, declare
> 	as external, or otherwise export a private item.  One clear win
> 	is the "private function", which in this case means VERY STATIC.
> 
> 				teltone!warren

Why can't the compiler figure this out for itself?  Any local variable
of which the address is never taken can be optimized in all the ways which
were suggested, no?
-- 
-----------------------
Stew Rubenstein     UUCP: ihnp4!harvard!stew
Harvard Chemistry   ARPA: stew@harvard

guy@rlgvax.UUCP (Guy Harris) (10/05/84)

> The idea of a "PRIVATE/LOCAL" variable is nifty, and gets rid of
> many "aliasing" problems, I'm sure. In a language such as "C", in
> which a pointer can contain ANY valid address (where "valid" refers
> to "hardware address space" and not "external variable") you
> won't get what you really want.

"private", in this case, would be a committment by the programmer not to
take the address of that variable.  It wouldn't be enforcable, but I
don't see that as a disadvantage, any more than I would see the fact that
just because a variable is not declared "volatile" (in the proposed ANSI
standard, it means "this variable can be asynchronously modified by
something other than this process", thus disabling some optimizations)
doesn't guarantee that it's not going to be changed by another process or
a device.

Yes, you could have a pointer pointing to a "private" variable; however,
if the program does so, either it was not written to do so, in which case
it has a bug, or it was written to do so, in which case if it doesn't have
a bug there'd better be a very good reason why it isn't a bug.

The fact that C is an "unsafe" language shouldn't prevent optimizing
compilers being written for it.  It merely means that just because a
program passes the compiler doesn't mean it's a valid program - but that's
been the tradition anyway, considering

	foo(s)
	char *s;
	{
		...
	}

	bar()
	{
		foo(73);
	}

is an invalid program, but lots and lots of compilers out there won't
complain.  Just because "lint" can catch this one, but not the case of
a variable mis-declared "private" or a volatile variable not so declared,
doesn't render those language enhancements useless.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy