[gambit-list] JavaScript backend

Bradley Lucier lucier at math.purdue.edu
Mon Jan 25 23:49:33 EST 2016


> On Jan 12, 2016, at 11:39 PM, Bradley Lucier <lucier at math.purdue.edu> wrote:
> 
> 
>> On Jan 12, 2016, at 11:11 PM, Marc Feeley <feeley at iro.umontreal.ca> wrote:
>> 
>> What is the transformation you have in mind?  It seems to me that for the optimization to operate at the basic block level, the construction of the vector and the indexing would have to be very close to each other, rather unlikely in complex code.
> 
> I think of transforming angle:apply-force in:
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> <omitted>

> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
> into
> 
> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
> 
> (define angle:apply-force
>  (lambda (angle)
>    (let* ((g287 (vector-ref angle 0))
>           (g288 (vector-ref g287 2))
>           (g289 (f64vector-ref g288 0))
>           (g290 (vector-ref g287 0))
>           (g291 (f64vector-ref g290 0))
>           (g292 (vector-ref angle 1))
>           (g293 (vector-ref g292 0))
>           (g294 (f64vector-ref g293 0))
>           (g295 (- g291 g294))
>           (g296 (vector-ref angle 2))
>           (g297 (vector-ref g296 0))
>           (g298 (f64vector-ref g297 0))
>           (g299 (- g298 g294))
>           (g300 (* g295 g299))
>           (g301 (f64vector-ref g290 1))
>           (g302 (f64vector-ref g293 1))
>           (g303 (- g301 g302))
>           (g304 (f64vector-ref g297 1))
>           (g305 (- g304 g302))
>           (g306 (* g303 g305))
>           (g307 (f64vector-ref g290 2))
>           (g308 (f64vector-ref g293 2))
>           (g309 (- g307 g308))
>           (g310 (f64vector-ref g297 2))
>           (g311 (- g310 g308))
>           (g312 (* g309 g311))
>           (g313 (+ g300 g306 g312))
>           (g314 (* g295 g295))
>           (g315 (* g303 g303))
>           (g316 (* g309 g309))
>           (g317 (+ g314 g315 g316))
>           (g318 (sqrt g317))
>           (g319 (* g299 g299))
>           (g320 (* g305 g305))
>           (g321 (* g311 g311))
>           (g322 (+ g319 g320 g321))
>           (g323 (sqrt g322))
>           (g324 (* g318 g323))
>           (g325 (/ g313 g324))
>           (g326 (vector-ref angle 4))
>           (g327 (min 1. g325))
>           (g328 (max -1. g327))
>           (g329 (acos g328))
>           (g330 (vector-ref angle 3))
>           (g331 (- g329 g330))
>           (g332 (* 2. g326 g331))
>           (g333 (sin g329))
>           (g334 (/ g332 g333))
>           (g335 (* g325 g334))
>           (g336 (/ g335 g317))
>           (g337 (* g336 g295))
>           (g338 (/ g334 g324))
>           (g339 (* g338 g299))
>           (g340 (- g337 g339))
>           (g341 (+ g289 g340))
>           (g342 (f64vector-set! g288 0 g341))
>           (g343 (f64vector-ref g288 1))
>           (g344 (* g336 g303))
>           (g345 (* g338 g305))
>           (g346 (- g344 g345))
>           (g347 (+ g343 g346))
>           (g348 (f64vector-set! g288 1 g347))
>           (g349 (f64vector-ref g288 2))
>           (g350 (* g336 g309))
>           (g351 (* g338 g311))
>           (g352 (- g350 g351))
>           (g353 (+ g349 g352))
>           (g354 (f64vector-set! g288 2 g353))
>           (g355 (vector-ref g292 2))
>           (g356 (f64vector-ref g355 0))
>           (g357 (- g356 g340))
>           (g358 (/ g335 g322))
>           (g359 (* g358 g299))
>           (g360 (* g338 g295))
>           (g361 (- g359 g360))
>           (g362 (- g357 g361))
>           (g363 (f64vector-set! g355 0 g362))
>           (g364 (f64vector-ref g355 1))
>           (g365 (- g364 g346))
>           (g366 (* g358 g305))
>           (g367 (* g338 g303))
>           (g368 (- g366 g367))
>           (g369 (- g365 g368))
>           (g370 (f64vector-set! g355 1 g369))
>           (g371 (f64vector-ref g355 2))
>           (g372 (- g371 g352))
>           (g373 (* g358 g311))
>           (g374 (* g338 g309))
>           (g375 (- g373 g374))
>           (g376 (- g372 g375))
>           (g377 (f64vector-set! g355 2 g376))
>           (g378 (vector-ref g296 2))
>           (g379 (f64vector-ref g378 0))
>           (g380 (+ g379 g361))
>           (g381 (f64vector-set! g378 0 g380))
>           (g382 (f64vector-ref g378 1))
>           (g383 (+ g382 g368))
>           (g384 (f64vector-set! g378 1 g383))
>           (g385 (f64vector-ref g378 2))
>           (g386 (+ g385 g375)))
>      (f64vector-set! g378 2 g386))))
> 
> ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
> 
> etc.  After inlining all the basic operations are close to one another.

