Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Diff of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml
ViewVC logotype

Diff of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 838, Mon Apr 18 02:53:09 2011 UTC revision 839, Mon Apr 18 16:50:47 2011 UTC
# Line 1  Line 1 
1  (* codegen-fn.sml  (* codegen-fn.sml
2   *   *
3   * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)   * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4   * All rights reserved.   * All rights reserved.
5   *   *
6   * Generic support for translating LowIL code to the target representation.  We   * Generic support for translating LowIL code to the target representation.
7   * assume that the LowIL has first been run through the splitting pass to match   *
8   * the target's vector widths.   * FIXME:
9     *      We need to run the TreeIL through a splitting pass to match the target's vector widths.
10   *)   *)
11    
12  functor CodeGenFn (T : TARGET) : sig  functor CodeGenFn (T : TARGET) : sig
# Line 15  Line 16 
16    end = struct    end = struct
17    
18      structure IL = TreeIL      structure IL = TreeIL
     structure Ty = IL.Ty  
     structure Op = IL.Op  
     structure V = IL.Var  
19    
20      structure LowToTree = LowToTreeFn(T)      structure LowToTree = LowToTreeFn(T)
21    
22    (* convert LowIL types to T types *)      fun trMethod (strand, stateVars, env) = let
23      fun cvtTy ty = (case ty            val env = T.Env.scopeMethod (env, stateVars)
24             of Ty.BoolTy => T.boolTy            fun tr (IL.Method{name, body}) = let
             | Ty.StringTy => T.stringTy  
             | Ty.IVecTy 1 => T.intTy  
             | Ty.IVecTy n => T.ivecTy n         (* FIXME: what about vector splits? *)  
             | Ty.TensorTy[] => T.realTy  
             | Ty.TensorTy[d] => T.vecTy d       (* FIXME: what about vector splits? *)  
             | Ty.TensorTy dd => T.tensorTy dd  
             | Ty.AddrTy info => T.imageDataTy info  
             | Ty.ImageTy info => T.imageTy info  
           (* end case *))  
   
     fun addBindings (env, xs, ys) =  
           ListPair.foldlEq (fn (x, y, env) => V.Map.insert(env, x, y)) env (xs, ys)  
   
     fun lookup (env, x) = (case V.Map.find (env, x)  
            of SOME x' => x'  
             | NONE => raise Fail(concat["lookup(_, ", V.name x, ")"])  
           (* end case *))  
   
     fun trExp (env, e) = (case e  
            of IL.E_Var x => (case V.kind x  
                  of IL.VK_Global => T.Expr.global(lookup(env, x))  
                   | IL.VK_State strand => T.Expr.getState(lookup(env, x))  
                   | IL.VK_Local => T.Expr.var(lookup(env, x))  
                 (* end case *))  
             | IL.E_Lit(Literal.Int n) => T.Expr.intLit n  
             | IL.E_Lit(Literal.Bool b) => T.Expr.boolLit b  
             | IL.E_Lit(Literal.Float f) => T.Expr.floatLit f  
             | IL.E_Lit(Literal.String s) => T.Expr.stringLit s  
             | IL.E_Op(rator, args) => (case (rator, trExps(env, args))  
                  of (Op.Add ty, [a, b])         => T.Expr.add(a, b)  
                   | (Op.Sub ty, [a, b])         => T.Expr.sub(a, b)  
                   | (Op.Mul ty, [a, b])         => T.Expr.mul(a, b)  
                   | (Op.Div ty, [a, b])         => T.Expr.divide(a, b)  
                   | (Op.Neg ty, [a])            => T.Expr.neg a  
                   | (Op.Abs ty, [a])            => T.Expr.abs a  
                   | (Op.LT ty, [a, b])          => T.Expr.lt(a, b)  
                   | (Op.LTE ty, [a, b])         => T.Expr.lte(a, b)  
                   | (Op.EQ ty, [a, b])          => T.Expr.equ(a, b)  
                   | (Op.NEQ ty, [a, b])         => T.Expr.neq(a, b)  
                   | (Op.GT ty, [a, b])          => T.Expr.gt(a, b)  
                   | (Op.GTE ty, [a, b])         => T.Expr.gte(a, b)  
                   | (Op.Not, [a])               => T.Expr.not a  
                   | (Op.Max, [a, b])            => T.Expr.max(a, b)  
                   | (Op.Min, [a, b])            => T.Expr.min(a, b)  
                   | (Op.Lerp ty, [a, b, c])     => T.Expr.lerp(a, b, c)  
                   | (Op.Dot d, [a, b])          => T.Expr.dot(a, b)  
                   | (Op.MulVecMat(d1, d2), [v, m]) => T.Expr.mulVecMat(v, m)  
                   | (Op.MulMatVec(d1, d2), [m, v]) => T.Expr.mulMatVec(m, v)  
                   | (Op.MulMatMat(d1, d2, d3), [m1, m2]) => T.Expr.mulMatMat(m1, m2)  
                   | (Op.Cross, [a, b])          => T.Expr.cross(a, b)  
                   | (Op.Select(ty, i), [a])     => T.Expr.select(i, a)  
                   | (Op.Norm(Ty.TensorTy[d]), [a]) => T.Expr.length a  
                   | (Op.Normalize d, [a])       => T.Expr.normalize a  
                   | (Op.Trace d, [a])           => T.Expr.trace a  
                   | (Op.Scale d, [a, b])        => T.Expr.mul(a, b)  
                   | (Op.CL, _)                  => raise Fail "CL unimplemented"  
                   | (Op.PrincipleEvec ty, _)    => raise Fail "PrincipleEvec unimplemented"  
                   | (Op.Subscript ty, [t, ix])  => T.Expr.subscript1(t, ix)  
                   | (Op.Subscript ty, [t, ix, jx]) => T.Expr.subscript2(t, ix, jx)  
                   | (Op.Subscript ty, t::(ixs as _::_)) => raise Fail "Subscript unimplemented"  
                   | (Op.Ceiling d, [a])         => T.Expr.ceil a  
                   | (Op.Floor d, [a])           => T.Expr.floor a  
                   | (Op.Round d, [a])           => T.Expr.round a  
                   | (Op.Trunc d, [a])           => T.Expr.trunc a  
                   | (Op.IntToReal, [a])         => T.Expr.toReal a  
                   | (Op.RealToInt d, [a])       => T.Expr.toInt a  
                   | (Op.ImageAddress d, [a])    => T.Expr.imageAddr a  
                   | (Op.LoadVoxels(info, 1), [a]) => T.Expr.getImgData a  
                   | (Op.LoadVoxels _, [a])      => raise Fail "impossible"  
                   | (Op.PosToImgSpace d, [v, x]) => T.Expr.posToImgSpace(v, x)  
                   | (Op.GradToWorldSpace d, [v, x]) => T.Expr.intLit 0 (* FIXME *)  
                   | (Op.LoadImage info, [a])    => raise Fail "impossible"  
                   | (Op.Inside(d, s), [x, v])   => T.Expr.inside(x, v, s)  
                   | (Op.Input(ty, name), [])    => raise Fail "impossible"  
                   | (Op.InputWithDefault(ty, name), [a]) => T.Expr.intLit 0 (* FIXME *)  
                   | _ => raise Fail(concat[  
                         "unknown or incorrect operator ", Op.toString rator  
                       ])  
                 (* end case *))  
             | IL.E_Apply(f, args) => T.Expr.apply(f, trExps(env, args))  
           (* end case *))  
   
     and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps  
   
     fun trBlock (env, saveState, blk) = let  
           fun trStmt (env, stm) = (case stm  
                  of IL.S_Comment text => [T.Stmt.comment text]  
                   | IL.S_Assign(x, exp) => (case V.kind x  
                        of IL.VK_Global => [T.Stmt.assign(lookup(env, x), trExp(env, exp))]  
                         | IL.VK_State strand =>  
                             [T.Stmt.assignState(lookup(env, x), trExp(env, exp))]  
                         | IL.VK_Local => [T.Stmt.assign(lookup(env, x), trExp(env, exp))]  
                       (* end case *))  
                   | IL.S_IfThen(cond, thenBlk) =>  
                       [T.Stmt.ifthen(trExp(env, cond), trBlk(env, thenBlk))]  
                   | IL.S_IfThenElse(cond, thenBlk, elseBlk) =>  
                       [T.Stmt.ifthenelse(trExp(env, cond),  
                         trBlk(env, thenBlk),  
                         trBlk(env, elseBlk))]  
25  (*  (*
                   | IL.S_For(x, e1, e2, blk) => let  
                       val x' = T.Var.var(cvtTy(V.ty x), V.name x)  
                       val env' = V.Map.insert(env, x, x')  
                       in [  
                         T.Stmt.for(x', trExp(env, e1), trExp(env, e2), trBlk(env', blk))  
                       ] end  
                   | IL.S_Cons(lhs, args) =>  
                       T.Stmt.cons(lookup(env, lhs), trExps(env, args))  
                   | IL.S_LoadVoxels(lhs, dim, addr) =>  
                       T.Stmt.getImgData(lookup(env, lhs), trExp(env, addr))  
 *)  
                   | IL.S_LoadImage(lhs, dim, name) =>  
                       T.Stmt.loadImage (lookup(env, lhs), dim, trExp(env, name))  
                   | IL.S_Input(lhs, name, optDflt) =>  
                       T.Stmt.input(lookup(env, lhs), name, Option.map (fn e => trExp(env, e)) optDflt)  
 (* FIXME: what about the args? *)  
                   | IL.S_Exit args => [T.Stmt.exit()]  
                   | IL.S_Active args => saveState (env, args, T.Stmt.active())  
                   | IL.S_Stabilize args => saveState (env, args, T.Stmt.stabilize())  
                   | IL.S_Die => [T.Stmt.die()]  
                 (* end case *))  
           and trBlk (env, IL.Block{locals, body}) = let  
                 val env = List.foldl  
                       (fn (x, env) => V.Map.insert(env, x, T.Var.var(cvtTy(V.ty x), V.name x)))  
                         env locals  
                 val stms = List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] body  
                 val stms = List.foldr  
                       (fn (x, stms) => T.Stmt.decl(lookup(env, x), NONE)::stms)  
                         stms locals  
                 in  
                   T.Stmt.block stms  
                 end  
           in  
             trBlk (env, blk)  
           end  
   
     fun trTopBlock (env, blk) = trBlock (env, fn _ => raise Fail "unexpected state save", blk)  
   
     fun trMethod (strand, stateVars, env) (IL.Method{name, body}) = let  
