1 (define (analyze-liveness cfg)
5 (define (instr-analyze-liveness instr live-after)
7 (cond ((call-instr? instr)
8 (let ((def-proc (call-instr-def-proc instr)))
10 (def-procedure-live-after-calls def-proc))
14 (if (not (set-equal? old new))
17 (def-procedure-live-after-calls-set! def-proc new))))
21 (map (lambda (def-var)
22 (value-bytes (def-variable-value def-var)))
23 (def-procedure-params def-proc)))
25 (value-bytes (def-procedure-value def-proc))))))
26 (if (bb? (def-procedure-entry def-proc))
28 (bb-live-before (def-procedure-entry def-proc))
31 ((return-instr? instr)
32 ;;(pp (list instr: instr))
33 (let ((def-proc (return-instr-def-proc instr)))
35 (if (def-procedure? def-proc)
36 (def-procedure-live-after-calls def-proc)
37 (value-bytes def-proc))))
38 (let ((live (keep byte-cell? live)))
39 ;;(pp (list live: live))
40 (set! live-after live)
44 ;;(pp (list instr: instr))
45 (let* ((src1 (instr-src1 instr))
46 (src2 (instr-src2 instr))
47 (dst (instr-dst instr))
48 (use (if (byte-cell? src1)
50 (union (list src1) (list src2))
55 (def (if (byte-cell? dst)
58 (if #f #;(and (byte-cell? dst) ; dead instruction?
59 (not (memq dst live-after))
60 (not (and (byte-cell? dst) (byte-cell-adr dst))))
62 (union use (diff live-after def))))))))
63 (instr-live-before-set! instr live-before)
64 (instr-live-after-set! instr live-after)
67 (define (bb-analyze-liveness bb)
68 (let loop ((rev-instrs (bb-rev-instrs bb))
69 (live-after (union-multi (map bb-live-before (bb-succs bb)))))
70 (if (null? rev-instrs)
71 (if (not (set-equal? live-after (bb-live-before bb)))
74 (bb-live-before-set! bb live-after)))
75 (let* ((instr (car rev-instrs))
76 (live-before (instr-analyze-liveness instr live-after)))
77 (loop (cdr rev-instrs)
84 (for-each bb-analyze-liveness (cfg-bbs cfg))
88 ;------------------------------------------------------------------------------
90 (define (cfg->vector cfg)
91 (let ((vect (make-vector (cfg-next-label-num cfg) #f)))
92 (for-each (lambda (bb)
93 (vector-set! vect (bb-label-num bb) bb))
97 (define (remove-branch-cascades-and-dead-code cfg)
98 (let ((bbs-vector (cfg->vector cfg)))
100 (define (chase-branch-cascade bb seen)
103 (let* ((rev-instrs (bb-rev-instrs bb))
104 (last (car rev-instrs)))
105 (if (null? (cdr rev-instrs))
107 (cond ((eq? (instr-id last) 'goto)
109 (car (bb-succs bb))))
111 (chase-branch-cascade old-dest
119 (define (bb-process bb)
125 (map (lambda (x) (chase-branch-cascade x seen)) old-succs)))
126 (for-each (lambda (old-dest new-dest)
127 (if (not (eq? old-dest new-dest))
129 (bb-succs-set! bb (replace old-dest new-dest (bb-succs bb)))
130 (bb-preds-set! old-dest
131 (remove bb (bb-preds old-dest)))
132 (bb-preds-set! new-dest
133 (cons bb (bb-preds old-dest))))))
137 (for-each bb-process (cfg-bbs cfg))))
139 ;------------------------------------------------------------------------------
141 ;; remove conditions whose 2 destination branches are the same, and replaces
142 ;; them with simple jumps
143 (define (remove-converging-branches cfg)
145 (define (bb-process bb)
146 (let ((instrs (bb-rev-instrs bb))
147 (succs (bb-succs bb)))
148 (if (and (memq (instr-id (car instrs)) conditional-instrs) ; conditional
149 (>= (length succs) 2)
150 (eq? (car succs) (cadr succs))) ; both destinations are the same
151 (bb-rev-instrs-set! bb (cons (new-instr 'goto #f #f #f)
154 (for-each bb-process (cfg-bbs cfg)))
156 ;------------------------------------------------------------------------------
158 ;; removes dead instructions (instructions after a return or after all jumps)
159 (define (remove-dead-instructions cfg)
161 (define (bb-process bb)
162 ;; since instructions are in erverse order, loop until we find a jump,
163 ;; and keep everything after
164 (let loop ((instrs (reverse (bb-rev-instrs bb)))
167 (error "no jump in the bb:" bb))
168 (let* ((head (car instrs))
169 (op (instr-id head)))
170 (if (or (eq? op 'return)
172 (memq op conditional-instrs))
173 (bb-rev-instrs-set! bb (cons head new-instrs))
175 (cons head new-instrs))))))
177 (for-each bb-process (cfg-bbs cfg)))