Just for the record, here’s what you get from current gsc with the declarations

(declare (standard-bindings)
	 (extended-bindings)
	 (block)
	 (flonum)
	 (not safe)
	 (inlining-limit 10000))

including 12 unnecessary calls to ##f64vector, for a total allocation of 384 bytes (which probably takes longer than all the floating-point operations combined), plus untold numbers of unnecessary f64vector-refs to get arguments back out of those f64vectors.

And it’s all just one basic block.

Brad

(define angle:apply-force
  (lambda (angle)
    (let ((atom1 ('#<procedure #10 ##vector-ref> angle 0)))
      (let ((atom2 ('#<procedure #10 ##vector-ref> angle 1)))
        (let ((atom3 ('#<procedure #10 ##vector-ref> angle 2)))
          (let ((r1r2 (let ((v2 ('#<procedure #10 ##vector-ref> atom2 0))
                            (v1 ('#<procedure #10 ##vector-ref> atom1 0)))
                        (let ((x ('#<procedure #12 ##fl->
                                  ('#<procedure #7 ##f64vector-ref> v1 0)
                                  ('#<procedure #7 ##f64vector-ref> v2 0)))
                              (y ('#<procedure #12 ##fl->
                                  ('#<procedure #7 ##f64vector-ref> v1 1)
                                  ('#<procedure #7 ##f64vector-ref> v2 1)))
                              (z ('#<procedure #12 ##fl->
                                  ('#<procedure #7 ##f64vector-ref> v1 2)
                                  ('#<procedure #7 ##f64vector-ref> v2 2))))
                          ('#<procedure #6 ##f64vector> x y z)))))
            (let ((r3r2 (let ((v2 ('#<procedure #10 ##vector-ref> atom2 0))
                              (v1 ('#<procedure #10 ##vector-ref> atom3 0)))
                          (let ((x ('#<procedure #12 ##fl->
                                    ('#<procedure #7 ##f64vector-ref> v1 0)
                                    ('#<procedure #7 ##f64vector-ref> v2 0)))
                                (y ('#<procedure #12 ##fl->
                                    ('#<procedure #7 ##f64vector-ref> v1 1)
                                    ('#<procedure #7 ##f64vector-ref> v2 1)))
                                (z ('#<procedure #12 ##fl->
                                    ('#<procedure #7 ##f64vector-ref> v1 2)
                                    ('#<procedure #7 ##f64vector-ref> v2 2))))
                            ('#<procedure #6 ##f64vector> x y z)))))
              (let ((length-r1r2^2
                     ('#<procedure #11 ##fl+>
                      ('#<procedure #13 ##fl*>
                       ('#<procedure #7 ##f64vector-ref> r1r2 0)
                       ('#<procedure #7 ##f64vector-ref> r1r2 0))
                      ('#<procedure #13 ##fl*>
                       ('#<procedure #7 ##f64vector-ref> r1r2 1)
                       ('#<procedure #7 ##f64vector-ref> r1r2 1))
                      ('#<procedure #13 ##fl*>
                       ('#<procedure #7 ##f64vector-ref> r1r2 2)
                       ('#<procedure #7 ##f64vector-ref> r1r2 2)))))
                (let ((length-r3r2^2
                       ('#<procedure #11 ##fl+>
                        ('#<procedure #13 ##fl*>
                         ('#<procedure #7 ##f64vector-ref> r3r2 0)
                         ('#<procedure #7 ##f64vector-ref> r3r2 0))
                        ('#<procedure #13 ##fl*>
                         ('#<procedure #7 ##f64vector-ref> r3r2 1)
                         ('#<procedure #7 ##f64vector-ref> r3r2 1))
                        ('#<procedure #13 ##fl*>
                         ('#<procedure #7 ##f64vector-ref> r3r2 2)
                         ('#<procedure #7 ##f64vector-ref> r3r2 2)))))
                  (let ((length-r1r2
                         ('#<procedure #2 ##flsqrt> length-r1r2^2)))
                    (let ((length-r3r2
                           ('#<procedure #2 ##flsqrt> length-r3r2^2)))
                      (let ((cos-theta
                             ('#<procedure #14 ##fl/>
                              ('#<procedure #11 ##fl+>
                               ('#<procedure #13 ##fl*>
                                ('#<procedure #7 ##f64vector-ref> r1r2 0)
                                ('#<procedure #7 ##f64vector-ref> r3r2 0))
                               ('#<procedure #13 ##fl*>
                                ('#<procedure #7 ##f64vector-ref> r1r2 1)
                                ('#<procedure #7 ##f64vector-ref> r3r2 1))
                               ('#<procedure #13 ##fl*>
                                ('#<procedure #7 ##f64vector-ref> r1r2 2)
                                ('#<procedure #7 ##f64vector-ref> r3r2 2)))
                              ('#<procedure #13 ##fl*>
                               length-r1r2
                               length-r3r2))))
                        (let ((theta ('#<procedure #4 ##flacos>
                                      ('#<procedure #3 ##flmax>
                                       -1.
                                       ('#<procedure #5 ##flmin>
                                        1.
                                        cos-theta)))))
                          (let ((derivative-of-energy
                                 ('#<procedure #14 ##fl/>
                                  ('#<procedure #13 ##fl*>
                                   2.
                                   ('#<procedure #10 ##vector-ref> angle 4)
                                   ('#<procedure #12 ##fl->
                                    theta
                                    ('#<procedure #10 ##vector-ref> angle 3)))
                                  ('#<procedure #15 ##flsin> theta))))
                            (let ((F1 (let ((v2 (let ((a ('#<procedure #14 ##fl/>
                                                          derivative-of-energy
                                                          ('#<procedure #13 ##fl*>
                                                           length-r1r2
                                                           length-r3r2))))
                                                  (let ((z ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r3r2
                                                             2)))
                                                        (y ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r3r2
                                                             1)))
                                                        (x ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r3r2
                                                             0))))
                                                    ('#<procedure #6 ##f64vector>
                                                     x
                                                     y
                                                     z))))
                                            (v1 (let ((a ('#<procedure #14 ##fl/>
                                                          ('#<procedure #13 ##fl*>
                                                           cos-theta
                                                           derivative-of-energy)
                                                          length-r1r2^2)))
                                                  (let ((z ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r1r2
                                                             2)))
                                                        (y ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r1r2
                                                             1)))
                                                        (x ('#<procedure #13 ##fl*>
                                                            a
                                                            ('#<procedure #7 ##f64vector-ref>
                                                             r1r2
                                                             0))))
                                                    ('#<procedure #6 ##f64vector>
                                                     x
                                                     y
                                                     z)))))
                                        (let ((x ('#<procedure #12 ##fl->
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v1
                                                   0)
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v2
                                                   0)))
                                              (y ('#<procedure #12 ##fl->
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v1
                                                   1)
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v2
                                                   1)))
                                              (z ('#<procedure #12 ##fl->
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v1
                                                   2)
                                                  ('#<procedure #7 ##f64vector-ref>
                                                   v2
                                                   2))))
                                          ('#<procedure #6 ##f64vector>
                                           x
                                           y
                                           z)))))
                              (let ((F3 (let ((v2 (let ((a ('#<procedure #14 ##fl/>
                                                            derivative-of-energy
                                                            ('#<procedure #13 ##fl*>
                                                             length-r1r2
                                                             length-r3r2))))
                                                    (let ((z ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r1r2
                                                               2)))
                                                          (y ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r1r2
                                                               1)))
                                                          (x ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r1r2
                                                               0))))
                                                      ('#<procedure #6 ##f64vector>
                                                       x
                                                       y
                                                       z))))
                                              (v1 (let ((a ('#<procedure #14 ##fl/>
                                                            ('#<procedure #13 ##fl*>
                                                             cos-theta
                                                             derivative-of-energy)
                                                            length-r3r2^2)))
                                                    (let ((z ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r3r2
                                                               2)))
                                                          (y ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r3r2
                                                               1)))
                                                          (x ('#<procedure #13 ##fl*>
                                                              a
                                                              ('#<procedure #7 ##f64vector-ref>
                                                               r3r2
                                                               0))))
                                                      ('#<procedure #6 ##f64vector>
                                                       x
                                                       y
                                                       z)))))
                                          (let ((x ('#<procedure #12 ##fl->
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v1
                                                     0)
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v2
                                                     0)))
                                                (y ('#<procedure #12 ##fl->
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v1
                                                     1)
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v2
                                                     1)))
                                                (z ('#<procedure #12 ##fl->
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v1
                                                     2)
                                                    ('#<procedure #7 ##f64vector-ref>
                                                     v2
                                                     2))))
                                            ('#<procedure #6 ##f64vector>
                                             x
                                             y
                                             z)))))
                                (let ((begin-temp.3
                                       (let ((v2 (let ((v1 ('#<procedure #10 ##vector-ref>
                                                            atom1
                                                            2)))
                                                   (let ((z ('#<procedure #11 ##fl+>
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              v1
                                                              2)
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              F1
                                                              2)))
                                                         (y ('#<procedure #11 ##fl+>
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              v1
                                                              1)
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              F1
                                                              1)))
                                                         (x ('#<procedure #11 ##fl+>
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              v1
                                                              0)
                                                             ('#<procedure #7 ##f64vector-ref>
                                                              F1
                                                              0))))
                                                     ('#<procedure #6 ##f64vector>
                                                      x
                                                      y
                                                      z))))
                                             (v1 ('#<procedure #10 ##vector-ref>
                                                  atom1
                                                  2)))
                                         (let ((begin-temp.1
                                                (let ((a ('#<procedure #7 ##f64vector-ref>
                                                          v2
                                                          0)))
                                                  ('#<procedure #8 ##f64vector-set!>
                                                   v1
                                                   0
                                                   a))))
                                           (let ((begin-temp.0
                                                  (let ((a ('#<procedure #7 ##f64vector-ref>
                                                            v2
                                                            1)))
                                                    ('#<procedure #8 ##f64vector-set!>
                                                     v1
                                                     1
                                                     a))))
                                             (let ((a ('#<procedure #7 ##f64vector-ref>
                                                       v2
                                                       2)))
                                               ('#<procedure #8 ##f64vector-set!>
                                                v1
                                                2
                                                a)))))))
                                  (let ((begin-temp.2
                                         (let ((v2 (let ((v1 (let ((v1 ('#<procedure #10 ##vector-ref>
;;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
                                atom2
                                2)))
                       (let ((x ('#<procedure #12 ##fl->
                                 ('#<procedure #7 ##f64vector-ref> v1 0)
                                 ('#<procedure #7 ##f64vector-ref> F1 0)))
                             (y ('#<procedure #12 ##fl->
                                 ('#<procedure #7 ##f64vector-ref> v1 1)
                                 ('#<procedure #7 ##f64vector-ref> F1 1)))
                             (z ('#<procedure #12 ##fl->
                                 ('#<procedure #7 ##f64vector-ref> v1 2)
                                 ('#<procedure #7 ##f64vector-ref> F1 2))))
                         ('#<procedure #6 ##f64vector> x y z)))))
;;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                                                     (let ((z ('#<procedure #12 ##fl->
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                v1
                                                                2)
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                F3
                                                                2)))
                                                           (y ('#<procedure #12 ##fl->
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                v1
                                                                1)
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                F3
                                                                1)))
                                                           (x ('#<procedure #12 ##fl->
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                v1
                                                                0)
                                                               ('#<procedure #7 ##f64vector-ref>
                                                                F3
                                                                0))))
                                                       ('#<procedure #6 ##f64vector>
                                                        x
                                                        y
                                                        z))))
                                               (v1 ('#<procedure #10 ##vector-ref>
                                                    atom2
                                                    2)))
                                           (let ((begin-temp.1
                                                  (let ((a ('#<procedure #7 ##f64vector-ref>
                                                            v2
                                                            0)))
                                                    ('#<procedure #8 ##f64vector-set!>
                                                     v1
                                                     0
                                                     a))))
                                             (let ((begin-temp.0
                                                    (let ((a ('#<procedure #7 ##f64vector-ref>
                                                              v2
                                                              1)))
                                                      ('#<procedure #8 ##f64vector-set!>
                                                       v1
                                                       1
                                                       a))))
                                               (let ((a ('#<procedure #7 ##f64vector-ref>
                                                         v2
                                                         2)))
                                                 ('#<procedure #8 ##f64vector-set!>
                                                  v1
                                                  2
                                                  a)))))))
                                    (let ((v2 (let ((v1 ('#<procedure #10 ##vector-ref>
                                                         atom3
                                                         2)))
                                                (let ((z ('#<procedure #11 ##fl+>
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           v1
                                                           2)
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           F3
                                                           2)))
                                                      (y ('#<procedure #11 ##fl+>
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           v1
                                                           1)
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           F3
                                                           1)))
                                                      (x ('#<procedure #11 ##fl+>
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           v1
                                                           0)
                                                          ('#<procedure #7 ##f64vector-ref>
                                                           F3
                                                           0))))
                                                  ('#<procedure #6 ##f64vector>
                                                   x
                                                   y
                                                   z))))
                                          (v1 ('#<procedure #10 ##vector-ref>
                                               atom3
                                               2)))
                                      (let ((begin-temp.1
                                             (let ((a ('#<procedure #7 ##f64vector-ref>
                                                       v2
                                                       0)))
                                               ('#<procedure #8 ##f64vector-set!>
                                                v1
                                                0
                                                a))))
                                        (let ((begin-temp.0
                                               (let ((a ('#<procedure #7 ##f64vector-ref>
                                                         v2
                                                         1)))
                                                 ('#<procedure #8 ##f64vector-set!>
                                                  v1
                                                  1
                                                  a))))
                                          (let ((a ('#<procedure #7 ##f64vector-ref>
                                                    v2
                                                    2)))
                                            ('#<procedure #8 ##f64vector-set!>
                                             v1
                                             2
                                             a)))))))))))))))))))))))




More information about the Gambit-list mailing list