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

SCM Repository

[diderot] Diff of /trunk/src/compiler/codegen/codegen-fn.sml
ViewVC logotype

Diff of /trunk/src/compiler/codegen/codegen-fn.sml

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

revision 455, Wed Oct 27 02:42:13 2010 UTC revision 1116, Thu May 5 04:49:02 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
13    
14      val generate : LowIL.program -> T.program      val generate : string * LowIL.program -> unit
   
   end = struct  
   
     structure Src = LowIL  
     structure SrcV = LowIL.Var  
     structure SrcOp = LowOps  
   
   (* a mapping from LowIL variables to target expressions.  Variables get  
    * removed when the expressions are used as arguments.  
    *)  
     structure VDefTbl : sig  
         type tbl  
   
         val newTbl : unit -> tbl  
         val getDefOf : tbl -> SrcV.var -> T.exp  
         val useDefOf : tbl -> SrcV.var -> T.exp  
         val setDefOf : tbl -> (SrcV.var * T.exp) -> unit  
   
         val clear : tbl -> unit  
   
         val bind : tbl -> (SrcV.var * T.exp) -> T.stm list  
   
       (* force all pending expressions into variables *)  
         val flush : tbl -> T.stm list  
15    
16        end = struct        end = struct
17    
18          type info = {      structure IL = TreeIL
             cnt : int ref,      (* count of oustanding uses (usually 1) *)  
             bind : T.exp  
           }  
   
         type tbl = info SrcV.Tbl.hash_table  
19    
20          fun newTbl () = SrcV.Tbl.mkTable (512, Fail "vtbl")      structure LowToTree = LowToTreeFn(T)
21    
22          fun getDefOf tbl x = (case SrcV.Tbl.find tbl x      fun trMethod (strand, stateVars, env) = let
23                 of NONE => ??            val varyingStateVars = List.mapPartial
24                  | SOME{bind, cnt} => bind                  (fn (IL.SV{varying = true, var, ...}) => SOME var | _ => NONE)
25                (* end case *))                    stateVars
26              val env = T.Env.scopeMethod (env, varyingStateVars)
27          fun useDefOf tbl x = (case SrcV.Tbl.find tbl x            fun tr (IL.Method{name, body}) = let
28                 of NONE => ??                  val body = T.Tr.block (env, body)
                 | SOME{cnt=ref n, bind} => (  
                     ignore (SrcV.Tbl.remove tbl x);  
                     bind)  
                 | SOME{cnt, bind} =>  => (  
                     cnt := !cnt - 1;  
                     bind)  
               (* end case *))  
   
         fun setDefOf tbl (x, exp) =  
               SrcV.Tbl.insert tbl (x, {cnt = ref(SrcV.useCount x), bind = exp})  
   
         fun assign tbl (x, exp) = let  
                     val lhs : T.local_var = ??  
29                      in                      in
30                        SrcV.Tbl.insert tbl                    T.Strand.method (strand, Atom.toString name, body)
                         (x, {cnt = SrcV.useCount x, bind = T.Expr.var lhs});  
                       [T.Stmt.assign(lhs, exp)]  
31                      end                      end
   
         fun bind tbl (x, exp) = (case SrcV.useCount lhs  
                of 1 => (SrcV.Tbl.insert tbl (x, {cnt = 1, bind = exp}); [])  
                 | n => let (* bind exp to a new target variable *)  
                     val lhs : T.local_var = ??  
32                      in                      in
33                        SrcV.Tbl.insert tbl (x, {cnt = n, bind = T.Expr.var lhs});              tr
                       [T.Stmt.assign(lhs, exp)]  
34                      end                      end
               (* end case *))  
   
       end (*  VDefTbl *)  
