[gambit-list] Re --enable-auto-forcing: Scope, how/where implemented, how build (with) it properly?
adam.mlmb at gmail.com
Mon Sep 18 15:07:15 EDT 2017
Thank you very much for clarifying.
Three brief followup questions at the bottom (marked 1. 2. 3.).
2017-09-18 23:55 GMT+08:00 Marc Feeley <feeley at iro.umontreal.ca>:
> > Also.. if I understand you right, there are cases when Gambit with
> auto-forcing enabled also would fail evaluating (abs (delay 0)) .
> With --enable-auto-forcing, this case works only when abs is not inlined,
> in other words an actual function call to abs is performed (because the
> library definition correctly forces the argument). This can be achieved in
> various ways, like (declare (not run-time-bindings abs)) or (declare
> (standard-bindings) (not inline-primitives abs)).
> This needs to be fixed so that those declarations, which typically improve
> execution speed, can be used reliably in a system built with
Ahaa, so that is a limit that exists currently for --enable-auto-forcing .
Thanks for pointing out!
> Also, when using the default (declare (safe)) the compiler converts (car
> lst) into
> (if (##pair? lst) (##car lst) (car lst))
> rather than the correct
> (let ((lst (##force lst)))
> (if (##pair? lst) (##car lst) (car lst)))
This was just another iteration of what you said already in the section
> > > Would it be possible for me to disable this particular aspect of the
> auto-forcing, to get higher performance?
> > Currently auto-forcing only works in interpreted code. So if your
> program does (f x) and (car y) and you compile that, then “f” will not be
> forced and “y” will not be forced if car is inlined, for example if you
> (declare (not safe)). You can consider this a bug… to be fixed.
> Actually this is not quite true… f will be forced in the call (f x)
[also in compiled mode - 3. I interpret you to mean that here, that is
thanks to this definition in lib/_kernel.scm:
> (define-prim (##apply-with-procedure-check oper args)
> (##declare (not interrupts-enabled))
> (macro-force-vars (oper)
> (if (##procedure? oper)
> (##apply oper args)
> (##raise-nonprocedure-operator-exception oper args #f #f))))
Wait, what does |##apply-with-procedure-check| actually do, in what
situations is it invoked, is this run on all (f a1 a2 ...) with oper = f
and args = (list a1 a2 ...) for any procedure call made anywhere, when
compiling with (declare (safe))?
1. So if I just remove the |macro-force-vars| in there, |f| will not be
forced in compiled mode?
2. Just if it is possible, is there some easy way to make also |f| *not* be
forced in compiled mode?
Not forcing |f| ever, would be useful in situations where you use the
auto-forcing only to force data structures but never any code.
I hypothesize that this will provide significant speed increases.
Will test and benchmark following your next clarification.
Thanks a lot!
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Gambit-list