-
Notifications
You must be signed in to change notification settings - Fork 1
/
limit-functions.rkt
96 lines (90 loc) · 3.89 KB
/
limit-functions.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
90
91
92
93
94
95
96
#lang racket
(require "utilities.rkt")
(provide limit-functions)
(define (limit-functions p)
(match p
[(ProgramDefs info def*)
(let ([def* (map limit-def def*)])
(ProgramDefs info (map (lambda (d)
(struct-copy Def d
[body (limit-calls (Def-body d))]))
def*)))]))
(define (limit-def d)
(match d
[(Def name param* rty info body)
(let* ([vec (gensym 'arg6-)]
[types (map caddr param*)]
[vectorized (if (> (length param*) 6)
(map car (drop param* 5))
'())]
[param* (if (> (length param*) 6)
(append (take param* 5)
`((,vec : ,(cons 'Vector (drop types 5)))))
param*)])
(Def name param* rty info ((update-body vec vectorized) body)))]))
(define ((update-body vec vectorized) body)
(if (not (null? vectorized))
(match body
[(Void) (Void)]
[(Int i) (Int i)]
[(Bool b) (Bool b)]
[(Var v) (if (member v vectorized)
(Prim 'vector-ref `(,(Var vec) ,(Int (index-of vectorized v))))
(Var v))]
[(HasType e t) (HasType ((update-body vec vectorized) e) t)]
[(If c t e) (If ((update-body vec vectorized) c)
((update-body vec vectorized) t)
((update-body vec vectorized) e))]
[(Let v e b)
; XXX : Trade off between this trick and deleteing elements?
(let ([vectorized1 (if (member v vectorized)
(list-update vectorized
(index-of vectorized v)
(gensym))
vectorized)])
(Let v ((update-body vec vectorized) e)
((update-body vec vectorized1) b)))]
[(Prim op es) #:when (member op '(read - + not < vector vector-length))
(Prim op (map (update-body vec vectorized) es))]
[(Prim 'vector-ref `(,e ,(Int i)))
(Prim 'vector-ref `(,((update-body vec vectorized) e) ,(Int i)))]
[(Prim 'vector-set! `(,e1 ,(Int i) ,e2))
(Prim 'vector-set! `(,((update-body vec vectorized) e1)
,(Int i)
,((update-body vec vectorized) e2)))]
; Invariant : only top level function definitions are allowed, no clause
; needed for Def
[(Apply fun arg*)
(Apply ((update-body vec vectorized) fun) (map (update-body vec vectorized) arg*))])
body))
(define (limit-calls e)
(match e
[(Void) (Void)]
[(Int i) (Int i)]
[(Bool b) (Bool b)]
[(Var v) (Var v)]
[(FunRef f) (FunRef f)]
[(HasType e t) (HasType (limit-calls e) t)]
[(If c t e) (If (limit-calls c)
(limit-calls t)
(limit-calls e))]
[(Let v e b)
; XXX : Trade off between this trick and deleteing elements?
(Let v (limit-calls e) (limit-calls b))]
[(Prim op es) #:when (member op '(read - + not < vector vector-length))
(Prim op (map limit-calls es))]
[(Prim 'vector-ref `(,e ,(Int i)))
(Prim 'vector-ref `(,(limit-calls e) ,(Int i)))]
[(Prim 'vector-set! `(,e1 ,(Int i) ,e2))
(Prim 'vector-set! `(,(limit-calls e1)
,(Int i)
,(limit-calls e2)))]
; Invariant : only top level function definitions are allowed, no clause
; needed for Def
[(Apply fun arg*)
(Apply (limit-calls fun)
(let ([arg* (if (> (length arg*) 6)
(append (take arg* 5)
`(,(Prim 'vector (drop arg* 5))))
arg*)])
(map limit-calls arg*)))]))