26            fun saveState (env, args, stm) =            fun saveState (env, args, stm) =
27                  ListPair.foldrEq                  ListPair.foldrEq
28                    (fn (x, e, stms) => T.Stmt.assignState(x, trExp(env, e))::stms)                    (fn (x, e, stms) => T.Stmt.assignState(x, trExp(env, e))::stms)
29                      [stm]                      [stm]
30                        (stateVars, args)                        (stateVars, args)
31            val body = trBlock (env, saveState, body)  *)
32                    val body = T.Tr.block (env, body)
33            in            in
34              T.Strand.method (strand, Atom.toString name, body)              T.Strand.method (strand, Atom.toString name, body)
35            end            end
36              in
37                tr
38              end
39    
40      fun trStrand (prog, env) (IL.Strand{name, params, state, stateInit, methods}) = let      fun trStrand (prog, env) (IL.Strand{name, params, state, stateInit, methods}) = let
41            val strand = T.Strand.define(prog, name)            val strand = T.Strand.define(prog, name)
42          (* map the state variables to target state variables, while extending the environment            val env = T.Env.scopeStrand (env, strand)
43           * and registering the output variables.          (* the output state variable *)
44           *)            val outputVar = ref NONE
45            val (env, state') = let          (* map the state variables to target state variables and extend the environment *)
46                  fun cvtSVar ((isOut, x), (env, xs)) = let            val env = let
47                        val x' = T.Var.state(strand, cvtTy(V.ty x), V.name x)                  fun cvtSVar ((isOut, x), env) = let
48                          val x' = T.Var.state(strand, x)
49                        in                        in
50                          if isOut then T.Strand.output(strand, x') else ();                          case (isOut, !outputVar)
51                          (V.Map.insert(env, x, x'), x'::xs)                           of (true, NONE) => outputVar := SOME x'
52                              | (false, _) => ()
53                              | _ => raise Fail("multiple outputs in " ^ Atom.toString name)
54                            (* end case *);
55                            T.Env.bind(env, x, x')
56                        end                        end
57                  in                  in
58                    List.foldr cvtSVar (env, []) state                    List.foldr cvtSVar (env, []) state
59                  end                  end
60          (* define the parameters and add them to the environment *)          (* define the parameters and add them to the environment *)
61            val params' = List.map (fn x => T.Var.param(cvtTy(V.ty x), V.name x)) params            val params' = List.map T.Var.param params
62            val env = addBindings (env, params, params')            val env =
63            in                  ListPair.foldlEq (fn (x, y, env) => T.Env.bind(env, x, y)) env  (params, params')
64              T.Strand.init (strand, params', trTopBlock (env, stateInit));            in
65              List.app (trMethod (strand, state', env)) methods              T.Strand.init (strand, params', T.Tr.block (env, stateInit));
66                case !outputVar
67                 of NONE => raise Fail("no output specified for strand " ^ Atom.toString name)
68                  | SOME x => T.Strand.output (strand, x)
69                (* end case *);
70                List.app (trMethod (strand, state, env)) methods
71            end            end
72    
73      fun trInitially (env0, prog, {isArray, iterPrefix, iters, createPrefix, strand, args}) = let      fun trInitially (env0, prog, {isArray, iterPrefix, iters, createPrefix, strand, args}) = let
74              val env0 = T.Env.scopeInitially env0
75            fun trIter ((param, lo, hi), (env, iters)) = let            fun trIter ((param, lo, hi), (env, iters)) = let
76                  val param' = T.Var.var(cvtTy(V.ty param), V.name param)                  val param' = T.Var.param param
77                  val env = V.Map.insert(env, param, param')                  val env = T.Env.bind (env, param, param')
78                  val iter = (param', trExp (env0, lo), trExp (env0, hi))                  val iter = (param', T.Tr.exp (env0, lo), T.Tr.exp (env0, hi))
79                  in                  in
80                    (env, iter::iters)                    (env, iter::iters)
81                  end                  end
82            val (env, iters) = List.foldr trIter (env0, []) iters            val (env, iters) = List.foldr trIter (env0, []) iters
83            in            in
84              T.initially {              T.Program.initially {
85                  prog = prog,                  prog = prog,
86                  isArray = isArray,                  isArray = isArray,
87                  iterPrefix = trTopBlock (env0, iterPrefix),                  iterPrefix = T.Tr.block (env0, iterPrefix),
88                  iters = iters,                  iters = iters,
89                  createPrefix = trTopBlock (env, createPrefix),                  createPrefix = T.Tr.block (env, createPrefix),
90                  strand = strand,                  strand = strand,
91                  args = trExps (env, args)                  args = List.map (fn e => T.Tr.exp(env, e)) args
92                }                }
93            end            end
94    
95      fun generate (fileStem, srcProg) = let      fun generate (fileStem, srcProg) = let
96            val treeProg as TreeIL.Program{globals, globalInit, strands, initially} = LowToTree.translate srcProg            val treeProg as TreeIL.Program{globals, globalInit, strands, initially} =
97                    LowToTree.translate srcProg
98  val _ = (  val _ = (
99  TextIO.output(Log.logFile(), "********** After translation to TreeIL **********\n");  TextIO.output(Log.logFile(), "********** After translation to TreeIL **********\n");
100  TreeILPP.program (Log.logFile(), treeProg))  TreeILPP.program (Log.logFile(), treeProg))
101            val prog = T.newProgram ()            val prog = T.Program.new ()
102              val env = T.Env.new prog
103          (* define the globals and initialize the environment *)          (* define the globals and initialize the environment *)
104            val env = let            val env = let
105                  fun gvar (x, env) =                  fun gvar (x, env) = T.Env.bind(env, x, T.Var.global(prog, x))
                       V.Map.insert(env, x, T.Var.global(prog, cvtTy(V.ty x), V.name x))  
106                  in                  in
107                    List.foldl gvar V.Map.empty globals                    List.foldl gvar (T.Env.scopeGlobal env) globals
108                  end                  end
109            in            in
110            (* global initialization *)            (* global initialization *)
111              T.globalInit (prog, trTopBlock (env, globalInit));              T.Program.init (prog, T.Tr.block (T.Env.scopeGlobal env, globalInit));
112            (* translate strands *)            (* translate strands *)
113              List.app (trStrand (prog, env)) strands;              List.app (trStrand (prog, env)) strands;
114            (* generate the initially function *)            (* generate the initially function *)
115              trInitially (env, prog, initially);              trInitially (env, prog, initially);
116            (* output the program *)            (* output the program *)
117              T.generate (fileStem, prog)              T.Program.generate (fileStem, prog)
118            end            end
119    
120    end    end

Legend:
Removed from v.838  
changed lines
  Added in v.839

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0