Commit | Line | Data |
---|---|---|
7f918cf1 CE |
1 | (* Copyright (C) 2011 Matthew Fluet. |
2 | * Copyright (C) 1999-2005 Henry Cejtin, Matthew Fluet, Suresh | |
3 | * Jagannathan, and Stephen Weeks. | |
4 | * Copyright (C) 1997-2000 NEC Research Institute. | |
5 | * | |
6 | * MLton is released under a BSD-style license. | |
7 | * See the file MLton-LICENSE for details. | |
8 | *) | |
9 | ||
10 | functor DeadCode (S: DEAD_CODE_STRUCTS): DEAD_CODE = | |
11 | struct | |
12 | ||
13 | open S | |
14 | open CoreML | |
15 | open Dec | |
16 | ||
17 | fun deadCode {prog} = | |
18 | let | |
19 | val {get = varIsUsed, set = setVarIsUsed, destroy, ...} = | |
20 | Property.destGetSet (Var.plist, Property.initConst false) | |
21 | fun patVarIsUsed (p: Pat.t): bool = | |
22 | Exn.withEscape | |
23 | (fn escape => | |
24 | (Pat.foreachVar (p, fn x => if varIsUsed x | |
25 | then escape true | |
26 | else ()) | |
27 | ; false)) | |
28 | fun decIsWildOrUnit (d: Dec.t): bool = | |
29 | case d of | |
30 | Val {rvbs, vbs, ...} => | |
31 | 0 = Vector.length rvbs | |
32 | andalso 1 = Vector.length vbs | |
33 | andalso let | |
34 | val pat = #pat (Vector.first vbs) | |
35 | in | |
36 | Pat.isWild pat orelse Pat.isUnit pat | |
37 | end | |
38 | | _ => false | |
39 | fun decIsNeeded (d: Dec.t): bool = | |
40 | case d of | |
41 | Datatype _ => true | |
42 | | Exception _ => true | |
43 | | Fun {decs, ...} => Vector.exists (decs, varIsUsed o #var) | |
44 | | Val {rvbs, vbs, ...} => | |
45 | Vector.exists (rvbs, varIsUsed o #var) | |
46 | orelse Vector.exists (vbs, patVarIsUsed o #pat) | |
47 | fun useVar x = setVarIsUsed (x, true) | |
48 | fun useExp (e: Exp.t): unit = Exp.foreachVar (e, useVar) | |
49 | fun useLambda (l: Lambda.t): unit = | |
50 | useExp (#body (Lambda.dest l)) | |
51 | fun useDec (d: Dec.t): unit = | |
52 | case d of | |
53 | Datatype _ => () | |
54 | | Exception _ => () | |
55 | | Fun {decs, ...} => Vector.foreach (decs, useLambda o #lambda) | |
56 | | Val {rvbs, vbs, ...} => | |
57 | (Vector.foreach (rvbs, useLambda o #lambda) | |
58 | ; Vector.foreach (vbs, useExp o #exp)) | |
59 | ||
60 | val n = Vector.length prog | |
61 | val m = n - 1 | |
62 | val prog = | |
63 | Vector.tabulate | |
64 | (n, fn i => | |
65 | let val (decs, deadCode) = Vector.sub (prog, m - i) | |
66 | in | |
67 | if deadCode | |
68 | then List.fold (rev decs, [], fn (dec, decs) => | |
69 | if decIsWildOrUnit dec orelse decIsNeeded dec | |
70 | then (useDec dec; dec :: decs) | |
71 | else decs) | |
72 | else (List.foreach (decs, useDec) | |
73 | ; decs) | |
74 | end) | |
75 | val _ = destroy () | |
76 | in {prog = Vector.rev prog} | |
77 | end | |
78 | ||
79 | end |