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