help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: inline function expansion


From: Stefan Monnier
Subject: Re: inline function expansion
Date: Sun, 28 May 2023 22:59:05 -0400
User-agent: Gnus/5.13 (Gnus v5.13)

>> I think `define-inline` is definitely not a good starting point for
>> the above.
>
> If you mean literally the current implementation of define-inline, I'd
> agree, except for the trick of defining both a compile-time (macro)
> and a residual function.

I see.  I'm maybe too close to `define-inline`s design to see the larger
picture (FWIW, the driving design is to take a compiler-macro and use
it to generate the body of the function it is meant to optimize,
because it puts the user of `define-inline` in charge of making it
work, whereas the usual design is to start with the *function*'s body
and automatically infer how to inline it, but that requires figuring
out what should be inlined, avoiding name captures, etc..).

>>  OTOH you might be able to layer your `define-inlined-method`
>> on top of the current `cl-generic.el`.  AFAICT the main thing you need is
>> some way to write a "call with enough «type» annotations" such that the
>> dispatch can be performed at compile time.
> I think that's the main point of designating parameters as "opaque",
> so they aren't really specialized against, and only the non-opaque
> parameters need to be wrapped in a form like (integer-ordering lt).
> I'm still not certain that's enough to avoid needing a full-fledged
> partial-evaluator embedded in the macroexpansion phase.

Indeed, the difficulty I see is how to propagate info for cascading
inlines (when inlining one call exposes info that (should) make another
call inlinable).  In most compilers, this is just "normal business" done
by combining inlining with constant propagation, constant folding,
etc.. (which you can call "partial evaluation").  But if you want to do
it as part of macroexpansion, then you can't rely on the compiler's
constant propagation, and constant folding.

>> > Although I would change "inline-const-p" to test for function purity
>> > (exclude stateful closures or otherwise impure functions).
>>
>> I think that would be a mistake.  "const-p" doesn't mean that the return
>> value is pure but that the expression itself always returns the same value.
>
> I think you mean the argument value, not the return value?

No, I mean that `inline-const-p` tells us something about the EXP it receives,
and this something is not that this EXP's return value is pure, but that
this EXP always returns the same value.  It's arguably a misnomer, what
it really means is "do we already know what EXP will return?".

This is evidenced by the fact that when we generate the function,
the `inline-const-p` call is just replaced by t (because once we get to
the function, EXP has already been evaluated so of course we know the
value).

> But that's exactly what I mean - a pure function is immutable, and
> other functions change with state, so that in the extensional sense
> they are not equal even if they are eq.
>
> For the purpose of partial evaluation, which I believe is the point of
> inline-const-p, an expression `expr' is constant if
> (equal (eval expr state0) (eval expr state1))

I agree.  And indeed if `exp` is an expression which always returns
`insert` or `buffer-substring`, then

    (equal (eval expr state0) (eval expr state1))

is true, even though `insert/buffer-substring` are definitely not
pure functions.

> Clearly exprs that are syntactic literals are constants by this
> definition.  Also, if `f' is a pure function, then (f C1 C2 .. Cn) for
> constant expressions C1,..Cn is also a constant expression.

Indeed, tho currently `inline-const-p` doesn't take advantage of that.


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]