making an optimizing compiler
the obvious
- less code
- to process
- to run
- to debug
the honest
- gee, vectors cause a lot of my bugs
- wow, functions cause a lot of my bugs
motivation
optimization pass overview
inline functions
reveal functions
minimize vectors
propagate let-bindings
simplify
convert to closures
repeat?
until
- effort limit reached
- ast and defs have not changed
inline functions
simple functions
complex functions
(define (sum3 [x_1 : Integer]
[y_2 : Integer]
[z_3 : Integer]) : Integer
(+ x_1 (+ y_2 z_3)))
(define (zero? [x_4 : Integer]) : Boolean
(eq? x_4 0))
(define (foo [x_5 : Integer]) : Integer
(if (zero? x_5)
42
(sum3 x_5 x_5 x_5)))(define (mult [x_1 : Integer]
[y_2 : Integer]) : Integer
(if (zero? x_1)
0
(+ y_2 (mult (sub1 x_1) y_2))))
(define (sq [x_3 : Integer]) : Integer
(mult x_3 x_3))
inline functions
(define (foo [x_5 : Integer]) : Integer
(if (zero? x_5) 42 (sum3 x_5 x_5 x_5)))by generating lets
(define (foo [x_5 : Integer]) : Integer
(if
(let ([x_4 x_5]) (eq? x_4 0))
42
(let ([x_1 x_5])
(let ([y_2 x_5])
(let ([z_3 x_5])
(+ x_1 (+ y_2 z_3)))))))minimize vectors
simple elements
(vector 40 (vector 42) 2 (mult 6 7))complex elements
minimize vectors
vector-set! can make simple elements complex
(let ([v_1 (vector (vector 42) 2)])
(let ([_2 (vector-set! v_1 1 (sq 3))])
(let ([_3 (vector-set! v_1 0 42)])
v_1)))with a caveat...
and make complex elements simple
... from anywhere in the program
by replacing simple vector-refs
(let ([v_1 (vector (mult 6 7) 2)])
(+ 40 2))minimize vectors
(let ([v_1 (vector (mult 6 7) 2)])
(let ([_3 (vector-set! v_1 0 40)])
(+ (vector-ref v_1 0) (vector-ref v_1 1))))(+ 40 2)on subsequent runs
complex lets should not be propagated
(let ([v_0 (vector 42)])
(let ([a_1 (mult 2 1)])
(let ([x_2 40])
(let ([y_3 (read)])
(let ([z_4 (+ 1 0)])
(mult (+ x_2 a_1) z_4))))))with a caveat...
propagate let-bindings
(let ([a_1 (mult 2 1)])
(let ([y_3 (read)])
(mult (+ 40 a_1) (+ 1 0))))but can still be removed if never referenced and no side effects
simplify

...is the best pass
(not #f)negations
simplify
#t(not (not (eq? (read) 0)))(eq? (read) 0)(- (- (read)))(read)(- 6)-6and
simplify
(and #f (eq? (read) (mult 6 7)))#f(and #t #t)#t(+ 40 2)operations
simplify
42(>= 4 5)#f(eq? 0 0)#tif statements
simplify
(if #f (read) (mult 6 7))(mult 6 7)(if #t 42 777)4242recursively
(if (and (eq? (+ 2 3) (- (+ 2 (- 3)))) (> (mult (read) 7) 42))
(let ([v_1 (vector (mult 6 7))])
(vector-ref v_1 0))
(if (not (not (<= 2 (+ 20 20))))
(+ 11 (- (- (+ 21 10))))
(- (- (read)))))simplify
all together now
results
questions?
More info about the compiler and language referenced can be found here:
https://homes.soic.indiana.edu/classes/fall2017/csci/p523-rrnewton/book.pdf
making an optimizing compiler
By Trevan Haskell
making an optimizing compiler
A short presentation on optimizing racket code during compilation. Based on this book: https://homes.soic.indiana.edu/classes/fall2017/csci/p523-rrnewton/book.pdf
- 1,902