|
10 | 10 | (class compile-reg-R0 |
11 | 11 | (super-new) |
12 | 12 |
|
| 13 | + (inherit liveness-ss first-offset variable-size on-stack?) |
| 14 | + |
13 | 15 | (define/override (primitives) |
14 | 16 | (set-union (super primitives) |
15 | 17 | (set 'eq? 'and 'or 'not))) |
|
54 | 56 | (unless (equal? T1 T2) |
55 | 57 | (error "checking equality between different-typed values")) |
56 | 58 | (values `(has-type (eq? ,e1^ ,e2^) Boolean) 'Boolean)] |
57 | | - [`(,op ,es ...) #:when (set-member? (send this primitives) op) |
| 59 | + [`(,op ,es ...) #:when (set-member? (primitives) op) |
58 | 60 | (define-values (new-es ts) |
59 | 61 | (for/lists (exprs types) ([e es]) ((type-check env) e))) |
60 | 62 | (define binary-ops |
|
93 | 95 | [`(has-type ,e ,t) `(has-type ,((uniquify env) e) ,t)] |
94 | 96 | [(? boolean? b) b] |
95 | 97 | [`(if ,cnd ,thn ,els) |
96 | | - (let ([cnd ((send this uniquify env) cnd)] |
97 | | - [thn ((send this uniquify env) thn)] |
98 | | - [els ((send this uniquify env) els)]) |
| 98 | + (let ([cnd ((uniquify env) cnd)] |
| 99 | + [thn ((uniquify env) thn)] |
| 100 | + [els ((uniquify env) els)]) |
99 | 101 | `(if ,cnd ,thn ,els))] |
100 | 102 | [`(program (type ,ty) ,e) |
101 | | - `(program (type ,ty) ,((send this uniquify env) e))] |
| 103 | + `(program (type ,ty) ,((uniquify env) e))] |
102 | 104 | [else ((super uniquify env) e)]))) |
103 | 105 |
|
104 | 106 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
108 | 110 | (lambda (ast) |
109 | 111 | (match ast |
110 | 112 | [`(if ,cnd ,thn ,els) |
111 | | - (append (append* (map (send this collect-locals) thn)) |
112 | | - (append* (map (send this collect-locals) els)))] |
| 113 | + (append (append* (map (collect-locals) thn)) |
| 114 | + (append* (map (collect-locals) els)))] |
113 | 115 | [else ((super collect-locals) ast)]))) |
114 | 116 |
|
115 | 117 | (define optimize-if #t) |
|
125 | 127 | [#f #:when optimize-if |
126 | 128 | (values new-els els-ss)] |
127 | 129 | [`(let ([,x ,e]) ,body) #:when optimize-if |
128 | | - (define-values (new-e e-ss) ((send this flatten #f) e)) |
| 130 | + (define-values (new-e e-ss) ((flatten #f) e)) |
129 | 131 | (define-values (new-body body-ss) |
130 | | - ((send this flatten-if new-thn thn-ss new-els els-ss) body)) |
| 132 | + ((flatten-if new-thn thn-ss new-els els-ss) body)) |
131 | 133 | (values new-body |
132 | 134 | (append e-ss |
133 | 135 | `((assign ,x ,new-e)) |
134 | 136 | body-ss))] |
135 | 137 | [`(not ,cnd) #:when optimize-if |
136 | | - ((send this flatten-if new-els els-ss new-thn thn-ss) cnd)] |
| 138 | + ((flatten-if new-els els-ss new-thn thn-ss) cnd)] |
137 | 139 | [`(eq? ,e1 ,e2) #:when optimize-if |
138 | | - (define-values (new-e1 e1-ss) ((send this flatten #t) e1)) |
139 | | - (define-values (new-e2 e2-ss) ((send this flatten #t) e2)) |
| 140 | + (define-values (new-e1 e1-ss) ((flatten #t) e1)) |
| 141 | + (define-values (new-e2 e2-ss) ((flatten #t) e2)) |
140 | 142 | (define tmp (gensym 'if)) |
141 | 143 | (define thn-ret `(assign ,tmp ,new-thn)) |
142 | 144 | (define els-ret `(assign ,tmp ,new-els)) |
|
146 | 148 | ,(append thn-ss (list thn-ret)) |
147 | 149 | ,(append els-ss (list els-ret))))))] |
148 | 150 | [else |
149 | | - (let-values ([(new-cnd cnd-ss) ((send this flatten #t) `(has-type ,cnd ,t))]) |
| 151 | + (let-values ([(new-cnd cnd-ss) ((flatten #t) `(has-type ,cnd ,t))]) |
150 | 152 | (define tmp (gensym 'if)) |
151 | 153 | (define thn-ret `(assign ,tmp ,new-thn)) |
152 | 154 | (define els-ret `(assign ,tmp ,new-els)) |
|
168 | 170 | ;; We override 'and' to place has-type's around the #t and #f |
169 | 171 | ;; in the generated code. -Jeremy |
170 | 172 | [`(has-type (and ,e1 ,e2) ,t) |
171 | | - (define-values (new-e1 e1-ss) ((send this flatten #t) e1)) |
172 | | - (define-values (new-e2 e2-ss) ((send this flatten #f) e2)) |
| 173 | + (define-values (new-e1 e1-ss) ((flatten #t) e1)) |
| 174 | + (define-values (new-e2 e2-ss) ((flatten #f) e2)) |
173 | 175 | (define tmp (gensym 'and)) |
174 | 176 | (values `(has-type ,tmp ,t) |
175 | 177 | (append e1-ss |
|
180 | 182 | ;; We override flattening for op's because we |
181 | 183 | ;; need to put a has-type on the LHS of the assign. -Jeremy |
182 | 184 | [`(has-type (,op ,es ...) ,t) |
183 | | - #:when (set-member? (send this primitives) op) |
184 | | - (define-values (new-es sss) (map2 (send this flatten #t) es)) |
| 185 | + #:when (set-member? (primitives) op) |
| 186 | + (define-values (new-es sss) (map2 (flatten #t) es)) |
185 | 187 | (define ss (append* sss)) |
186 | 188 | (define prim-apply `(,op ,@new-es)) |
187 | 189 | (cond |
|
193 | 195 |
|
194 | 196 | ;; For 'let' we just need to strip the enclosing has-type. -Jeremy |
195 | 197 | [`(has-type (let ([,x ,e]) ,body) ,t) |
196 | | - ((send this flatten need-atomic) `(let ([,x ,e]) ,body))] |
| 198 | + ((flatten need-atomic) `(let ([,x ,e]) ,body))] |
197 | 199 |
|
198 | 200 | [`(has-type (if ,cnd ,thn ,els) ,t) |
199 | | - (define-values (new-thn thn-ss) ((send this flatten #t) thn)) |
200 | | - (define-values (new-els els-ss) ((send this flatten #t) els)) |
| 201 | + (define-values (new-thn thn-ss) ((flatten #t) thn)) |
| 202 | + (define-values (new-els els-ss) ((flatten #t) els)) |
201 | 203 | ((flatten-if new-thn thn-ss new-els els-ss) cnd)] |
202 | 204 |
|
203 | 205 | [`(program ,e) |
204 | | - (define-values (new-e ss) ((send this flatten #t) e)) |
205 | | - (define xs (append* (map (send this collect-locals) ss))) |
| 206 | + (define-values (new-e ss) ((flatten #t) e)) |
| 207 | + (define xs (append* (map (collect-locals) ss))) |
206 | 208 | `(program ,(remove-duplicates xs) ,@(append ss `((return ,new-e))))] |
207 | 209 | [`(program (type ,ty) ,e) |
208 | | - (define-values (new-e ss) ((send this flatten #t) e)) |
209 | | - (define xs (append* (map (send this collect-locals) ss))) |
| 210 | + (define-values (new-e ss) ((flatten #t) e)) |
| 211 | + (define xs (append* (map (collect-locals) ss))) |
210 | 212 | `(program ,(remove-duplicates xs) (type ,ty) ,@(append ss `((return ,new-e))))] |
211 | 213 | [else ((super flatten need-atomic) e)]))) |
212 | 214 |
|
|
238 | 240 | [`(assign ,lhs (has-type ,rhs ,t)) |
239 | 241 | ((select-instructions) `(assign ,lhs ,rhs))] |
240 | 242 | [`(assign ,lhs ,b) #:when (boolean? b) |
241 | | - (let ([lhs ((send this select-instructions) lhs)] |
242 | | - [b ((send this select-instructions) b)]) |
| 243 | + (let ([lhs ((select-instructions) lhs)] |
| 244 | + [b ((select-instructions) b)]) |
243 | 245 | `((movq ,b ,lhs)))] |
244 | 246 | [`(assign ,lhs (not ,e)) |
245 | | - (define new-lhs ((send this select-instructions) lhs)) |
246 | | - (define new-e ((send this select-instructions) e)) |
| 247 | + (define new-lhs ((select-instructions) lhs)) |
| 248 | + (define new-e ((select-instructions) e)) |
247 | 249 | (cond [(equal? new-e new-lhs) |
248 | 250 | `((xorq (int 1) ,new-lhs))] |
249 | 251 | [else `((movq ,new-e ,new-lhs) |
250 | 252 | (xorq (int 1) ,new-lhs))])] |
251 | 253 | [`(assign ,lhs (eq? ,e1 ,e2)) |
252 | | - (define new-lhs ((send this select-instructions) lhs)) |
253 | | - (define new-e1 ((send this select-instructions) e1)) |
254 | | - (define new-e2 ((send this select-instructions) e2)) |
| 254 | + (define new-lhs ((select-instructions) lhs)) |
| 255 | + (define new-e1 ((select-instructions) e1)) |
| 256 | + (define new-e2 ((select-instructions) e2)) |
255 | 257 | ;; second operand of cmpq can't be an immediate |
256 | 258 | (define comparison |
257 | 259 | (cond [(and (immediate? new-e1) (immediate? new-e2)) |
|
268 | 270 | )] |
269 | 271 | ;; Keep the if statement to simplify register allocation |
270 | 272 | [`(if ,cnd ,thn-ss ,els-ss) |
271 | | - (let ([cnd ((send this select-instructions) cnd)] |
272 | | - [thn-ss (append* (map (send this select-instructions) |
| 273 | + (let ([cnd ((select-instructions) cnd)] |
| 274 | + [thn-ss (append* (map (select-instructions) |
273 | 275 | thn-ss))] |
274 | | - [els-ss (append* (map (send this select-instructions) |
| 276 | + [els-ss (append* (map (select-instructions) |
275 | 277 | els-ss))]) |
276 | 278 | `((if ,cnd ,thn-ss ,els-ss)))] |
277 | 279 | [`(eq? ,a1 ,a2) |
278 | | - `(eq? ,((send this select-instructions) a1) |
279 | | - ,((send this select-instructions) a2))] |
| 280 | + `(eq? ,((select-instructions) a1) |
| 281 | + ,((select-instructions) a2))] |
280 | 282 | [`(program ,locals (type ,ty) ,ss ...) |
281 | | - (let ([new-ss (map (send this select-instructions) ss)]) |
| 283 | + (let ([new-ss (map (select-instructions) ss)]) |
282 | 284 | `(program ,locals (type ,ty) ,@(append* new-ss)))] |
283 | 285 | [else ((super select-instructions) e)] |
284 | 286 | ))) |
|
289 | 291 | (define/override (free-vars a) |
290 | 292 | (match a |
291 | 293 | [`(byte-reg ,r) (set (byte-reg->full-reg r))] |
292 | | - [`(eq? ,e1 ,e2) (set-union (send this free-vars e1) |
293 | | - (send this free-vars e2))] |
| 294 | + [`(eq? ,e1 ,e2) (set-union (free-vars e1) |
| 295 | + (free-vars e2))] |
294 | 296 | [else (super free-vars a)] |
295 | 297 | )) |
296 | 298 |
|
297 | 299 | (define/override (read-vars instr) |
298 | 300 | (match instr |
299 | | - [`(movzbq ,s ,d) (send this free-vars s)] |
300 | | - [`(cmpq ,s1 ,s2) (set-union (send this free-vars s1) |
301 | | - (send this free-vars s2))] |
| 301 | + [`(movzbq ,s ,d) (free-vars s)] |
| 302 | + [`(cmpq ,s1 ,s2) (set-union (free-vars s1) |
| 303 | + (free-vars s2))] |
302 | 304 | [(or `(andq ,s ,d) `(orq ,s ,d) `(xorq ,s ,d)) |
303 | | - (set-union (send this free-vars s) (send this free-vars d))] |
304 | | - [`(notq ,d) (send this free-vars d)] |
| 305 | + (set-union (free-vars s) (free-vars d))] |
| 306 | + [`(notq ,d) (free-vars d)] |
305 | 307 | [`(sete ,d) (set)] |
306 | 308 | [else (super read-vars instr)])) |
307 | 309 |
|
308 | 310 | (define/override (write-vars instr) |
309 | 311 | (match instr |
310 | | - [`(movzbq ,s ,d) (send this free-vars d)] |
| 312 | + [`(movzbq ,s ,d) (free-vars d)] |
311 | 313 | [`(cmpq ,s1 ,s2) (set '__flag)] |
312 | 314 | [(or `(andq ,s ,d) `(orq ,s ,d) `(xorq ,s ,d)) |
313 | | - (send this free-vars d)] |
314 | | - [`(notq ,d) (send this free-vars d)] |
315 | | - [`(sete ,d) (send this free-vars d)] |
| 315 | + (free-vars d)] |
| 316 | + [`(notq ,d) (free-vars d)] |
| 317 | + [`(sete ,d) (free-vars d)] |
316 | 318 | [else (super write-vars instr)])) |
317 | 319 |
|
318 | 320 | (define/override (uncover-live live-after) |
319 | 321 | (lambda (ast) |
320 | 322 | (match ast |
321 | 323 | [`(if ,cnd ,thn-ss ,els-ss) |
322 | 324 | (define-values (new-thn-ss thn-lives) |
323 | | - ((send this liveness-ss live-after) thn-ss)) |
| 325 | + ((liveness-ss live-after) thn-ss)) |
324 | 326 | (define-values (new-els-ss els-lives) |
325 | | - ((send this liveness-ss live-after) els-ss)) |
| 327 | + ((liveness-ss live-after) els-ss)) |
326 | 328 | ;; I doubt that thn-lives can be null -Jeremy |
327 | 329 | (define live-after-thn (cond [(null? thn-lives) live-after] |
328 | 330 | [else (car thn-lives)])) |
329 | 331 | (define live-after-els (cond [(null? els-lives) live-after] |
330 | 332 | [else (car els-lives)])) |
331 | 333 | (values `(if ,cnd ,new-thn-ss ,(cdr thn-lives) ,new-els-ss ,(cdr els-lives)) |
332 | 334 | (set-union live-after-thn live-after-els |
333 | | - (send this free-vars cnd)))] |
| 335 | + (free-vars cnd)))] |
334 | 336 | [else ((super uncover-live live-after) ast)] |
335 | 337 | ))) |
336 | 338 |
|
|
349 | 351 | ast] |
350 | 352 | [`(if ,cnd ,thn-ss ,thn-lives ,els-ss ,els-lives) |
351 | 353 | (define (build-inter inst live-after) |
352 | | - ((send this build-interference live-after G) inst)) |
| 354 | + ((build-interference live-after G) inst)) |
353 | 355 | (define new-thn (map build-inter thn-ss thn-lives)) |
354 | 356 | (define new-els (map build-inter els-ss els-lives)) |
355 | 357 | `(if ,cnd ,new-thn ,new-els)] |
|
362 | 364 | (lambda (e) |
363 | 365 | (match e |
364 | 366 | [`(byte-reg ,r) `(byte-reg ,r)] |
365 | | - [`(eq? ,e1 ,e2) `(eq? ,((send this assign-homes homes) e1) |
366 | | - ,((send this assign-homes homes) e2))] |
| 367 | + [`(eq? ,e1 ,e2) `(eq? ,((assign-homes homes) e1) |
| 368 | + ,((assign-homes homes) e2))] |
367 | 369 | [`(if ,cnd ,thn-ss ,els-ss) |
368 | | - (let ([cnd ((send this assign-homes homes) cnd)] |
369 | | - [thn-ss (map (send this assign-homes homes) thn-ss)] |
370 | | - [els-ss (map (send this assign-homes homes) els-ss)]) |
| 370 | + (let ([cnd ((assign-homes homes) cnd)] |
| 371 | + [thn-ss (map (assign-homes homes) thn-ss)] |
| 372 | + [els-ss (map (assign-homes homes) els-ss)]) |
371 | 373 | `(if ,cnd ,thn-ss ,els-ss))] |
372 | 374 | [`(program (,xs ...) (type ,ty) ,ss ...) |
373 | 375 | ;; create mapping of variables to stack locations |
374 | 376 | (define (make-stack-loc n) |
375 | | - `(stack ,(+ (send this first-offset) |
376 | | - (* (send this variable-size) n)))) |
| 377 | + `(stack ,(+ (first-offset) |
| 378 | + (* (variable-size) n)))) |
377 | 379 | (define new-homes |
378 | 380 | (make-hash (map cons xs |
379 | 381 | (map make-stack-loc |
380 | 382 | (stream->list (in-range 0 (length xs))))))) |
381 | 383 | (define stack-space (align |
382 | 384 | (* (length xs) |
383 | | - (send this variable-size)) |
| 385 | + (variable-size)) |
384 | 386 | 16)) |
385 | 387 | `(program ,stack-space (type ,ty) |
386 | | - ,@(map (send this assign-homes new-homes) ss))] |
| 388 | + ,@(map (assign-homes new-homes) ss))] |
387 | 389 | [else ((super assign-homes homes) e)] |
388 | 390 | ))) |
389 | 391 |
|
|
397 | 399 | [`(int ,n) `(int ,n)] |
398 | 400 | [`(reg ,r) `(reg ,r)] |
399 | 401 | [`(if (eq? ,a1 ,a2) ,thn-ss ,els-ss) |
400 | | - (let ([thn-ss (append* (map (send this lower-conditionals) thn-ss))] |
401 | | - [els-ss (append* (map (send this lower-conditionals) els-ss))] |
| 402 | + (let ([thn-ss (append* (map (lower-conditionals) thn-ss))] |
| 403 | + [els-ss (append* (map (lower-conditionals) els-ss))] |
402 | 404 | [thn-label (gensym 'then)] |
403 | 405 | [end-label (gensym 'if_end)]) |
404 | 406 | (append `((cmpq ,a1 ,a2)) |
|
407 | 409 | ))] |
408 | 410 | [`(callq ,f) `((callq ,f))] |
409 | 411 | [`(program ,stack-space (type ,ty) ,ss ...) |
410 | | - (let ([new-ss (append* (map (send this lower-conditionals) ss))]) |
| 412 | + (let ([new-ss (append* (map (lower-conditionals) ss))]) |
411 | 413 | `(program ,stack-space (type ,ty) ,@new-ss))] |
412 | 414 | [`(,instr ,args ...) |
413 | 415 | `((,instr ,@args))] |
|
417 | 419 |
|
418 | 420 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
419 | 421 | (define/override (patch-instructions) |
420 | | - (define (mem? x) (send this on-stack? x)) |
| 422 | + (define (mem? x) (on-stack? x)) |
421 | 423 | (lambda (e) |
422 | 424 | (match e |
423 | 425 | [`(je ,label) `((je ,label))] |
|
441 | 443 | (movq (reg rax) ,d))] |
442 | 444 | [`(program ,stack-space (type ,ty) ,ss ...) |
443 | 445 | `(program ,stack-space (type ,ty) |
444 | | - ,@(append* (map (send this patch-instructions) ss)))] |
| 446 | + ,@(append* (map (patch-instructions) ss)))] |
445 | 447 | [else ((super patch-instructions) e)] |
446 | 448 | ))) |
447 | 449 |
|
|
451 | 453 | (lambda (e) |
452 | 454 | (match e |
453 | 455 | [`(byte-reg ,r) (format "%~a" r)] |
454 | | - [`(sete ,d) (format "\tsete\t~a\n" ((send this print-x86) d))] |
| 456 | + [`(sete ,d) (format "\tsete\t~a\n" ((print-x86) d))] |
455 | 457 | [`(cmpq ,s1 ,s2) |
456 | | - (format "\tcmpq\t~a, ~a\n" ((send this print-x86) s1) |
457 | | - ((send this print-x86) s2))] |
| 458 | + (format "\tcmpq\t~a, ~a\n" ((print-x86) s1) |
| 459 | + ((print-x86) s2))] |
458 | 460 | [`(je ,label) (format "\tje ~a\n" label)] |
459 | 461 | [`(jmp ,label) (format "\tjmp ~a\n" label)] |
460 | 462 | [`(label ,l) (format "~a:\n" l)] |
|
467 | 469 | (for/list ([r (reverse callee-reg)]) |
468 | 470 | (format "\tpopq\t%~a\n" r))) |
469 | 471 | (define callee-space (* (length (set->list callee-save)) |
470 | | - (send this variable-size))) |
| 472 | + (variable-size))) |
471 | 473 | (define stack-adj (- (align (+ callee-space spill-space) 16) |
472 | 474 | callee-space)) |
473 | 475 | (string-append |
|
478 | 480 | (string-append* save-callee-reg) |
479 | 481 | (format "\tsubq\t$~a, %rsp\n" stack-adj) |
480 | 482 | "\n" |
481 | | - (string-append* (map (send this print-x86) ss)) |
| 483 | + (string-append* (map (print-x86) ss)) |
482 | 484 | "\n" |
483 | 485 | (print-by-type ty) |
484 | 486 | (format "\tmovq\t$0, %rax\n") |
|
0 commit comments