arguments in registers

chris at umcp-cs.UUCP chris at umcp-cs.UUCP
Sun Apr 27 13:41:39 AEST 1986


In article <155 at cbmvax.cbmvax.cbm.UUCP> grr at cbmvax.UUCP (George Robbins) writes:
>[Passing arguments in registers] would be fine if C had nested
>procedures or inlines or something, but a disaster otherwise.

In fact, a compiler is free to optimise any function into inline code,
so long as it provides a `regular' version of those that can be called
from external modules.  For example, given the following as a complete
C module, the compiler can eliminate the routine `local1' completely,
but not `local2' nor `global':

	static int
	local1()
	{
		static int count;

		return (++count);
	}

	static void
	local2()
	{
		void ext0(), ext1();

		switch (local1()) {
		case 0:
			ext0();
			break;

		case 1:
			ext1();
			break;
		}
	}

	void
	global(ppfv)
		void (**pfv)();
	{

		*pfv = local2;
	}

[Aside to Joe Yao:  Hello!  I just used `M' in vi again.]

Here the routine `local1' is not accessible outside this module,
so a compiler may elide it completely and replace the call in
`local2' with a direct reference to an unnamed static variable.
However, `local2' is externally accessible, since global() (which
is itself reachable) sets the supplied pointer to point at local2.
(A really clever compiler will discover unreachable local functions
and remove them, which may reveal more unreachable locals.)

One can also come up with examples wherein a good compiler might
provide a function externally yet also expand calls to it in line
within that module:

	int
	do_the_obvious(a, b)
		int a, b;
	{

		return (a > b ? a : b);
	}

	void
	something()
	{
		register int *p, *q;
		...
		otherproc(do_the_obvious(*p++, *q++));
		...
	}

There is no reason a compiler cannot pretend the call to
`do_the_obvious' was a built-in `max' function, and generate
something like this Vax code:

	_do_the_obvious: .globl _do_the_obvious
		.word	0		# only scratch regs used
		movq	4(ap),r0	# get a and b into r0 and r1
					# assume return a
		cmpl	r0,r1		# if a > b, skip this:
		bgtr	0f
		movl	r1,r0		# return b
	0:	ret

	_something: .globl _something
		...
		movl	(r11)+,r0	# get *p++
		movl	(r10)+,r1	# get *q++
		cmpl	r0,r1		# if the value from *p is greater
		bgtr	0f		# than that from *q, skip this:
		movl	r1,r0		# move the from-*q value to r0
	0:	pushl	r0		# result onto stack
		calls	$1,_otherproc	# go run otherproc
		...

Incidentally, I have not seen any optimising C compilers myself;
are there any available that would have done what I did above?
(Just curious.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris at umcp-cs		ARPA:	chris at mimsy.umd.edu



More information about the Comp.unix.wizards mailing list