-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconstant_folding.ml
More file actions
79 lines (72 loc) · 2.79 KB
/
constant_folding.ml
File metadata and controls
79 lines (72 loc) · 2.79 KB
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
open Low_level_tree
open Utils
type cached_value =
| ConstIncrease of int
| ConstValue of int
| IncreasedVariable of memory_location * int
let add x = function
| ConstIncrease y -> ConstIncrease (x+y)
| ConstValue y -> ConstValue (x+y)
| IncreasedVariable (offset, y) -> IncreasedVariable (offset, x+y)
let get_value memory = function
| Const x -> `Const x
| Memory offset ->
if IntMap.mem offset memory then
match IntMap.find offset memory with
| ConstValue x -> `Const x
| IncreasedVariable (offset2, 0) -> `Variable offset2
| _ -> `Variable offset
else
`Variable offset
let realize memory offset =
if IntMap.mem offset memory then
match IntMap.find offset memory with
| ConstIncrease x -> [Add (offset, Const x)]
| ConstValue x -> [Set (offset, Const x)]
| IncreasedVariable (offset2, x) ->
[Set (offset, Memory offset2); Add (offset, Const x)]
else
[]
let realize_all memory = List.concat (List.map (realize memory) (IntMap.keys memory))
let rec optimize memory = function
| [] -> realize_all memory
| Add (offset, value) :: rest ->
(match get_value memory value with
| `Const x ->
let new_value =
if IntMap.mem offset memory then
add x (IntMap.find offset memory)
else
ConstIncrease x
in
optimize (IntMap.add offset new_value memory) rest
| `Variable offset2 ->
if IntMap.mem offset memory then
match IntMap.find offset memory with
| ConstValue x ->
optimize (IntMap.add offset (IncreasedVariable (offset2, x)) memory) rest
| _ ->
realize memory offset @ (Add (offset, value) :: optimize memory rest)
else
Add (offset, value) :: optimize memory rest)
| Set (offset, Memory offset2) :: rest ->
optimize (IntMap.add offset (IncreasedVariable (offset2, 0)) memory) rest
| Set (offset, Const x) :: rest ->
optimize (IntMap.add offset (ConstValue x) memory) rest
| Input offset :: rest ->
Input offset :: optimize (IntMap.remove offset memory) rest
| Output (Memory offset) :: rest ->
(match get_value memory (Memory offset) with
| `Const x -> Output (Const x) :: optimize memory rest
| `Variable offset2 ->
realize memory offset2 @ Output (Memory offset2) :: optimize IntMap.empty rest)
| Store :: rest ->
let instructions = realize_all memory in
instructions @ Store :: optimize IntMap.empty rest
| Loop body :: rest ->
realize_all memory @ Loop (optimize IntMap.empty body) :: optimize IntMap.empty rest
| BalancedLoop (offset, body) :: rest ->
realize_all memory @ BalancedLoop (offset, optimize IntMap.empty body) :: optimize IntMap.empty rest
| statement :: rest ->
statement :: optimize memory rest
let optimize = optimize IntMap.empty