This repository has been archived by the owner on Oct 26, 2023. It is now read-only.
forked from iambrj/imin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-interference.rkt
66 lines (59 loc) · 2.31 KB
/
build-interference.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
#lang racket
(require graph
"utilities.rkt"
"utils.rkt"
"constants.rkt")
(provide build-interference)
(define (build-interference d)
(match d
[(ProgramDefs info def*)
(ProgramDefs info (map bi-def def*))]))
(define (bi-def d)
(match d
[(Def name param* rty info label-block*)
(let* ([g (undirected-graph '())]
[types (dict-ref info 'locals-types)]
[_ (map (compose (bi-block g types) cdr) label-block*)])
(printf "Interference graph: ~a\n" (graphviz g))
(Def name param* rty (dict-set info 'conflicts g) label-block*))]))
(define ((bi-block g types) blk)
(match blk
[(Block info instrs)
(let* ([live-after (dict-ref info 'live-after)]
[vertices (apply set-union live-after)]
[_ (for ([v (set->list vertices)]) (add-vertex! g v))]
[_ (for ([i instrs] [la live-after]) (bi-instr i la g types))])
g)]))
(define (bi-instr instr live-after g types)
(match instr
[(Instr 'movq `(,s ,d))
(let* ([d (deref->reg d)]
[_ (for ([v (map deref->reg (set->list live-after))])
(unless (or (equal? v d) (equal? v s)) (add-edge! g d v)))])
g)]
; Don't want TailJmp's argument to be a callee-saved register, since we pop
; off callee saved registers before tail jumping!
[(Instr 'leaq `(,_ ,d))
(let* ([_ (for* ([d (map deref->reg (set->list (instr-w instr)))]
[v (map deref->reg (set->list live-after))])
(unless (equal? v d) (add-edge! g d v)))]
[_ (for* ([r callee-saved])
(add-edge! g d r))])
g)]
[(Callq 'collect _)
(let* ([v-live (filter (lambda (x)
(and (symbol? x)
(Vector? (dict-ref types x))))
(set->list live-after))]
[_ (for* ([v (map deref->reg v-live)]
[r (map deref->reg callee-saved)])
(add-edge! g v r))])
g)]
[else (let* ([_ (for* ([d (map deref->reg (set->list (instr-w instr)))]
[v (map deref->reg (set->list live-after))])
(unless (equal? v d) (add-edge! g d v)))])
g)]))
(define (deref->reg d)
(match d
[(Deref r _) (Reg r)]
[_ d]))