[gambit-list] Guile's new compiler

Marc Feeley feeley at iro.umontreal.ca
Fri Nov 6 11:54:48 EST 2015


One issue with your example is that ##string-length (and many other ## primitives) were not being constant folded.  That is now fixed.

Another issue is that for the (let loop ((i 0)) …) there is no loop peeling occurring.  Note that the let loop expands to a (letrec ((loop (lambda (i) …))) (loop 0)) .  I noticed that the beta-reducer was not constant propagating the value of i in (let ((i 0)) …) after the first inlining of the function.  So I added a beta-reduction of the let.

But there is another issue…  The inliner will limit the expansion of the code to some factor of the size of the call site.  Here the call site which starts the loop is (loop 0), a tiny call of size 3 (the size is the number of parse-tree nodes).  Increasing the inlining-limit at the top of the file does not help because the body of the loop function is expanded before the call site is considered for inlining, so the body of the loop function is bigger and doesn’t get inlined.  So a workaround is to rewrite the loop so that it is a separate function, and then attach a high inlining limit to the call.  An alternative is to have a high inlining limit for the (let loop …) and a low inlining limit for the loop body.  For example:

(declare (standard-bindings) (fixnum) (not safe))

(let ((s "yo"))
  (define char-at
    (lambda (n) (string-ref s n)))
  (define len
    (lambda () (string-length s)))
  (declare (inlining-limit 2000))
  (let loop ((i 0))
    (declare (inlining-limit 100))
    (if (< i (len))
        (cons (char-at i)
              (loop (+ 1 i)))
        '())))

With that source code, gsc now expands it to:

('#<procedure #2 ##cons> #\y ('#<procedure #2 ##cons> #\o '()))

Which can’t be improved without violating eq?-ness of the resulting list.

It isn’t clear how to fix this to avoid the need for the programmer to change the inlining limit.  The simple approach of not beta-reducing the body of the function before it is inlined doesn’t work well when the body is actually made smaller by the beta-reduction.

Marc


> On Nov 6, 2015, at 1:44 AM, Bradley Lucier <lucier at math.purdue.edu> wrote:
> 
> Re your previous message:
> 
>> As far as I can tell, all of those optimizations are currently done by the Gambit compiler except for loop-invariant code motion and loop inversion.  I’m not sure how much those optimizations are useful however.
> 
> doesn’t loop inversion strip off the first few iterations of the loop with known values (i.e., start with i=0 in loop, compare it with ('#<procedure #8 ##string-length> "yo”), see that it truly is <, do the cons whose first argument is ('#<procedure #9 ##string-ref> "yo" 0), etc.) before defining a general loop body for later use?  (Am I being at all clear?)
> 
> Brad




More information about the Gambit-list mailing list