annotate src/especialize.sml @ 1080:a4979e31e4bf

Another try at reasonable Especialize, this time with a custom traversal
author Adam Chlipala <adamc@hcoop.net>
date Sun, 20 Dec 2009 15:17:43 -0500
parents d069b193ed6b
children 2eb585274501
rev   line source
adamc@1080 1 (* Copyright (c) 2008-2009, Adam Chlipala
adamc@443 2 * All rights reserved.
adamc@443 3 *
adamc@443 4 * Redistribution and use in source and binary forms, with or without
adamc@443 5 * modification, are permitted provided that the following conditions are met:
adamc@443 6 *
adamc@443 7 * - Redistributions of source code must retain the above copyright notice,
adamc@443 8 * this list of conditions and the following disclaimer.
adamc@443 9 * - Redistributions in binary form must reproduce the above copyright notice,
adamc@443 10 * this list of conditions and the following disclaimer in the documentation
adamc@443 11 * and/or other materials provided with the distribution.
adamc@443 12 * - The names of contributors may not be used to endorse or promote products
adamc@443 13 * derived from this software without specific prior written permission.
adamc@443 14 *
adamc@443 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
adamc@443 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
adamc@443 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
adamc@443 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
adamc@443 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
adamc@443 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
adamc@443 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
adamc@443 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
adamc@443 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
adamc@443 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
adamc@443 25 * POSSIBILITY OF SUCH DAMAGE.
adamc@443 26 *)
adamc@443 27
adamc@443 28 structure ESpecialize :> ESPECIALIZE = struct
adamc@443 29
adamc@443 30 open Core
adamc@443 31
adamc@443 32 structure E = CoreEnv
adamc@443 33 structure U = CoreUtil
adamc@443 34
adamc@479 35 type skey = exp
adamc@453 36
adamc@453 37 structure K = struct
adamc@479 38 type ord_key = exp list
adamc@479 39 val compare = Order.joinL U.Exp.compare
adamc@443 40 end
adamc@443 41
adamc@453 42 structure KM = BinaryMapFn(K)
adamc@443 43 structure IM = IntBinaryMap
adamc@482 44 structure IS = IntBinarySet
adamc@443 45
adamc@626 46 val freeVars = U.Exp.foldB {kind = fn (_, _, xs) => xs,
adamc@488 47 con = fn (_, _, xs) => xs,
adamc@488 48 exp = fn (bound, e, xs) =>
adamc@488 49 case e of
adamc@488 50 ERel x =>
adamc@488 51 if x >= bound then
adamc@488 52 IS.add (xs, x - bound)
adamc@488 53 else
adamc@488 54 xs
adamc@488 55 | _ => xs,
adamc@488 56 bind = fn (bound, b) =>
adamc@488 57 case b of
adamc@488 58 U.Exp.RelE _ => bound + 1
adamc@488 59 | _ => bound}
adamc@488 60 0 IS.empty
adamc@479 61
adamc@522 62 val isPoly = U.Decl.exists {kind = fn _ => false,
adamc@522 63 con = fn _ => false,
adamc@522 64 exp = fn ECAbs _ => true
adamc@1080 65 | EKAbs _ => true
adamc@522 66 | _ => false,
adamc@522 67 decl = fn _ => false}
adamc@522 68
adamc@488 69 fun positionOf (v : int, ls) =
adamc@488 70 let
adamc@488 71 fun pof (pos, ls) =
adamc@488 72 case ls of
adamc@488 73 [] => raise Fail "Defunc.positionOf"
adamc@488 74 | v' :: ls' =>
adamc@488 75 if v = v' then
adamc@488 76 pos
adamc@488 77 else
adamc@488 78 pof (pos + 1, ls')
adamc@488 79 in
adamc@488 80 pof (0, ls)
adamc@488 81 end
adamc@488 82
adamc@1079 83 fun squish fvs =
adamc@626 84 U.Exp.mapB {kind = fn _ => fn k => k,
adamc@488 85 con = fn _ => fn c => c,
adamc@488 86 exp = fn bound => fn e =>
adamc@479 87 case e of
adamc@488 88 ERel x =>
adamc@488 89 if x >= bound then
adamc@1079 90 ERel (positionOf (x - bound, fvs) + bound)
adamc@488 91 else
adamc@488 92 e
adamc@488 93 | _ => e,
adamc@488 94 bind = fn (bound, b) =>
adamc@488 95 case b of
adamc@488 96 U.Exp.RelE _ => bound + 1
adamc@488 97 | _ => bound}
adamc@488 98 0
adamc@453 99
adamc@443 100 type func = {
adamc@443 101 name : string,
adamc@453 102 args : int KM.map,
adamc@443 103 body : exp,
adamc@443 104 typ : con,
adamc@443 105 tag : string
adamc@443 106 }
adamc@443 107
adamc@443 108 type state = {
adamc@443 109 maxName : int,
adamc@443 110 funcs : func IM.map,
adamc@1079 111 decls : (string * int * con * exp * string) list,
adamc@1080 112 specialized : IS.set
adamc@443 113 }
adamc@443 114
adamc@488 115 fun default (_, x, st) = (x, st)
adamc@443 116
adamc@800 117 structure SS = BinarySetFn(struct
adamc@800 118 type ord_key = string
adamc@800 119 val compare = String.compare
adamc@800 120 end)
adamc@800 121
adamc@800 122 val mayNotSpec = ref SS.empty
adamc@800 123
adamc@1080 124 fun specialize' (funcs, specialized) file =
adamc@443 125 let
adamc@488 126 fun bind (env, b) =
adamc@488 127 case b of
adamc@521 128 U.Decl.RelE xt => xt :: env
adamc@521 129 | _ => env
adamc@488 130
adamc@1080 131 fun exp (env, e as (_, loc), st : state) =
adamc@482 132 let
adamc@721 133 (*val () = Print.prefaces "exp" [("e", CorePrint.p_exp CoreEnv.empty
adamc@721 134 (e, ErrorMsg.dummySpan))]*)
adamc@721 135
adamc@1080 136 fun getApp (e, _) =
adamc@482 137 case e of
adamc@488 138 ENamed f => SOME (f, [])
adamc@482 139 | EApp (e1, e2) =>
adamc@1080 140 (case getApp e1 of
adamc@482 141 NONE => NONE
adamc@488 142 | SOME (f, xs) => SOME (f, xs @ [e2]))
adamc@482 143 | _ => NONE
adamc@1080 144
adamc@1080 145 val getApp = fn e => case getApp e of
adamc@1080 146 v as SOME (_, _ :: _) => v
adamc@1080 147 | _ => NONE
adamc@1080 148
adamc@1080 149 fun default () =
adamc@1080 150 case #1 e of
adamc@1080 151 EPrim _ => (e, st)
adamc@1080 152 | ERel _ => (e, st)
adamc@1080 153 | ENamed _ => (e, st)
adamc@1080 154 | ECon (_, _, _, NONE) => (e, st)
adamc@1080 155 | ECon (dk, pc, cs, SOME e) =>
adamc@1080 156 let
adamc@1080 157 val (e, st) = exp (env, e, st)
adamc@1080 158 in
adamc@1080 159 ((ECon (dk, pc, cs, SOME e), loc), st)
adamc@1080 160 end
adamc@1080 161 | EFfi _ => (e, st)
adamc@1080 162 | EFfiApp (m, x, es) =>
adamc@1080 163 let
adamc@1080 164 val (es, st) = ListUtil.foldlMap (fn (e, st) => exp (env, e, st)) st es
adamc@1080 165 in
adamc@1080 166 ((EFfiApp (m, x, es), loc), st)
adamc@1080 167 end
adamc@1080 168 | EApp (e1, e2) =>
adamc@1080 169 let
adamc@1080 170 val (e1, st) = exp (env, e1, st)
adamc@1080 171 val (e2, st) = exp (env, e2, st)
adamc@1080 172 in
adamc@1080 173 ((EApp (e1, e2), loc), st)
adamc@1080 174 end
adamc@1080 175 | EAbs (x, d, r, e) =>
adamc@1080 176 let
adamc@1080 177 val (e, st) = exp ((x, d) :: env, e, st)
adamc@1080 178 in
adamc@1080 179 ((EAbs (x, d, r, e), loc), st)
adamc@1080 180 end
adamc@1080 181 | ECApp (e, c) =>
adamc@1080 182 let
adamc@1080 183 val (e, st) = exp (env, e, st)
adamc@1080 184 in
adamc@1080 185 ((ECApp (e, c), loc), st)
adamc@1080 186 end
adamc@1080 187 | ECAbs _ => raise Fail "Especialize: Impossible ECAbs"
adamc@1080 188 | EKAbs _ => raise Fail "Especialize: Impossible EKAbs"
adamc@1080 189 | EKApp (e, k) =>
adamc@1080 190 let
adamc@1080 191 val (e, st) = exp (env, e, st)
adamc@1080 192 in
adamc@1080 193 ((EKApp (e, k), loc), st)
adamc@1080 194 end
adamc@1080 195 | ERecord fs =>
adamc@1080 196 let
adamc@1080 197 val (fs, st) = ListUtil.foldlMap (fn ((c1, e, c2), st) =>
adamc@1080 198 let
adamc@1080 199 val (e, st) = exp (env, e, st)
adamc@1080 200 in
adamc@1080 201 ((c1, e, c2), st)
adamc@1080 202 end) st fs
adamc@1080 203 in
adamc@1080 204 ((ERecord fs, loc), st)
adamc@1080 205 end
adamc@1080 206 | EField (e, c, cs) =>
adamc@1080 207 let
adamc@1080 208 val (e, st) = exp (env, e, st)
adamc@1080 209 in
adamc@1080 210 ((EField (e, c, cs), loc), st)
adamc@1080 211 end
adamc@1080 212 | EConcat (e1, c1, e2, c2) =>
adamc@1080 213 let
adamc@1080 214 val (e1, st) = exp (env, e1, st)
adamc@1080 215 val (e2, st) = exp (env, e2, st)
adamc@1080 216 in
adamc@1080 217 ((EConcat (e1, c1, e2, c2), loc), st)
adamc@1080 218 end
adamc@1080 219 | ECut (e, c, cs) =>
adamc@1080 220 let
adamc@1080 221 val (e, st) = exp (env, e, st)
adamc@1080 222 in
adamc@1080 223 ((ECut (e, c, cs), loc), st)
adamc@1080 224 end
adamc@1080 225 | ECutMulti (e, c, cs) =>
adamc@1080 226 let
adamc@1080 227 val (e, st) = exp (env, e, st)
adamc@1080 228 in
adamc@1080 229 ((ECutMulti (e, c, cs), loc), st)
adamc@1080 230 end
adamc@1080 231
adamc@1080 232 | ECase (e, pes, cs) =>
adamc@1080 233 let
adamc@1080 234 val (e, st) = exp (env, e, st)
adamc@1080 235 val (pes, st) = ListUtil.foldlMap (fn ((p, e), st) =>
adamc@1080 236 let
adamc@1080 237 val (e, st) = exp (E.patBindsL p @ env, e, st)
adamc@1080 238 in
adamc@1080 239 ((p, e), st)
adamc@1080 240 end) st pes
adamc@1080 241 in
adamc@1080 242 ((ECase (e, pes, cs), loc), st)
adamc@1080 243 end
adamc@1080 244
adamc@1080 245 | EWrite e =>
adamc@1080 246 let
adamc@1080 247 val (e, st) = exp (env, e, st)
adamc@1080 248 in
adamc@1080 249 ((EWrite e, loc), st)
adamc@1080 250 end
adamc@1080 251 | EClosure (n, es) =>
adamc@1080 252 let
adamc@1080 253 val (es, st) = ListUtil.foldlMap (fn (e, st) => exp (env, e, st)) st es
adamc@1080 254 in
adamc@1080 255 ((EClosure (n, es), loc), st)
adamc@1080 256 end
adamc@1080 257 | ELet (x, t, e1, e2) =>
adamc@1080 258 let
adamc@1080 259 val (e1, st) = exp (env, e1, st)
adamc@1080 260 val (e2, st) = exp ((x, t) :: env, e2, st)
adamc@1080 261 in
adamc@1080 262 ((ELet (x, t, e1, e2), loc), st)
adamc@1080 263 end
adamc@1080 264 | EServerCall (n, es, t) =>
adamc@1080 265 let
adamc@1080 266 val (es, st) = ListUtil.foldlMap (fn (e, st) => exp (env, e, st)) st es
adamc@1080 267 in
adamc@1080 268 ((EServerCall (n, es, t), loc), st)
adamc@1080 269 end
adamc@482 270 in
adamc@482 271 case getApp e of
adamc@1080 272 NONE => default ()
adamc@488 273 | SOME (f, xs) =>
adamc@485 274 case IM.find (#funcs st, f) of
adamc@1080 275 NONE => default ()
adamc@485 276 | SOME {name, args, body, typ, tag} =>
adamc@488 277 let
adamc@1080 278 val (xs, st) = ListUtil.foldlMap (fn (e, st) => exp (env, e, st)) st xs
adamc@1080 279
adamc@721 280 (*val () = Print.prefaces "Consider" [("e", CorePrint.p_exp CoreEnv.empty
adamc@721 281 (e, ErrorMsg.dummySpan))]*)
adamc@721 282
adamc@488 283 val functionInside = U.Con.exists {kind = fn _ => false,
adamc@488 284 con = fn TFun _ => true
adamc@488 285 | CFfi ("Basis", "transaction") => true
adamc@794 286 | CFfi ("Basis", "eq") => true
adamc@794 287 | CFfi ("Basis", "num") => true
adamc@794 288 | CFfi ("Basis", "ord") => true
adamc@794 289 | CFfi ("Basis", "show") => true
adamc@794 290 | CFfi ("Basis", "read") => true
adamc@794 291 | CFfi ("Basis", "sql_injectable_prim") => true
adamc@794 292 | CFfi ("Basis", "sql_injectable") => true
adamc@488 293 | _ => false}
adamc@488 294 val loc = ErrorMsg.dummySpan
adamc@488 295
adamc@1080 296 fun findSplit av (xs, typ, fxs, fvs, fin) =
adamc@488 297 case (#1 typ, xs) of
adamc@488 298 (TFun (dom, ran), e :: xs') =>
adamc@1078 299 let
adamc@1079 300 val av = case #1 e of
adamc@1079 301 ERel _ => av
adamc@1079 302 | _ => false
adamc@1078 303 in
adamc@1079 304 if functionInside dom orelse (av andalso case #1 e of
adamc@1079 305 ERel _ => true
adamc@1079 306 | _ => false) then
adamc@1079 307 findSplit av (xs',
adamc@1079 308 ran,
adamc@1079 309 e :: fxs,
adamc@1080 310 IS.union (fvs, freeVars e),
adamc@1080 311 fin orelse functionInside dom)
adamc@1078 312 else
adamc@1080 313 (rev fxs, xs, fvs, fin)
adamc@1078 314 end
adamc@1080 315 | _ => (rev fxs, xs, fvs, fin)
adamc@488 316
adamc@1080 317 val (fxs, xs, fvs, fin) = findSplit true (xs, typ, [], IS.empty, false)
adamc@1079 318
adamc@1079 319 val fxs' = map (squish (IS.listItems fvs)) fxs
adamc@488 320 in
adamc@800 321 (*Print.preface ("fxs'", Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs');*)
adamc@1080 322 if not fin
adamc@1080 323 orelse List.all (fn (ERel _, _) => true
adamc@1080 324 | _ => false) fxs'
adamc@1079 325 orelse (IS.numItems fvs >= length fxs
adamc@1079 326 andalso IS.exists (fn n => functionInside (#2 (List.nth (env, n)))) fvs) then
adamc@1080 327 default ()
adamc@488 328 else
adamc@1079 329 case (KM.find (args, fxs'),
adamc@1080 330 SS.member (!mayNotSpec, name) orelse IS.member (#specialized st, f)) of
adamc@800 331 (SOME f', _) =>
adamc@485 332 let
adamc@488 333 val e = (ENamed f', loc)
adamc@488 334 val e = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc))
adamc@488 335 e fvs
adamc@1079 336 val e = foldl (fn (arg, e) => (EApp (e, arg), loc))
adamc@488 337 e xs
adamc@488 338 in
adamc@488 339 (*Print.prefaces "Brand new (reuse)"
adamc@721 340 [("e'", CorePrint.p_exp CoreEnv.empty e)];*)
adamc@1080 341 (e, st)
adamc@488 342 end
adamc@818 343 | (_, true) => ((*Print.prefaces ("No(" ^ name ^ ")")
adamc@818 344 [("fxs'",
adamc@818 345 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')];*)
adamc@1080 346 default ())
adamc@800 347 | (NONE, false) =>
adamc@488 348 let
adamc@800 349 (*val () = Print.prefaces "New one"
adamc@800 350 [("f", Print.PD.string (Int.toString f)),
adamc@800 351 ("mns", Print.p_list Print.PD.string
adamc@800 352 (SS.listItems (!mayNotSpec)))]*)
adamc@800 353
adamc@818 354 (*val () = Print.prefaces ("Yes(" ^ name ^ ")")
adamc@818 355 [("fxs'",
adamc@818 356 Print.p_list (CorePrint.p_exp CoreEnv.empty) fxs')]*)
adamc@818 357
adamc@1079 358 fun subBody (body, typ, fxs') =
adamc@1079 359 case (#1 body, #1 typ, fxs') of
adamc@488 360 (_, _, []) => SOME (body, typ)
adamc@1079 361 | (EAbs (_, _, _, body'), TFun (_, typ'), x :: fxs'') =>
adamc@488 362 let
adamc@1079 363 val body'' = E.subExpInExp (0, x) body'
adamc@488 364 in
adamc@488 365 subBody (body'',
adamc@488 366 typ',
adamc@1079 367 fxs'')
adamc@488 368 end
adamc@488 369 | _ => NONE
adamc@488 370 in
adamc@1079 371 case subBody (body, typ, fxs') of
adamc@1080 372 NONE => default ()
adamc@488 373 | SOME (body', typ') =>
adamc@488 374 let
adamc@488 375 val f' = #maxName st
adamc@488 376 val args = KM.insert (args, fxs', f')
adamc@488 377 val funcs = IM.insert (#funcs st, f, {name = name,
adamc@488 378 args = args,
adamc@488 379 body = body,
adamc@488 380 typ = typ,
adamc@488 381 tag = tag})
adamc@1079 382
adamc@488 383 val st = {
adamc@488 384 maxName = f' + 1,
adamc@488 385 funcs = funcs,
adamc@1079 386 decls = #decls st,
adamc@1080 387 specialized = IS.add (#specialized st, f')
adamc@488 388 }
adamc@487 389
adamc@488 390 (*val () = Print.prefaces "specExp"
adamc@488 391 [("f", CorePrint.p_exp env (ENamed f, loc)),
adamc@488 392 ("f'", CorePrint.p_exp env (ENamed f', loc)),
adamc@488 393 ("xs", Print.p_list (CorePrint.p_exp env) xs),
adamc@488 394 ("fxs'", Print.p_list
adamc@488 395 (CorePrint.p_exp E.empty) fxs'),
adamc@488 396 ("e", CorePrint.p_exp env (e, loc))]*)
adamc@488 397 val (body', typ') = IS.foldl (fn (n, (body', typ')) =>
adamc@488 398 let
adamc@521 399 val (x, xt) = List.nth (env, n)
adamc@488 400 in
adamc@488 401 ((EAbs (x, xt, typ', body'),
adamc@488 402 loc),
adamc@488 403 (TFun (xt, typ'), loc))
adamc@488 404 end)
adamc@488 405 (body', typ') fvs
adamc@800 406 val mns = !mayNotSpec
adamc@1080 407 (*val () = mayNotSpec := SS.add (mns, name)*)
adamc@1080 408 (*val () = Print.preface ("PRE", CorePrint.p_exp CoreEnv.empty body')*)
adamc@1080 409 val (body', st) = exp (env, body', st)
adamc@800 410 val () = mayNotSpec := mns
adamc@482 411
adamc@488 412 val e' = (ENamed f', loc)
adamc@488 413 val e' = IS.foldr (fn (arg, e) => (EApp (e, (ERel arg, loc)), loc))
adamc@488 414 e' fvs
adamc@1079 415 val e' = foldl (fn (arg, e) => (EApp (e, arg), loc))
adamc@488 416 e' xs
adamc@488 417 (*val () = Print.prefaces "Brand new"
adamc@721 418 [("e'", CorePrint.p_exp CoreEnv.empty e'),
adamc@1080 419 ("e", CorePrint.p_exp CoreEnv.empty e),
adamc@721 420 ("body'", CorePrint.p_exp CoreEnv.empty body')]*)
adamc@488 421 in
adamc@1080 422 (e',
adamc@488 423 {maxName = #maxName st,
adamc@488 424 funcs = #funcs st,
adamc@1079 425 decls = (name, f', typ', body', tag) :: #decls st,
adamc@1079 426 specialized = #specialized st})
adamc@488 427 end
adamc@485 428 end
adamc@488 429 end
adamc@485 430 end
adamc@482 431
adamc@521 432 fun doDecl (d, (st : state, changed)) =
adamc@488 433 let
adamc@521 434 (*val befor = Time.now ()*)
adamc@482 435
adamc@453 436 val funcs = #funcs st
adamc@453 437 val funcs =
adamc@453 438 case #1 d of
adamc@453 439 DValRec vis =>
adamc@453 440 foldl (fn ((x, n, c, e, tag), funcs) =>
adamc@453 441 IM.insert (funcs, n, {name = x,
adamc@453 442 args = KM.empty,
adamc@453 443 body = e,
adamc@453 444 typ = c,
adamc@453 445 tag = tag}))
adamc@453 446 funcs vis
adamc@453 447 | _ => funcs
adamc@453 448
adamc@453 449 val st = {maxName = #maxName st,
adamc@453 450 funcs = funcs,
adamc@1079 451 decls = [],
adamc@1079 452 specialized = #specialized st}
adamc@453 453
adamc@482 454 (*val () = Print.prefaces "decl" [("d", CorePrint.p_decl CoreEnv.empty d)]*)
adamc@521 455
adamc@1080 456 val () = mayNotSpec := SS.empty
adamc@1080 457
adamc@522 458 val (d', st) =
adamc@522 459 if isPoly d then
adamc@522 460 (d, st)
adamc@522 461 else
adamc@1080 462 case #1 d of
adamc@1080 463 DVal (x, n, t, e, s) =>
adamc@1080 464 let
adamc@1080 465 val (e, st) = exp ([], e, st)
adamc@1080 466 in
adamc@1080 467 ((DVal (x, n, t, e, s), #2 d), st)
adamc@1080 468 end
adamc@1080 469 | DValRec vis =>
adamc@1080 470 let
adamc@1080 471 val (vis, st) = ListUtil.foldlMap (fn ((x, n, t, e, s), st) =>
adamc@1080 472 let
adamc@1080 473 val (e, st) = exp ([], e, st)
adamc@1080 474 in
adamc@1080 475 ((x, n, t, e, s), st)
adamc@1080 476 end) st vis
adamc@1080 477 in
adamc@1080 478 ((DValRec vis, #2 d), st)
adamc@1080 479 end
adamc@1080 480 | DTable (s, n, t, s1, e1, t1, e2, t2) =>
adamc@1080 481 let
adamc@1080 482 val (e1, st) = exp ([], e1, st)
adamc@1080 483 val (e2, st) = exp ([], e2, st)
adamc@1080 484 in
adamc@1080 485 ((DTable (s, n, t, s1, e1, t2, e2, t2), #2 d), st)
adamc@1080 486 end
adamc@1080 487 | DView (x, n, s, e, t) =>
adamc@1080 488 let
adamc@1080 489 val (e, st) = exp ([], e, st)
adamc@1080 490 in
adamc@1080 491 ((DView (x, n, s, e, t), #2 d), st)
adamc@1080 492 end
adamc@1080 493 | DTask (e1, e2) =>
adamc@1080 494 let
adamc@1080 495 val (e1, st) = exp ([], e1, st)
adamc@1080 496 val (e2, st) = exp ([], e2, st)
adamc@1080 497 in
adamc@1080 498 ((DTask (e1, e2), #2 d), st)
adamc@1080 499 end
adamc@1080 500 | _ => (d, st)
adamc@1080 501
adamc@1080 502 val () = mayNotSpec := SS.empty
adamc@521 503
adamc@482 504 (*val () = print "/decl\n"*)
adamc@443 505
adamc@443 506 val funcs = #funcs st
adamc@443 507 val funcs =
adamc@443 508 case #1 d of
adamc@443 509 DVal (x, n, c, e as (EAbs _, _), tag) =>
adamc@443 510 IM.insert (funcs, n, {name = x,
adamc@453 511 args = KM.empty,
adamc@443 512 body = e,
adamc@443 513 typ = c,
adamc@443 514 tag = tag})
adamc@469 515 | DVal (_, n, _, (ENamed n', _), _) =>
adamc@469 516 (case IM.find (funcs, n') of
adamc@469 517 NONE => funcs
adamc@469 518 | SOME v => IM.insert (funcs, n, v))
adamc@443 519 | _ => funcs
adamc@443 520
adamc@453 521 val (changed, ds) =
adamc@443 522 case #decls st of
adamc@453 523 [] => (changed, [d'])
adamc@453 524 | vis =>
adamc@453 525 (true, case d' of
adamc@453 526 (DValRec vis', _) => [(DValRec (vis @ vis'), ErrorMsg.dummySpan)]
adamc@453 527 | _ => [(DValRec vis, ErrorMsg.dummySpan), d'])
adamc@443 528 in
adamc@802 529 (*Print.prefaces "doDecl" [("d", CorePrint.p_decl E.empty d),
adamc@802 530 ("d'", CorePrint.p_decl E.empty d')];*)
adamc@521 531 (ds, ({maxName = #maxName st,
adamc@453 532 funcs = funcs,
adamc@1079 533 decls = [],
adamc@1079 534 specialized = #specialized st}, changed))
adamc@443 535 end
adamc@443 536
adamc@1079 537 val (ds, (st, changed)) = ListUtil.foldlMapConcat doDecl
adamc@521 538 ({maxName = U.File.maxName file + 1,
adamc@1080 539 funcs = funcs,
adamc@1079 540 decls = [],
adamc@1079 541 specialized = specialized},
adamc@488 542 false)
adamc@488 543 file
adamc@443 544 in
adamc@1080 545 (changed, ds, #funcs st, #specialized st)
adamc@443 546 end
adamc@443 547
adamc@1080 548 fun specializeL (funcs, specialized) file =
adamc@453 549 let
adamc@721 550 val file = ReduceLocal.reduce file
adamc@520 551 (*val file = ReduceLocal.reduce file*)
adamc@1080 552 val (changed, file, funcs, specialized) = specialize' (funcs, specialized) file
adamc@520 553 (*val file = ReduceLocal.reduce file
adamc@520 554 val file = CoreUntangle.untangle file
adamc@488 555 val file = Shake.shake file*)
adamc@453 556 in
adamc@488 557 (*print "Round over\n";*)
adamc@453 558 if changed then
adamc@520 559 let
adamc@721 560 (*val file = ReduceLocal.reduce file*)
adamc@802 561 (*val () = Print.prefaces "Pre-untangle" [("file", CorePrint.p_file CoreEnv.empty file)]*)
adamc@520 562 val file = CoreUntangle.untangle file
adamc@802 563 (*val () = Print.prefaces "Post-untangle" [("file", CorePrint.p_file CoreEnv.empty file)]*)
adamc@520 564 val file = Shake.shake file
adamc@520 565 in
adamc@520 566 (*print "Again!\n";*)
adamc@1080 567 (*Print.prefaces "Again" [("file", CorePrint.p_file CoreEnv.empty file)];*)
adamc@1080 568 specializeL (funcs, specialized) file
adamc@520 569 end
adamc@453 570 else
adamc@453 571 file
adamc@453 572 end
adamc@453 573
adamc@1080 574 val specialize = specializeL (IM.empty, IS.empty)
adamc@1079 575
adamc@443 576 end