* pre-spilling call-live variables works for the test cases now.

This commit is contained in:
Abdulaziz Ghuloum 2007-02-17 18:09:03 -05:00
parent 85bf359150
commit 0304c85082
4 changed files with 664 additions and 193 deletions

Binary file not shown.

View File

@ -1638,6 +1638,8 @@
(values (cons (car regs) r*)
(cons (car args) rl*)
f*))])))
(define (make-set lhs rhs)
(make-asm-instr 'move lhs rhs))
(define (do-bind-frmt* nf* v* ac)
(cond
[(null? nf*) ac]
@ -1652,7 +1654,8 @@
(let-values ([(reg-locs reg-args frm-args)
(nontail-locations (cons rator rands))])
(let ([regt* (map (lambda (x) (unique-var 'rt)) reg-args)]
[frmt* (map (lambda (x) (make-nfvar 'unset-conflicts #f)) frm-args)])
[frmt* (map (lambda (x) (make-nfv 'unset-conflicts #f #f #f #f))
frm-args)])
(let* ([call
(make-ntcall call-targ value-dest
(cons argc-register (append reg-locs frmt*))
@ -1838,9 +1841,11 @@
(argc-convention (length rands))))
(cond
[target
(make-primcall 'direct-jump (cons target locs))]
(make-primcall 'direct-jump
(cons target (cons argc-register locs)))]
[else
(make-primcall 'indirect-jump locs)]))))))))
(make-primcall 'indirect-jump
(cons argc-register locs))]))))))))
(define (Tail x)
(record-case x
[(constant) (VT x)]
@ -1926,6 +1931,12 @@
(Program x))
(module ListyGraphs
(empty-graph add-edge! empty-graph? print-graph node-neighbors
delete-node!)
@ -1989,6 +2000,9 @@
#|ListyGraphs|#)
(begin
(define empty-set '())
(define (set-member? x s) (memq x s))
(define (set-add x s)
(cond
[(memq x s) s]
@ -2012,6 +2026,578 @@
[else (cons (car s1) (set-union (cdr s1) s2))])))
(module (assign-frame-sizes)
;;; assign-frame-sizes module
(define (has-nontail-call? x)
(define who 'has-nontail-call?)
(define (E x)
(record-case x
[(seq e0 e1) (or (E e0) (E e1))]
[(conditional e0 e1 e2)
(or (P e0) (E e1) (E e2))]
[(nframe) #t]
[(asm-instr) #f]
[(primcall op args)
(case op
[(nop) #f]
[else (error who "invalid effect ~s" (unparse x))])]
[else (error who "invalid effect ~s" x)]))
(define (P x)
(record-case x
[(seq e0 e1) (or (E e0) (P e1))]
[(conditional e0 e1 e2)
(or (P e0) (P e1) (P e2))]
[(asm-instr) #f]
[(constant) #f]
[else (error who "invalid pred ~s" x)]))
(define (T x)
(record-case x
[(seq e0 e1)
(or (E e0) (T e1))]
[(conditional e0 e1 e2)
(or (P e0) (T e1) (T e2))]
[(primcall) #f]
[else (error who "invalid tail ~s" x)]))
(T x))
;;;
(begin
(define (init-var-conf! x)
(set-var-var-conf! x (empty-var-set))
(set-var-reg-conf! x (empty-reg-set))
(set-var-frm-conf! x (empty-frm-set)))
(define (init-nfv! x)
(set-nfv-frm-conf! x (empty-frm-set))
(set-nfv-nfv-conf! x (empty-nfv-set))
(set-nfv-var-conf! x (empty-var-set)))
(define (reg? x) (symbol? x))
(define (empty-frm-set) empty-set)
(define (empty-nfv-set) empty-set)
(define (empty-var-set) empty-set)
(define (add-var x s) (set-add x s))
(define (rem-var x s) (set-rem x s))
(define (union-vars s1 s2) (union s1 s2))
(define (empty-reg-set) empty-set)
(define (add-reg x s) (set-add x s))
(define (rem-reg x s) (set-rem x s))
(define (mem-reg? x s) (set-member? x s))
(define (union-regs s1 s2) (union s1 s2))
(define (add-frm x s) (set-add x s))
(define (rem-frm x s) (set-rem x s))
(define (union-frms s1 s2) (union s1 s2))
(define (for-each-var s f) (for-each f s))
(define (add-nfv x s) (set-add x s))
(define (rem-nfv x s) (set-rem x s))
(define (union-nfvs s1 s2) (union s1 s2))
(define (for-each-nfv s f) (for-each f s)))
;;;
(define (uncover-frame-conflicts x)
(define who 'uncover-frame-conflicts)
(define spill-set '())
(define-syntax assert
(syntax-rules ()
[(_ p0 p1 v0 v1)
(unless (and (p0 v0)
(andmap p1 v1))
(error 'assert "failed in ~s" '(assert p0 p1 v0 v1)))]))
(define (mark-reg/vars-conf! r vs)
(assert reg? var? r vs)
(for-each-var vs
(lambda (v)
(set-var-reg-conf! v
(add-reg r (var-reg-conf v))))))
(define (mark-frm/vars-conf! f vs)
(assert fvar? var? f vs)
(for-each-var vs
(lambda (v)
(set-var-frm-conf! v
(add-frm f (var-frm-conf v))))))
(define (mark-frm/nfvs-conf! f ns)
(assert fvar? nfv? f ns)
(for-each-nfv ns
(lambda (n)
(set-nfv-frm-conf! n
(add-frm f (nfv-frm-conf n))))))
(define (mark-var/vars-conf! v vs)
(assert var? var? v vs)
(for-each-var vs
(lambda (w)
(set-var-var-conf! w
(add-var v (var-var-conf w)))))
(set-var-var-conf! v
(union-vars vs (var-var-conf v))))
(define (mark-var/frms-conf! v fs)
(assert var? fvar? v fs)
(set-var-frm-conf! v
(union-frms fs (var-frm-conf v))))
(define (mark-var/regs-conf! v rs)
(assert var? reg? v rs)
(set-var-reg-conf! v
(union-regs rs (var-reg-conf v))))
(define (mark-var/nfvs-conf! v ns)
(assert var? nfv? v ns)
(for-each-nfv ns
(lambda (n)
(set-nfv-var-conf! n
(add-var v (nfv-var-conf n))))))
(define (mark-nfv/vars-conf! n vs)
(assert nfv? var? n vs)
(set-nfv-var-conf! n
(union-vars vs (nfv-var-conf n))))
(define (mark-nfv/frms-conf! n fs)
(assert nfv? fvar? n fs)
(set-nfv-frm-conf! n
(union-frms fs (nfv-frm-conf n))))
(define (mark-nfv/nfvs-conf! n ns)
(assert nfv? nfv? n ns)
(set-nfv-nfv-conf! n
(union-nfvs ns (nfv-nfv-conf n)))
(for-each-nfv ns
(lambda (m)
(set-nfv-nfv-conf! m
(add-nfv n (nfv-nfv-conf m))))))
(define (const? x)
(or (constant? x)
(code-loc? x)))
(define (R x vs rs fs ns)
(cond
[(const? x) (values vs rs fs ns)]
[(reg? x)
(values vs (add-reg x rs) fs ns)]
[(fvar? x)
(values vs rs (add-frm x fs) ns)]
[(var? x)
(values (add-var x vs) rs fs ns)]
[(nfv? x)
(values vs rs fs (add-nfv x ns))]
[(disp? x)
(let-values ([(vs rs fs ns) (R (disp-s0 x) vs rs fs ns)])
(R (disp-s1 x) vs rs fs ns))]
[else (error who "invalid R ~s" x)]))
(define (R* ls vs rs fs ns)
(cond
[(null? ls) (values vs rs fs ns)]
[else
(let-values ([(vs rs fs ns) (R (car ls) vs rs fs ns)])
(R* (cdr ls) vs rs fs ns))]))
(define (E x vs rs fs ns)
(record-case x
[(seq e0 e1)
(let-values ([(vs rs fs ns) (E e1 vs rs fs ns)])
(E e0 vs rs fs ns))]
[(conditional e0 e1 e2)
(let-values ([(vs1 rs1 fs1 ns1) (E e1 vs rs fs ns)]
[(vs2 rs2 fs2 ns2) (E e2 vs rs fs ns)])
(P e0
vs1 rs1 fs1 ns1
vs2 rs2 fs2 ns2
(union-vars vs1 vs2)
(union-regs rs1 rs2)
(union-frms fs1 fs2)
(union-nfvs ns1 ns2)))]
[(asm-instr op d s)
(case op
[(move)
(cond
[(reg? d)
(cond
[(not (mem-reg? d rs)) (error who "dead register")]
[(or (const? s) (disp? s))
(let ([rs (rem-reg d rs)])
(mark-reg/vars-conf! d vs)
(R s vs rs fs ns))]
[(var? s)
(let ([rs (rem-reg d rs)]
[vs (rem-var s vs)])
(mark-reg/vars-conf! d vs)
(values (add-var s vs) rs fs ns))]
[else (error who "invalid rs ~s" s)])]
[(fvar? d)
(cond
[(var? s)
(let ([fs (rem-frm d fs)]
[vs (rem-var s vs)])
(mark-frm/vars-conf! d vs)
(mark-frm/nfvs-conf! d ns)
(values (add-var s vs) rs fs ns))]
[else (error who "invalid fs ~s" s)])]
[(var? d)
(cond
[(or (disp? s) (constant? s))
(let ([vs (rem-var d vs)])
(mark-var/vars-conf! d vs)
(mark-var/frms-conf! d fs)
(mark-var/regs-conf! d rs)
(mark-var/nfvs-conf! d ns)
(R s vs rs fs ns))]
[(reg? s)
(let ([vs (rem-var d vs)]
[rs (rem-reg s rs)])
(mark-var/vars-conf! d vs)
(mark-var/frms-conf! d fs)
(mark-var/regs-conf! d rs)
(mark-var/nfvs-conf! d ns)
(values vs (add-reg s rs) fs ns))]
[(var? s)
(let ([vs (rem-var d (rem-var s vs))])
(mark-var/vars-conf! d vs)
(mark-var/frms-conf! d fs)
(mark-var/regs-conf! d rs)
(mark-var/nfvs-conf! d ns)
(values (add-var s vs) rs fs ns))]
[(fvar? s)
(let ([vs (rem-var d vs)]
[fs (rem-frm s fs)])
(mark-var/vars-conf! d vs)
(mark-var/frms-conf! d fs)
(mark-var/regs-conf! d rs)
(mark-var/nfvs-conf! d ns)
(values vs rs (add-var s fs) ns))]
[else (error who "invalid vs ~s" s)])]
[(nfv? d)
(cond
[(var? s)
(let ([ns (rem-nfv d ns)]
[vs (rem-var s vs)])
(mark-nfv/vars-conf! d vs)
(mark-nfv/frms-conf! d fs)
(values (add-var s vs) rs fs ns))]
[else (error who "invalid ns ~s" s)])]
[else (error who "invalid d ~s" d)])]
[(logand logor sll sra int+)
(cond
[(var? d)
(let ([vs (rem-var d vs)])
(mark-var/vars-conf! d vs)
(mark-var/frms-conf! d fs)
(mark-var/nfvs-conf! d ns)
(mark-var/regs-conf! d rs)
(R s (set-add d vs) rs fs ns))]
[(reg? d)
(let ([rs (rem-reg d rs)])
(mark-reg/vars-conf! d vs)
(R s vs (set-add d rs) fs ns))]
[else (error who "invalid op d ~s" (unparse x))])]
[(mset)
(R* (list s d) vs rs fs ns)]
[else (error who "invalid effect op ~s" (unparse x))])]
[(ntcall target value args mask size)
(set! spill-set (union-vars vs spill-set))
(R* args vs (empty-reg-set) fs ns)]
[(nframe nfvs live body)
(for-each init-nfv! nfvs)
(set-nframe-live! x (vector vs fs ns))
(E body vs rs fs ns)]
[(primcall op args)
(case op
[(nop) (values vs rs fs ns)]
[else (error who "invalid effect op ~s" op)])]
[else (error who "invalid effect ~s" (unparse x))]))
(define (P x vst rst fst nst
vsf rsf fsf nsf
vsu rsu fsu nsu)
(record-case x
[(seq e0 e1)
(let-values ([(vs rs fs ns)
(P e1 vst rst fst nst
vsf rsf fsf nsf
vsu rsu fsu nsu)])
(E e0 vs rs fs ns))]
[(conditional e0 e1 e2)
(let-values ([(vs1 rs1 fs1 ns1)
(P e1 vst rst fst nst
vsf rsf fsf nsf
vsu rsu fsu nsu)]
[(vs2 rs2 fs2 ns2)
(P e2 vst rst fst nst
vsf rsf fsf nsf
vsu rsu fsu nsu)])
(P e0
vs1 rs1 fs1 ns1
vs2 rs2 fs2 ns2
(union-vars vs1 vs2)
(union-regs rs1 rs2)
(union-frms fs1 fs2)
(union-nfvs ns1 ns2)))]
[(constant t)
(if t
(values vst rst fst nst)
(values vsf rsf fsf nsf))]
[(asm-instr op d s)
(R* (list d s) vsu rsu fsu nsu)]
[else (error who "invalid pred ~s" (unparse x))]))
(define (T x)
(record-case x
[(seq e0 e1)
(let-values ([(vs rs fs ns) (T e1)])
(E e0 vs rs fs ns))]
[(conditional e0 e1 e2)
(let-values ([(vs1 rs1 fs1 ns1) (T e1)]
[(vs2 rs2 fs2 ns2) (T e2)])
(P e0
vs1 rs1 fs1 ns1
vs2 rs2 fs2 ns2
(union-vars vs1 vs2)
(union-regs rs1 rs2)
(union-frms fs1 fs2)
(union-nfvs ns1 ns2)))]
[(primcall op arg*)
(case op
[(return indirect-jump direct-jump)
(R* arg* (empty-var-set)
(empty-reg-set)
(empty-frm-set)
(empty-nfv-set))]
[else (error who "invalid tail op ~s" x)])]
[else (error who "invalid tail ~s" x)]))
(T x)
spill-set)
;;;
;(define (frm-loc x)
; (unless (fvar? x)
; (error 'frm-loc "invalid ~s" (unparse x)))
; (fvar-idx x))
(define-syntax frm-loc
(syntax-rules ()
[(_ x)
(let ([t x])
(if (fvar? t)
(fvar-idx t)
(error 'frm-loc "in ~s ~s" (unparse t) '(frm-loc x))))]))
(define (frame-conflict? i vs fs)
(define (frm-conf x)
(unless (fvar? x) (error 'here3 "herea"))
(fx= i (frm-loc x)))
(define (var-conf x)
(let ([loc (var-loc x)])
(and loc
(if (fvar? loc) #t
(error 'frame-conflict "non-fvar"))
(fx= i (frm-loc loc)))))
(unless (andmap fvar? fs) (error 'frame-conflict? "nonfvars"))
(or (ormap frm-conf fs)
(ormap var-conf vs)))
;;;
(define (assign-locations! ls)
(define (assign x)
(unless (var? x) (error 'assign "not a var"))
(when (var-loc x) (error 'assign "already assigned"))
(let ([frms (var-frm-conf x)]
[vars (var-var-conf x)])
(let f ([i 1])
(cond
[(frame-conflict? i vars frms) (f (fxadd1 i))]
[else
(let ([fv (mkfvar i)])
(set-var-loc! x fv)
(for-each
(lambda (var)
(set-var-var-conf! var
(rem-var x (var-var-conf var)))
(set-var-frm-conf! var
(add-frm fv (var-frm-conf var))))
vars))]))))
(for-each assign ls))
(define (rewrite x)
(define who 'rewrite)
(define (NFE idx mask x)
(record-case x
[(seq e0 e1) (make-seq (E e0) (NFE idx mask e1))]
[(ntcall target value args mask^ size)
(make-ntcall target value
(map (lambda (x)
(cond
[(symbol? x) x]
[(nfv? x) (nfv-loc x)]
[else (error who "invalid arg")]))
args)
mask idx)]
[else (error who "invalid NF effect ~s" x)]))
(define (R x)
(cond
[(or (constant? x) (reg? x) (fvar? x)) x]
[(nfv? x)
(or (nfv-loc x)
(error who "unassigned nfv"))]
[(var? x)
(or (var-loc x) x)]
[(disp? x)
(make-disp (R (disp-s0 x)) (R (disp-s1 x)))]
[else (error who "invalid R ~s" (unparse x))]))
(define (E x)
(record-case x
[(seq e0 e1)
(make-seq (E e0) (E e1))]
[(conditional e0 e1 e2)
(make-conditional (P e0) (E e1) (E e2))]
[(asm-instr op d s)
(case op
[(move)
(let ([d (R d)] [s (R s)])
(cond
[(eq? d s) (make-primcall 'nop '())]
[else
(make-asm-instr 'move d s)]))]
[(logand logor int+ mset sll sra)
(make-asm-instr op (R d) (R s))]
[else (error who "invalid op ~s" op)])]
[(nframe vars live body)
(let ([live-vars (vector-ref live 0)]
[live-frms (vector-ref live 1)]
[live-nfvs (vector-ref live 2)])
(define (max-frm ls i)
(cond
[(null? ls) i]
[else
(max-frm (cdr ls)
(max i (fvar-idx (car ls))))]))
(define (max-nfv ls i)
(cond
[(null? ls) i]
[else
(let ([loc (nfv-loc (car ls))])
(unless loc (error 'max-nfv "not assigned"))
(max-nfv (cdr ls) (max i (frm-loc loc))))]))
(define (max-var ls i)
(cond
[(null? ls) i]
[else
(max-var (cdr ls)
(let ([loc (var-loc (car ls))])
(if loc
(max i (fvar-idx loc))
(error who "unspilled var"))))]))
(define (actual-frame-size vars i)
(define (frame-size-ok? i vars)
(or (null? vars)
(and (let ([x (car vars)])
(not (frame-conflict? i
(nfv-var-conf x)
(nfv-frm-conf x))))
(frame-size-ok? (fxadd1 i) (cdr vars)))))
(cond
[(frame-size-ok? i vars) i]
[else (actual-frame-size vars (fxadd1 i))]))
(define (assign-frame-vars! vars i)
(unless (null? vars)
(let ([v (car vars)] [fv (mkfvar i)])
(set-nfv-loc! v fv)
(for-each
(lambda (x)
(when (fx= (frm-loc x) i)
(error who "invalid assignment")))
(nfv-frm-conf v))
(for-each
(lambda (x)
(let ([loc (nfv-loc x)])
(cond
[loc
(when (fx= (frm-loc loc) i)
(error who "invalid assignment"))]
[else
(set-nfv-nfv-conf! x
(rem-nfv v (nfv-nfv-conf x)))
(set-nfv-frm-conf! x
(add-frm fv (nfv-frm-conf x)))])))
(nfv-nfv-conf v))
(for-each
(lambda (x)
(let ([loc (var-loc x)])
(cond
[loc
(when (fx= (frm-loc loc) i)
(error who "invalid assignment"))]
[else
(set-var-frm-conf! x
(add-frm fv (var-frm-conf x)))])))
(nfv-var-conf v)))
(assign-frame-vars! (cdr vars) (fxadd1 i))))
(define (make-mask n)
(let ([v (make-vector (fxsra (fx+ n 7) 3) 0)])
(define (set-bit idx)
(let ([q (fxsra idx 3)]
[r (fxlogand idx 7)])
(vector-set! v q
(fxlogor (vector-ref v q) (fxsll 1 r)))))
(for-each (lambda (x) (set-bit (fvar-idx x))) live-frms)
(for-each (lambda (x)
(let ([loc (nfv-loc x)])
(when loc
(set-bit (fvar-idx loc)))))
live-nfvs)
(for-each (lambda (x)
(let ([loc (var-loc x)])
(when loc
(set-bit (fvar-idx loc)))))
live-vars)
v))
(let ([i (actual-frame-size vars
(fx+ 2
(max-var live-vars
(max-nfv live-nfvs
(max-frm live-frms 0)))))])
(assign-frame-vars! vars i)
(NFE (fxsub1 i) (make-mask (fxsub1 i)) body)))]
[(primcall op args)
(case op
[(nop) x]
[else (error who "invalid effect prim ~s" op)])]
[else (error who "invalid effect ~s" (unparse x))]))
(define (P x)
(record-case x
[(seq e0 e1) (make-seq (E e0) (P e1))]
[(conditional e0 e1 e2)
(make-conditional (P e0) (P e1) (P e2))]
[(asm-instr op d s) (make-asm-instr op (R d) (R s))]
[(constant) x]
[else (error who "invalid pred ~s" (unparse x))]))
(define (T x)
(record-case x
[(seq e0 e1)
(make-seq (E e0) (T e1))]
[(conditional e0 e1 e2)
(make-conditional (P e0) (T e1) (T e2))]
[(primcall op args) x]
[else (error who "invalid tail ~s" (unparse x))]))
(T x))
;;;
(define (Main x)
(record-case x
[(locals vars body)
(cond
[(has-nontail-call? body)
(for-each init-var-conf! vars)
(printf "a")
(let ([call-live* (uncover-frame-conflicts body)])
(printf "b")
(assign-locations! call-live*)
(printf "c")
(let ([body (rewrite body)])
(make-locals (set-difference vars call-live*) body)))]
[else x])]
[else (error 'assign-frame-sizes "invalid main ~s" x)]))
;;;
(define (ClambdaCase x)
(record-case x
[(clambda-case info body)
(make-clambda-case info (Main body))]))
;;;
(define (Clambda x)
(record-case x
[(clambda label case* free*)
(make-clambda label (map ClambdaCase case*) free*)]))
;;;
(define (Program x)
(record-case x
[(codes code* body)
(make-codes (map Clambda code*) (Main body))]))
;;;
(define (assign-frame-sizes x)
(Program x)))
(module (color-by-chaitin)
(import ListyGraphs)
;;;
@ -2027,7 +2613,7 @@
[(constant) '()]
[(var) (list x)]
[(disp s0 s1) (union (R s0) (R s1))]
[(nfvar) (list x)]
[(nfv) (list x)]
[(fvar) (if (reg? x) (list x) '())]
[(code-loc) '()]
[else
@ -2037,28 +2623,27 @@
;;; build effect
(define (E x s)
(record-case x
[(set x v)
(let ([s (set-rem x s)])
(record-case x
[(nfvar c i)
(if (list? c)
(set-nfvar-conf! x
(set-union c s))
(set-nfvar-conf! x s))
(union (R v) s)]
[else
(for-each (lambda (y) (add-edge! g x y)) s)
(union (R v) s)]))]
[(asm-instr op d v)
(case op
[(move)
(let ([s (set-rem d s)])
(record-case d
[(nfv c i)
(if (list? c)
(set-nfv-conf! d
(set-union c s))
(set-nfv-conf! d s))
(union (R v) s)]
[else
(for-each (lambda (y) (add-edge! g d y)) s)
(union (R v) s)]))]
[(logand logxor int+ int- int* logor sll sra)
(let ([s (set-rem d s)])
(record-case d
[(nfvar c i)
[(nfv c i)
(if (list? c)
(set-nfvar-conf! d
(set-union c s))
(set-nfvar-conf! d s))
(set-nfv-conf! d (set-union c s))
(set-nfv-conf! d s))
(union (union (R v) (R d)) s)]
[else
(for-each (lambda (y) (add-edge! g d y)) s)
@ -2094,17 +2679,6 @@
[(conditional e0 e1 e2)
(let ([s1 (E e1 s)] [s2 (E e2 s)])
(P e0 s1 s2 (set-union s1 s2)))]
[(nframe vars live body)
(when (reg? return-value-register)
(for-each
(lambda (x)
(for-each (lambda (r)
(add-edge! g x r))
all-registers))
s))
(let ([s (set-difference s all-registers)])
(set-nframe-live! x s)
(E body s))]
[(ntcall targ value args mask size)
(union (R* args) s)]
[(primcall op arg*)
@ -2193,44 +2767,6 @@
;;;
(define (substitute env x frm-graph)
(define who 'substitute)
(define (max-live vars i)
(cond
[(null? vars) i]
[else (max-live (cdr vars)
(record-case (car vars)
[(fvar j) (max i j)]
[else i]))]))
(define (actual-frame-size vars i)
(define (conflicts? i ls)
(and (not (null? ls))
(or (let f ([x (car ls)])
(record-case x
[(fvar j) (eq? i j)]
[(var)
(cond
[(assq x env) => (lambda (x) (f (cdr x)))]
[else #f])]
[(nfvar conf loc) (f loc)]
[else #f]))
(conflicts? i (cdr ls)))))
(define (frame-size-ok? i vars)
(or (null? vars)
(and (not (conflicts? i (nfvar-conf (car vars))))
(frame-size-ok? (fxadd1 i) (cdr vars)))))
(cond
[(frame-size-ok? i vars) i]
[else (actual-frame-size vars (fxadd1 i))]))
(define (assign-frame-vars! vars i)
(unless (null? vars)
(let ([v (car vars)]
[fv (mkfvar i)])
(set-nfvar-loc! v fv)
(for-each
(lambda (x)
(when (var? x)
(add-edge! frm-graph x fv)))
(nfvar-conf v)))
(assign-frame-vars! (cdr vars) (fxadd1 i))))
(define (Var x)
(cond
[(assq x env) => cdr]
@ -2248,34 +2784,9 @@
(define (Lhs x)
(record-case x
[(var) (Var x)]
[(nfvar confs loc)
[(nfv confs loc)
(or loc (error who "LHS not set ~s" x))]
[else x]))
(define (NFE idx mask x)
(record-case x
[(seq e0 e1) (make-seq (E e0) (NFE idx mask e1))]
[(ntcall target value args mask^ size)
(make-ntcall target value
(map (lambda (x)
(if (symbol? x)
x
(Lhs x)))
args)
mask idx)]
[else (error who "invalid NF effect ~s" x)]))
(define (make-mask n live*)
(let ([v (make-vector (fxsra (fx+ n 7) 3) 0)])
(for-each
(lambda (x)
(record-case x
[(fvar idx)
(let ([q (fxsra idx 3)]
[r (fxlogand idx 7)])
(vector-set! v q
(fxlogor (vector-ref v q) (fxsll 1 r))))]
[else (void)]))
live*)
v))
(define (D x)
(record-case x
[(constant) x]
@ -2288,24 +2799,14 @@
[(constant) x]
[(var) (Var x)]
[(fvar) x]
[(nfvar c loc)
(or loc (error who "unset nfvar ~s in R" x))]
[(nfv c loc)
(or loc (error who "unset nfv ~s in R" x))]
[(disp s0 s1) (make-disp (D s0) (D s1))]
[else
(if (symbol? x) x (error who "invalid R ~s" x))]))
;;; substitute effect
(define (E x)
(record-case x
[(set lhs rhs)
(let ([lhs (R lhs)] [rhs (R rhs)])
(cond
[(or (eq? lhs rhs)
(and (fvar? lhs) (fvar? rhs)
(fixnum? (fvar-idx lhs))
(fixnum? (fvar-idx rhs))
(fx= (fvar-idx lhs) (fvar-idx rhs))))
(make-primcall 'nop '())]
[else (make-set lhs rhs)]))]
[(seq e0 e1) (make-seq (E e0) (E e1))]
[(conditional e0 e1 e2)
(make-conditional (P e0) (E e1) (E e2))]
@ -2313,25 +2814,6 @@
(make-asm-instr op (R x) (R v))]
[(primcall op rands)
(make-primcall op (map R rands))]
[(nframe vars live body)
(let ([live-fv*
(map (lambda (x)
(record-case x
[(var)
(let ([l (Var x)])
(if (fvar? l)
l
(error who "unspilled live-after ~s"
x)))]
[(nfvar c loc)
(or loc (error who "unspilled live-after ~s" x))]
[else
(error who "invalid live-after ~s" x)]))
live)])
(let ([i (actual-frame-size vars
(fx+ 2 (max-live live-fv* 0)))])
(assign-frame-vars! vars i)
(NFE (fxsub1 i) (make-mask (fxsub1 i) live-fv*) body)))]
[(ntcall) x]
[else (error who "invalid effect ~s" x)]))
(define (P x)
@ -2385,7 +2867,7 @@
(k x)]
[else
(let ([u (mku)])
(make-seq (E (make-set u x)) (k u)))]))
(make-seq (E (make-asm-instr 'move u x)) (k u)))]))
(define (S* ls k)
(cond
[(null? ls) (k '())]
@ -2400,35 +2882,17 @@
;;; unspillable effect
(define (E x)
(record-case x
[(set lhs rhs)
(cond
[(or (constant? rhs) (var? rhs) (symbol? rhs)) x]
[(fvar? lhs)
(cond
[else
(let ([u (mku)])
(make-seq
(E (make-set u rhs))
(make-set lhs u)))])]
[(fvar? rhs) x]
[(disp? rhs)
(S (disp-s0 rhs)
(lambda (s0)
(S (disp-s1 rhs)
(lambda (s1)
(make-set lhs (make-disp s0 s1))))))]
[else (error who "invalid set in ~s" x)])]
[(seq e0 e1) (make-seq (E e0) (E e1))]
[(conditional e0 e1 e2)
(make-conditional (P e0) (E e1) (E e2))]
[(asm-instr op a b)
(case op
[(logor logxor logand int+ int- int*)
[(logor logxor logand int+ int- int* move)
(cond
[(and (mem? a) (mem? b))
(let ([u (mku)])
(make-seq
(E (make-set u b))
(E (make-asm-instr 'move u b))
(E (make-asm-instr op a u))))]
[else x])]
[(cltd)
@ -2452,7 +2916,7 @@
[(mem? b)
(let ([u (mku)])
(make-seq
(E (make-set u b))
(E (make-asm-instr 'move u b))
(E (make-asm-instr op a u))))]
[else
(let ([s1 (disp-s0 a)] [s2 (disp-s1 a)])
@ -2461,7 +2925,7 @@
(let ([u (mku)])
(make-seq
(make-seq
(E (make-set u s1))
(E (make-asm-instr 'move u s1))
(E (make-asm-instr 'int+ u s2)))
(make-asm-instr op
(make-disp u (make-constant 0))
@ -2469,12 +2933,12 @@
[(mem? s1)
(let ([u (mku)])
(make-seq
(E (make-set u s1))
(E (make-asm-instr 'move u s1))
(make-asm-instr op (make-disp u s2) b)))]
[(mem? s2)
(let ([u (mku)])
(make-seq
(E (make-set u s2))
(E (make-asm-instr 'move u s2))
(make-asm-instr op (make-disp u s1) b)))]
[else x]))])]
[else (error who "invalid effect ~s" op)])]
@ -2497,7 +2961,7 @@
[(and (fvar? a0) (fvar? a1))
(let ([u (mku)])
(make-seq
(make-set u a0)
(make-asm-instr 'move u a0)
(make-primcall op (list u a1))))]
[else x]))]
[(conditional e0 e1 e2)
@ -2508,7 +2972,7 @@
[(and (mem? a) (mem? b))
(let ([u (mku)])
(make-seq
(E (make-set u b))
(E (make-asm-instr 'move u b))
(make-asm-instr op a u)))]
[else x])]
[else (error who "invalid pred ~s" x)]))
@ -2528,28 +2992,18 @@
[(locals sp* body)
(let ([frame-g (build-graph body fvar?)])
(let loop ([sp* sp*] [un* '()] [body body])
(printf "a")
(let ([g (build-graph body
(lambda (x)
(and (symbol? x)
(memq x all-registers))))])
; (printf "loop:\n")
; (print-code body)
;(print-graph g)
(printf "b")
(let-values ([(spills sp* env) (color-graph sp* un* g)])
(printf "c")
(cond
[(null? spills) (substitute env body frame-g)]
[else
(printf "d")
(let* ([env (do-spill spills frame-g)]
[body (substitute env body frame-g)])
(printf "e")
(let-values ([(un* body)
(add-unspillables un* body)])
(printf "f")
(loop sp* un* body)))])))))]))
(let-values ([(un* body) (add-unspillables un* body)])
(let ([g (build-graph body
(lambda (x)
(and (symbol? x)
(memq x all-registers))))])
(let-values ([(spills sp* env) (color-graph sp* un* g)])
(cond
[(null? spills) (substitute env body frame-g)]
[else
(let* ([env (do-spill spills frame-g)]
[body (substitute env body frame-g)])
(loop sp* un* body))]))))))]))
;;;
(define (color-by-chaitin x)
;;;
@ -2632,8 +3086,6 @@
(define (E x ac)
(record-case x
[(seq e0 e1) (E e0 (E e1 ac))]
[(set lhs rhs)
(cons `(movl ,(R rhs) ,(R lhs)) ac)]
[(conditional e0 e1 e2)
(let ([lf (unique-label)] [le (unique-label)])
(P e0 #f lf
@ -2695,6 +3147,7 @@
[(logor) (cons `(orl ,(R s) ,(R d)) ac)]
[(logxor) (cons `(xorl ,(R s) ,(R d)) ac)]
[(mset) (cons `(movl ,(R s) ,(R d)) ac)]
[(move) (cons `(movl ,(R s) ,(R d)) ac)]
[(bset/c) (cons `(movb ,(BYTE s) ,(R d)) ac)]
[(bset/h) (cons `(movb ,(reg/h s) ,(R d)) ac)]
[(sll) (cons `(sall ,(R/cl s) ,(R d)) ac)]
@ -2933,6 +3386,8 @@
;[foo (print-code x)]
[x (impose-calling-convention/evaluation-order x)]
[foo (printf "5")]
[x (assign-frame-sizes x)]
[foo (printf "5.5")]
[x (color-by-chaitin x)]
[foo (printf "6")]
;[foo (print-code x)]

View File

@ -221,7 +221,7 @@
(define-record constant (value))
(define-record code-loc (label))
(define-record foreign-label (label))
(define-record var (name assigned referenced))
(define-record var (name assigned referenced reg-conf frm-conf var-conf loc))
(define-record cp-var (idx))
(define-record frame-var (idx))
(define-record new-frame (base-idx size body))
@ -254,11 +254,10 @@
(define-record fvar (idx))
(define-record set (lhs rhs))
(define-record object (val))
(define-record locals (vars body))
(define-record nframe (vars live body))
(define-record nfvar (conf loc))
(define-record nfv (conf loc var-conf frm-conf nfv-conf))
(define-record ntcall (target value args mask size))
(define-record asm-instr (op dst src))
(define-record disp (s0 s1))
@ -277,7 +276,7 @@
[else (error 'mkfvar "~s is not a fixnum" i)]))))
(define (unique-var x)
(make-var (gensym x) #f #f))
(make-var (gensym x) #f #f #f #f #f #f))
(define (recordize x)
(define *cookie* (gensym))
@ -468,13 +467,18 @@
`(tailcall-cp ,convention ,label ,arg-count)]
[(foreign-label x) `(foreign-label ,x)]
[(mvcall prod cons) `(mvcall ,(E prod) ,(E cons))]
[(set lhs rhs) `(set ,(E lhs) ,(E rhs))]
[(fvar idx) (string->symbol (format "fv.~a" idx))]
[(nfv idx) 'nfv]
[(locals vars body) `(locals ,(map E vars) ,(E body))]
[(nframe vars live body) `(nframe [vars: ,(map E vars)]
[live: ,(map E live)]
[(asm-instr op d s)
`(asm ,op ,(E d) ,(E s))]
[(nframe vars live body) `(nframe ;[vars: ,(map E vars)]
;[live: ,(map E live)]
,(E body))]
[else x]))
[else
(if (symbol? x)
x
"#<unknown>")]))
(E x))
(define open-mvcalls (make-parameter #t))

View File

@ -3861,14 +3861,25 @@
(lambda (x)
((current-expand) x)))
(primitive-set! '$make-environment
(lambda (token mutable?)
(let ((top-ribcage (make-top-ribcage token mutable?)))
(make-env
top-ribcage
(make-wrap
(wrap-marks top-wrap)
(cons top-ribcage (wrap-subst top-wrap)))))))
;(primitive-set! '$make-environment
; (lambda (token mutable?)
; (let ((top-ribcage (make-top-ribcage token mutable?)))
; (make-env
; top-ribcage
; (make-wrap
; (wrap-marks top-wrap)
; (cons top-ribcage (wrap-subst top-wrap)))))))
(let ([make-env
(lambda (token mutable?)
(let ((top-ribcage (make-top-ribcage token mutable?)))
(make-env
top-ribcage
(make-wrap
(wrap-marks top-wrap)
(cons top-ribcage (wrap-subst top-wrap))))))])
(primitive-set! '$make-environment make-env))
(primitive-set! 'environment?
(lambda (x)
@ -3888,6 +3899,7 @@
x
(error 'interaction-environment "~s is not an environment" x)))))
(printf "ENV=~s\n" (interaction-environment))
(primitive-set! 'identifier?
(lambda (x)