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

SCM Repository

[diderot] Diff of /trunk/src/compiler/tree-il/low-to-tree-fn.sml
ViewVC logotype

Diff of /trunk/src/compiler/tree-il/low-to-tree-fn.sml

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

revision 1301, Thu Jun 9 23:58:40 2011 UTC revision 1640, Wed Nov 16 02:19:51 2011 UTC
# Line 11  Line 11 
11    
12  functor LowToTreeFn (Target : sig  functor LowToTreeFn (Target : sig
13    
14        val supportsPrinting : unit -> bool (* does the target support the Print op? *)
15    
16    (* tests for whether various expression forms can appear inline *)    (* tests for whether various expression forms can appear inline *)
17      val inlineCons : int -> bool        (* can n'th-order tensor construction appear inline *)      val inlineCons : int -> bool        (* can n'th-order tensor construction appear inline *)
18      val inlineMatrixExp : bool          (* can matrix-valued expressions appear inline? *)      val inlineMatrixExp : bool          (* can matrix-valued expressions appear inline? *)
# Line 24  Line 26 
26      structure IL = LowIL      structure IL = LowIL
27      structure Ty = LowILTypes      structure Ty = LowILTypes
28      structure V = LowIL.Var      structure V = LowIL.Var
29        structure StV = LowIL.StateVar
30      structure Op = LowOps      structure Op = LowOps
31      structure Nd = LowIL.Node      structure Nd = LowIL.Node
32      structure CFG = LowIL.CFG      structure CFG = LowIL.CFG
# Line 47  Line 50 
50              end              end
51      in      in
52      fun newGlobal x = newVar ("G_" ^ V.name x, T.VK_Global, V.ty x)      fun newGlobal x = newVar ("G_" ^ V.name x, T.VK_Global, V.ty x)
     fun newStateVar (strand, x) =  
           newVar (concat[Atom.toString strand, "_", V.name x], T.VK_State strand, V.ty x)  
53      fun newParam x = newVar (genName("p_" ^ V.name x), T.VK_Local, V.ty x)      fun newParam x = newVar (genName("p_" ^ V.name x), T.VK_Local, V.ty x)
54      fun newLocal x = newVar (genName("l_" ^ V.name x), T.VK_Local, V.ty x)      fun newLocal x = newVar (genName("l_" ^ V.name x), T.VK_Local, V.ty x)
55      fun newIter x = newVar (genName("i_" ^ V.name x), T.VK_Local, V.ty x)      fun newIter x = newVar (genName("i_" ^ V.name x), T.VK_Local, V.ty x)
56      end      end
57    
58      (* associate Tree IL state variables with Low IL variables using properties *)
59        local
60          fun mkStateVar x = T.SV{
61                  name = StV.name x,
62                  id = Stamp.new(),
63                  ty = StV.ty x,
64                  varying = VA.isVarying x,
65                  output = StV.isOutput x
66                }
67        in
68        val {getFn = getStateVar, ...} = StV.newProp mkStateVar
69        end
70    
71      fun mkBlock stms = T.Block{locals=[], body=stms}      fun mkBlock stms = T.Block{locals=[], body=stms}
72      fun mkIf (x, stms, []) = T.S_IfThen(x, mkBlock stms)      fun mkIf (x, stms, []) = T.S_IfThen(x, mkBlock stms)
73        | mkIf (x, stms1, stms2) = T.S_IfThenElse(x, mkBlock stms1, mkBlock stms2)        | mkIf (x, stms1, stms2) = T.S_IfThenElse(x, mkBlock stms1, mkBlock stms2)
# Line 138  Line 152 
152            else let            else let
153              val t = newLocal lhs              val t = newLocal lhs
154              in              in
155                (rename(addLocal(env, t), lhs, t), [T.S_Assign(t, rhs)])                (rename(addLocal(env, t), lhs, t), [T.S_Assign([t], rhs)])
156              end              end
157    
158      fun bind (env, lhs, rhs) = (case peekGlobal (env, lhs)      fun bind (env, lhs, rhs) = (case peekGlobal (env, lhs)
159             of SOME x => (env, [T.S_Assign(x, rhs)])             of SOME x => (env, [T.S_Assign([x], rhs)])
160              | NONE => bindLocal (env, lhs, rhs)              | NONE => bindLocal (env, lhs, rhs)
161            (* end case *))            (* end case *))
162    
163    (* set the definition of a variable, where the RHS is either a literal constant or a variable *)    (* set the definition of a variable, where the RHS is either a literal constant or a variable *)
164      fun bindSimple (env as E{tbl, ...}, lhs, rhs) = (      fun bindSimple (env as E{tbl, ...}, lhs, rhs) = (
165            case peekGlobal (env, lhs)            case peekGlobal (env, lhs)
166             of SOME x => (env, [T.S_Assign(x, rhs)])             of SOME x => (env, [T.S_Assign([x], rhs)])
167              | NONE => (VT.insert tbl (lhs, DEF rhs); (env, []))              | NONE => (VT.insert tbl (lhs, DEF rhs); (env, []))
168            (* end case *))            (* end case *))
169    
# Line 161  Line 175 
175                  val t = newLocal x                  val t = newLocal x
176                  in                  in
177                    VT.insert tbl (x, DEF(T.E_Var t));                    VT.insert tbl (x, DEF(T.E_Var t));
178                    (t::locals, T.S_Assign(t, e)::stms)                    (t::locals, T.S_Assign([t], e)::stms)
179                  end                  end
180              | doVar (_, _, acc) = acc              | doVar (_, _, acc) = acc
181            val (locals, stms) = VT.foldi doVar (locals, blkStms) tbl            val (locals, stms) = VT.foldi doVar (locals, blkStms) tbl
# Line 173  Line 187 
187          (* t will be the variable in the continuation of the JOIN *)          (* t will be the variable in the continuation of the JOIN *)
188            val t = newLocal lhs            val t = newLocal lhs
189            val predBlks = ListPair.map            val predBlks = ListPair.map
190                  (fn (x, stms) => T.S_Assign(t, useVar env x)::stms)                  (fn (x, stms) => T.S_Assign([t], useVar env x)::stms)
191                    (rhs, predBlks)                    (rhs, predBlks)
192            in            in
193              (rename (addLocal(env, t), lhs, t), predBlks)              (rename (addLocal(env, t), lhs, t), predBlks)
# Line 203  Line 217 
217                | Op.Neg ty => chkTensorTy ty                | Op.Neg ty => chkTensorTy ty
218                | Op.Scale ty => chkTensorTy ty                | Op.Scale ty => chkTensorTy ty
219                | Op.MulMatMat _ => Target.inlineMatrixExp                | Op.MulMatMat _ => Target.inlineMatrixExp
220                  | Op.EigenVecs2x2 => false
221                  | Op.EigenVecs3x3 => false
222                  | Op.EigenVals2x2 => false
223                  | Op.EigenVals3x3 => false
224                | Op.Identity _ => Target.inlineMatrixExp                | Op.Identity _ => Target.inlineMatrixExp
225                | Op.Zero _ => Target.inlineMatrixExp                | Op.Zero _ => Target.inlineMatrixExp
226                | Op.TensorToWorldSpace(_, ty) => chkTensorTy ty                | Op.TensorToWorldSpace(_, ty) => chkTensorTy ty
# Line 225  Line 243 
243                (* operations that return matrices may not be supported inline *)                (* operations that return matrices may not be supported inline *)
244                  val (env, t) = doLHS()                  val (env, t) = doLHS()
245                  in                  in
246                    (env, [T.S_Assign(t, exp)])                    (env, [T.S_Assign([t], exp)])
247                  end                  end
248            in            in
249              case rhs              case rhs
250               of IL.VAR x => bindSimple (env, lhs, useVar env x)               of IL.STATE x => bindSimple (env, lhs, T.E_State(getStateVar x))
251                  | IL.VAR x => bindSimple (env, lhs, useVar env x)
252                | IL.LIT lit => bindSimple (env, lhs, T.E_Lit lit)                | IL.LIT lit => bindSimple (env, lhs, T.E_Lit lit)
253                | IL.OP(Op.LoadImage info, [a]) => let                | IL.OP(Op.LoadImage info, [a]) => let
254                    val (env, t) = doLHS()                    val (env, t) = doLHS()
# Line 257  Line 276 
276                    bind (env, lhs, T.E_Apply(f, List.map (useVar env) args))                    bind (env, lhs, T.E_Apply(f, List.map (useVar env) args))
277                | IL.CONS(ty, args) => let                | IL.CONS(ty, args) => let
278                    val inline = (case ty                    val inline = (case ty
279                           of Ty.IVecTy _ => true                           of Ty.SeqTy(Ty.IntTy, _) => true
280                            | Ty.TensorTy dd => Target.inlineCons(List.length dd)                            | Ty.TensorTy dd => Target.inlineCons(List.length dd)
281                          (* end case *))                          (* end case *))
282                    val exp = T.E_Cons(ty, List.map (useVar env) args)                    val exp = T.E_Cons(ty, List.map (useVar env) args)
# Line 336  Line 355 
355                        in                        in
356                          doNode (env, ifStk, stms' @ stms, !succ)                          doNode (env, ifStk, stms' @ stms, !succ)
357                        end                        end
358                      | IL.MASSIGN{stm=(ys, rator, xs), succ, ...} => let
359                          fun doit () = let
360                                fun doLHSVar (y, (env, ys)) = (case peekGlobal(env, y)
361                                       of SOME y' => (env, y'::ys)
362                                        | NONE => let
363                                            val t = newLocal y
364                                            in
365                                              (rename (addLocal(env, t), y, t), t::ys)
366                                            end
367                                      (* end case *))
368                                val (env, ys) = List.foldr doLHSVar (env, []) ys
369                                val exp = T.E_Op(rator, List.map (useVar env) xs)
370                                val stm = T.S_Assign(ys, exp)
371                                in
372                                  doNode (env, ifStk, stm :: stms, !succ)
373                                end
374                          in
375                            case rator
376                             of Op.Print _ => if Target.supportsPrinting()
377                                  then doit ()
378                                  else doNode (env, ifStk, stms, !succ)
379                              | _ => doit()
380                            (* end case *)
381                          end
382                    | IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented"                    | IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented"
383                      | IL.SAVE{lhs, rhs, succ, ...} => let
384                          val stm = T.S_Save([getStateVar lhs], useVar env rhs)
385                          in
386                            doNode (env, ifStk, stm::stms, !succ)
387                          end
388                    | k as IL.EXIT{kind, live, ...} => (case kind                    | k as IL.EXIT{kind, live, ...} => (case kind
389                         of ExitKind.FRAGMENT =>                         of ExitKind.FRAGMENT =>
390                              endScope (env, prefix @ List.revAppend(stms, finish env))                              endScope (env, prefix @ List.revAppend(stms, finish env))
391                          | ExitKind.SINIT => let                          | ExitKind.SINIT => let
392  (* FIXME: we should probably call flushPending here! *)  (* FIXME: we should probably call flushPending here! *)
393                              val suffix = finish env @ [T.S_Exit(List.map (useVar env) live)]                              val suffix = finish env @ [T.S_Exit[]]
394                              in                              in
395                                endScope (env, prefix @ List.revAppend(stms, suffix))                                endScope (env, prefix @ List.revAppend(stms, suffix))
396                              end                              end
# Line 354  Line 402 
402                              end                              end
403                          | ExitKind.ACTIVE => let                          | ExitKind.ACTIVE => let
404  (* FIXME: we should probably call flushPending here! *)  (* FIXME: we should probably call flushPending here! *)
405                              val suffix = finish env @ [T.S_Active(List.map (useVar env) live)]                              val suffix = finish env @ [T.S_Active]
406                              in                              in
407                                endScope (env, prefix @ List.revAppend(stms, suffix))                                endScope (env, prefix @ List.revAppend(stms, suffix))
408                              end                              end
409                          | ExitKind.STABILIZE => let                          | ExitKind.STABILIZE => let
410  (* FIXME: we should probably call flushPending here! *)  (* FIXME: we should probably call flushPending here! *)
411                              val stms = T.S_Stabilize(List.map (useVar env) live) :: stms                              val stms = T.S_Stabilize :: stms
412                              in                              in
413  (* FIXME: we should probably call flushPending here! *)  (* FIXME: we should probably call flushPending here! *)
414                                join (env, ifStk, stms, k)                                join (env, ifStk, stms, k)
# Line 392  Line 440 
440              args = List.map (useVar env) args              args = List.map (useVar env) args
441            } end            } end
442    
443      fun trMethod (env, stateVars) (IL.Method{name, stateIn, body}) = let      fun trMethod env (IL.Method{name, body}) = T.Method{
444            fun bindStateVar (x, T.SV{var, ...}, (env, stms)) = let              name = name,
445                  val (env, stms') = bindLocal(env, x, T.E_Var var)              body = trCFG (env, [], fn _ => [], body)
446                  in            }
                   (env, stms' @ stms)  
                 end  
           val (env, stms) = ListPair.foldrEq bindStateVar (env, []) (stateIn, stateVars)  
           in  
             T.Method{name = name, body = trCFG (env, stms, fn _ => [], body)}  
           end  
447    
448      fun trStrand env (IL.Strand{name, params, state, stateInit, methods}) = let      fun trStrand globalEnv (IL.Strand{name, params, state, stateInit, methods}) = let
449            val params' = List.map newParam params            val params' = List.map newParam params
450            val env = ListPair.foldlEq (fn (x, x', env) => rename(env, x, x')) env (params, params')            val env = ListPair.foldlEq (fn (x, x', env) => rename(env, x, x')) globalEnv (params, params')
           val stateVars = let  
                 fun cvtVar (isOut, x) = T.SV{  
                         varying = (case VA.varScope x  
                            of VA.StrandConstState => false  
                             | VA.StrandState => true  
                             | s => raise Fail(concat[  
                                   "state variable ", IL.Var.toString x,  
                                   " has bogus scope annotation ", VA.scopeToString s  
                                 ])  
                           (* end case *)),  
                         output = isOut, var = newStateVar(name, x)  
                       }  
                 in  
                   List.map cvtVar state  
                 end  
451            in            in
452              T.Strand{              T.Strand{
453                  name = name,                  name = name,
454                  params = params',                  params = params',
455                  state = stateVars,                  state = List.map getStateVar state,
456                  stateInit = trCFG (env, [], fn _ => [], stateInit),                  stateInit = trCFG (env, [], fn _ => [], stateInit),
457                  methods = List.map (trMethod(env, stateVars)) methods                  methods = List.map (trMethod env) methods
458                }                }
459            end            end
460    
     fun checkProps strands = let  
           val hasDie = ref false  
           val hasNew = ref false  
           fun chkStm e = (case e  
                  of T.S_IfThen(_, b) => chkBlk b  
                   | T.S_IfThenElse(_, b1, b2) => (chkBlk b1; chkBlk b2)  
                   | T.S_New _ => (hasNew := true)  
                   | T.S_Die => (hasDie := true)  
                   | _ => ()  
               (* end case *))  
           and chkBlk (T.Block{body, ...}) = List.app chkStm body  
           fun chkStrand (T.Strand{stateInit, methods, ...}) = let  
                 fun chkMeth (T.Method{body, ...}) = chkBlk body  
                 in  
                   chkBlk stateInit;  
                   List.app chkMeth methods  
                 end  
           fun condCons (x, v, l) = if !x then v::l else l  
           in  
             List.app chkStrand strands;  
             condCons (hasDie, T.StrandsMayDie,  
             condCons (hasNew, T.NewStrands, []))  
           end  
   
461    (* split the globalInit into the part that specifies the inputs and the rest of    (* split the globalInit into the part that specifies the inputs and the rest of
462     * the global initialization.     * the global initialization.
463     *)     *)
# Line 494  Line 497 
497    
498      fun translate prog = let      fun translate prog = let
499          (* first we do a variable analysis pass on the Low IL *)          (* first we do a variable analysis pass on the Low IL *)
500            val prog as IL.Program{globalInit, initially, strands} = VA.optimize prog            val prog as IL.Program{props, globalInit, initially, strands} = VA.optimize prog
501  (* FIXME: here we should do a contraction pass to eliminate unused variables that VA may have created *)  (* FIXME: here we should do a contraction pass to eliminate unused variables that VA may have created *)
502            val _ = (* DEBUG *)            val _ = (* DEBUG *)
503                  LowPP.output (Log.logFile(), "LowIL after variable analysis", prog)                  LowPP.output (Log.logFile(), "LowIL after variable analysis", prog)
# Line 506  Line 509 
509            val strands = List.map (trStrand env) strands            val strands = List.map (trStrand env) strands
510            in            in
511              T.Program{              T.Program{
512                  props = checkProps strands,                  props = props,
513                  globals = globals,                  globals = globals,
514                  inputInit = trCFG (env, [], fn _ => [], inputInit),                  inputInit = trCFG (env, [], fn _ => [], inputInit),
515                  globalInit = trCFG (env, [], fn _ => [], globalInit),                  globalInit = trCFG (env, [], fn _ => [], globalInit),

Legend:
Removed from v.1301  
changed lines
  Added in v.1640

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