Import Debian changes 20180207-1
[hcoop/debian/mlton.git] / mlton / ssa / common-block.fun
CommitLineData
7f918cf1
CE
1(* Copyright (C) 1999-2006 Henry Cejtin, Matthew Fluet, Suresh
2 * Jagannathan, and Stephen Weeks.
3 * Copyright (C) 1997-2000 NEC Research Institute.
4 *
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
7 *)
8
9functor CommonBlock (S: SSA_TRANSFORM_STRUCTS): SSA_TRANSFORM =
10struct
11
12open S
13open Exp Transfer
14
15fun transform (Program.T {globals, datatypes, functions, main}) =
16 let
17 val shrink = shrinkFunction {globals = globals}
18
19 local
20 fun make transfer = let
21 val l = Label.newNoname ()
22 in
23 Block.T {label = l,
24 args = Vector.new0 (),
25 statements = Vector.new0 (),
26 transfer = transfer}
27 end
28 in
29 fun makeRaise var = make (Raise (Vector.new1 var))
30 fun makeReturn var = make (Return (Vector.new1 var))
31 fun makeGoto (dst, var) = make (Goto {dst = dst, args = Vector.new1 var})
32 end
33 fun makeNullaryGoto dst = Goto {dst = dst, args = Vector.new0 ()}
34
35 val {get = varInfo:
36 Var.t -> {returner: (Func.t * Label.t) option ref,
37 raiser: (Func.t * Label.t) option ref,
38 gotoers: (Func.t * (Label.t * Label.t) list ref) option ref} option,
39 set = setVarInfo, ...} =
40 Property.getSetOnce
41 (Var.plist, Property.initConst NONE)
42
43 val _ =
44 Vector.foreach
45 (globals, fn Statement.T {var, ...} =>
46 setVarInfo(valOf var, SOME {returner = ref NONE,
47 raiser = ref NONE,
48 gotoers = ref NONE}))
49
50 fun eliminateFunction f =
51 let
52 val {args, blocks, mayInline, name, returns, raises, start} =
53 Function.dest f
54 val newBlocks = ref []
55 local
56 fun common (sel, make) var =
57 case varInfo var of
58 NONE => NONE
59 | SOME varInfo =>
60 let
61 val c = sel varInfo
62
63 fun install () =
64 let
65 val b = make var
66 val l = Block.label b
67 in
68 List.push(newBlocks, b) ;
69 c := SOME (name, l) ;
70 SOME l
71 end
72 in
73 case !c of
74 NONE => install ()
75 | SOME (name', l') =>
76 if Func.equals(name, name')
77 then SOME l'
78 else install ()
79 end
80 in
81 val commonReturner = common (#returner, makeReturn)
82 val commonRaiser = common (#raiser, makeRaise)
83 end
84 fun commonGotoers (k, var) =
85 case varInfo var of
86 NONE => NONE
87 | SOME {gotoers, ...} =>
88 let
89 fun install info =
90 let
91 val b = makeGoto (k, var)
92 val l = Block.label b
93 in
94 List.push(newBlocks, b) ;
95 List.push(info, (k, l)) ;
96 SOME l
97 end
98 fun install' () =
99 let
100 val info = ref []
101 in
102 gotoers := SOME (name, info);
103 install info
104 end
105 in
106 case !gotoers of
107 NONE => install' ()
108 | SOME (name', info') =>
109 if Func.equals(name, name')
110 then case List.peek (!info', fn (k', _) =>
111 Label.equals(k', k)) of
112 NONE => install info'
113 | SOME (_, l') => SOME l'
114 else install' ()
115 end
116
117 val blocks =
118 Vector.map
119 (blocks, fn Block.T {label, args, statements, transfer} =>
120 let
121 val doit = fn SOME l => makeNullaryGoto l
122 | NONE => transfer
123 val transfer =
124 if Vector.isEmpty statements
125 then case transfer of
126 Goto {dst, args = xs} =>
127 if Vector.length xs = 1
128 then doit (commonGotoers
129 (dst, Vector.first xs))
130 else transfer
131 | Return xs =>
132 if Vector.length xs = 1
133 then doit (commonReturner
134 (Vector.first xs))
135 else transfer
136 | Raise xs =>
137 if Vector.length xs = 1
138 then doit (commonRaiser
139 (Vector.first xs))
140 else transfer
141 | _ => transfer
142 else transfer
143 in
144 Block.T {label = label,
145 args = args,
146 statements = statements,
147 transfer = transfer}
148 end)
149 val blocks = Vector.concat [Vector.fromList (!newBlocks), blocks]
150 in
151 shrink (Function.new {args = args,
152 blocks = blocks,
153 mayInline = mayInline,
154 name = name,
155 raises = raises,
156 returns = returns,
157 start = start})
158 end
159
160 val program =
161 Program.T {datatypes = datatypes,
162 globals = globals,
163 functions = List.revMap (functions, eliminateFunction),
164 main = main}
165 val _ = Program.clearTop program
166 in
167 program
168 end
169end