|
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