[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