35    
36  (* FIXME: what about splitting code where the target width doesn't match the      fun trStrand (prog, env) (IL.Strand{name, params, state, stateInit, methods}) = let
37   * source width?            val strand = T.Strand.define(prog, name)
38   *)            val env = T.Env.scopeStrand (env, List.map (fn (IL.SV{var, ...}) => var) state)
39      fun doRator (vtbl, lhs, rator, args) = let          (* the output state variable *)
40            val args' = List.map (VDefTbl.useDefOf vtbl) args            val outputVar = ref NONE
41            val rhs' = (case rator          (* map the state variables to target state variables and extend the environment *)
42  (* ??? *)            val env = let
43                  (* end case *))                  fun cvtSVar (IL.SV{output, var=x, ...}, env) = let
44            in                        val x' = T.Var.state(strand, x)
             VDefTbl.bind vtbl (lhs, rhs')  
           end  
   
   (* translate a LowIL assignment to a list of zero or more target statements *)  
     fun doAssign vtbl (lhs, rhs) = let  
           fun setDef rhs = (VTbl.setDefOf vtbl (lhs, rhs); [])  
           in  
             case rhs  
              of Src.VAR x => setDef (T.Expr.var(VDefTbl.useDefOf vtbl x))  
               | Src.LIT(Literal.Int n) => setDef (T.Expr.intLit n)  
               | Src.LIT(Literal.Bool b) => setDef (T.Expr.boolLit b)  
               | Src.LIT(Literal.Float f) => setDef (T.Expr.floatLit f)  
               | Src.LIT(Literal.String s) => setDef (T.Expr.stringLit s)  
               | Src.OP(rator, args) => doRator(vtbl, lhs, rator, args)  
               | Src.CONS args =>  
                   VTbl.assign ctbl (lhs, T.Expr.vector (List.map (VDefTbl.useDefOf vtbl) args))  
             (* end case *)  
           end  
   
     fun gen (vtbl, stm) = let  
           val doAssign = doAssign vtbl  
           fun doStmt (SrcIL.STM{kind, next, ...}) = let  
                 val stms = (case kind  
                        of SrcIL.S_SIMPLE nd => doNode nd  
                         | SrcIL.S_IF{cond, thenBranch, elseBranch} =>  
                         | SrcIL.S_LOOP{hdr, cond, body} =>  
                       (* end case *))  
                 val rest = (case next  
                        of NONE => VDefTbl.flush vtbl  
                         | SOME stm = doStmt stm  
                       (* end case *))  
45                  in                  in
46                    stms @ rest                          case (output, !outputVar)
47                             of (true, NONE) => outputVar := SOME(IL.Var.ty x, x')
48                              | (false, _) => ()
49                              | _ => raise Fail("multiple outputs in " ^ Atom.toString name)
50                            (* end case *);
51                            T.Env.bind(env, x, x')
52                  end                  end
53            in            in
54                    (* note that we folr right-to-left to get the order of state variables in the
55                     * target strand in the right order.
56                     *)
57                      List.foldr cvtSVar env state
58                    end
59            (* define the parameters and add them to the environment *)
60              val params' = List.map T.Var.param params
61              val env = ListPair.foldlEq (fn (x, y, env) => T.Env.bind(env, x, y)) env (params, params')
62              in
63                T.Strand.init (strand, params', T.Tr.block (env, stateInit));
64                case !outputVar
65                 of NONE => raise Fail("no output specified for strand " ^ Atom.toString name)
66                  | SOME(ty, x) => T.Strand.output (strand, ty, x)
67                (* end case *);
68                List.app (trMethod (strand, state, env)) methods
69              end
70    
71        fun trInitially (env0, prog, {isArray, iterPrefix, iters, createPrefix, strand, args}) = let
72              val env0 = T.Env.scopeInitially env0
73              fun trIter ((param, lo, hi), (env, iters)) = let
74                    val param' = T.Var.param param
75                    val env = T.Env.bind (env, param, param')
76                    val iter = (param', T.Tr.exp (env0, lo), T.Tr.exp (env0, hi))
77                    in
78                      (env, iter::iters)
79                    end
80              val (env, iters) = List.foldr trIter (env0, []) iters
81              in
82                T.Program.initially {
83                    prog = prog,
84                    isArray = isArray,
85                    iterPrefix = T.Tr.block (env0, iterPrefix),
86                    iters = iters,
87                    createPrefix = T.Tr.block (env, createPrefix),
88                    strand = strand,
89                    args = List.map (fn e => T.Tr.exp(env, e)) args
90                  }
91              end
92    
93        fun generate (fileStem, srcProg) = let
94              val treeProg as TreeIL.Program{globals, globalInit, strands, initially} =
95                    PhaseTimer.withTimer Timers.timeLowToTree LowToTree.translate srcProg
96    val _ = (
97    TextIO.output(Log.logFile(), "********** After translation to TreeIL **********\n");
98    TreeILPP.program (Log.logFile(), treeProg))
99              val prog = T.Program.new ()
100              val env = T.Env.new prog
101            (* define the globals and initialize the environment *)
102              val env = let
103                  (* produce a list of target variables for the globals, such that each global
104                   * has a unique name.
105                   *)
106                    fun genName (x, (cnt, globs)) = let
107                          val name = IL.Var.name x
108                          fun uniqueName (name, cnt) =
109                                if List.exists (fn (_, y) => (name = T.Var.name y)) globs
110                                  then uniqueName(name ^ Int.toString cnt, cnt+1)
111                                  else (name, cnt)
112                          val (name, cnt) = uniqueName (IL.Var.name x, cnt)
113                          in
114                            (cnt, (x, T.Var.global(prog, name, IL.Var.ty x))::globs)
115                          end
116                    val (_, globs) = List.foldl genName (0, []) globals
117                    fun gvar ((x, x'), env) = T.Env.bind(env, x, x')
118                    in
119                      List.foldl gvar (T.Env.scopeGlobal env) globs
120                    end
121              in
122              (* global initialization *)
123                T.Program.init (prog, T.Tr.block (T.Env.scopeGlobal env, globalInit));
124              (* translate strands *)
125                List.app (trStrand (prog, env)) strands;
126              (* generate the initially function *)
127                trInitially (env, prog, initially);
128              (* output the program *)
129                T.Program.generate (fileStem, prog)
130            end            end
131    
132    end    end

Legend:
Removed from v.455  
changed lines
  Added in v.1116

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