|
9 | 9 | (class compile-R2
|
10 | 10 | (super-new)
|
11 | 11 |
|
12 |
| - (inherit primitives liveness-ss) |
| 12 | + (inherit primitives liveness-ss allocate-homes color-graph) |
13 | 13 |
|
14 | 14 | (define/public (non-apply-ast)
|
15 | 15 | (set-union (primitives)
|
|
127 | 127 | ))
|
128 | 128 | ret)))
|
129 | 129 |
|
| 130 | + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
| 131 | + ;; expose allocation : C1 -> ? |
| 132 | + ;; This pass has to thread a new environment through that isn't extended |
| 133 | + ;; This could be overcome with pointers or we could use |
| 134 | + |
| 135 | + (define/override (expose-allocation) |
| 136 | + (lambda (e) |
| 137 | + (verbose "expose-allocation" e) |
| 138 | + (match e |
| 139 | + [`(app ,(app (expose-allocation) es) ...) |
| 140 | + `(app ,@es)] |
| 141 | + [`(function-ref ,f) |
| 142 | + `(function-ref ,f)] |
| 143 | + [`(program (type ,ty) ,ds ... |
| 144 | + ,(app (expose-allocation) new-e)) |
| 145 | + `(program (type ,ty) ,@(map (lambda (d) (expose-allocation-def d)) |
| 146 | + ds) ,new-e)] |
| 147 | + [else |
| 148 | + ((super expose-allocation) e)]))) |
| 149 | + |
| 150 | + (define/public (expose-allocation-def def) |
| 151 | + (match def |
| 152 | + [`(define (,f ,p:t* ...) : ,t |
| 153 | + ,(app (expose-allocation) e)) |
| 154 | + `(define (,f ,@p:t*) : ,t ,e)] |
| 155 | + [else (error 'expose-allocation-def "unmatched ~a" def)])) |
| 156 | + |
130 | 157 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
131 | 158 | ;; flatten : S3 -> C3-expr x (C3-stmt list)
|
132 | 159 |
|
133 | 160 | (define/public (flatten-body body)
|
134 | 161 | (define-values (new-body ss locals) ((flatten #t) body))
|
135 |
| - (values locals |
136 |
| - (append ss `((return ,new-body))))) |
| 162 | + (values locals (append ss `((return ,new-body))))) |
137 | 163 |
|
138 | 164 | (define/override (flatten need-atomic)
|
139 | 165 | (lambda (ast)
|
|
149 | 175 | ,@new-body)]
|
150 | 176 | [`(has-type (function-ref ,f) ,t)
|
151 | 177 | (define tmp (gensym 'tmp))
|
152 |
| - (values `(has-type ,tmp ,t) |
153 |
| - (list `(assign ,tmp (has-type (function-ref ,f) ,t))) |
| 178 | + (values tmp |
| 179 | + (list `(assign ,tmp (function-ref ,f))) |
154 | 180 | (list (cons tmp t)))]
|
155 | 181 | [`(has-type (app ,f ,es ...) ,t)
|
156 | 182 | (define-values (new-f f-ss xs1) ((flatten #t) f))
|
|
161 | 187 | (cond
|
162 | 188 | [need-atomic
|
163 | 189 | (define tmp (gensym 'tmp))
|
164 |
| - (values `(has-type ,tmp ,t) |
165 |
| - (append ss `((assign ,tmp (has-type ,fun-apply ,t)))) |
| 190 | + (values tmp |
| 191 | + (append ss `((assign ,tmp ,fun-apply))) |
166 | 192 | (cons (cons tmp t) (append xs1 xs2))
|
167 | 193 | )]
|
168 | 194 | [else
|
169 |
| - (values `(has-type ,fun-apply ,t) ss (append xs1 xs2))])] |
| 195 | + (values fun-apply ss (append xs1 xs2))])] |
170 | 196 | [else ((super flatten need-atomic) ast)])))
|
171 | 197 |
|
172 | 198 | (inherit root-type?)
|
173 | 199 |
|
174 |
| - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
175 |
| - ;; expose allocation : C1 -> ? |
176 |
| - ;; This pass has to thread a new environment through that isn't extended |
177 |
| - ;; This could be overcome with pointers or we could use |
178 |
| - |
179 |
| -; (inherit expose-allocation-seq) |
180 |
| - (define/override (expose-allocation) |
181 |
| - (lambda (prog) |
182 |
| - (match prog |
183 |
| - [`(program (,xs ...) (type ,ty) |
184 |
| - (defines ,(app expose-allocation-def ds) ...) |
185 |
| - ,e) |
186 |
| - (let ([new-e (expose-allocation e)]) |
187 |
| - `(program ,xs |
188 |
| - (type ,ty) |
189 |
| - (defines ,@ds) |
190 |
| - ,new-e))] |
191 |
| - [else (error 'expose-allocation "unmatched ~a" prog)]))) |
192 |
| - |
193 |
| - (define/public (expose-allocation-def def) |
194 |
| - (match def |
195 |
| - [`(define (,f ,p:t* ...) : ,t (,l* ...) |
196 |
| - . ,(app expose-allocation e)) |
197 |
| - `(define (,f ,@p:t*) : ,t ,l* ,e)] |
198 |
| - [else (error 'expose-allocation-def "unmatched ~a" def)])) |
199 |
| - |
200 | 200 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
201 | 201 | ;; select-instructions : env -> S3 -> S3
|
202 | 202 |
|
|
226 | 226 | `(define (,f)
|
227 | 227 | ,(length xs) (,(append (map cons xs ps) locals) ,max-stack)
|
228 | 228 | ,@new-ss)]
|
229 |
| - [`(assign ,lhs (has-type (function-ref ,f) ,t)) |
| 229 | + [`(assign ,lhs (function-ref ,f)) |
230 | 230 | (define new-lhs ((select-instructions) lhs))
|
231 | 231 | `((leaq (function-ref ,f) ,new-lhs))]
|
232 |
| - [`(assign ,lhs (has-type (app ,f ,es ...) ,t)) |
| 232 | + [`(assign ,lhs (app ,f ,es ...)) |
233 | 233 | (define new-lhs ((select-instructions) lhs))
|
234 | 234 | (define new-f ((select-instructions) f))
|
235 | 235 | (define new-es (map (select-instructions) es))
|
|
298 | 298 | ;; build-interference : live-after x graph -> pseudo-x86* -> pseudo-x86*
|
299 | 299 | ;; *annotate program with interference graph
|
300 | 300 |
|
301 |
| - (define/override (build-interference live-after G) |
| 301 | + (define/override (build-interference live-after G xs) |
302 | 302 | (lambda (ast)
|
303 | 303 | (vomit "build-interference" ast live-after G)
|
304 | 304 | (match ast
|
305 | 305 | [`(define (,f) ,n (,locals ,max-stack ,lives) ,ss ...)
|
306 | 306 | (define new-G (make-graph (map car locals)))
|
307 | 307 | (define new-ss
|
308 | 308 | (for/list ([inst ss] [live-after lives])
|
309 |
| - ((build-interference live-after new-G) inst))) |
| 309 | + ((build-interference live-after new-G locals) inst))) |
310 | 310 | `(define (,f) ,n (,locals ,max-stack ,new-G) ,@new-ss)]
|
311 |
| - [`(program (,locals ,max-stack ,lives) (type ,ty) (defines ,ds ...) ,ss ...) |
| 311 | + [`(program (,locals ,max-stack ,lives) (type ,ty) |
| 312 | + (defines ,ds ...) ,ss ...) |
312 | 313 | (define new-G (make-graph (map car locals)))
|
313 | 314 | (define new-ds
|
314 | 315 | (for/list ([d ds])
|
315 |
| - ((build-interference (void) (void)) d))) |
| 316 | + ((build-interference (void) (void) (void)) d))) |
316 | 317 | (define new-ss
|
317 | 318 | (for/list ([inst ss] [live-after lives])
|
318 |
| - ((build-interference live-after new-G) inst))) |
319 |
| - `(program (,locals ,max-stack ,new-G) (type ,ty) (defines ,@new-ds) ,@new-ss)] |
320 |
| - [else ((super build-interference live-after G) ast)] |
| 319 | + ((build-interference live-after new-G locals) inst))) |
| 320 | + `(program (,locals ,max-stack ,new-G) (type ,ty) |
| 321 | + (defines ,@new-ds) ,@new-ss)] |
| 322 | + [else ((super build-interference live-after G xs) ast)] |
321 | 323 | )))
|
322 | 324 |
|
323 | 325 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
327 | 329 | (define/override (build-move-graph G)
|
328 | 330 | (lambda (ast)
|
329 | 331 | (match ast
|
330 |
| - [`(program (,locals ,max-stack ,IG) (type ,ty) (defines ,ds ...) ,ss ...) |
| 332 | + [`(program (,locals ,max-stack ,IG) (type ,ty) |
| 333 | + (defines ,ds ...) ,ss ...) |
331 | 334 | (define new-ds (for/list ([d ds])
|
332 | 335 | ((build-move-graph (void)) d)))
|
333 | 336 | (define MG (make-graph (map car locals)))
|
334 | 337 | (define new-ss
|
335 | 338 | (for/list ([inst ss])
|
336 | 339 | ((build-move-graph MG) inst)))
|
337 | 340 | (print-dot MG "./move.dot")
|
338 |
| - `(program (,locals ,max-stack ,IG ,MG) (type ,ty) (defines ,@new-ds) ,@new-ss)] |
| 341 | + `(program (,locals ,max-stack ,IG ,MG) (type ,ty) |
| 342 | + (defines ,@new-ds) ,@new-ss)] |
339 | 343 | [`(define (,f) ,n (,locals ,max-stack ,IG) ,ss ...)
|
340 | 344 | (define MG (make-graph (map car locals)))
|
341 | 345 | (define new-ss
|
|
355 | 359 | (define/override (assign-homes homes)
|
356 | 360 | (lambda (e)
|
357 | 361 | (match e
|
358 |
| - #;[`(stack ,i) `(stack ,i)] |
359 |
| - [`(stack-arg ,i) `(stack-arg ,i)] |
| 362 | + [`(stack-arg ,i) `(stack-arg ,i)] ;; obsolete?? -JGS |
360 | 363 | [`(indirect-callq ,f)
|
361 | 364 | `(indirect-callq ,((assign-homes homes) f))]
|
362 | 365 | [`(function-ref ,f) `(function-ref ,f) ]
|
|
369 | 372 | (define/override (allocate-registers)
|
370 | 373 | (lambda (ast)
|
371 | 374 | (match ast
|
372 |
| - ;; FIX ME -Jeremy |
373 |
| - #;[`(define (,f) ,n (,xs ,max-stack ,IG ,MG) ,ss ...) |
374 |
| - (define-values (homes stk-size) |
375 |
| - (allocate-homes IG MG (map car xs) ss)) |
| 375 | + [`(define (,f) ,n (,locals ,max-stack ,IG ,MG) ,ss ...) |
| 376 | + (define color (color-graph IG MG (map car locals))) |
| 377 | + (define-values (homes stack-spills root-spills) |
| 378 | + (allocate-homes locals color)) |
| 379 | + |
376 | 380 | (define new-ss (map (assign-homes homes) ss))
|
377 |
| - `(define (,f) ,n ,(align (+ stk-size (* 8 max-stack)) 16) ,@new-ss)] |
378 |
| - ;; FIX ME -Jeremy |
379 |
| - #;[`(program (,locals ,max-stack ,IG ,MG) (type ,ty) (defines ,ds ...) |
| 381 | + (define stack-size (align (+ (* stack-spills (variable-size)) |
| 382 | + (* max-stack (variable-size))) 16)) |
| 383 | + (define root-size (* root-spills (variable-size))) |
| 384 | + `(define (,f) ,n (,stack-size ,root-size) ,@new-ss)] |
| 385 | + |
| 386 | + [`(program (,locals ,max-stack ,IG ,MG) (type ,ty) (defines ,ds ...) |
380 | 387 | ,ss ...)
|
381 | 388 | (define new-ds (map (allocate-registers) ds))
|
382 |
| - (define-values (homes stk-size) |
383 |
| - (allocate-homes IG MG (map car locals) ss)) |
| 389 | + (define color (color-graph IG MG (map car locals))) |
| 390 | + (define-values (homes stack-spills root-spills) |
| 391 | + (allocate-homes locals color)) |
384 | 392 | (define new-ss (map (assign-homes homes) ss))
|
385 |
| - `(program ,(+ stk-size (* 8 max-stack)) (type ,ty) |
| 393 | + |
| 394 | + (define stack-size (align (+ (* stack-spills (variable-size)) |
| 395 | + (* max-stack (variable-size))) 16)) |
| 396 | + (define root-size (* root-spills (variable-size))) |
| 397 | + `(program (,stack-size ,root-size) (type ,ty) |
386 | 398 | (defines ,@new-ds) ,@new-ss)]
|
387 | 399 | )))
|
388 | 400 |
|
|
456 | 468 | (format "\tcallq\t*~a\n" ((print-x86) f))]
|
457 | 469 | [`(stack-arg ,i)
|
458 | 470 | (format "~a(%rsp)" i)]
|
459 |
| - [`(define (,f) ,n ,spill-space ,ss ...) |
| 471 | + [`(define (,f) ,n (,spill-space ,root-space) ,ss ...) |
460 | 472 | (define callee-reg (set->list callee-save))
|
461 | 473 | (define save-callee-reg
|
462 | 474 | (for/list ([r callee-reg])
|
|
468 | 480 | (variable-size)))
|
469 | 481 | (define stack-adj (- (align (+ callee-space spill-space) 16)
|
470 | 482 | callee-space))
|
| 483 | + (define initialize-roots |
| 484 | + (for/list ([i (range (/ root-space (variable-size)))]) |
| 485 | + (string-append |
| 486 | + (format "\tmovq $0, (%~a)\n" rootstack-reg) |
| 487 | + (format "\taddq $~a, %~a\n" |
| 488 | + (variable-size) rootstack-reg)))) |
471 | 489 | (string-append
|
472 | 490 | (format "\t.globl ~a\n" f)
|
473 | 491 | (format "~a:\n" f)
|
474 | 492 | (format "\tpushq\t%rbp\n")
|
475 | 493 | (format "\tmovq\t%rsp, %rbp\n")
|
476 | 494 | (string-append* save-callee-reg)
|
477 | 495 | (format "\tsubq\t$~a, %rsp\n" stack-adj)
|
| 496 | + (string-append* initialize-roots) |
478 | 497 | ;; Push callee saves at the bottom of the stack
|
479 | 498 | ;; frame because the current code for stack nodes
|
480 | 499 | ;; doesn't reason about them. -andre
|
|
483 | 502 | "\n"
|
484 | 503 | (format "\taddq\t$~a, %rsp\n" stack-adj)
|
485 | 504 | (string-append* restore-callee-reg)
|
| 505 | + (format "\tsubq $~a, %~a\n" root-space rootstack-reg) |
486 | 506 | (format "\tpopq\t%rbp\n")
|
487 | 507 | (format "\tretq\n")
|
488 | 508 | )]
|
489 |
| - [`(program ,stack-space (type ,ty) (defines ,ds ...) ,ss ...) |
| 509 | + [`(program ,space (type ,ty) (defines ,ds ...) ,ss ...) |
490 | 510 | (string-append
|
491 | 511 | (string-append* (for/list ([d ds]) ((print-x86) d)))
|
492 | 512 | "\n"
|
493 |
| - ((super print-x86) `(program ,stack-space (type ,ty) ,@ss)))] |
| 513 | + ((super print-x86) `(program ,space (type ,ty) ,@ss)))] |
494 | 514 | [else ((super print-x86) e)]
|
495 | 515 | )))
|
496 | 516 |
|
|
522 | 542 | ("liveness analysis" ,(send compiler uncover-live (void))
|
523 | 543 | ,(send interp interp-x86 '()))
|
524 | 544 | ("build interference" ,(send compiler build-interference
|
525 |
| - (void) (void)) |
| 545 | + (void) (void) (void)) |
526 | 546 | ,(send interp interp-x86 '()))
|
527 | 547 | ("build move graph" ,(send compiler
|
528 | 548 | build-move-graph (void))
|
|
0 commit comments