[gambit-list] inlining eqv? etc.

Christian christian at pflanze.mine.nu
Thu Oct 12 09:48:41 EDT 2006


At 0:08 Uhr -0400 10.10.2006, Bradley Lucier wrote:
>Perhaps one can use a similar strategy for inlining equal?

I'm sometimes defining functions like |equal?| or |force| myself in 
some module (or more precisely: in some compilation block (I'm almost 
always using the block compilation declaration)), which is kind like 
inlining -- the compiler may actually inline it in some cases; but at 
least it's cheaper to call when inside the same block than across 
block/module/sharedobject (not sure which word I should choose to 
name it accurately) boundaries.

I'm wondering: in which step of the compilation phase are inlinings 
of the kind that you are suggesting done? Is it in the code 
generation step? So will it inline the code *always*, even multiple 
times in the same compilation block, and not be subject to the 
inlining-limit declaration? If so, wouldn't it be better to change 
that to actually create a function, but in the same block, and let 
the function inliner decide how to handle that? In my measurements, a 
real function call in the same block is only about 30-40 cycles or 
so, whereas a function call across block boundaries is about 200 
cycles (or was it 240?). Probably for something like |equal?| it's 
good enough to reduce the overhead from ~200 cycles down to 30-40. 
This should help reduce the code bloat.

Handling "optional inlining" is something I plan to do in chjmodule 
(I'm continuing to work on it currently), so that one can export 
functions from some module A as "inlinable", which means that they 
will be copied verbatim (but within the original namespace, by 
putting a ##namespace declaration around/into it) into caller 
modules, so e.g. module B importing module A will contain such a copy 
in it's toplevel. That doesn't necessarily mean that it is being 
inlined into every call site inside B: it's open to the normal Gambit 
inliner. At the very least the costs drop from ~200 to 30-40 cycles.

Using such module techniques, instead of hard coding functions like 
|equal?| into Gambit, they could be defined in a standard module like 
"R5RS" with an inlinable export flag and be imported from there.

(BTW one could also split |equal?| like that:

(define (equal? a b)
    (or (eq? a b)
        (real-equal? a b)))
(define (real-equal? a b)
    ..recursive definition))

and so make it possible that the first part, which doesn't generate 
much code bloat, can be inlined whereas the rest still isn't.

Christian.



More information about the Gambit-list mailing list