Hi Marc,
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@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 --enable-auto-forcing.
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 above right?
[..]
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 correct, right?]
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!