1 (define (cfg->vector cfg)
2 (let ((vect (make-vector (cfg-next-label-num cfg) #f)))
4 (vector-set! vect (bb-label-num bb) bb))
8 (define (remove-branch-cascades-and-dead-code cfg)
9 (let ((bbs-vector (cfg->vector cfg)))
11 (define (chase-branch-cascade bb seen)
14 (let* ((rev-instrs (bb-rev-instrs bb))
15 (last (car rev-instrs)))
16 (if (null? (cdr rev-instrs))
18 (cond ((eq? (instr-id last) 'goto)
22 (chase-branch-cascade old-dest
30 (define (bb-process bb)
36 (map (lambda (x) (chase-branch-cascade x seen)) old-succs)))
37 (for-each (lambda (old-dest new-dest)
38 (if (not (eq? old-dest new-dest))
40 (bb-succs-set! bb (replace old-dest new-dest (bb-succs bb)))
41 (bb-preds-set! old-dest
42 (remove bb (bb-preds old-dest)))
43 (bb-preds-set! new-dest
44 (cons bb (bb-preds old-dest))))))
48 (for-each bb-process (cfg-bbs cfg))))
50 ;------------------------------------------------------------------------------
52 ;; remove conditions whose 2 destination branches are the same, and replaces
53 ;; them with simple jumps
54 (define (remove-converging-branches cfg)
56 (define (bb-process bb)
57 (let ((instrs (bb-rev-instrs bb))
58 (succs (bb-succs bb)))
59 (if (and (memq (instr-id (car instrs)) conditional-instrs) ; conditional
61 (eq? (car succs) (cadr succs))) ; both destinations are the same
62 (bb-rev-instrs-set! bb (cons (new-instr 'goto #f #f #f)
65 (for-each bb-process (cfg-bbs cfg)))
67 ;------------------------------------------------------------------------------
69 ;; removes dead instructions (instructions after a return or after all jumps)
70 (define (remove-dead-instructions cfg)
72 (define (bb-process bb)
73 ;; since instructions are in erverse order, loop until we find a jump,
74 ;; and keep everything after
75 (let loop ((instrs (reverse (bb-rev-instrs bb)))
78 (error "no jump in the bb:" bb))
79 (let* ((head (car instrs))
81 (if (or (eq? op 'return)
83 (memq op conditional-instrs))
84 (bb-rev-instrs-set! bb (cons head new-instrs))
86 (cons head new-instrs))))))
88 (for-each bb-process (cfg-bbs cfg)))