Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / mlton / core-ml / dead-code.fun
CommitLineData
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
10functor DeadCode (S: DEAD_CODE_STRUCTS): DEAD_CODE =
11struct
12
13open S
14open CoreML
15open Dec
16
17fun 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
79end