-
Notifications
You must be signed in to change notification settings - Fork 0
/
uncover-live.rkt
89 lines (73 loc) · 2.58 KB
/
uncover-live.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#lang racket
(require "type-check-Cif.rkt")
(require "interp-Cif.rkt")
(require "utilities.rkt")
(require graph)
(require "multigraph.rkt")
(require "instr-utils.rkt")
(require data/queue)
(provide uncover-live)
(define (analyze-dataflow G transfer bottom join)
(define mapping (make-hash))
(for ([v (in-vertices G)])
(dict-set! mapping v bottom))
(define worklist (make-queue))
(for ([v (in-vertices G)])
(enqueue! worklist v))
(define trans-G (transpose G))
(while (not (queue-empty? worklist))
(define node (dequeue! worklist))
(define input
(for/fold ([state bottom])
([pred (in-neighbors trans-G node)])
(join state (dict-ref mapping pred))))
(define output (transfer node input))
(cond [(not (equal? output (dict-ref mapping node)))
(dict-set! mapping node output)
(for ([v (in-neighbors G node)])
(enqueue! worklist v))]))
mapping)
(define (build-cfg p)
(error "todo: complete this function")) ; hint: use multigraph.rkt
(define (uncover-live p)
; we add a list of live-after sets to each block. Recall that a program contains
; one block for each label
;; (define (fold-instr instr live-sets)
;; (match instr
;; [(Jmp label)
;; (cons (dict-ref label->live label) live-sets)]
;; [(JmpIf cc label)
;; (define after (set-union (first live-sets) (dict-ref label->live label)))
;; (cons
;; (set-union
;; (set-subtract after (locs-write instr))
;; (locs-read instr))
;; live-sets)]
;; [else
;; (define after (first live-sets))
;; (cons
;; (set-union
;; (set-subtract after (locs-write instr))
;; (locs-read instr))
;; live-sets)]))
(match p
[(X86Program info blocks)
(define label->live (list (cons 'conclusion (set (Reg 'rax) (Reg 'rsp)))))
(define (fold-instr instr live-sets)
(define after (first live-sets))
(cons
(set-union
(set-subtract after (locs-write instr))
(locs-read instr))
live-sets))
(define (transfer label live-after)
(define block (dict-ref blocks label))
(match block
[(Block info instrs)
(define live-sets
(foldl fold-instr (list live-after) (reverse instrs)))
(set! info (dict-set info 'live-sets live-sets))
(set! blocks (dict-set blocks label (Block info instrs)))
(first live-sets)]))
(analyze-dataflow (transpose (build-cfg p)) transfer (set) set-union)
(X86Program info blocks)]))