1 (* Copyright (C) 2017 Matthew Fluet.
2 * Copyright (C) 2004-2008 Henry Cejtin, Matthew Fluet, Suresh
3 * Jagannathan, and Stephen Weeks.
5 * MLton is released under a BSD-style license.
6 * See the file MLton-LICENSE for details.
9 functor SsaToSsa2 (S: SSA_TO_SSA2_STRUCTS): SSA_TO_SSA2 =
21 structure Label = Label
33 fun convert (S.Program.T {datatypes, functions, globals, main}) =
35 val {get = convertType: S.Type.t -> S2.Type.t, ...} =
39 (fn (t, convertType) =>
41 S.Type.Array t => S2.Type.array1 (convertType t)
42 | S.Type.CPointer => S2.Type.cpointer
43 | S.Type.Datatype tycon => S2.Type.datatypee tycon
44 | S.Type.IntInf => S2.Type.intInf
45 | S.Type.Real s => S2.Type.real s
46 | S.Type.Ref t => S2.Type.reff1 (convertType t)
47 | S.Type.Thread => S2.Type.thread
49 S2.Type.tuple (Prod.make
50 (Vector.map (ts, fn t =>
53 | S.Type.Vector t => S2.Type.vector1 (convertType t)
54 | S.Type.Weak t => S2.Type.weak (convertType t)
55 | S.Type.Word s => S2.Type.word s))
56 fun convertTypes ts = Vector.map (ts, convertType)
57 val {get = conType: Con.t -> S2.Type.t, set = setConType, ...} =
58 Property.getSetOnce (Con.plist,
59 Property.initRaise ("type", Con.layout))
62 (datatypes, fn S.Datatype.T {cons, tycon} =>
64 {cons = Vector.map (cons, fn {args, con} =>
68 (Vector.map (args, fn t =>
72 setConType (con, S2.Type.conApp (con, args))
78 fun convertPrim p = S.Prim.map (p, convertType)
79 fun convertStatement (S.Statement.T {exp, ty, var})
80 : S2.Statement.t vector =
82 val ty = convertType ty
83 fun simple (exp: S2.Exp.t): S2.Statement.t vector =
84 Vector.new1 (S2.Statement.Bind {exp = exp, ty = ty, var = var})
85 fun maybeBindUnit (stmt: S2.Statement.t): S2.Statement.t vector =
87 NONE => Vector.new1 stmt
90 (S2.Statement.Bind {var = var,
96 S.Exp.ConApp {args, con} =>
99 case S2.Type.dest ty of
100 S2.Type.Datatype tycon => tycon
101 | _ => Error.bug "SsaToSsa2.convertStatement: strange ConApp"
102 val variant = Var.newNoname ()
105 (S2.Statement.Bind {exp = S2.Exp.Object {args = args,
109 S2.Statement.Bind {exp = S2.Exp.Inject {variant = variant,
114 | S.Exp.Const c => simple (S2.Exp.Const c)
115 | S.Exp.PrimApp {args, prim, ...} =>
117 fun arg i = Vector.sub (args, i)
120 (S2.Exp.Select {base = Base.VectorSub {index = arg 1,
123 datatype z = datatype Prim.Name.t
125 case Prim.name prim of
130 {base = Base.VectorSub {index = arg 1,
137 {base = Base.Object (arg 0),
141 simple (S2.Exp.Select {base = Base.Object (arg 0),
144 simple (S2.Exp.Object {args = Vector.new1 (arg 0),
147 simple (S2.Exp.PrimApp {args = args,
148 prim = Prim.arrayLength})
149 | Vector_sub => sub ()
152 val siws = S2.WordSize.seqIndex ()
153 fun mkIStmt (iVar, i) =
155 {exp = (S2.Exp.Const o S2.Const.word o S2.WordX.fromIntInf)
156 (IntInf.fromInt i, siws),
157 ty = S2.Type.word siws,
159 val nVar = Var.newString "n"
160 val aVar = Var.newString "a"
163 {exp = S2.Exp.PrimApp {args = Vector.new1 aVar,
164 prim = Prim.arrayToVector},
169 (args, [vStmt], fn (i, arg, stmts) =>
171 val iVar = Var.newString "i"
172 val iStmt = mkIStmt (iVar, i)
175 {base = Base.VectorSub {index = iVar,
182 val nStmt = mkIStmt (nVar, Vector.length args)
185 {exp = S2.Exp.PrimApp {args = Vector.new1 nVar,
186 prim = Prim.arrayAlloc
188 ty = S2.Type.array1 (S2.Type.deVector1 ty),
190 val stmts = nStmt::aStmt::stmts
192 Vector.fromList stmts
195 simple (S2.Exp.PrimApp {args = args,
196 prim = convertPrim prim})
198 | S.Exp.Profile e => maybeBindUnit (S2.Statement.Profile e)
199 | S.Exp.Select {offset, tuple} =>
200 simple (S2.Exp.Select {base = Base.Object tuple,
202 | S.Exp.Tuple v => simple (S2.Exp.Object {args = v, con = NONE})
203 | S.Exp.Var x => simple (S2.Exp.Var x)
205 val convertStatement =
206 Trace.trace ("SsaToSsa2.convertStatement",
208 Vector.layout S2.Statement.layout)
210 fun convertHandler (h: S.Handler.t): S2.Handler.t =
212 S.Handler.Caller => S2.Handler.Caller
213 | S.Handler.Dead => S2.Handler.Dead
214 | S.Handler.Handle l => S2.Handler.Handle l
215 fun convertReturn (r: S.Return.t): S2.Return.t =
217 S.Return.Dead => S2.Return.Dead
218 | S.Return.NonTail {cont, handler} =>
219 S2.Return.NonTail {cont = cont,
220 handler = convertHandler handler}
221 | S.Return.Tail => S2.Return.Tail
222 val extraBlocks: S2.Block.t list ref = ref []
223 fun convertCases (cs: S.Cases.t): S2.Cases.t =
230 val objectTy = conType c
232 case S2.Type.dest objectTy of
233 S2.Type.Object {args, ...} =>
238 val l' = Label.newNoname ()
239 val object = Var.newNoname ()
240 val (xs, statements) =
243 (Prod.dest args, fn (i, {elt = ty, ...}) =>
245 val x = Var.newNoname ()
248 {base = Base.Object object,
252 S2.Statement.Bind {exp = exp,
257 S2.Transfer.Goto {args = xs, dst = l}
258 val args = Vector.new1 (object, objectTy)
262 S2.Block.T {args = args,
264 statements = statements,
265 transfer = transfer})
269 | _ => Error.bug "SsaToSsa2.convertCases: strange object type"
271 | S.Cases.Word v => S2.Cases.Word v
272 fun convertTransfer (t: S.Transfer.t): S2.Transfer.t =
274 S.Transfer.Arith {args, overflow, prim, success, ty} =>
275 S2.Transfer.Arith {args = args,
277 prim = convertPrim prim,
280 | S.Transfer.Bug => S2.Transfer.Bug
281 | S.Transfer.Call {args, func, return} =>
282 S2.Transfer.Call {args = args,
284 return = convertReturn return}
285 | S.Transfer.Case {cases, default, test} =>
286 S2.Transfer.Case {cases = convertCases cases,
289 | S.Transfer.Goto r => S2.Transfer.Goto r
290 | S.Transfer.Raise v => S2.Transfer.Raise v
291 | S.Transfer.Return v => S2.Transfer.Return v
292 | S.Transfer.Runtime {args, prim, return} =>
293 S2.Transfer.Runtime {args = args,
294 prim = convertPrim prim,
296 fun convertStatements ss =
297 Vector.concatV (Vector.map (ss, convertStatement))
298 fun convertFormals xts = Vector.map (xts, fn (x, t) => (x, convertType t))
299 fun convertBlock (S.Block.T {args, label, statements, transfer}) =
300 S2.Block.T {args = convertFormals args,
302 statements = convertStatements statements,
303 transfer = convertTransfer transfer}
308 val {args, blocks, mayInline, name, raises, returns, start} =
310 fun rr tvo = Option.map (tvo, convertTypes)
311 val blocks = Vector.map (blocks, convertBlock)
312 val blocks = Vector.concat [blocks, Vector.fromList (!extraBlocks)]
313 val () = extraBlocks := []
315 S2.Function.new {args = convertFormals args,
317 mayInline = mayInline,
320 returns = rr returns,
323 val globals = convertStatements globals
325 S2.Program.T {datatypes = datatypes,
326 functions = functions,